Merge tag 'kvm-arm-for-4.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-master

KVM/ARM changes for 4.3-rc2

- Fix timer interrupt injection after the rework
  that went in during the merge window
- Reset the timer to zero on reboot
- Make sure the TCR_EL2 RES1 bits are really set to 1
- Fix a PSCI affinity bug for non-existing vcpus
This commit is contained in:
Paolo Bonzini
2015-09-14 17:07:35 +02:00
4 changed files with 49 additions and 23 deletions

View File

@@ -199,6 +199,14 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
*/
timer->irq = irq;
/*
* The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8
* and to 0 for ARMv7. We provide an implementation that always
* resets the timer to be disabled and unmasked and is compliant with
* the ARMv7 architecture.
*/
timer->cntv_ctl = 0;
/*
* Tell the VGIC that the virtual interrupt is tied to a
* physical interrupt. We do that once per VCPU.

View File

@@ -1144,26 +1144,11 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
struct irq_phys_map *map;
map = vgic_irq_map_search(vcpu, irq);
/*
* If we have a mapping, and the virtual interrupt is
* being injected, then we must set the state to
* active in the physical world. Otherwise the
* physical interrupt will fire and the guest will
* exit before processing the virtual interrupt.
*/
if (map) {
int ret;
BUG_ON(!map->active);
vlr.hwirq = map->phys_irq;
vlr.state |= LR_HW;
vlr.state &= ~LR_EOI_INT;
ret = irq_set_irqchip_state(map->irq,
IRQCHIP_STATE_ACTIVE,
true);
WARN_ON(ret);
/*
* Make sure we're not going to sample this
* again, as a HW-backed interrupt cannot be
@@ -1255,7 +1240,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
unsigned long *pa_percpu, *pa_shared;
int i, vcpu_id;
int i, vcpu_id, lr, ret;
int overflow = 0;
int nr_shared = vgic_nr_shared_irqs(dist);
@@ -1310,6 +1295,31 @@ epilog:
*/
clear_bit(vcpu_id, dist->irq_pending_on_cpu);
}
for (lr = 0; lr < vgic->nr_lr; lr++) {
struct vgic_lr vlr;
if (!test_bit(lr, vgic_cpu->lr_used))
continue;
vlr = vgic_get_lr(vcpu, lr);
/*
* If we have a mapping, and the virtual interrupt is
* presented to the guest (as pending or active), then we must
* set the state to active in the physical world. See
* Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt.
*/
if (vlr.state & LR_HW) {
struct irq_phys_map *map;
map = vgic_irq_map_search(vcpu, vlr.irq);
ret = irq_set_irqchip_state(map->irq,
IRQCHIP_STATE_ACTIVE,
true);
WARN_ON(ret);
}
}
}
static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)