Skip to contentSkip to conversation

nestedsvm: fix VMEXIT emulation

PATCH In review Christoph Egger 2 participants 2 messages Oct 17, 2012 – Oct 22, 2012

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nestedsvm: fix VMEXIT emulation

Values in regs can be newer than those in the shadow vmcb (e.g. due to an instruction emulation right before). So use the values from regs.

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
xen/arch/x86/hvm/svm/nestedsvm.c +11 -6
diff -r 6b73078a4403 xen/arch/x86/hvm/svm/nestedsvm.c
@@ -990,7 +999,7 @@ nsvm_vmcb_guest_intercepts_trap(struct v
 }
 
 static int
-nsvm_vmcb_prepare4vmexit(struct vcpu *v)
+nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct cpu_user_regs *regs)
 {
     struct nestedvcpu *nv = &vcpu_nestedhvm(v);
     struct nestedsvm *svm = &vcpu_nestedsvm(v);
@@ -1114,17 +1123,22 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v)
     ns_vmcb->_dr7 = n2vmcb->_dr7;
     ns_vmcb->_dr6 = n2vmcb->_dr6;
 
+    /* Restore registers from regs as those values
+     * can be newer than in n2vmcb (e.g. due to an
+     * instruction emulation right before).
+     */
+
     /* RFLAGS */
-    ns_vmcb->rflags = n2vmcb->rflags;
+    ns_vmcb->rflags = n2vmcb->rflags = regs->rflags;
 
     /* RIP */
-    ns_vmcb->rip = n2vmcb->rip;
+    ns_vmcb->rip = n2vmcb->rip = regs->rip;
 
     /* RSP */
-    ns_vmcb->rsp = n2vmcb->rsp;
+    ns_vmcb->rsp = n2vmcb->rsp = regs->rsp;
 
     /* RAX */
-    ns_vmcb->rax = n2vmcb->rax;
+    ns_vmcb->rax = n2vmcb->rax = regs->rax;
 
     /* Keep the l2 guest values of the fs, gs, ldtr, tr, kerngsbase,
      * star, lstar, cstar, sfmask, sysenter_cs, sysenter_esp,
@@ -1358,7 +1372,7 @@ nestedsvm_vmexit_n2n1(struct vcpu *v, st
     ASSERT(vcpu_nestedhvm(v).nv_vmswitch_in_progress);
     ASSERT(nestedhvm_vcpu_in_guestmode(v));
 
-    rc = nsvm_vmcb_prepare4vmexit(v);
+    rc = nsvm_vmcb_prepare4vmexit(v, regs);
     if (rc)
         ret = NESTEDHVM_VMEXIT_ERROR;
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

Acked-by on v1 1/1
#1 lore raw
Quoted 6 lines · Christoph Egger

Values in regs can be newer than those in the shadow vmcb (e.g. due to an instruction emulation right before). So use the values from regs.

Content-Description: xen_nh_vmexit.diff

Quoted 53 lines

diff -r 6b73078a4403 xen/arch/x86/hvm/svm/nestedsvm.c

xen/arch/x86/hvm/svm/nestedsvm.c +11 -6
@@ -990,7 +999,7 @@ nsvm_vmcb_guest_intercepts_trap(struct v
 }
 
 static int
-nsvm_vmcb_prepare4vmexit(struct vcpu *v)
+nsvm_vmcb_prepare4vmexit(struct vcpu *v, struct cpu_user_regs *regs)
 {
     struct nestedvcpu *nv = &vcpu_nestedhvm(v);
     struct nestedsvm *svm = &vcpu_nestedsvm(v);
@@ -1114,17 +1123,22 @@ nsvm_vmcb_prepare4vmexit(struct vcpu *v)
     ns_vmcb->_dr7 = n2vmcb->_dr7;
     ns_vmcb->_dr6 = n2vmcb->_dr6;
 
+    /* Restore registers from regs as those values
+     * can be newer than in n2vmcb (e.g. due to an
+     * instruction emulation right before).
+     */
+
     /* RFLAGS */
-    ns_vmcb->rflags = n2vmcb->rflags;
+    ns_vmcb->rflags = n2vmcb->rflags = regs->rflags;
 
     /* RIP */
-    ns_vmcb->rip = n2vmcb->rip;
+    ns_vmcb->rip = n2vmcb->rip = regs->rip;
 
     /* RSP */
-    ns_vmcb->rsp = n2vmcb->rsp;
+    ns_vmcb->rsp = n2vmcb->rsp = regs->rsp;
 
     /* RAX */
-    ns_vmcb->rax = n2vmcb->rax;
+    ns_vmcb->rax = n2vmcb->rax = regs->rax;
 
     /* Keep the l2 guest values of the fs, gs, ldtr, tr, kerngsbase,
      * star, lstar, cstar, sfmask, sysenter_cs, sysenter_esp,
@@ -1358,7 +1372,7 @@ nestedsvm_vmexit_n2n1(struct vcpu *v, st
     ASSERT(vcpu_nestedhvm(v).nv_vmswitch_in_progress);
     ASSERT(nestedhvm_vcpu_in_guestmode(v));
 
-    rc = nsvm_vmcb_prepare4vmexit(v);
+    rc = nsvm_vmcb_prepare4vmexit(v, regs);
     if (rc)
         ret = NESTEDHVM_VMEXIT_ERROR;
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel