ia64/xen-unstable

changeset 12752:5c82a274733e

[HVM] Cache segment-register contents during PTE-update emulations.
Also clean up page-fault propagation to inject the correct error
code and CR2 value.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Dec 01 15:45:59 2006 +0000 (2006-12-01)
parents 1e6f9222a1e1
children c4225c95dbcd
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/mm/shadow/private.h xen/include/asm-x86/domain.h xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/shadow.h
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Dec 01 15:12:48 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Dec 01 15:45:59 2006 +0000
     1.3 @@ -812,9 +812,13 @@ static void svm_vcpu_destroy(struct vcpu
     1.4      svm_destroy_vmcb(v);
     1.5  }
     1.6  
     1.7 -static void svm_hvm_inject_exception(unsigned int trapnr, int errcode)
     1.8 +static void svm_hvm_inject_exception(
     1.9 +    unsigned int trapnr, int errcode, unsigned long cr2)
    1.10  {
    1.11 -    svm_inject_exception(current, trapnr, (errcode != -1), errcode);
    1.12 +    struct vcpu *v = current;
    1.13 +    svm_inject_exception(v, trapnr, (errcode != -1), errcode);
    1.14 +    if ( trapnr == TRAP_page_fault )
    1.15 +        v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2;
    1.16  }
    1.17  
    1.18  int start_svm(void)
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Dec 01 15:12:48 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Dec 01 15:45:59 2006 +0000
     2.3 @@ -715,9 +715,13 @@ static void vmx_update_host_cr3(struct v
     2.4      __vmwrite(HOST_CR3, v->arch.cr3);
     2.5  }
     2.6  
     2.7 -static void vmx_inject_exception(unsigned int trapnr, int errcode)
     2.8 +static void vmx_inject_exception(
     2.9 +    unsigned int trapnr, int errcode, unsigned long cr2)
    2.10  {
    2.11 -    vmx_inject_hw_exception(current, trapnr, errcode);
    2.12 +    struct vcpu *v = current;
    2.13 +    vmx_inject_hw_exception(v, trapnr, errcode);
    2.14 +    if ( trapnr == TRAP_page_fault )
    2.15 +        v->arch.hvm_vmx.cpu_cr2 = cr2;
    2.16  }
    2.17  
    2.18  /* Setup HVM interfaces */
     3.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Dec 01 15:12:48 2006 +0000
     3.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Dec 01 15:45:59 2006 +0000
     3.3 @@ -69,42 +69,52 @@ int _shadow_mode_refcounts(struct domain
     3.4  /* x86 emulator support for the shadow code
     3.5   */
     3.6  
     3.7 +struct segment_register *hvm_get_seg_reg(
     3.8 +    enum x86_segment seg, struct sh_emulate_ctxt *sh_ctxt)
     3.9 +{
    3.10 +    struct segment_register *seg_reg = &sh_ctxt->seg_reg[seg];
    3.11 +    if ( !__test_and_set_bit(seg, &sh_ctxt->valid_seg_regs) )
    3.12 +        hvm_get_segment_register(current, seg, seg_reg);
    3.13 +    return seg_reg;
    3.14 +}
    3.15 +
    3.16  static int hvm_translate_linear_addr(
    3.17      enum x86_segment seg,
    3.18      unsigned long offset,
    3.19      unsigned int bytes,
    3.20      unsigned int is_write,
    3.21 +    struct sh_emulate_ctxt *sh_ctxt,
    3.22      unsigned long *paddr)
    3.23  {
    3.24 -    struct segment_register creg, dreg;
    3.25 +    struct segment_register *creg, *dreg;
    3.26      unsigned long limit, addr = offset;
    3.27      uint32_t last_byte;
    3.28  
    3.29 -    hvm_get_segment_register(current, x86_seg_cs, &creg);
    3.30 -    hvm_get_segment_register(current, seg,        &dreg);
    3.31 -
    3.32 -    if ( !creg.attr.fields.l || !hvm_long_mode_enabled(current) )
    3.33 +    creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt);
    3.34 +    dreg = hvm_get_seg_reg(seg,        sh_ctxt);
    3.35 +
    3.36 +    if ( !creg->attr.fields.l || !hvm_long_mode_enabled(current) )
    3.37      {
    3.38          /*
    3.39           * COMPATIBILITY MODE: Apply segment checks and add base.
    3.40           */
    3.41  
    3.42          /* If this is a store, is the segment a writable data segment? */
    3.43 -        if ( is_write && ((dreg.attr.fields.type & 0xa) != 0x2) )
    3.44 +        if ( is_write && ((dreg->attr.fields.type & 0xa) != 0x2) )
    3.45              goto gpf;
    3.46  
    3.47          /* Calculate the segment limit, including granularity flag. */
    3.48 -        limit = dreg.limit;
    3.49 -        if ( dreg.attr.fields.g )
    3.50 +        limit = dreg->limit;
    3.51 +        if ( dreg->attr.fields.g )
    3.52              limit = (limit << 12) | 0xfff;
    3.53  
    3.54          last_byte = offset + bytes - 1;
    3.55  
    3.56          /* Is this a grows-down data segment? Special limit check if so. */
    3.57 -        if ( (dreg.attr.fields.type & 0xc) == 0x4 )
    3.58 +        if ( (dreg->attr.fields.type & 0xc) == 0x4 )
    3.59          {
    3.60              /* Is upper limit 0xFFFF or 0xFFFFFFFF? */
    3.61 -            if ( !dreg.attr.fields.db )
    3.62 +            if ( !dreg->attr.fields.db )
    3.63                  last_byte = (uint16_t)last_byte;
    3.64  
    3.65              /* Check first byte and last byte against respective bounds. */
    3.66 @@ -118,7 +128,7 @@ static int hvm_translate_linear_addr(
    3.67           * Hardware truncates to 32 bits in compatibility mode.
    3.68           * It does not truncate to 16 bits in 16-bit address-size mode.
    3.69           */
    3.70 -        addr = (uint32_t)(addr + dreg.base);
    3.71 +        addr = (uint32_t)(addr + dreg->base);
    3.72      }
    3.73      else
    3.74      {
    3.75 @@ -127,7 +137,7 @@ static int hvm_translate_linear_addr(
    3.76           */
    3.77  
    3.78          if ( (seg == x86_seg_fs) || (seg == x86_seg_gs) )
    3.79 -            addr += dreg.base;
    3.80 +            addr += dreg->base;
    3.81  
    3.82          if ( !is_canonical_address(addr) )
    3.83              goto gpf;
    3.84 @@ -138,7 +148,7 @@ static int hvm_translate_linear_addr(
    3.85  
    3.86   gpf:
    3.87      /* Inject #GP(0). */
    3.88 -    hvm_inject_exception(TRAP_gp_fault, 0);
    3.89 +    hvm_inject_exception(TRAP_gp_fault, 0, 0);
    3.90      return X86EMUL_PROPAGATE_FAULT;
    3.91  }
    3.92  
    3.93 @@ -149,10 +159,12 @@ sh_x86_emulate_read(enum x86_segment seg
    3.94                      unsigned int bytes,
    3.95                      struct x86_emulate_ctxt *ctxt)
    3.96  {
    3.97 +    struct sh_emulate_ctxt *sh_ctxt =
    3.98 +        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
    3.99      unsigned long addr;
   3.100 -    int rc;
   3.101 -
   3.102 -    rc = hvm_translate_linear_addr(seg, offset, bytes, 0, &addr);
   3.103 +    int rc, errcode;
   3.104 +
   3.105 +    rc = hvm_translate_linear_addr(seg, offset, bytes, 0, sh_ctxt, &addr);
   3.106      if ( rc )
   3.107          return rc;
   3.108  
   3.109 @@ -161,7 +173,7 @@ sh_x86_emulate_read(enum x86_segment seg
   3.110      //        It entirely ignores the permissions in the page tables.
   3.111      //        In this case, that is only a user vs supervisor access check.
   3.112      //
   3.113 -    if ( hvm_copy_from_guest_virt(val, addr, bytes) == 0 )
   3.114 +    if ( (rc = hvm_copy_from_guest_virt(val, addr, bytes)) == 0 )
   3.115      {
   3.116  #if 0
   3.117          struct vcpu *v = current;
   3.118 @@ -176,6 +188,8 @@ sh_x86_emulate_read(enum x86_segment seg
   3.119       * was mapped here.  This should never happen: we're here because
   3.120       * of a write fault at the end of the instruction we're emulating. */ 
   3.121      SHADOW_PRINTK("read failed to va %#lx\n", addr);
   3.122 +    errcode = ring_3(sh_ctxt->ctxt.regs) ? PFEC_user_mode : 0;
   3.123 +    hvm_inject_exception(TRAP_page_fault, errcode, addr + bytes - rc);
   3.124      return X86EMUL_PROPAGATE_FAULT;
   3.125  }
   3.126  
   3.127 @@ -186,11 +200,13 @@ sh_x86_emulate_write(enum x86_segment se
   3.128                       unsigned int bytes,
   3.129                       struct x86_emulate_ctxt *ctxt)
   3.130  {
   3.131 +    struct sh_emulate_ctxt *sh_ctxt =
   3.132 +        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   3.133      struct vcpu *v = current;
   3.134      unsigned long addr;
   3.135      int rc;
   3.136  
   3.137 -    rc = hvm_translate_linear_addr(seg, offset, bytes, 1, &addr);
   3.138 +    rc = hvm_translate_linear_addr(seg, offset, bytes, 1, sh_ctxt, &addr);
   3.139      if ( rc )
   3.140          return rc;
   3.141  
   3.142 @@ -198,7 +214,8 @@ sh_x86_emulate_write(enum x86_segment se
   3.143      SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
   3.144                    v->domain->domain_id, v->vcpu_id, addr, val, bytes);
   3.145  #endif
   3.146 -    return v->arch.shadow.mode->x86_emulate_write(v, addr, &val, bytes, ctxt);
   3.147 +    return v->arch.shadow.mode->x86_emulate_write(
   3.148 +        v, addr, &val, bytes, sh_ctxt);
   3.149  }
   3.150  
   3.151  static int 
   3.152 @@ -209,11 +226,13 @@ sh_x86_emulate_cmpxchg(enum x86_segment 
   3.153                         unsigned int bytes,
   3.154                         struct x86_emulate_ctxt *ctxt)
   3.155  {
   3.156 +    struct sh_emulate_ctxt *sh_ctxt =
   3.157 +        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   3.158      struct vcpu *v = current;
   3.159      unsigned long addr;
   3.160      int rc;
   3.161  
   3.162 -    rc = hvm_translate_linear_addr(seg, offset, bytes, 1, &addr);
   3.163 +    rc = hvm_translate_linear_addr(seg, offset, bytes, 1, sh_ctxt, &addr);
   3.164      if ( rc )
   3.165          return rc;
   3.166  
   3.167 @@ -221,8 +240,8 @@ sh_x86_emulate_cmpxchg(enum x86_segment 
   3.168      SHADOW_PRINTK("d=%u v=%u a=%#lx o?=%#lx n:=%#lx bytes=%u\n",
   3.169                     v->domain->domain_id, v->vcpu_id, addr, old, new, bytes);
   3.170  #endif
   3.171 -    return v->arch.shadow.mode->x86_emulate_cmpxchg(v, addr, old, new,
   3.172 -                                                     bytes, ctxt);
   3.173 +    return v->arch.shadow.mode->x86_emulate_cmpxchg(
   3.174 +        v, addr, old, new, bytes, sh_ctxt);
   3.175  }
   3.176  
   3.177  static int 
   3.178 @@ -234,11 +253,13 @@ sh_x86_emulate_cmpxchg8b(enum x86_segmen
   3.179                           unsigned long new_hi,
   3.180                           struct x86_emulate_ctxt *ctxt)
   3.181  {
   3.182 +    struct sh_emulate_ctxt *sh_ctxt =
   3.183 +        container_of(ctxt, struct sh_emulate_ctxt, ctxt);
   3.184      struct vcpu *v = current;
   3.185      unsigned long addr;
   3.186      int rc;
   3.187  
   3.188 -    rc = hvm_translate_linear_addr(seg, offset, 8, 1, &addr);
   3.189 +    rc = hvm_translate_linear_addr(seg, offset, 8, 1, sh_ctxt, &addr);
   3.190      if ( rc )
   3.191          return rc;
   3.192  
   3.193 @@ -247,8 +268,8 @@ sh_x86_emulate_cmpxchg8b(enum x86_segmen
   3.194                     v->domain->domain_id, v->vcpu_id, addr, old_hi, old_lo,
   3.195                     new_hi, new_lo, ctxt);
   3.196  #endif
   3.197 -    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(v, addr, old_lo, old_hi,
   3.198 -                                                       new_lo, new_hi, ctxt);
   3.199 +    return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
   3.200 +        v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
   3.201  }
   3.202  
   3.203  
     4.1 --- a/xen/arch/x86/mm/shadow/multi.c	Fri Dec 01 15:12:48 2006 +0000
     4.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Fri Dec 01 15:45:59 2006 +0000
     4.3 @@ -2582,7 +2582,7 @@ static int sh_page_fault(struct vcpu *v,
     4.4      mfn_t gmfn, sl1mfn=_mfn(0);
     4.5      shadow_l1e_t sl1e, *ptr_sl1e;
     4.6      paddr_t gpa;
     4.7 -    struct x86_emulate_ctxt emul_ctxt;
     4.8 +    struct sh_emulate_ctxt emul_ctxt;
     4.9      int r, mmio;
    4.10      fetch_type_t ft = 0;
    4.11  
    4.12 @@ -2808,17 +2808,17 @@ static int sh_page_fault(struct vcpu *v,
    4.13      return EXCRET_fault_fixed;
    4.14  
    4.15   emulate:
    4.16 -    /* Take the register set we were called with */
    4.17 -    if ( is_hvm_domain(d) )
    4.18 -        hvm_store_cpu_guest_regs(v, regs, NULL);
    4.19 -    emul_ctxt.regs = regs;
    4.20 -    emul_ctxt.mode = (is_hvm_domain(d) ?
    4.21 -                      hvm_guest_x86_mode(v) : X86EMUL_MODE_HOST);
    4.22 +    if ( !is_hvm_domain(d) )
    4.23 +        goto not_a_shadow_fault;
    4.24 +
    4.25 +    hvm_store_cpu_guest_regs(v, regs, NULL);
    4.26 +    emul_ctxt.ctxt.regs = regs;
    4.27 +    emul_ctxt.ctxt.mode = (is_hvm_domain(d) ?
    4.28 +                           hvm_guest_x86_mode(v) : X86EMUL_MODE_HOST);
    4.29 +    emul_ctxt.valid_seg_regs = 0;
    4.30  
    4.31      SHADOW_PRINTK("emulate: eip=%#lx\n", regs->eip);
    4.32  
    4.33 -    v->arch.shadow.propagate_fault = 0;
    4.34 -
    4.35      /*
    4.36       * We do not emulate user writes. Instead we use them as a hint that the
    4.37       * page is no longer a page table. This behaviour differs from native, but
    4.38 @@ -2826,7 +2826,7 @@ static int sh_page_fault(struct vcpu *v,
    4.39       * We also disallow guest PTE updates from within Xen.
    4.40       */
    4.41      if ( (regs->error_code & PFEC_user_mode) || !guest_mode(regs) ||
    4.42 -         x86_emulate_memop(&emul_ctxt, &shadow_emulator_ops) )
    4.43 +         x86_emulate_memop(&emul_ctxt.ctxt, &shadow_emulator_ops) )
    4.44      {
    4.45          SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", 
    4.46                         mfn_x(gmfn));
    4.47 @@ -2835,19 +2835,10 @@ static int sh_page_fault(struct vcpu *v,
    4.48           * to support more operations in the emulator.  More likely, 
    4.49           * though, this is a hint that this page should not be shadowed. */
    4.50          shadow_remove_all_shadows(v, gmfn);
    4.51 -        /* This means that actual missing operations will cause the 
    4.52 -         * guest to loop on the same page fault. */
    4.53 -        goto done;
    4.54      }
    4.55  
    4.56 -    /* Emulation triggered another page fault? */
    4.57 -    if ( v->arch.shadow.propagate_fault )
    4.58 -        goto not_a_shadow_fault;
    4.59 -
    4.60      /* Emulator has changed the user registers: write back */
    4.61 -    if ( is_hvm_domain(d) )
    4.62 -        hvm_load_cpu_guest_regs(v, regs);
    4.63 -
    4.64 +    hvm_load_cpu_guest_regs(v, regs);
    4.65      goto done;
    4.66  
    4.67   mmio:
    4.68 @@ -3786,11 +3777,11 @@ int sh_remove_l3_shadow(struct vcpu *v, 
    4.69   * or NULL for error. */
    4.70  static inline void * emulate_map_dest(struct vcpu *v,
    4.71                                        unsigned long vaddr,
    4.72 -                                      struct x86_emulate_ctxt *ctxt,
    4.73 +                                      struct sh_emulate_ctxt *sh_ctxt,
    4.74                                        mfn_t *mfnp)
    4.75  {
    4.76      walk_t gw;
    4.77 -    u32 flags;
    4.78 +    u32 flags, errcode;
    4.79      gfn_t gfn;
    4.80      mfn_t mfn;
    4.81  
    4.82 @@ -3801,13 +3792,17 @@ static inline void * emulate_map_dest(st
    4.83      sh_audit_gw(v, &gw);
    4.84      unmap_walk(v, &gw);
    4.85  
    4.86 -    if ( !(flags & _PAGE_PRESENT) 
    4.87 -         || !(flags & _PAGE_RW) 
    4.88 -         || (!(flags & _PAGE_USER) && ring_3(ctxt->regs)) )
    4.89 +    if ( !(flags & _PAGE_PRESENT) )
    4.90      {
    4.91 -        /* This write would have faulted even on bare metal */
    4.92 -        v->arch.shadow.propagate_fault = 1;
    4.93 -        return NULL;
    4.94 +        errcode = 0;
    4.95 +        goto page_fault;
    4.96 +    }
    4.97 +
    4.98 +    if ( !(flags & _PAGE_RW) ||
    4.99 +         (!(flags & _PAGE_USER) && ring_3(sh_ctxt->ctxt.regs)) )
   4.100 +    {
   4.101 +        errcode = PFEC_page_present;
   4.102 +        goto page_fault;
   4.103      }
   4.104  
   4.105      /* Attempted a write to a bad gfn? This should never happen:
   4.106 @@ -3817,11 +3812,18 @@ static inline void * emulate_map_dest(st
   4.107      ASSERT(sh_mfn_is_a_page_table(mfn));
   4.108      *mfnp = mfn;
   4.109      return sh_map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
   4.110 +
   4.111 + page_fault:
   4.112 +    errcode |= PFEC_write_access;
   4.113 +    if ( ring_3(sh_ctxt->ctxt.regs) )
   4.114 +        errcode |= PFEC_user_mode;
   4.115 +    hvm_inject_exception(TRAP_page_fault, errcode, vaddr);
   4.116 +    return NULL;
   4.117  }
   4.118  
   4.119  int
   4.120  sh_x86_emulate_write(struct vcpu *v, unsigned long vaddr, void *src,
   4.121 -                      u32 bytes, struct x86_emulate_ctxt *ctxt)
   4.122 +                      u32 bytes, struct sh_emulate_ctxt *sh_ctxt)
   4.123  {
   4.124      mfn_t mfn;
   4.125      void *addr;
   4.126 @@ -3832,7 +3834,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
   4.127      ASSERT(shadow_lock_is_acquired(v->domain));
   4.128      ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
   4.129  
   4.130 -    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
   4.131 +    if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
   4.132          return X86EMUL_PROPAGATE_FAULT;
   4.133  
   4.134      memcpy(addr, src, bytes);
   4.135 @@ -3850,7 +3852,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
   4.136  int
   4.137  sh_x86_emulate_cmpxchg(struct vcpu *v, unsigned long vaddr, 
   4.138                          unsigned long old, unsigned long new,
   4.139 -                        unsigned int bytes, struct x86_emulate_ctxt *ctxt)
   4.140 +                        unsigned int bytes, struct sh_emulate_ctxt *sh_ctxt)
   4.141  {
   4.142      mfn_t mfn;
   4.143      void *addr;
   4.144 @@ -3863,7 +3865,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
   4.145      if ( vaddr & (bytes-1) )
   4.146          return X86EMUL_UNHANDLEABLE;
   4.147  
   4.148 -    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
   4.149 +    if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
   4.150          return X86EMUL_PROPAGATE_FAULT;
   4.151  
   4.152      switch ( bytes )
   4.153 @@ -3899,7 +3901,7 @@ int
   4.154  sh_x86_emulate_cmpxchg8b(struct vcpu *v, unsigned long vaddr, 
   4.155                            unsigned long old_lo, unsigned long old_hi,
   4.156                            unsigned long new_lo, unsigned long new_hi,
   4.157 -                          struct x86_emulate_ctxt *ctxt)
   4.158 +                          struct sh_emulate_ctxt *sh_ctxt)
   4.159  {
   4.160      mfn_t mfn;
   4.161      void *addr;
   4.162 @@ -3911,7 +3913,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
   4.163      if ( vaddr & 7 )
   4.164          return X86EMUL_UNHANDLEABLE;
   4.165  
   4.166 -    if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
   4.167 +    if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
   4.168          return X86EMUL_PROPAGATE_FAULT;
   4.169  
   4.170      old = (((u64) old_hi) << 32) | (u64) old_lo;
     5.1 --- a/xen/arch/x86/mm/shadow/private.h	Fri Dec 01 15:12:48 2006 +0000
     5.2 +++ b/xen/arch/x86/mm/shadow/private.h	Fri Dec 01 15:45:59 2006 +0000
     5.3 @@ -506,6 +506,19 @@ static inline void sh_unpin(struct vcpu 
     5.4      }
     5.5  }
     5.6  
     5.7 +
     5.8 +/**************************************************************************/
     5.9 +/* PTE-write emulation. */
    5.10 +
    5.11 +struct sh_emulate_ctxt {
    5.12 +    struct x86_emulate_ctxt ctxt;
    5.13 +
    5.14 +    /* Cache of segment registers already gathered for this emulation. */
    5.15 +    unsigned int valid_seg_regs;
    5.16 +    struct segment_register seg_reg[6];
    5.17 +};
    5.18 +
    5.19 +
    5.20  #endif /* _XEN_SHADOW_PRIVATE_H */
    5.21  
    5.22  /*
     6.1 --- a/xen/include/asm-x86/domain.h	Fri Dec 01 15:12:48 2006 +0000
     6.2 +++ b/xen/include/asm-x86/domain.h	Fri Dec 01 15:45:59 2006 +0000
     6.3 @@ -147,8 +147,6 @@ struct shadow_vcpu {
     6.4      unsigned long last_writeable_pte_smfn;
     6.5      /* HVM guest: paging enabled (CR0.PG)?  */
     6.6      unsigned int translate_enabled:1;
     6.7 -    /* Emulated fault needs to be propagated to guest? */
     6.8 -    unsigned int propagate_fault:1;
     6.9  };
    6.10  
    6.11  struct arch_vcpu
     7.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Dec 01 15:12:48 2006 +0000
     7.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Dec 01 15:45:59 2006 +0000
     7.3 @@ -110,7 +110,8 @@ struct hvm_function_table {
     7.4      void (*stts)(struct vcpu *v);
     7.5      void (*set_tsc_offset)(struct vcpu *v, u64 offset);
     7.6  
     7.7 -    void (*inject_exception)(unsigned int trapnr, int errcode);
     7.8 +    void (*inject_exception)(unsigned int trapnr, int errcode,
     7.9 +                             unsigned long cr2);
    7.10  
    7.11      void (*init_ap_context)(struct vcpu_guest_context *ctxt,
    7.12                              int vcpuid, int trampoline_vector);
    7.13 @@ -225,9 +226,9 @@ hvm_init_ap_context(struct vcpu_guest_co
    7.14  }
    7.15  
    7.16  static inline void
    7.17 -hvm_inject_exception(unsigned int trapnr, int errcode)
    7.18 +hvm_inject_exception(unsigned int trapnr, int errcode, unsigned long cr2)
    7.19  {
    7.20 -    hvm_funcs.inject_exception(trapnr, errcode);
    7.21 +    hvm_funcs.inject_exception(trapnr, errcode, cr2);
    7.22  }
    7.23  
    7.24  int hvm_bringup_ap(int vcpuid, int trampoline_vector);
     8.1 --- a/xen/include/asm-x86/shadow.h	Fri Dec 01 15:12:48 2006 +0000
     8.2 +++ b/xen/include/asm-x86/shadow.h	Fri Dec 01 15:45:59 2006 +0000
     8.3 @@ -246,7 +246,7 @@ shadow_vcpu_mode_translate(struct vcpu *
     8.4  /**************************************************************************/
     8.5  /* Mode-specific entry points into the shadow code */
     8.6  
     8.7 -struct x86_emulate_ctxt;
     8.8 +struct sh_emulate_ctxt;
     8.9  struct shadow_paging_mode {
    8.10      int           (*page_fault            )(struct vcpu *v, unsigned long va,
    8.11                                              struct cpu_user_regs *regs);
    8.12 @@ -267,18 +267,18 @@ struct shadow_paging_mode {
    8.13      void          (*detach_old_tables     )(struct vcpu *v);
    8.14      int           (*x86_emulate_write     )(struct vcpu *v, unsigned long va,
    8.15                                              void *src, u32 bytes,
    8.16 -                                            struct x86_emulate_ctxt *ctxt);
    8.17 +                                            struct sh_emulate_ctxt *sh_ctxt);
    8.18      int           (*x86_emulate_cmpxchg   )(struct vcpu *v, unsigned long va,
    8.19                                              unsigned long old, 
    8.20                                              unsigned long new,
    8.21                                              unsigned int bytes,
    8.22 -                                            struct x86_emulate_ctxt *ctxt);
    8.23 +                                            struct sh_emulate_ctxt *sh_ctxt);
    8.24      int           (*x86_emulate_cmpxchg8b )(struct vcpu *v, unsigned long va,
    8.25                                              unsigned long old_lo, 
    8.26                                              unsigned long old_hi, 
    8.27                                              unsigned long new_lo,
    8.28                                              unsigned long new_hi,
    8.29 -                                            struct x86_emulate_ctxt *ctxt);
    8.30 +                                            struct sh_emulate_ctxt *sh_ctxt);
    8.31      mfn_t         (*make_monitor_table    )(struct vcpu *v);
    8.32      void          (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn);
    8.33      void *        (*guest_map_l1e         )(struct vcpu *v, unsigned long va,