diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0007-KVM-x86-ioapic-Fix-level-triggered-EOI-and-IOAPIC-re.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0007-KVM-x86-ioapic-Fix-level-triggered-EOI-and-IOAPIC-re.patch | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0007-KVM-x86-ioapic-Fix-level-triggered-EOI-and-IOAPIC-re.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0007-KVM-x86-ioapic-Fix-level-triggered-EOI-and-IOAPIC-re.patch new file mode 100644 index 00000000..2ca432cf --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0007-KVM-x86-ioapic-Fix-level-triggered-EOI-and-IOAPIC-re.patch @@ -0,0 +1,72 @@ +From 34cbfb000e9bd72eb48fb3d1e61be034053f743f Mon Sep 17 00:00:00 2001 +From: Nikita Leshenko <nikita.leshchenko@oracle.com> +Date: Sun, 5 Nov 2017 15:52:29 +0200 +Subject: [PATCH 07/33] KVM: x86: ioapic: Fix level-triggered EOI and IOAPIC + reconfigure race +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 0fc5a36dd6b345eb0d251a65c236e53bead3eef7 ] + +KVM uses ioapic_handled_vectors to track vectors that need to notify the +IOAPIC on EOI. The problem is that IOAPIC can be reconfigured while an +interrupt with old configuration is pending or running and +ioapic_handled_vectors only remembers the newest configuration; +thus EOI from the old interrupt is not delievered to the IOAPIC. + +A previous commit db2bdcbbbd32 +("KVM: x86: fix edge EOI and IOAPIC reconfig race") +addressed this issue by adding pending edge-triggered interrupts to +ioapic_handled_vectors, fixing this race for edge-triggered interrupts. +The commit explicitly ignored level-triggered interrupts, +but this race applies to them as well: + +1) IOAPIC sends a level triggered interrupt vector to VCPU0 +2) VCPU0's handler deasserts the irq line and reconfigures the IOAPIC + to route the vector to VCPU1. The reconfiguration rewrites only the + upper 32 bits of the IOREDTBLn register. (Causes KVM to update + ioapic_handled_vectors for VCPU0 and it no longer includes the vector.) +3) VCPU0 sends EOI for the vector, but it's not delievered to the + IOAPIC because the ioapic_handled_vectors doesn't include the vector. +4) New interrupts are not delievered to VCPU1 because remote_irr bit + is set forever. + +Therefore, the correct behavior is to add all pending and running +interrupts to ioapic_handled_vectors. + +This commit introduces a slight performance hit similar to +commit db2bdcbbbd32 ("KVM: x86: fix edge EOI and IOAPIC reconfig race") +for the rare case that the vector is reused by a non-IOAPIC source on +VCPU0. We prefer to keep solution simple and not handle this case just +as the original commit does. + +Fixes: db2bdcbbbd32 ("KVM: x86: fix edge EOI and IOAPIC reconfig race") + +Signed-off-by: Nikita Leshenko <nikita.leshchenko@oracle.com> +Reviewed-by: Liran Alon <liran.alon@oracle.com> +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> +Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + arch/x86/kvm/ioapic.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c +index 6e219e5..a7ac868 100644 +--- a/arch/x86/kvm/ioapic.c ++++ b/arch/x86/kvm/ioapic.c +@@ -257,8 +257,7 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors) + index == RTC_GSI) { + if (kvm_apic_match_dest(vcpu, NULL, 0, + e->fields.dest_id, e->fields.dest_mode) || +- (e->fields.trig_mode == IOAPIC_EDGE_TRIG && +- kvm_apic_pending_eoi(vcpu, e->fields.vector))) ++ kvm_apic_pending_eoi(vcpu, e->fields.vector)) + __set_bit(e->fields.vector, + ioapic_handled_vectors); + } +-- +2.7.4 + |