ia64/xen-unstable

changeset 9534:f0e14b4e535c

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@intel.com>

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Mar 30 14:37:22 2006 +0100 (2006-03-30)
parents 6cb5928fa026
children cee79e351357
files tools/libxc/xc_ptrace.c tools/libxc/xc_ptrace.h xen/arch/x86/domain.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/svm/svm.h xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/tools/libxc/xc_ptrace.c	Thu Mar 30 14:31:57 2006 +0100
     1.2 +++ b/tools/libxc/xc_ptrace.c	Thu Mar 30 14:37:22 2006 +0100
     1.3 @@ -153,6 +153,79 @@ online_vcpus_changed(cpumap_t cpumap)
     1.4  }
     1.5  
     1.6  /* --------------------- */
     1.7 +/* XXX application state */
     1.8 +static long                     nr_pages = 0;
     1.9 +static unsigned long           *page_array = NULL;
    1.10 +
    1.11 +static void *
    1.12 +map_domain_va_32(
    1.13 +    int xc_handle,
    1.14 +    int cpu,
    1.15 +    void *guest_va,
    1.16 +    int perm)
    1.17 +{
    1.18 +    unsigned long pde, page;
    1.19 +    unsigned long va = (unsigned long)guest_va;
    1.20 +
    1.21 +    static unsigned long  cr3_phys[MAX_VIRT_CPUS];
    1.22 +    static uint32_t *cr3_virt[MAX_VIRT_CPUS];
    1.23 +    static unsigned long  pde_phys[MAX_VIRT_CPUS];
    1.24 +    static uint32_t *pde_virt[MAX_VIRT_CPUS];
    1.25 +    static unsigned long  page_phys[MAX_VIRT_CPUS];
    1.26 +    static uint32_t *page_virt[MAX_VIRT_CPUS];    
    1.27 +    static int            prev_perm[MAX_VIRT_CPUS];
    1.28 +
    1.29 +   if (ctxt[cpu].ctrlreg[3] == 0)
    1.30 +       return NULL;
    1.31 +   if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
    1.32 +    {
    1.33 +        cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
    1.34 +        if ( cr3_virt[cpu] )
    1.35 +            munmap(cr3_virt[cpu], PAGE_SIZE);
    1.36 +        cr3_virt[cpu] = xc_map_foreign_range(
    1.37 +            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
    1.38 +            cr3_phys[cpu] >> PAGE_SHIFT);
    1.39 +        if ( cr3_virt[cpu] == NULL )
    1.40 +            return NULL;
    1.41 +    }
    1.42 +    if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
    1.43 +        return NULL;
    1.44 +    if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
    1.45 +        pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
    1.46 +    if ( pde != pde_phys[cpu] )
    1.47 +    {
    1.48 +        pde_phys[cpu] = pde;
    1.49 +        if ( pde_virt[cpu] )
    1.50 +            munmap(pde_virt[cpu], PAGE_SIZE);
    1.51 +        pde_virt[cpu] = xc_map_foreign_range(
    1.52 +            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
    1.53 +            pde_phys[cpu] >> PAGE_SHIFT);
    1.54 +        if ( pde_virt[cpu] == NULL )
    1.55 +            return NULL;
    1.56 +    }
    1.57 +    if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
    1.58 +        return NULL;
    1.59 +    if (ctxt[cpu].flags & VGCF_HVM_GUEST)
    1.60 +        page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
    1.61 +    if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
    1.62 +    {
    1.63 +        page_phys[cpu] = page;
    1.64 +        if ( page_virt[cpu] )
    1.65 +            munmap(page_virt[cpu], PAGE_SIZE);
    1.66 +        page_virt[cpu] = xc_map_foreign_range(
    1.67 +            xc_handle, current_domid, PAGE_SIZE, perm,
    1.68 +            page_phys[cpu] >> PAGE_SHIFT);
    1.69 +        if ( page_virt[cpu] == NULL )
    1.70 +        {
    1.71 +            page_phys[cpu] = 0;
    1.72 +            return NULL;
    1.73 +        }
    1.74 +        prev_perm[cpu] = perm;
    1.75 +    } 
    1.76 +
    1.77 +    return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
    1.78 +}
    1.79 +
    1.80  
    1.81  static void *
    1.82  map_domain_va_pae(
    1.83 @@ -165,28 +238,31 @@ map_domain_va_pae(
    1.84      uint64_t *l3, *l2, *l1;
    1.85      static void *v;
    1.86  
    1.87 -    if (fetch_regs(xc_handle, cpu, NULL))
    1.88 -        return NULL;
    1.89 -
    1.90      l3 = xc_map_foreign_range(
    1.91          xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
    1.92      if ( l3 == NULL )
    1.93          return NULL;
    1.94  
    1.95      l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
    1.96 +    l2p = page_array[l2p];
    1.97      l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
    1.98 +    munmap(l3, PAGE_SIZE);
    1.99      if ( l2 == NULL )
   1.100          return NULL;
   1.101  
   1.102      l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
   1.103 +    l1p = page_array[l1p];
   1.104      l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
   1.105 +    munmap(l2, PAGE_SIZE);
   1.106      if ( l1 == NULL )
   1.107          return NULL;
   1.108  
   1.109      p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
   1.110 +    p = page_array[p];
   1.111      if ( v != NULL )
   1.112          munmap(v, PAGE_SIZE);
   1.113      v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
   1.114 +    munmap(l1, PAGE_SIZE);
   1.115      if ( v == NULL )
   1.116          return NULL;
   1.117  
   1.118 @@ -195,46 +271,58 @@ map_domain_va_pae(
   1.119  
   1.120  #ifdef __x86_64__
   1.121  static void *
   1.122 -map_domain_va(
   1.123 +map_domain_va_64(
   1.124      int xc_handle,
   1.125      int cpu,
   1.126      void *guest_va,
   1.127      int perm)
   1.128  {
   1.129 -    unsigned long l3p, l2p, l1p, p, va = (unsigned long)guest_va;
   1.130 +    unsigned long l3p, l2p, l1p, l1e, p, va = (unsigned long)guest_va;
   1.131      uint64_t *l4, *l3, *l2, *l1;
   1.132      static void *v;
   1.133  
   1.134      if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */
   1.135 -        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
   1.136 +        return map_domain_va_32(xc_handle, cpu, guest_va, perm);
   1.137  
   1.138 -    if (fetch_regs(xc_handle, cpu, NULL))
   1.139 -        return NULL;
   1.140 -
   1.141 -    l4 = xc_map_foreign_range(
   1.142 -        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
   1.143 +    l4 = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE, 
   1.144 +            PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
   1.145      if ( l4 == NULL )
   1.146          return NULL;
   1.147  
   1.148      l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT;
   1.149 +    l3p = page_array[l3p];
   1.150      l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p);
   1.151 +    munmap(l4, PAGE_SIZE);
   1.152      if ( l3 == NULL )
   1.153          return NULL;
   1.154  
   1.155      l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT;
   1.156 +    l2p = page_array[l2p];
   1.157      l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
   1.158 +    munmap(l3, PAGE_SIZE);
   1.159      if ( l2 == NULL )
   1.160          return NULL;
   1.161  
   1.162 -    l1p = l2[l2_table_offset(va)] >> PAGE_SHIFT;
   1.163 -    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
   1.164 -    if ( l1 == NULL )
   1.165 -        return NULL;
   1.166 +    l1 = NULL;
   1.167 +    l1e = l2[l2_table_offset(va)];
   1.168 +    l1p = l1e >> PAGE_SHIFT;
   1.169 +    if (l1e & 0x80)  { /* 2M pages */
   1.170 +        p = (l1p + l1_table_offset(va));
   1.171 +    } else { /* 4K pages */
   1.172 +        l1p = page_array[l1p];
   1.173 +        l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
   1.174 +        munmap(l2, PAGE_SIZE);
   1.175 +        if ( l1 == NULL )
   1.176 +            return NULL;
   1.177  
   1.178 -    p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
   1.179 +        p = l1[l1_table_offset(va)] >> PAGE_SHIFT;
   1.180 +    }
   1.181 +    p = page_array[p];
   1.182      if ( v != NULL )
   1.183          munmap(v, PAGE_SIZE);
   1.184      v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
   1.185 +    if (l1)
   1.186 +        munmap(l1, PAGE_SIZE);
   1.187      if ( v == NULL )
   1.188          return NULL;
   1.189  
   1.190 @@ -242,11 +330,6 @@ map_domain_va(
   1.191  }
   1.192  #endif
   1.193  
   1.194 -#ifdef __i386__
   1.195 -/* XXX application state */
   1.196 -static long                     nr_pages = 0;
   1.197 -static unsigned long           *page_array = NULL;
   1.198 -
   1.199  static void *
   1.200  map_domain_va(
   1.201      int xc_handle,
   1.202 @@ -254,20 +337,9 @@ map_domain_va(
   1.203      void *guest_va,
   1.204      int perm)
   1.205  {
   1.206 -
   1.207 -    unsigned long pde, page;
   1.208 -    unsigned long va = (unsigned long)guest_va;
   1.209 +    unsigned long va = (unsigned long) guest_va;
   1.210      long npgs = xc_get_tot_pages(xc_handle, current_domid);
   1.211 -
   1.212 -
   1.213 -    static uint32_t  cr3_phys[MAX_VIRT_CPUS];
   1.214 -    static unsigned long *cr3_virt[MAX_VIRT_CPUS];
   1.215 -    static unsigned long  pde_phys[MAX_VIRT_CPUS];
   1.216 -    static unsigned long *pde_virt[MAX_VIRT_CPUS];
   1.217 -    static unsigned long  page_phys[MAX_VIRT_CPUS];
   1.218 -    static unsigned long *page_virt[MAX_VIRT_CPUS];    
   1.219 -    static int            prev_perm[MAX_VIRT_CPUS];
   1.220 -    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE, MODE_64 } mode;
   1.221 +    static enum { MODE_UNKNOWN, MODE_64, MODE_32, MODE_PAE } mode;
   1.222  
   1.223      if ( mode == MODE_UNKNOWN )
   1.224      {
   1.225 @@ -281,9 +353,6 @@ map_domain_va(
   1.226              mode = MODE_32;
   1.227      }
   1.228  
   1.229 -    if ( mode == MODE_PAE )
   1.230 -        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
   1.231 -
   1.232      if ( nr_pages != npgs )
   1.233      {
   1.234          if ( nr_pages > 0 )
   1.235 @@ -305,61 +374,33 @@ map_domain_va(
   1.236      if (fetch_regs(xc_handle, cpu, NULL))
   1.237          return NULL;
   1.238  
   1.239 -    if (paging_enabled(&ctxt[cpu])) {
   1.240 -       if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
   1.241 -        {
   1.242 -            cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
   1.243 -            if ( cr3_virt[cpu] )
   1.244 -                munmap(cr3_virt[cpu], PAGE_SIZE);
   1.245 -            cr3_virt[cpu] = xc_map_foreign_range(
   1.246 -                xc_handle, current_domid, PAGE_SIZE, PROT_READ,
   1.247 -                cr3_phys[cpu] >> PAGE_SHIFT);
   1.248 -            if ( cr3_virt[cpu] == NULL )
   1.249 -                return NULL;
   1.250 -        }
   1.251 -        if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
   1.252 +    if (!paging_enabled(&ctxt[cpu])) { 
   1.253 +        static void * v;
   1.254 +        unsigned long page;
   1.255 +
   1.256 +        if ( v != NULL )
   1.257 +            munmap(v, PAGE_SIZE);
   1.258 +
   1.259 +        page = page_array[va >> PAGE_SHIFT] << PAGE_SHIFT;
   1.260 +
   1.261 +        v = xc_map_foreign_range( xc_handle, current_domid, PAGE_SIZE, 
   1.262 +                perm, page >> PAGE_SHIFT);
   1.263 +    
   1.264 +        if ( v == NULL )
   1.265              return NULL;
   1.266 -        if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
   1.267 -            pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
   1.268 -        if ( pde != pde_phys[cpu] )
   1.269 -        {
   1.270 -            pde_phys[cpu] = pde;
   1.271 -            if ( pde_virt[cpu] )
   1.272 -                munmap(pde_virt[cpu], PAGE_SIZE);
   1.273 -            pde_virt[cpu] = xc_map_foreign_range(
   1.274 -                xc_handle, current_domid, PAGE_SIZE, PROT_READ,
   1.275 -                pde_phys[cpu] >> PAGE_SHIFT);
   1.276 -            if ( pde_virt[cpu] == NULL )
   1.277 -                return NULL;
   1.278 -        }
   1.279 -        if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
   1.280 -            return NULL;
   1.281 -    } else {
   1.282 -        page = va;
   1.283 +
   1.284 +        return (void *)(((unsigned long)v) | (va & BSD_PAGE_MASK));
   1.285      }
   1.286 -    if (ctxt[cpu].flags & VGCF_HVM_GUEST)
   1.287 -        page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
   1.288 -    if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
   1.289 -    {
   1.290 -        page_phys[cpu] = page;
   1.291 -        if ( page_virt[cpu] )
   1.292 -            munmap(page_virt[cpu], PAGE_SIZE);
   1.293 -        page_virt[cpu] = xc_map_foreign_range(
   1.294 -            xc_handle, current_domid, PAGE_SIZE, perm,
   1.295 -            page_phys[cpu] >> PAGE_SHIFT);
   1.296 -        if ( page_virt[cpu] == NULL )
   1.297 -        {
   1.298 -            page_phys[cpu] = 0;
   1.299 -            return NULL;
   1.300 -        }
   1.301 -        prev_perm[cpu] = perm;
   1.302 -    } 
   1.303 -
   1.304 -    return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
   1.305 +#ifdef __x86_64__
   1.306 +    if ( mode == MODE_64 )
   1.307 +        return map_domain_va_64(xc_handle, cpu, guest_va, perm);
   1.308 +#endif
   1.309 +    if ( mode == MODE_PAE )
   1.310 +        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
   1.311 +    /* else ( mode == MODE_32 ) */
   1.312 +    return map_domain_va_32(xc_handle, cpu, guest_va, perm);
   1.313  }
   1.314  
   1.315 -#endif
   1.316 -
   1.317  static int 
   1.318  __xc_waitdomain(
   1.319      int xc_handle,
   1.320 @@ -470,7 +511,7 @@ xc_ptrace(
   1.321          break;
   1.322  
   1.323      case PTRACE_SETREGS:
   1.324 -        if (!current_isfile)
   1.325 +        if (current_isfile)
   1.326                  goto out_unspported; /* XXX not yet supported */
   1.327          SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
   1.328          if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, 
   1.329 @@ -492,7 +533,7 @@ xc_ptrace(
   1.330  
   1.331      case PTRACE_CONT:
   1.332      case PTRACE_DETACH:
   1.333 -        if (!current_isfile)
   1.334 +        if (current_isfile)
   1.335              goto out_unspported; /* XXX not yet supported */
   1.336          if ( request != PTRACE_SINGLESTEP )
   1.337          {
     2.1 --- a/tools/libxc/xc_ptrace.h	Thu Mar 30 14:31:57 2006 +0100
     2.2 +++ b/tools/libxc/xc_ptrace.h	Thu Mar 30 14:37:22 2006 +0100
     2.3 @@ -31,7 +31,7 @@ struct gdb_regs
     2.4    unsigned long orig_rax;
     2.5    unsigned long rip;
     2.6    unsigned long xcs;
     2.7 -  unsigned long eflags;
     2.8 +  unsigned long rflags;
     2.9    unsigned long rsp;
    2.10    unsigned long xss;
    2.11    unsigned long fs_base;
    2.12 @@ -61,7 +61,7 @@ struct gdb_regs
    2.13      pt.rax = xc.rax;                            \
    2.14      pt.rip = xc.rip;                            \
    2.15      pt.xcs = xc.cs;                             \
    2.16 -    pt.eflags = xc.eflags;                      \
    2.17 +    pt.rflags = xc.rflags;                      \
    2.18      pt.rsp = xc.rsp;                            \
    2.19      pt.xss = xc.ss;                             \
    2.20      pt.xes = xc.es;                             \
    2.21 @@ -89,7 +89,7 @@ struct gdb_regs
    2.22      xc.rax = pt->rax;                           \
    2.23      xc.rip = pt->rip;                           \
    2.24      xc.cs = pt->xcs;                            \
    2.25 -    xc.eflags = pt->eflags;                     \
    2.26 +    xc.rflags = pt->rflags & 0xffffffff;        \
    2.27      xc.rsp = pt->rsp;                           \
    2.28      xc.ss = pt->xss;                            \
    2.29      xc.es = pt->xes;                            \
     3.1 --- a/xen/arch/x86/domain.c	Thu Mar 30 14:31:57 2006 +0100
     3.2 +++ b/xen/arch/x86/domain.c	Thu Mar 30 14:37:22 2006 +0100
     3.3 @@ -393,7 +393,7 @@ int arch_set_info_guest(
     3.4      }
     3.5      else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     3.6      {
     3.7 -        hvm_modify_guest_state(v);
     3.8 +        hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
     3.9      }
    3.10  
    3.11      if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     4.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Mar 30 14:31:57 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Mar 30 14:37:22 2006 +0100
     4.3 @@ -382,11 +382,6 @@ static inline int long_mode_do_msr_write
     4.4      return 1;
     4.5  }
     4.6  
     4.7 -void svm_modify_guest_state(struct vcpu *v)
     4.8 -{
     4.9 -    svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
    4.10 -}
    4.11 -
    4.12  int svm_realmode(struct vcpu *v)
    4.13  {
    4.14      unsigned long cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
    4.15 @@ -449,8 +444,6 @@ int start_svm(void)
    4.16      hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
    4.17      hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
    4.18  
    4.19 -    hvm_funcs.modify_guest_state = svm_modify_guest_state;
    4.20 -
    4.21      hvm_funcs.realmode = svm_realmode;
    4.22      hvm_funcs.paging_enabled = svm_paging_enabled;
    4.23      hvm_funcs.instruction_length = svm_instruction_length;
     5.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Thu Mar 30 14:31:57 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Thu Mar 30 14:37:22 2006 +0100
     5.3 @@ -161,23 +161,6 @@ static int construct_vmcb_controls(struc
     5.4  
     5.5  
     5.6  /*
     5.7 - * modify guest eflags and execption bitmap for gdb
     5.8 - */
     5.9 -int svm_modify_vmcb(struct vcpu *v, struct cpu_user_regs *regs)
    5.10 -{
    5.11 -    int error;
    5.12 -    if ((error = load_vmcb(&v->arch.hvm_svm, v->arch.hvm_svm.host_save_pa))) 
    5.13 -    {
    5.14 -        printk("svm_modify_vmcb: load_vmcb failed: VMCB = %lx\n",
    5.15 -                (unsigned long) v->arch.hvm_svm.host_save_pa);
    5.16 -        return -EINVAL; 
    5.17 -    }
    5.18 -    svm_load_cpu_user_regs(v,regs);
    5.19 -    return 0;
    5.20 -}
    5.21 -
    5.22 -
    5.23 -/*
    5.24   * Initially set the same environement as host.
    5.25   */
    5.26  static int construct_init_vmcb_guest(struct arch_svm_struct *arch_svm, 
     6.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Thu Mar 30 14:31:57 2006 +0100
     6.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Thu Mar 30 14:37:22 2006 +0100
     6.3 @@ -487,32 +487,6 @@ void destroy_vmcs(struct arch_vmx_struct
     6.4      arch_vmx->io_bitmap_b = NULL;
     6.5  }
     6.6  
     6.7 -/*
     6.8 - * modify guest eflags and execption bitmap for gdb
     6.9 - */
    6.10 -int modify_vmcs(struct arch_vmx_struct *arch_vmx,
    6.11 -                struct cpu_user_regs *regs)
    6.12 -{
    6.13 -    int error;
    6.14 -    u64 vmcs_phys_ptr, old, old_phys_ptr;
    6.15 -    vmcs_phys_ptr = (u64) virt_to_maddr(arch_vmx->vmcs);
    6.16 -
    6.17 -    old_phys_ptr = virt_to_maddr(&old);
    6.18 -    __vmptrst(old_phys_ptr);
    6.19 -    if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
    6.20 -        printk("modify_vmcs: load_vmcs failed: VMCS = %lx\n",
    6.21 -               (unsigned long) vmcs_phys_ptr);
    6.22 -        return -EINVAL;
    6.23 -    }
    6.24 -
    6.25 -/* XXX VMX change modify_vmcs arg to v */
    6.26 -    hvm_load_cpu_guest_regs(current, regs);
    6.27 -
    6.28 -    __vmptrld(old_phys_ptr);
    6.29 -
    6.30 -    return 0;
    6.31 -}
    6.32 -
    6.33  void vm_launch_fail(unsigned long eflags)
    6.34  {
    6.35      unsigned long error;
     7.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Mar 30 14:31:57 2006 +0100
     7.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Mar 30 14:37:22 2006 +0100
     7.3 @@ -400,7 +400,7 @@ void vmx_migrate_timers(struct vcpu *v)
     7.4          migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
     7.5  }
     7.6  
     7.7 -struct vmx_store_cpu_guest_regs_callback_info {
     7.8 +struct vmx_cpu_guest_regs_callback_info {
     7.9      struct vcpu *v;
    7.10      struct cpu_user_regs *regs;
    7.11      unsigned long *crs;
    7.12 @@ -409,12 +409,21 @@ struct vmx_store_cpu_guest_regs_callback
    7.13  static void vmx_store_cpu_guest_regs(
    7.14      struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
    7.15  
    7.16 +static void vmx_load_cpu_guest_regs(
    7.17 +    struct vcpu *v, struct cpu_user_regs *regs);
    7.18 +
    7.19  static void vmx_store_cpu_guest_regs_callback(void *data)
    7.20  {
    7.21 -    struct vmx_store_cpu_guest_regs_callback_info *info = data;
    7.22 +    struct vmx_cpu_guest_regs_callback_info *info = data;
    7.23      vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
    7.24  }
    7.25  
    7.26 +static void vmx_load_cpu_guest_regs_callback(void *data)
    7.27 +{
    7.28 +    struct vmx_cpu_guest_regs_callback_info *info = data;
    7.29 +    vmx_load_cpu_guest_regs(info->v, info->regs);
    7.30 +}
    7.31 +
    7.32  static void vmx_store_cpu_guest_regs(
    7.33      struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
    7.34  {
    7.35 @@ -426,7 +435,7 @@ static void vmx_store_cpu_guest_regs(
    7.36          if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
    7.37          {
    7.38              /* Get register details from remote CPU. */
    7.39 -            struct vmx_store_cpu_guest_regs_callback_info info = {
    7.40 +            struct vmx_cpu_guest_regs_callback_info info = {
    7.41                  .v = v, .regs = regs, .crs = crs };
    7.42              cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
    7.43              on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
    7.44 @@ -479,8 +488,33 @@ static void vmx_store_cpu_guest_regs(
    7.45  
    7.46  void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
    7.47  {
    7.48 +    if ( v != current )
    7.49 +    {
    7.50 +        /* Non-current VCPUs must be paused to set the register snapshot. */
    7.51 +        ASSERT(atomic_read(&v->pausecnt) != 0);
    7.52 +
    7.53 +        if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
    7.54 +        {
    7.55 +            struct vmx_cpu_guest_regs_callback_info info = {
    7.56 +                .v = v, .regs = regs };
    7.57 +            cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
    7.58 +            on_selected_cpus(cpumask, vmx_load_cpu_guest_regs_callback,
    7.59 +                             &info, 1, 1);
    7.60 +            return;
    7.61 +        }
    7.62 +
    7.63 +        /* Register details are on this CPU. Load the correct VMCS. */
    7.64 +        __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
    7.65 +    }
    7.66 +
    7.67 +    ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
    7.68 +
    7.69  #if defined (__x86_64__)
    7.70      __vmwrite(GUEST_SS_SELECTOR, regs->ss);
    7.71 +    __vmwrite(GUEST_DS_SELECTOR, regs->ds);
    7.72 +    __vmwrite(GUEST_ES_SELECTOR, regs->es);
    7.73 +    __vmwrite(GUEST_GS_SELECTOR, regs->gs);
    7.74 +    __vmwrite(GUEST_FS_SELECTOR, regs->fs);
    7.75      __vmwrite(GUEST_RSP, regs->rsp);
    7.76  
    7.77      __vmwrite(GUEST_RFLAGS, regs->rflags);
    7.78 @@ -493,6 +527,11 @@ void vmx_load_cpu_guest_regs(struct vcpu
    7.79      __vmwrite(GUEST_RIP, regs->rip);
    7.80  #elif defined (__i386__)
    7.81      __vmwrite(GUEST_SS_SELECTOR, regs->ss);
    7.82 +    __vmwrite(GUEST_DS_SELECTOR, regs->ds);
    7.83 +    __vmwrite(GUEST_ES_SELECTOR, regs->es);
    7.84 +    __vmwrite(GUEST_GS_SELECTOR, regs->gs);
    7.85 +    __vmwrite(GUEST_FS_SELECTOR, regs->fs);
    7.86 +
    7.87      __vmwrite(GUEST_RSP, regs->esp);
    7.88  
    7.89      __vmwrite(GUEST_RFLAGS, regs->eflags);
    7.90 @@ -503,14 +542,11 @@ void vmx_load_cpu_guest_regs(struct vcpu
    7.91  
    7.92      __vmwrite(GUEST_CS_SELECTOR, regs->cs);
    7.93      __vmwrite(GUEST_RIP, regs->eip);
    7.94 -#else
    7.95 -#error Unsupported architecture
    7.96  #endif
    7.97 -}
    7.98  
    7.99 -void vmx_modify_guest_state(struct vcpu *v)
   7.100 -{
   7.101 -    modify_vmcs(&v->arch.hvm_vmx, &v->arch.guest_context.user_regs);
   7.102 +    /* Reload current VCPU's VMCS if it was temporarily unloaded. */
   7.103 +    if ( (v != current) && hvm_guest(current) )
   7.104 +        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
   7.105  }
   7.106  
   7.107  int vmx_realmode(struct vcpu *v)
   7.108 @@ -661,8 +697,6 @@ int start_vmx(void)
   7.109      hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
   7.110      hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
   7.111  
   7.112 -    hvm_funcs.modify_guest_state = vmx_modify_guest_state;
   7.113 -
   7.114      hvm_funcs.realmode = vmx_realmode;
   7.115      hvm_funcs.paging_enabled = vmx_paging_enabled;
   7.116      hvm_funcs.instruction_length = vmx_instruction_length;
     8.1 --- a/xen/include/asm-x86/hvm/hvm.h	Thu Mar 30 14:31:57 2006 +0100
     8.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Thu Mar 30 14:37:22 2006 +0100
     8.3 @@ -47,8 +47,6 @@ struct hvm_function_table {
     8.4          struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
     8.5      void (*load_cpu_guest_regs)(
     8.6          struct vcpu *v, struct cpu_user_regs *r);
     8.7 -    void (*modify_guest_state)(struct vcpu *v);
     8.8 -
     8.9      /*
    8.10       * Examine specifics of the guest state:
    8.11       * 1) determine whether the guest is in real or vm8086 mode,
    8.12 @@ -105,12 +103,6 @@ hvm_load_cpu_guest_regs(struct vcpu *v, 
    8.13      hvm_funcs.load_cpu_guest_regs(v, r);
    8.14  }
    8.15  
    8.16 -static inline void
    8.17 -hvm_modify_guest_state(struct vcpu *v)
    8.18 -{
    8.19 -    hvm_funcs.modify_guest_state(v);
    8.20 -}
    8.21 -
    8.22  static inline int
    8.23  hvm_realmode(struct vcpu *v)
    8.24  {
     9.1 --- a/xen/include/asm-x86/hvm/svm/svm.h	Thu Mar 30 14:31:57 2006 +0100
     9.2 +++ b/xen/include/asm-x86/hvm/svm/svm.h	Thu Mar 30 14:37:22 2006 +0100
     9.3 @@ -39,7 +39,6 @@ extern unsigned int cpu_rev;
     9.4  extern void svm_stop(void);
     9.5  extern void svm_save_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs);
     9.6  extern void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs);
     9.7 -extern int svm_modify_vmcb(struct vcpu *v, struct cpu_user_regs *regs);
     9.8  extern void svm_vmread(struct vcpu *v, int index, unsigned long *value);
     9.9  extern void svm_vmwrite(struct vcpu *v, int index, unsigned long value);
    9.10  extern void svm_final_setup_guest(struct vcpu *v); 
    10.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Mar 30 14:31:57 2006 +0100
    10.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Thu Mar 30 14:37:22 2006 +0100
    10.3 @@ -89,8 +89,6 @@ struct arch_vmx_struct {
    10.4  
    10.5  void vmx_do_resume(struct vcpu *);
    10.6  struct vmcs_struct *alloc_vmcs(void);
    10.7 -int modify_vmcs(struct arch_vmx_struct *arch_vmx,
    10.8 -                struct cpu_user_regs *regs);
    10.9  void destroy_vmcs(struct arch_vmx_struct *arch_vmx);
   10.10  
   10.11  extern void vmx_request_clear_vmcs(struct vcpu *v);