diff options
author | Paolo Bonzini | 2019-08-09 16:53:50 +0200 |
---|---|---|
committer | Paolo Bonzini | 2019-08-09 16:53:50 +0200 |
commit | a738b5e75b4c13be3485c82eb62c30047aa9f164 (patch) | |
tree | f47fca53ee79938be283e13cf5d48def68f9dad2 /virt/kvm/arm/vgic/vgic-mmio.c | |
parent | Merge tag 'kvmarm-fixes-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel... (diff) | |
parent | KVM: arm/arm64: vgic: Reevaluate level sensitive interrupts on enable (diff) | |
download | kernel-qcow2-linux-a738b5e75b4c13be3485c82eb62c30047aa9f164.tar.gz kernel-qcow2-linux-a738b5e75b4c13be3485c82eb62c30047aa9f164.tar.xz kernel-qcow2-linux-a738b5e75b4c13be3485c82eb62c30047aa9f164.zip |
Merge tag 'kvmarm-fixes-for-5.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm fixes for 5.3, take #2
- Fix our system register reset so that we stop writing
non-sensical values to them, and track which registers
get reset instead.
- Sync VMCR back from the GIC on WFI so that KVM has an
exact vue of PMR.
- Reevaluate state of HW-mapped, level triggered interrupts
on enable.
Diffstat (limited to 'virt/kvm/arm/vgic/vgic-mmio.c')
-rw-r--r-- | virt/kvm/arm/vgic/vgic-mmio.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c index 3ba7278fb533..44efc2ff863f 100644 --- a/virt/kvm/arm/vgic/vgic-mmio.c +++ b/virt/kvm/arm/vgic/vgic-mmio.c @@ -113,6 +113,22 @@ void vgic_mmio_write_senable(struct kvm_vcpu *vcpu, struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); + if (vgic_irq_is_mapped_level(irq)) { + bool was_high = irq->line_level; + + /* + * We need to update the state of the interrupt because + * the guest might have changed the state of the device + * while the interrupt was disabled at the VGIC level. + */ + irq->line_level = vgic_get_phys_line_level(irq); + /* + * Deactivate the physical interrupt so the GIC will let + * us know when it is asserted again. + */ + if (!irq->active && was_high && !irq->line_level) + vgic_irq_set_phys_active(irq, false); + } irq->enabled = true; vgic_queue_irq_unlock(vcpu->kvm, irq, flags); |