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

[Xen-changelog] More fixes to gdbserver for HVM guest debugging. Also fix



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID f0e14b4e535c7d99c56c286384b0d512c5220884
# Parent  6cb5928fa0268884adab1b72fb921cb3a5187bd6
More fixes to gdbserver for HVM guest debugging. Also fix
writing back of register state for HVM guests.

From: Nitin A Kamble <nitin.a.kamble@xxxxxxxxx>

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 6cb5928fa026 -r f0e14b4e535c tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c   Thu Mar 30 13:31:57 2006
+++ b/tools/libxc/xc_ptrace.c   Thu Mar 30 13:37:22 2006
@@ -153,190 +153,58 @@
 }
 
 /* --------------------- */
+/* XXX application state */
+static long                     nr_pages = 0;
+static unsigned long           *page_array = NULL;
 
 static void *
-map_domain_va_pae(
+map_domain_va_32(
     int xc_handle,
     int cpu,
     void *guest_va,
     int perm)
 {
-    unsigned long l2p, l1p, p, va = (unsigned long)guest_va;
-    uint64_t *l3, *l2, *l1;
-    static void *v;
-
-    if (fetch_regs(xc_handle, cpu, NULL))
-        return NULL;
-
-    l3 = xc_map_foreign_range(
-        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
-    if ( l3 == NULL )
-        return NULL;
-
-    l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
-    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
-    if ( l2 == NULL )
-        return NULL;
-
-    l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
-    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
-    if ( l1 == NULL )
-        return NULL;
-
-    p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
-    if ( v != NULL )
-        munmap(v, PAGE_SIZE);
-    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
-    if ( v == NULL )
-        return NULL;
-
-    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
-}
-
-#ifdef __x86_64__
-static void *
-map_domain_va(
-    int xc_handle,
-    int cpu,
-    void *guest_va,
-    int perm)
-{
-    unsigned long l3p, l2p, l1p, p, va = (unsigned long)guest_va;
-    uint64_t *l4, *l3, *l2, *l1;
-    static void *v;
-
-    if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
-        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
-
-    if (fetch_regs(xc_handle, cpu, NULL))
-        return NULL;
-
-    l4 = xc_map_foreign_range(
-        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
-    if ( l4 == NULL )
-        return NULL;
-
-    l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
-    l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l3p);
-    if ( l3 == NULL )
-        return NULL;
-
-    l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
-    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
-    if ( l2 == NULL )
-        return NULL;
-
-    l1p = l2[l2_table_offset(va)] >> PAGE_SHIFT;
-    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
-    if ( l1 == NULL )
-        return NULL;
-
-    p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
-    if ( v != NULL )
-        munmap(v, PAGE_SIZE);
-    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
-    if ( v == NULL )
-        return NULL;
-
-    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
-}
-#endif
-
-#ifdef __i386__
-/* XXX application state */
-static long                     nr_pages = 0;
-static unsigned long           *page_array = NULL;
-
-static void *
-map_domain_va(
-    int xc_handle,
-    int cpu,
-    void *guest_va,
-    int perm)
-{
-
     unsigned long pde, page;
     unsigned long va = (unsigned long)guest_va;
-    long npgs = xc_get_tot_pages(xc_handle, current_domid);
-
-
-    static uint32_t  cr3_phys[MAX_VIRT_CPUS];
-    static unsigned long *cr3_virt[MAX_VIRT_CPUS];
+
+    static unsigned long  cr3_phys[MAX_VIRT_CPUS];
+    static uint32_t *cr3_virt[MAX_VIRT_CPUS];
     static unsigned long  pde_phys[MAX_VIRT_CPUS];
-    static unsigned long *pde_virt[MAX_VIRT_CPUS];
+    static uint32_t *pde_virt[MAX_VIRT_CPUS];
     static unsigned long  page_phys[MAX_VIRT_CPUS];
-    static unsigned long *page_virt[MAX_VIRT_CPUS];    
+    static uint32_t *page_virt[MAX_VIRT_CPUS];    
     static int            prev_perm[MAX_VIRT_CPUS];
-    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE, MODE_64 } mode;
-
-    if ( mode == MODE_UNKNOWN )
+
+   if (ctxt[cpu].ctrlreg[3] == 0)
+       return NULL;
+   if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
     {
-        xen_capabilities_info_t caps;
-        (void)xc_version(xc_handle, XENVER_capabilities, caps);
-        if ( strstr(caps, "-x86_64") )
-            mode = MODE_64;
-        else if ( strstr(caps, "-x86_32p") )
-            mode = MODE_PAE;
-        else if ( strstr(caps, "-x86_32") ) 
-            mode = MODE_32;
-    }
-
-    if ( mode == MODE_PAE )
-        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
-
-    if ( nr_pages != npgs )
+        cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
+        if ( cr3_virt[cpu] )
+            munmap(cr3_virt[cpu], PAGE_SIZE);
+        cr3_virt[cpu] = xc_map_foreign_range(
+            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+            cr3_phys[cpu] >> PAGE_SHIFT);
+        if ( cr3_virt[cpu] == NULL )
+            return NULL;
+    }
+    if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
+        return NULL;
+    if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
+        pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
+    if ( pde != pde_phys[cpu] )
     {
-        if ( nr_pages > 0 )
-            free(page_array);
-        nr_pages = npgs;
-        if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
-        {
-            printf("Could not allocate memory\n");
+        pde_phys[cpu] = pde;
+        if ( pde_virt[cpu] )
+            munmap(pde_virt[cpu], PAGE_SIZE);
+        pde_virt[cpu] = xc_map_foreign_range(
+            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
+            pde_phys[cpu] >> PAGE_SHIFT);
+        if ( pde_virt[cpu] == NULL )
             return NULL;
-        }
-        if ( xc_get_pfn_list(xc_handle, current_domid,
-                             page_array, nr_pages) != nr_pages )
-        {
-            printf("Could not get the page frame list\n");
-            return NULL;
-        }
-    }
-
-    if (fetch_regs(xc_handle, cpu, NULL))
-        return NULL;
-
-    if (paging_enabled(&ctxt[cpu])) {
-       if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
-        {
-            cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
-            if ( cr3_virt[cpu] )
-                munmap(cr3_virt[cpu], PAGE_SIZE);
-            cr3_virt[cpu] = xc_map_foreign_range(
-                xc_handle, current_domid, PAGE_SIZE, PROT_READ,
-                cr3_phys[cpu] >> PAGE_SHIFT);
-            if ( cr3_virt[cpu] == NULL )
-                return NULL;
-        }
-        if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
-            return NULL;
-        if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
-            pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
-        if ( pde != pde_phys[cpu] )
-        {
-            pde_phys[cpu] = pde;
-            if ( pde_virt[cpu] )
-                munmap(pde_virt[cpu], PAGE_SIZE);
-            pde_virt[cpu] = xc_map_foreign_range(
-                xc_handle, current_domid, PAGE_SIZE, PROT_READ,
-                pde_phys[cpu] >> PAGE_SHIFT);
-            if ( pde_virt[cpu] == NULL )
-                return NULL;
-        }
-        if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
-            return NULL;
-    } else {
-        page = va;
-    }
+    }
+    if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
+        return NULL;
     if (ctxt[cpu].flags & VGCF_HVM_GUEST)
         page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
     if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
@@ -358,7 +226,180 @@
     return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
 }
 
+
+static void *
+map_domain_va_pae(
+    int xc_handle,
+    int cpu,
+    void *guest_va,
+    int perm)
+{
+    unsigned long l2p, l1p, p, va = (unsigned long)guest_va;
+    uint64_t *l3, *l2, *l1;
+    static void *v;
+
+    l3 = xc_map_foreign_range(
+        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] 
>> PAGE_SHIFT);
+    if ( l3 == NULL )
+        return NULL;
+
+    l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
+    l2p = page_array[l2p];
+    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
+    munmap(l3, PAGE_SIZE);
+    if ( l2 == NULL )
+        return NULL;
+
+    l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
+    l1p = page_array[l1p];
+    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
+    munmap(l2, PAGE_SIZE);
+    if ( l1 == NULL )
+        return NULL;
+
+    p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
+    p = page_array[p];
+    if ( v != NULL )
+        munmap(v, PAGE_SIZE);
+    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+    munmap(l1, PAGE_SIZE);
+    if ( v == NULL )
+        return NULL;
+
+    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+}
+
+#ifdef __x86_64__
+static void *
+map_domain_va_64(
+    int xc_handle,
+    int cpu,
+    void *guest_va,
+    int perm)
+{
+    unsigned long l3p, l2p, l1p, l1e, p, va = (unsigned long)guest_va;
+    uint64_t *l4, *l3, *l2, *l1;
+    static void *v;
+
+    if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
+        return map_domain_va_32(xc_handle, cpu, guest_va, perm);
+
+    l4 = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE, 
+            PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
+    if ( l4 == NULL )
+        return NULL;
+
+    l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
+    l3p = page_array[l3p];
+    l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l3p);
+    munmap(l4, PAGE_SIZE);
+    if ( l3 == NULL )
+        return NULL;
+
+    l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
+    l2p = page_array[l2p];
+    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, 
l2p);
+    munmap(l3, PAGE_SIZE);
+    if ( l2 == NULL )
+        return NULL;
+
+    l1 = NULL;
+    l1e = l2[l2_table_offset(va)];
+    l1p = l1e >> PAGE_SHIFT;
+    if (l1e & 0x80)  { /* 2M pages */
+        p = (l1p + l1_table_offset(va));
+    } else { /* 4K pages */
+        l1p = page_array[l1p];
+        l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, 
l1p);
+        munmap(l2, PAGE_SIZE);
+        if ( l1 == NULL )
+            return NULL;
+
+        p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
+    }
+    p = page_array[p];
+    if ( v != NULL )
+        munmap(v, PAGE_SIZE);
+    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
+    if (l1)
+        munmap(l1, PAGE_SIZE);
+    if ( v == NULL )
+        return NULL;
+
+    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
+}
 #endif
+
+static void *
+map_domain_va(
+    int xc_handle,
+    int cpu,
+    void *guest_va,
+    int perm)
+{
+    unsigned long va = (unsigned long) guest_va;
+    long npgs = xc_get_tot_pages(xc_handle, current_domid);
+    static enum { MODE_UNKNOWN, MODE_64, MODE_32, MODE_PAE } mode;
+
+    if ( mode == MODE_UNKNOWN )
+    {
+        xen_capabilities_info_t caps;
+        (void)xc_version(xc_handle, XENVER_capabilities, caps);
+        if ( strstr(caps, "-x86_64") )
+            mode = MODE_64;
+        else if ( strstr(caps, "-x86_32p") )
+            mode = MODE_PAE;
+        else if ( strstr(caps, "-x86_32") ) 
+            mode = MODE_32;
+    }
+
+    if ( nr_pages != npgs )
+    {
+        if ( nr_pages > 0 )
+            free(page_array);
+        nr_pages = npgs;
+        if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+        {
+            printf("Could not allocate memory\n");
+            return NULL;
+        }
+        if ( xc_get_pfn_list(xc_handle, current_domid,
+                             page_array, nr_pages) != nr_pages )
+        {
+            printf("Could not get the page frame list\n");
+            return NULL;
+        }
+    }
+
+    if (fetch_regs(xc_handle, cpu, NULL))
+        return NULL;
+
+    if (!paging_enabled(&ctxt[cpu])) { 
+        static void * v;
+        unsigned long page;
+
+        if ( v != NULL )
+            munmap(v, PAGE_SIZE);
+
+        page = page_array[va >> PAGE_SHIFT] << PAGE_SHIFT;
+
+        v = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE, 
+                perm, page >> PAGE_SHIFT);
+    
+        if ( v == NULL )
+            return NULL;
+
+        return (void *)(((unsigned long)v) | (va & BSD_PAGE_MASK));
+    }
+#ifdef __x86_64__
+    if ( mode == MODE_64 )
+        return map_domain_va_64(xc_handle, cpu, guest_va, perm);
+#endif
+    if ( mode == MODE_PAE )
+        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
+    /* else ( mode == MODE_32 ) */
+    return map_domain_va_32(xc_handle, cpu, guest_va, perm);
+}
 
 static int 
 __xc_waitdomain(
@@ -470,7 +511,7 @@
         break;
 
     case PTRACE_SETREGS:
-        if (!current_isfile)
+        if (current_isfile)
                 goto out_unspported; /* XXX not yet supported */
         SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
         if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, 
@@ -492,7 +533,7 @@
 
     case PTRACE_CONT:
     case PTRACE_DETACH:
-        if (!current_isfile)
+        if (current_isfile)
             goto out_unspported; /* XXX not yet supported */
         if ( request != PTRACE_SINGLESTEP )
         {
diff -r 6cb5928fa026 -r f0e14b4e535c tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h   Thu Mar 30 13:31:57 2006
+++ b/tools/libxc/xc_ptrace.h   Thu Mar 30 13:37:22 2006
@@ -31,7 +31,7 @@
   unsigned long orig_rax;
   unsigned long rip;
   unsigned long xcs;
-  unsigned long eflags;
+  unsigned long rflags;
   unsigned long rsp;
   unsigned long xss;
   unsigned long fs_base;
@@ -61,7 +61,7 @@
     pt.rax = xc.rax;                            \
     pt.rip = xc.rip;                            \
     pt.xcs = xc.cs;                             \
-    pt.eflags = xc.eflags;                      \
+    pt.rflags = xc.rflags;                      \
     pt.rsp = xc.rsp;                            \
     pt.xss = xc.ss;                             \
     pt.xes = xc.es;                             \
@@ -89,7 +89,7 @@
     xc.rax = pt->rax;                           \
     xc.rip = pt->rip;                           \
     xc.cs = pt->xcs;                            \
-    xc.eflags = pt->eflags;                     \
+    xc.rflags = pt->rflags & 0xffffffff;        \
     xc.rsp = pt->rsp;                           \
     xc.ss = pt->xss;                            \
     xc.es = pt->xes;                            \
diff -r 6cb5928fa026 -r f0e14b4e535c xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Mar 30 13:31:57 2006
+++ b/xen/arch/x86/domain.c     Thu Mar 30 13:37:22 2006
@@ -393,7 +393,7 @@
     }
     else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     {
-        hvm_modify_guest_state(v);
+        hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
     }
 
     if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
diff -r 6cb5928fa026 -r f0e14b4e535c xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Mar 30 13:31:57 2006
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Mar 30 13:37:22 2006
@@ -382,11 +382,6 @@
     return 1;
 }
 
-void svm_modify_guest_state(struct vcpu *v)
-{
-    svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
-}
-
 int svm_realmode(struct vcpu *v)
 {
     unsigned long cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
@@ -448,8 +443,6 @@
 
     hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
     hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
-
-    hvm_funcs.modify_guest_state = svm_modify_guest_state;
 
     hvm_funcs.realmode = svm_realmode;
     hvm_funcs.paging_enabled = svm_paging_enabled;
diff -r 6cb5928fa026 -r f0e14b4e535c xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Thu Mar 30 13:31:57 2006
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Thu Mar 30 13:37:22 2006
@@ -156,23 +156,6 @@
     vmcb->iopm_base_pa = (u64) virt_to_maddr(iopm);
     vmcb->msrpm_base_pa = (u64) virt_to_maddr(msrpm);
 
-    return 0;
-}
-
-
-/*
- * modify guest eflags and execption bitmap for gdb
- */
-int svm_modify_vmcb(struct vcpu *v, struct cpu_user_regs *regs)
-{
-    int error;
-    if ((error = load_vmcb(&v->arch.hvm_svm, v->arch.hvm_svm.host_save_pa))) 
-    {
-        printk("svm_modify_vmcb: load_vmcb failed: VMCB = %lx\n",
-                (unsigned long) v->arch.hvm_svm.host_save_pa);
-        return -EINVAL; 
-    }
-    svm_load_cpu_user_regs(v,regs);
     return 0;
 }
 
diff -r 6cb5928fa026 -r f0e14b4e535c xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Thu Mar 30 13:31:57 2006
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Thu Mar 30 13:37:22 2006
@@ -487,32 +487,6 @@
     arch_vmx->io_bitmap_b = NULL;
 }
 
-/*
- * modify guest eflags and execption bitmap for gdb
- */
-int modify_vmcs(struct arch_vmx_struct *arch_vmx,
-                struct cpu_user_regs *regs)
-{
-    int error;
-    u64 vmcs_phys_ptr, old, old_phys_ptr;
-    vmcs_phys_ptr = (u64) virt_to_maddr(arch_vmx->vmcs);
-
-    old_phys_ptr = virt_to_maddr(&old);
-    __vmptrst(old_phys_ptr);
-    if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
-        printk("modify_vmcs: load_vmcs failed: VMCS = %lx\n",
-               (unsigned long) vmcs_phys_ptr);
-        return -EINVAL;
-    }
-
-/* XXX VMX change modify_vmcs arg to v */
-    hvm_load_cpu_guest_regs(current, regs);
-
-    __vmptrld(old_phys_ptr);
-
-    return 0;
-}
-
 void vm_launch_fail(unsigned long eflags)
 {
     unsigned long error;
diff -r 6cb5928fa026 -r f0e14b4e535c xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Mar 30 13:31:57 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Mar 30 13:37:22 2006
@@ -400,7 +400,7 @@
         migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
 }
 
-struct vmx_store_cpu_guest_regs_callback_info {
+struct vmx_cpu_guest_regs_callback_info {
     struct vcpu *v;
     struct cpu_user_regs *regs;
     unsigned long *crs;
@@ -409,10 +409,19 @@
 static void vmx_store_cpu_guest_regs(
     struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
 
+static void vmx_load_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *regs);
+
 static void vmx_store_cpu_guest_regs_callback(void *data)
 {
-    struct vmx_store_cpu_guest_regs_callback_info *info = data;
+    struct vmx_cpu_guest_regs_callback_info *info = data;
     vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
+}
+
+static void vmx_load_cpu_guest_regs_callback(void *data)
+{
+    struct vmx_cpu_guest_regs_callback_info *info = data;
+    vmx_load_cpu_guest_regs(info->v, info->regs);
 }
 
 static void vmx_store_cpu_guest_regs(
@@ -426,7 +435,7 @@
         if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
         {
             /* Get register details from remote CPU. */
-            struct vmx_store_cpu_guest_regs_callback_info info = {
+            struct vmx_cpu_guest_regs_callback_info info = {
                 .v = v, .regs = regs, .crs = crs };
             cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
             on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
@@ -479,8 +488,33 @@
 
 void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
 {
+    if ( v != current )
+    {
+        /* Non-current VCPUs must be paused to set the register snapshot. */
+        ASSERT(atomic_read(&v->pausecnt) != 0);
+
+        if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
+        {
+            struct vmx_cpu_guest_regs_callback_info info = {
+                .v = v, .regs = regs };
+            cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
+            on_selected_cpus(cpumask, vmx_load_cpu_guest_regs_callback,
+                             &info, 1, 1);
+            return;
+        }
+
+        /* Register details are on this CPU. Load the correct VMCS. */
+        __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+    }
+
+    ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
+
 #if defined (__x86_64__)
     __vmwrite(GUEST_SS_SELECTOR, regs->ss);
+    __vmwrite(GUEST_DS_SELECTOR, regs->ds);
+    __vmwrite(GUEST_ES_SELECTOR, regs->es);
+    __vmwrite(GUEST_GS_SELECTOR, regs->gs);
+    __vmwrite(GUEST_FS_SELECTOR, regs->fs);
     __vmwrite(GUEST_RSP, regs->rsp);
 
     __vmwrite(GUEST_RFLAGS, regs->rflags);
@@ -493,6 +527,11 @@
     __vmwrite(GUEST_RIP, regs->rip);
 #elif defined (__i386__)
     __vmwrite(GUEST_SS_SELECTOR, regs->ss);
+    __vmwrite(GUEST_DS_SELECTOR, regs->ds);
+    __vmwrite(GUEST_ES_SELECTOR, regs->es);
+    __vmwrite(GUEST_GS_SELECTOR, regs->gs);
+    __vmwrite(GUEST_FS_SELECTOR, regs->fs);
+
     __vmwrite(GUEST_RSP, regs->esp);
 
     __vmwrite(GUEST_RFLAGS, regs->eflags);
@@ -503,14 +542,11 @@
 
     __vmwrite(GUEST_CS_SELECTOR, regs->cs);
     __vmwrite(GUEST_RIP, regs->eip);
-#else
-#error Unsupported architecture
 #endif
-}
-
-void vmx_modify_guest_state(struct vcpu *v)
-{
-    modify_vmcs(&v->arch.hvm_vmx, &v->arch.guest_context.user_regs);
+
+    /* Reload current VCPU's VMCS if it was temporarily unloaded. */
+    if ( (v != current) && hvm_guest(current) )
+        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
 }
 
 int vmx_realmode(struct vcpu *v)
@@ -660,8 +696,6 @@
 
     hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
     hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
-
-    hvm_funcs.modify_guest_state = vmx_modify_guest_state;
 
     hvm_funcs.realmode = vmx_realmode;
     hvm_funcs.paging_enabled = vmx_paging_enabled;
diff -r 6cb5928fa026 -r f0e14b4e535c xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Thu Mar 30 13:31:57 2006
+++ b/xen/include/asm-x86/hvm/hvm.h     Thu Mar 30 13:37:22 2006
@@ -47,8 +47,6 @@
         struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
     void (*load_cpu_guest_regs)(
         struct vcpu *v, struct cpu_user_regs *r);
-    void (*modify_guest_state)(struct vcpu *v);
-
     /*
      * Examine specifics of the guest state:
      * 1) determine whether the guest is in real or vm8086 mode,
@@ -105,12 +103,6 @@
     hvm_funcs.load_cpu_guest_regs(v, r);
 }
 
-static inline void
-hvm_modify_guest_state(struct vcpu *v)
-{
-    hvm_funcs.modify_guest_state(v);
-}
-
 static inline int
 hvm_realmode(struct vcpu *v)
 {
diff -r 6cb5928fa026 -r f0e14b4e535c xen/include/asm-x86/hvm/svm/svm.h
--- a/xen/include/asm-x86/hvm/svm/svm.h Thu Mar 30 13:31:57 2006
+++ b/xen/include/asm-x86/hvm/svm/svm.h Thu Mar 30 13:37:22 2006
@@ -39,7 +39,6 @@
 extern void svm_stop(void);
 extern void svm_save_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs);
 extern void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs);
-extern int svm_modify_vmcb(struct vcpu *v, struct cpu_user_regs *regs);
 extern void svm_vmread(struct vcpu *v, int index, unsigned long *value);
 extern void svm_vmwrite(struct vcpu *v, int index, unsigned long value);
 extern void svm_final_setup_guest(struct vcpu *v); 
diff -r 6cb5928fa026 -r f0e14b4e535c xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Mar 30 13:31:57 2006
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Thu Mar 30 13:37:22 2006
@@ -89,8 +89,6 @@
 
 void vmx_do_resume(struct vcpu *);
 struct vmcs_struct *alloc_vmcs(void);
-int modify_vmcs(struct arch_vmx_struct *arch_vmx,
-                struct cpu_user_regs *regs);
 void destroy_vmcs(struct arch_vmx_struct *arch_vmx);
 
 extern void vmx_request_clear_vmcs(struct vcpu *v);

_______________________________________________
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®.