]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/x86/kvm/svm.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[linux.git] / arch / x86 / kvm / svm.c
index fb23497cf91574dcba962b3a7f5cb533619a3db5..1107626938ccff4f26da130f8b570928ca7c8efb 100644 (file)
@@ -2423,15 +2423,29 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
        if (!is_guest_mode(&svm->vcpu))
                return 0;
 
+       vmexit = nested_svm_intercept(svm);
+       if (vmexit != NESTED_EXIT_DONE)
+               return 0;
+
        svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
        svm->vmcb->control.exit_code_hi = 0;
        svm->vmcb->control.exit_info_1 = error_code;
-       svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
 
-       vmexit = nested_svm_intercept(svm);
-       if (vmexit == NESTED_EXIT_DONE)
-               svm->nested.exit_required = true;
+       /*
+        * FIXME: we should not write CR2 when L1 intercepts an L2 #PF exception.
+        * The fix is to add the ancillary datum (CR2 or DR6) to structs
+        * kvm_queued_exception and kvm_vcpu_events, so that CR2 and DR6 can be
+        * written only when inject_pending_event runs (DR6 would written here
+        * too).  This should be conditional on a new capability---if the
+        * capability is disabled, kvm_multiple_exception would write the
+        * ancillary information to CR2 or DR6, for backwards ABI-compatibility.
+        */
+       if (svm->vcpu.arch.exception.nested_apf)
+               svm->vmcb->control.exit_info_2 = svm->vcpu.arch.apf.nested_apf_token;
+       else
+               svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
 
+       svm->nested.exit_required = true;
        return vmexit;
 }
 
@@ -2653,7 +2667,7 @@ static int nested_svm_intercept(struct vcpu_svm *svm)
                }
                /* async page fault always cause vmexit */
                else if ((exit_code == SVM_EXIT_EXCP_BASE + PF_VECTOR) &&
-                        svm->vcpu.arch.apf.host_apf_reason != 0)
+                        svm->vcpu.arch.exception.nested_apf != 0)
                        vmexit = NESTED_EXIT_DONE;
                break;
        }