[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Clean-up hvm/shadow interaction around cr3 updates.



# HG changeset patch
# User Steven Hand <steven@xxxxxxxxxxxxx>
# Node ID 6cbed96fedacc9fd495c1491a36319a11b00d364
# Parent  ea12d26877a4df03eb67f82995ace666fc7260e8
Clean-up hvm/shadow interaction around cr3 updates.

Signed-off-by: Steven Hand <steven@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c          |    6 ++++++
 xen/arch/x86/hvm/svm/svm.c      |   12 ++++++------
 xen/arch/x86/hvm/vmx/vmcs.c     |    6 ++----
 xen/arch/x86/hvm/vmx/vmx.c      |   30 +++++++++++++++++-------------
 xen/arch/x86/mm/shadow/common.c |    4 +++-
 xen/arch/x86/mm/shadow/multi.c  |    6 +++---
 xen/include/asm-x86/hvm/hvm.h   |    7 +++++++
 7 files changed, 44 insertions(+), 27 deletions(-)

diff -r ea12d26877a4 -r 6cbed96fedac xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Fri Dec 15 11:47:24 2006 +0000
@@ -535,6 +535,12 @@ void hvm_do_hypercall(struct cpu_user_re
 }
 
 #endif /* defined(__x86_64__) */
+
+void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3)
+{
+    v->arch.hvm_vcpu.hw_cr3 = guest_cr3;
+    hvm_funcs.update_guest_cr3(v);
+}
 
 /* Initialise a hypercall transfer page for a VMX domain using
    paravirtualised drivers. */
diff -r ea12d26877a4 -r 6cbed96fedac xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Fri Dec 15 11:47:24 2006 +0000
@@ -498,6 +498,11 @@ void svm_update_host_cr3(struct vcpu *v)
     /* SVM doesn't have a HOST_CR3 equivalent to update. */
 }
 
+void svm_update_guest_cr3(struct vcpu *v)
+{
+    v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
+}
+
 unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
 {
     switch ( num )
@@ -883,6 +888,7 @@ int start_svm(void)
     hvm_funcs.get_segment_register = svm_get_segment_register;
 
     hvm_funcs.update_host_cr3 = svm_update_host_cr3;
+    hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
     
     hvm_funcs.stts = svm_stts;
     hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
@@ -1608,7 +1614,6 @@ static int svm_set_cr0(unsigned long val
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx", 
                     (unsigned long) (mfn << PAGE_SHIFT));
 
-        vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
         set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
     }
 
@@ -1630,7 +1635,6 @@ static int svm_set_cr0(unsigned long val
             return 0;
         }
         shadow_update_paging_modes(v);
-        vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
         set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
     }
     else if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PE )
@@ -1642,7 +1646,6 @@ static int svm_set_cr0(unsigned long val
         }
         /* we should take care of this kind of situation */
         shadow_update_paging_modes(v);
-        vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
         set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
     }
 
@@ -1768,7 +1771,6 @@ static int mov_to_cr(int gpreg, int cr, 
 
             v->arch.hvm_svm.cpu_cr3 = value;
             update_cr3(v);
-            vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
             HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
         }
         break;
@@ -1803,8 +1805,6 @@ static int mov_to_cr(int gpreg, int cr, 
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                             (unsigned long) (mfn << PAGE_SHIFT));
-
-                vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
 
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, 
                             "Update CR3 value = %lx, mfn = %lx",
diff -r ea12d26877a4 -r 6cbed96fedac xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Fri Dec 15 11:47:24 2006 +0000
@@ -430,11 +430,9 @@ static void construct_vmcs(struct vcpu *
     __vmwrite(GUEST_TR_BASE, 0);
     __vmwrite(GUEST_TR_LIMIT, 0xff);
 
-    shadow_update_paging_modes(v);
-    __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
-    __vmwrite(HOST_CR3, v->arch.cr3);
-
     vmx_vmcs_exit(v);
+
+    shadow_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
 }
 
 int vmx_create_vmcs(struct vcpu *v)
diff -r ea12d26877a4 -r 6cbed96fedac xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Dec 15 11:47:24 2006 +0000
@@ -708,12 +708,22 @@ static int vmx_pae_enabled(struct vcpu *
     return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
 }
 
-/* Works only for vcpu == current */
 static void vmx_update_host_cr3(struct vcpu *v)
 {
-    ASSERT(v == current);
+    ASSERT( (v == current) || !vcpu_runnable(v) );
+    vmx_vmcs_enter(v);
     __vmwrite(HOST_CR3, v->arch.cr3);
-}
+    vmx_vmcs_exit(v);
+}
+
+static void vmx_update_guest_cr3(struct vcpu *v)
+{
+    ASSERT( (v == current) || !vcpu_runnable(v) );
+    vmx_vmcs_enter(v);
+    __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
+    vmx_vmcs_exit(v);
+}
+
 
 static void vmx_inject_exception(
     unsigned int trapnr, int errcode, unsigned long cr2)
@@ -747,6 +757,7 @@ static void vmx_setup_hvm_funcs(void)
     hvm_funcs.get_segment_register = vmx_get_segment_register;
 
     hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
+    hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
 
     hvm_funcs.stts = vmx_stts;
     hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
@@ -1531,7 +1542,6 @@ static int vmx_world_restore(struct vcpu
     __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
 
     shadow_update_paging_modes(v);
-    __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
     return 0;
 
  bad_cr3:
@@ -1689,7 +1699,6 @@ static int vmx_set_cr0(unsigned long val
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                     (unsigned long) (mfn << PAGE_SHIFT));
 
-        __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
         /*
          * arch->shadow_table should hold the next CR3 for shadow
          */
@@ -1761,7 +1770,6 @@ static int vmx_set_cr0(unsigned long val
             __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
         }
         shadow_update_paging_modes(v);
-        __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
     }
 
     return 1;
@@ -1869,9 +1877,7 @@ static int mov_to_cr(int gp, int cr, str
              */
             v->arch.hvm_vmx.cpu_cr3 = value;
             update_cr3(v);
-            HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx",
-                        value);
-            __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
+            HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
         }
         break;
 
@@ -1902,13 +1908,11 @@ static int mov_to_cr(int gp, int cr, str
                 HVM_DBG_LOG(DBG_LEVEL_VMMU, "New arch.guest_table = %lx",
                             (unsigned long) (mfn << PAGE_SHIFT));
 
-                __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
-
                 /*
                  * arch->shadow_table should hold the next CR3 for shadow
                  */
-
-                HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx, mfn = 
%lx",
+                HVM_DBG_LOG(DBG_LEVEL_VMMU, 
+                            "Update CR3 value = %lx, mfn = %lx",
                             v->arch.hvm_vmx.cpu_cr3, mfn);
 #endif
             }
diff -r ea12d26877a4 -r 6cbed96fedac xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/arch/x86/mm/shadow/common.c   Fri Dec 15 11:47:24 2006 +0000
@@ -2495,7 +2495,9 @@ void sh_update_paging_modes(struct vcpu 
         {
             mfn_t mmfn = shadow_make_monitor_table(v);
             v->arch.monitor_table = pagetable_from_mfn(mmfn);
-        } 
+            make_cr3(v, mfn_x(mmfn));
+            hvm_update_host_cr3(v);
+        }
 
         if ( v->arch.shadow.mode != old_mode )
         {
diff -r ea12d26877a4 -r 6cbed96fedac xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c    Fri Dec 15 11:47:24 2006 +0000
@@ -2817,7 +2817,7 @@ static int sh_page_fault(struct vcpu *v,
 
     if ( is_hvm_domain(d) )
         hvm_store_cpu_guest_regs(v, regs, NULL);
-    SHADOW_PRINTK("emulate: eip=%#lx\n", regs->eip);
+    SHADOW_PRINTK("emulate: eip=%#lx\n", (unsigned long)regs->eip);
 
     emul_ops = shadow_init_emulation(&emul_ctxt, regs);
 
@@ -3561,10 +3561,10 @@ sh_update_cr3(struct vcpu *v)
         ASSERT(is_hvm_domain(d));
 #if SHADOW_PAGING_LEVELS == 3
         /* 2-on-3 or 3-on-3: Use the PAE shadow l3 table we just fabricated */
-        v->arch.hvm_vcpu.hw_cr3 = virt_to_maddr(&v->arch.shadow.l3table);
+        hvm_update_guest_cr3(v, virt_to_maddr(&v->arch.shadow.l3table));
 #else
         /* 2-on-2 or 4-on-4: Just use the shadow top-level directly */
-        v->arch.hvm_vcpu.hw_cr3 = pagetable_get_paddr(v->arch.shadow_table[0]);
+        hvm_update_guest_cr3(v, pagetable_get_paddr(v->arch.shadow_table[0]));
 #endif
     }
 
diff -r ea12d26877a4 -r 6cbed96fedac xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Fri Dec 15 11:33:50 2006 +0000
+++ b/xen/include/asm-x86/hvm/hvm.h     Fri Dec 15 11:47:24 2006 +0000
@@ -103,6 +103,11 @@ struct hvm_function_table {
     void (*update_host_cr3)(struct vcpu *v);
 
     /*
+     * Called to inform HVM layer that a guest cr3 has changed
+     */
+    void (*update_guest_cr3)(struct vcpu *v);
+
+    /*
      * Update specifics of the guest state:
      * 1) TS bit in guest cr0 
      * 2) TSC offset in guest
@@ -187,6 +192,8 @@ hvm_update_host_cr3(struct vcpu *v)
 {
     hvm_funcs.update_host_cr3(v);
 }
+
+void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
 
 void hvm_hypercall_page_initialise(struct domain *d,
                                    void *hypercall_page);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.