aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.9.21/0007-KVM-x86-ioapic-Fix-level-triggered-EOI-and-IOAPIC-re.patch
diff options
context:
space:
mode:
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.patch72
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
+