]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.38 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 5 May 2011 23:00:27 +0000 (16:00 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 5 May 2011 23:00:27 +0000 (16:00 -0700)
queue-2.6.38/kvm-svm-check-for-progress-after-iret-interception.patch [new file with mode: 0644]
queue-2.6.38/series

diff --git a/queue-2.6.38/kvm-svm-check-for-progress-after-iret-interception.patch b/queue-2.6.38/kvm-svm-check-for-progress-after-iret-interception.patch
new file mode 100644 (file)
index 0000000..64bd35a
--- /dev/null
@@ -0,0 +1,63 @@
+From bd3d1ec3d26b61120bb4f60b18ee99aa81839e6b Mon Sep 17 00:00:00 2001
+From: Avi Kivity <avi@redhat.com>
+Date: Thu, 3 Feb 2011 15:29:52 +0200
+Subject: KVM: SVM: check for progress after IRET interception
+
+From: Avi Kivity <avi@redhat.com>
+
+commit bd3d1ec3d26b61120bb4f60b18ee99aa81839e6b upstream.
+
+When we enable an NMI window, we ask for an IRET intercept, since
+the IRET re-enables NMIs.  However, the IRET intercept happens before
+the instruction executes, while the NMI window architecturally opens
+afterwards.
+
+To compensate for this mismatch, we only open the NMI window in the
+following exit, assuming that the IRET has by then executed; however,
+this assumption is not always correct; we may exit due to a host interrupt
+or page fault, without having executed the instruction.
+
+Fix by checking for forward progress by recording and comparing the IRET's
+rip.  This is somewhat of a hack, since an unchaging rip does not mean that
+no forward progress has been made, but is the simplest fix for now.
+
+Signed-off-by: Avi Kivity <avi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kvm/svm.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -135,6 +135,8 @@ struct vcpu_svm {
+       u32 *msrpm;
++      ulong nmi_iret_rip;
++
+       struct nested_state nested;
+       bool nmi_singlestep;
+@@ -2653,6 +2655,7 @@ static int iret_interception(struct vcpu
+       ++svm->vcpu.stat.nmi_window_exits;
+       clr_intercept(svm, INTERCEPT_IRET);
+       svm->vcpu.arch.hflags |= HF_IRET_MASK;
++      svm->nmi_iret_rip = kvm_rip_read(&svm->vcpu);
+       return 1;
+ }
+@@ -3474,7 +3477,12 @@ static void svm_complete_interrupts(stru
+       svm->int3_injected = 0;
+-      if (svm->vcpu.arch.hflags & HF_IRET_MASK) {
++      /*
++       * If we've made progress since setting HF_IRET_MASK, we've
++       * executed an IRET and can allow NMI injection.
++       */
++      if ((svm->vcpu.arch.hflags & HF_IRET_MASK)
++          && kvm_rip_read(&svm->vcpu) != svm->nmi_iret_rip) {
+               svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK);
+               kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
+       }
index 572440ad8e79e6fd41ca7195e5c885dfc659e0c1..0611b4f66515103a7581393b8cf2c6f8e92508ee 100644 (file)
@@ -34,3 +34,4 @@ open-with-o_creat-flag-set-fails-to-open-existing-files-on-non-writable-director
 can-add-missing-socket-check-in-can-bcm-release.patch
 fs-partitions-ldm.c-fix-oops-caused-by-corrupted-partition-table.patch
 cx88-fix-hvr4000-ir-keymap.patch
+kvm-svm-check-for-progress-after-iret-interception.patch