ia64/xen-unstable

changeset 10179:41de9cd7971b

Change the x86_emulate() interface to pack all context arguments
into a context structure. This context can then be handed to
callback operations.

Based on an original patch from Mats Petersson <mats.petersson@amd.com>

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu May 25 15:52:38 2006 +0100 (2006-05-25)
parents 79d74ce206bb
children 4c058926e92b
files tools/tests/test_x86_emulator.c xen/arch/x86/mm.c xen/arch/x86/x86_emulate.c xen/include/asm-x86/x86_emulate.h
line diff
     1.1 --- a/tools/tests/test_x86_emulator.c	Thu May 25 14:54:43 2006 +0100
     1.2 +++ b/tools/tests/test_x86_emulator.c	Thu May 25 15:52:38 2006 +0100
     1.3 @@ -17,7 +17,8 @@ typedef int64_t            s64;
     1.4  static int read_any(
     1.5      unsigned long addr,
     1.6      unsigned long *val,
     1.7 -    unsigned int bytes)
     1.8 +    unsigned int bytes,
     1.9 +    struct x86_emulate_ctxt *ctxt)
    1.10  {
    1.11      switch ( bytes )
    1.12      {
    1.13 @@ -32,7 +33,8 @@ static int read_any(
    1.14  static int write_any(
    1.15      unsigned long addr,
    1.16      unsigned long val,
    1.17 -    unsigned int bytes)
    1.18 +    unsigned int bytes,
    1.19 +    struct x86_emulate_ctxt *ctxt)
    1.20  {
    1.21      switch ( bytes )
    1.22      {
    1.23 @@ -48,7 +50,8 @@ static int cmpxchg_any(
    1.24      unsigned long addr,
    1.25      unsigned long old,
    1.26      unsigned long new,
    1.27 -    unsigned int bytes)
    1.28 +    unsigned int bytes,
    1.29 +    struct x86_emulate_ctxt *ctxt)
    1.30  {
    1.31      switch ( bytes )
    1.32      {
    1.33 @@ -65,34 +68,38 @@ static int cmpxchg8b_any(
    1.34      unsigned long old_lo,
    1.35      unsigned long old_hi,
    1.36      unsigned long new_lo,
    1.37 -    unsigned long new_hi)
    1.38 +    unsigned long new_hi,
    1.39 +    struct x86_emulate_ctxt *ctxt)
    1.40  {
    1.41      ((unsigned long *)addr)[0] = new_lo;
    1.42      ((unsigned long *)addr)[1] = new_hi;
    1.43      return X86EMUL_CONTINUE;
    1.44  }
    1.45  
    1.46 -static struct x86_mem_emulator emulops = {
    1.47 +static struct x86_emulate_ops emulops = {
    1.48      read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any
    1.49  };
    1.50  
    1.51  int main(int argc, char **argv)
    1.52  {
    1.53 +    struct x86_emulate_ctxt ctxt;
    1.54      struct cpu_user_regs regs;
    1.55      char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
    1.56      unsigned int res = 0x7FFFFFFF;
    1.57      u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 };
    1.58 -    unsigned long cr2;
    1.59      int rc;
    1.60  
    1.61 +    ctxt.regs = &regs;
    1.62 +    ctxt.mode = X86EMUL_MODE_PROT32;
    1.63 +
    1.64      printf("%-40s", "Testing addl %%ecx,(%%eax)...");
    1.65      instr[0] = 0x01; instr[1] = 0x08;
    1.66      regs.eflags = 0x200;
    1.67      regs.eip    = (unsigned long)&instr[0];
    1.68      regs.ecx    = 0x12345678;
    1.69 -    cr2         = (unsigned long)&res;
    1.70 +    ctxt.cr2    = (unsigned long)&res;
    1.71      res         = 0x7FFFFFFF;
    1.72 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
    1.73 +    rc = x86_emulate_memop(&ctxt, &emulops);
    1.74      if ( (rc != 0) || 
    1.75           (res != 0x92345677) || 
    1.76           (regs.eflags != 0xa94) ||
    1.77 @@ -109,8 +116,8 @@ int main(int argc, char **argv)
    1.78  #else
    1.79      regs.ecx    = 0x12345678UL;
    1.80  #endif
    1.81 -    cr2         = (unsigned long)&res;
    1.82 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
    1.83 +    ctxt.cr2    = (unsigned long)&res;
    1.84 +    rc = x86_emulate_memop(&ctxt, &emulops);
    1.85      if ( (rc != 0) || 
    1.86           (res != 0x92345677) || 
    1.87           (regs.ecx != 0x8000000FUL) ||
    1.88 @@ -124,8 +131,8 @@ int main(int argc, char **argv)
    1.89      regs.eip    = (unsigned long)&instr[0];
    1.90      regs.eax    = 0x92345677UL;
    1.91      regs.ecx    = 0xAA;
    1.92 -    cr2         = (unsigned long)&res;
    1.93 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);    
    1.94 +    ctxt.cr2    = (unsigned long)&res;
    1.95 +    rc = x86_emulate_memop(&ctxt, &emulops);
    1.96      if ( (rc != 0) || 
    1.97           (res != 0x923456AA) || 
    1.98           (regs.eflags != 0x244) ||
    1.99 @@ -140,8 +147,8 @@ int main(int argc, char **argv)
   1.100      regs.eip    = (unsigned long)&instr[0];
   1.101      regs.eax    = 0xAABBCC77UL;
   1.102      regs.ecx    = 0xFF;
   1.103 -    cr2         = (unsigned long)&res;
   1.104 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);    
   1.105 +    ctxt.cr2    = (unsigned long)&res;
   1.106 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.107      if ( (rc != 0) || 
   1.108           (res != 0x923456AA) || 
   1.109           ((regs.eflags&0x240) != 0x200) ||
   1.110 @@ -156,8 +163,8 @@ int main(int argc, char **argv)
   1.111      regs.eflags = 0x200;
   1.112      regs.eip    = (unsigned long)&instr[0];
   1.113      regs.ecx    = 0x12345678;
   1.114 -    cr2         = (unsigned long)&res;
   1.115 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);    
   1.116 +    ctxt.cr2    = (unsigned long)&res;
   1.117 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.118      if ( (rc != 0) || 
   1.119           (res != 0x12345678) || 
   1.120           (regs.eflags != 0x200) ||
   1.121 @@ -173,8 +180,8 @@ int main(int argc, char **argv)
   1.122      regs.eip    = (unsigned long)&instr[0];
   1.123      regs.eax    = 0x923456AAUL;
   1.124      regs.ecx    = 0xDDEEFF00L;
   1.125 -    cr2         = (unsigned long)&res;
   1.126 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);    
   1.127 +    ctxt.cr2    = (unsigned long)&res;
   1.128 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.129      if ( (rc != 0) || 
   1.130           (res != 0xDDEEFF00) || 
   1.131           (regs.eflags != 0x244) ||
   1.132 @@ -192,8 +199,8 @@ int main(int argc, char **argv)
   1.133      regs.esi    = (unsigned long)&res + 0;
   1.134      regs.edi    = (unsigned long)&res + 2;
   1.135      regs.error_code = 0; /* read fault */
   1.136 -    cr2         = regs.esi;
   1.137 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);    
   1.138 +    ctxt.cr2    = regs.esi;
   1.139 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.140      if ( (rc != 0) || 
   1.141           (res != 0x44554455) ||
   1.142           (regs.eflags != 0x200) ||
   1.143 @@ -210,8 +217,8 @@ int main(int argc, char **argv)
   1.144      regs.eflags = 0x200;
   1.145      regs.eip    = (unsigned long)&instr[0];
   1.146      regs.edi    = (unsigned long)&res;
   1.147 -    cr2         = regs.edi;
   1.148 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);    
   1.149 +    ctxt.cr2    = regs.edi;
   1.150 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.151      if ( (rc != 0) || 
   1.152           (res != 0x2233445D) ||
   1.153           ((regs.eflags&0x201) != 0x201) ||
   1.154 @@ -228,8 +235,8 @@ int main(int argc, char **argv)
   1.155      regs.ecx    = 0xCCCCFFFF;
   1.156      regs.eip    = (unsigned long)&instr[0];
   1.157      regs.edi    = (unsigned long)cmpxchg8b_res;
   1.158 -    cr2         = regs.edi;
   1.159 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
   1.160 +    ctxt.cr2    = regs.edi;
   1.161 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.162      if ( (rc != 0) || 
   1.163           (cmpxchg8b_res[0] != 0x9999AAAA) ||
   1.164           (cmpxchg8b_res[1] != 0xCCCCFFFF) ||
   1.165 @@ -242,8 +249,8 @@ int main(int argc, char **argv)
   1.166      instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
   1.167      regs.eip    = (unsigned long)&instr[0];
   1.168      regs.edi    = (unsigned long)cmpxchg8b_res;
   1.169 -    cr2         = regs.edi;
   1.170 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
   1.171 +    ctxt.cr2    = regs.edi;
   1.172 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.173      if ( (rc != 0) || 
   1.174           (cmpxchg8b_res[0] != 0x9999AAAA) ||
   1.175           (cmpxchg8b_res[1] != 0xCCCCFFFF) ||
   1.176 @@ -258,9 +265,9 @@ int main(int argc, char **argv)
   1.177      instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
   1.178      regs.eip    = (unsigned long)&instr[0];
   1.179      regs.ecx    = 0x12345678;
   1.180 -    cr2         = (unsigned long)&res;
   1.181 +    ctxt.cr2    = (unsigned long)&res;
   1.182      res         = 0x82;
   1.183 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
   1.184 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.185      if ( (rc != 0) ||
   1.186           (res != 0x82) ||
   1.187           (regs.ecx != 0xFFFFFF82) ||
   1.188 @@ -273,9 +280,9 @@ int main(int argc, char **argv)
   1.189      instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
   1.190      regs.eip    = (unsigned long)&instr[0];
   1.191      regs.ecx    = 0x12345678;
   1.192 -    cr2         = (unsigned long)&res;
   1.193 +    ctxt.cr2    = (unsigned long)&res;
   1.194      res         = 0x1234aa82;
   1.195 -    rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
   1.196 +    rc = x86_emulate_memop(&ctxt, &emulops);
   1.197      if ( (rc != 0) ||
   1.198           (res != 0x1234aa82) ||
   1.199           (regs.ecx != 0xaa82) ||
     2.1 --- a/xen/arch/x86/mm.c	Thu May 25 14:54:43 2006 +0100
     2.2 +++ b/xen/arch/x86/mm.c	Thu May 25 15:52:38 2006 +0100
     2.3 @@ -3220,15 +3220,16 @@ static int ptwr_emulated_update(
     2.4      /* Turn a sub-word access into a full-word access. */
     2.5      if ( bytes != sizeof(paddr_t) )
     2.6      {
     2.7 -        int           rc;
     2.8 -        paddr_t    full;
     2.9 -        unsigned int  offset = addr & (sizeof(paddr_t)-1);
    2.10 +        paddr_t      full;
    2.11 +        unsigned int offset = addr & (sizeof(paddr_t)-1);
    2.12  
    2.13          /* Align address; read full word. */
    2.14          addr &= ~(sizeof(paddr_t)-1);
    2.15 -        if ( (rc = x86_emulate_read_std(addr, (unsigned long *)&full,
    2.16 -                                        sizeof(paddr_t))) )
    2.17 -            return rc; 
    2.18 +        if ( copy_from_user(&full, (void *)addr, sizeof(paddr_t)) )
    2.19 +        {
    2.20 +            propagate_page_fault(addr, 4); /* user mode, read fault */
    2.21 +            return X86EMUL_PROPAGATE_FAULT;
    2.22 +        }
    2.23          /* Mask out bits provided by caller. */
    2.24          full &= ~((((paddr_t)1 << (bytes*8)) - 1) << (offset*8));
    2.25          /* Shift the caller value and OR in the missing bits. */
    2.26 @@ -3306,7 +3307,8 @@ static int ptwr_emulated_update(
    2.27  static int ptwr_emulated_write(
    2.28      unsigned long addr,
    2.29      unsigned long val,
    2.30 -    unsigned int bytes)
    2.31 +    unsigned int bytes,
    2.32 +    struct x86_emulate_ctxt *ctxt)
    2.33  {
    2.34      return ptwr_emulated_update(addr, 0, val, bytes, 0);
    2.35  }
    2.36 @@ -3315,7 +3317,8 @@ static int ptwr_emulated_cmpxchg(
    2.37      unsigned long addr,
    2.38      unsigned long old,
    2.39      unsigned long new,
    2.40 -    unsigned int bytes)
    2.41 +    unsigned int bytes,
    2.42 +    struct x86_emulate_ctxt *ctxt)
    2.43  {
    2.44      return ptwr_emulated_update(addr, old, new, bytes, 1);
    2.45  }
    2.46 @@ -3325,7 +3328,8 @@ static int ptwr_emulated_cmpxchg8b(
    2.47      unsigned long old,
    2.48      unsigned long old_hi,
    2.49      unsigned long new,
    2.50 -    unsigned long new_hi)
    2.51 +    unsigned long new_hi,
    2.52 +    struct x86_emulate_ctxt *ctxt)
    2.53  {
    2.54      if ( CONFIG_PAGING_LEVELS == 2 )
    2.55          return X86EMUL_UNHANDLEABLE;
    2.56 @@ -3334,7 +3338,7 @@ static int ptwr_emulated_cmpxchg8b(
    2.57              addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
    2.58  }
    2.59  
    2.60 -static struct x86_mem_emulator ptwr_mem_emulator = {
    2.61 +static struct x86_emulate_ops ptwr_emulate_ops = {
    2.62      .read_std           = x86_emulate_read_std,
    2.63      .write_std          = x86_emulate_write_std,
    2.64      .read_emulated      = x86_emulate_read_std,
    2.65 @@ -3353,6 +3357,7 @@ int ptwr_do_page_fault(struct domain *d,
    2.66      l2_pgentry_t    *pl2e, l2e;
    2.67      int              which, flags;
    2.68      unsigned long    l2_idx;
    2.69 +    struct x86_emulate_ctxt emul_ctxt;
    2.70  
    2.71      if ( unlikely(shadow_mode_enabled(d)) )
    2.72          return 0;
    2.73 @@ -3507,8 +3512,10 @@ int ptwr_do_page_fault(struct domain *d,
    2.74      return EXCRET_fault_fixed;
    2.75  
    2.76   emulate:
    2.77 -    if ( x86_emulate_memop(guest_cpu_user_regs(), addr,
    2.78 -                           &ptwr_mem_emulator, X86EMUL_MODE_HOST) )
    2.79 +    emul_ctxt.regs = guest_cpu_user_regs();
    2.80 +    emul_ctxt.cr2  = addr;
    2.81 +    emul_ctxt.mode = X86EMUL_MODE_HOST;
    2.82 +    if ( x86_emulate_memop(&emul_ctxt, &ptwr_emulate_ops) )
    2.83          return 0;
    2.84      perfc_incrc(ptwr_emulations);
    2.85      return EXCRET_fault_fixed;
     3.1 --- a/xen/arch/x86/x86_emulate.c	Thu May 25 14:54:43 2006 +0100
     3.2 +++ b/xen/arch/x86/x86_emulate.c	Thu May 25 15:52:38 2006 +0100
     3.3 @@ -363,12 +363,13 @@ do{ __asm__ __volatile__ (              
     3.4  #endif /* __i386__ */
     3.5  
     3.6  /* Fetch next part of the instruction being emulated. */
     3.7 -#define insn_fetch(_type, _size, _eip) \
     3.8 -({ unsigned long _x; \
     3.9 -   if ( (rc = ops->read_std((unsigned long)(_eip), &_x, (_size))) != 0 ) \
    3.10 -       goto done; \
    3.11 -   (_eip) += (_size); \
    3.12 -   (_type)_x; \
    3.13 +#define insn_fetch(_type, _size, _eip)                                  \
    3.14 +({ unsigned long _x;                                                    \
    3.15 +   rc = ops->read_std((unsigned long)(_eip), &_x, (_size), ctxt);       \
    3.16 +   if ( rc != 0 )                                                       \
    3.17 +       goto done;                                                       \
    3.18 +   (_eip) += (_size);                                                   \
    3.19 +   (_type)_x;                                                           \
    3.20  })
    3.21  
    3.22  /* Access/update address held in a register, based on addressing mode. */
    3.23 @@ -426,12 +427,10 @@ decode_register(
    3.24      return p;
    3.25  }
    3.26  
    3.27 -int 
    3.28 +int
    3.29  x86_emulate_memop(
    3.30 -    struct cpu_user_regs *regs,
    3.31 -    unsigned long cr2,
    3.32 -    struct x86_mem_emulator *ops,
    3.33 -    int mode)
    3.34 +    struct x86_emulate_ctxt *ctxt,
    3.35 +    struct x86_emulate_ops  *ops)
    3.36  {
    3.37      uint8_t b, d, sib, twobyte = 0, rex_prefix = 0;
    3.38      uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
    3.39 @@ -439,9 +438,11 @@ x86_emulate_memop(
    3.40      unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
    3.41      int rc = 0;
    3.42      struct operand src, dst;
    3.43 +    unsigned long cr2 = ctxt->cr2;
    3.44 +    int mode = ctxt->mode;
    3.45  
    3.46      /* Shadow copy of register state. Committed on successful emulation. */
    3.47 -    struct cpu_user_regs _regs = *regs;
    3.48 +    struct cpu_user_regs _regs = *ctxt->regs;
    3.49  
    3.50      switch ( mode )
    3.51      {
    3.52 @@ -628,7 +629,7 @@ x86_emulate_memop(
    3.53          dst.bytes = (d & ByteOp) ? 1 : op_bytes;
    3.54          if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
    3.55               ((rc = ops->read_emulated((unsigned long)dst.ptr,
    3.56 -                                       &dst.val, dst.bytes)) != 0) )
    3.57 +                                       &dst.val, dst.bytes, ctxt)) != 0) )
    3.58               goto done;
    3.59          break;
    3.60      }
    3.61 @@ -670,7 +671,7 @@ x86_emulate_memop(
    3.62          src.type  = OP_MEM;
    3.63          src.ptr   = (unsigned long *)cr2;
    3.64          if ( (rc = ops->read_emulated((unsigned long)src.ptr, 
    3.65 -                                      &src.val, src.bytes)) != 0 )
    3.66 +                                      &src.val, src.bytes, ctxt)) != 0 )
    3.67              goto done;
    3.68          src.orig_val = src.val;
    3.69          break;
    3.70 @@ -776,7 +777,7 @@ x86_emulate_memop(
    3.71          if ( mode == X86EMUL_MODE_PROT64 )
    3.72              dst.bytes = 8;
    3.73          if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp),
    3.74 -                                 &dst.val, dst.bytes)) != 0 )
    3.75 +                                 &dst.val, dst.bytes, ctxt)) != 0 )
    3.76              goto done;
    3.77          register_address_increment(_regs.esp, dst.bytes);
    3.78          break;
    3.79 @@ -854,12 +855,12 @@ x86_emulate_memop(
    3.80              {
    3.81                  dst.bytes = 8;
    3.82                  if ( (rc = ops->read_std((unsigned long)dst.ptr,
    3.83 -                                         &dst.val, 8)) != 0 )
    3.84 +                                         &dst.val, 8, ctxt)) != 0 )
    3.85                      goto done;
    3.86              }
    3.87              register_address_increment(_regs.esp, -dst.bytes);
    3.88              if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp),
    3.89 -                                      dst.val, dst.bytes)) != 0 )
    3.90 +                                      dst.val, dst.bytes, ctxt)) != 0 )
    3.91                  goto done;
    3.92              dst.val = dst.orig_val; /* skanky: disable writeback */
    3.93              break;
    3.94 @@ -887,10 +888,11 @@ x86_emulate_memop(
    3.95          case OP_MEM:
    3.96              if ( lock_prefix )
    3.97                  rc = ops->cmpxchg_emulated(
    3.98 -                    (unsigned long)dst.ptr, dst.orig_val, dst.val, dst.bytes);
    3.99 +                    (unsigned long)dst.ptr, dst.orig_val,
   3.100 +                    dst.val, dst.bytes, ctxt);
   3.101              else
   3.102                  rc = ops->write_emulated(
   3.103 -                    (unsigned long)dst.ptr, dst.val, dst.bytes);
   3.104 +                    (unsigned long)dst.ptr, dst.val, dst.bytes, ctxt);
   3.105              if ( rc != 0 )
   3.106                  goto done;
   3.107          default:
   3.108 @@ -899,7 +901,7 @@ x86_emulate_memop(
   3.109      }
   3.110  
   3.111      /* Commit shadow register state. */
   3.112 -    *regs = _regs;
   3.113 +    *ctxt->regs = _regs;
   3.114  
   3.115   done:
   3.116      return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
   3.117 @@ -911,11 +913,11 @@ x86_emulate_memop(
   3.118      {
   3.119          if ( _regs.ecx == 0 )
   3.120          {
   3.121 -            regs->eip = _regs.eip;
   3.122 +            ctxt->regs->eip = _regs.eip;
   3.123              goto done;
   3.124          }
   3.125          _regs.ecx--;
   3.126 -        _regs.eip = regs->eip;
   3.127 +        _regs.eip = ctxt->regs->eip;
   3.128      }
   3.129      switch ( b )
   3.130      {
   3.131 @@ -928,14 +930,15 @@ x86_emulate_memop(
   3.132              dst.ptr = (unsigned long *)cr2;
   3.133              if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds,
   3.134                                                        _regs.esi),
   3.135 -                                     &dst.val, dst.bytes)) != 0 )
   3.136 +                                     &dst.val, dst.bytes, ctxt)) != 0 )
   3.137                  goto done;
   3.138          }
   3.139          else
   3.140          {
   3.141              /* Read fault: source is special memory. */
   3.142              dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi);
   3.143 -            if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
   3.144 +            if ( (rc = ops->read_emulated(cr2, &dst.val,
   3.145 +                                          dst.bytes, ctxt)) != 0 )
   3.146                  goto done;
   3.147          }
   3.148          register_address_increment(
   3.149 @@ -958,7 +961,7 @@ x86_emulate_memop(
   3.150          dst.type  = OP_REG;
   3.151          dst.bytes = (d & ByteOp) ? 1 : op_bytes;
   3.152          dst.ptr   = (unsigned long *)&_regs.eax;
   3.153 -        if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 )
   3.154 +        if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0 )
   3.155              goto done;
   3.156          register_address_increment(
   3.157              _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
   3.158 @@ -1074,8 +1077,8 @@ x86_emulate_memop(
   3.159  #if defined(__i386__)
   3.160      {
   3.161          unsigned long old_lo, old_hi;
   3.162 -        if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4)) != 0) ||
   3.163 -             ((rc = ops->read_emulated(cr2+4, &old_hi, 4)) != 0) )
   3.164 +        if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4, ctxt)) != 0) ||
   3.165 +             ((rc = ops->read_emulated(cr2+4, &old_hi, 4, ctxt)) != 0) )
   3.166              goto done;
   3.167          if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
   3.168          {
   3.169 @@ -1090,8 +1093,8 @@ x86_emulate_memop(
   3.170          }
   3.171          else
   3.172          {
   3.173 -            if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi,
   3.174 -                                               _regs.ebx, _regs.ecx)) != 0 )
   3.175 +            if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, _regs.ebx,
   3.176 +                                               _regs.ecx, ctxt)) != 0 )
   3.177                  goto done;
   3.178              _regs.eflags |= EFLG_ZF;
   3.179          }
   3.180 @@ -1136,7 +1139,8 @@ int
   3.181  x86_emulate_read_std(
   3.182      unsigned long addr,
   3.183      unsigned long *val,
   3.184 -    unsigned int bytes)
   3.185 +    unsigned int bytes,
   3.186 +    struct x86_emulate_ctxt *ctxt)
   3.187  {
   3.188      *val = 0;
   3.189      if ( copy_from_user((void *)val, (void *)addr, bytes) )
   3.190 @@ -1151,7 +1155,8 @@ int
   3.191  x86_emulate_write_std(
   3.192      unsigned long addr,
   3.193      unsigned long val,
   3.194 -    unsigned int bytes)
   3.195 +    unsigned int bytes,
   3.196 +    struct x86_emulate_ctxt *ctxt)
   3.197  {
   3.198      if ( copy_to_user((void *)addr, (void *)&val, bytes) )
   3.199      {
     4.1 --- a/xen/include/asm-x86/x86_emulate.h	Thu May 25 14:54:43 2006 +0100
     4.2 +++ b/xen/include/asm-x86/x86_emulate.h	Thu May 25 15:52:38 2006 +0100
     4.3 @@ -9,8 +9,10 @@
     4.4  #ifndef __X86_EMULATE_H__
     4.5  #define __X86_EMULATE_H__
     4.6  
     4.7 +struct x86_emulate_ctxt;
     4.8 +
     4.9  /*
    4.10 - * x86_mem_emulator:
    4.11 + * x86_emulate_ops:
    4.12   * 
    4.13   * These operations represent the instruction emulator's interface to memory.
    4.14   * There are two categories of operation: those that act on ordinary memory
    4.15 @@ -47,7 +49,7 @@
    4.16  #define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
    4.17  #define X86EMUL_RETRY_INSTR     2 /* retry the instruction for some reason */
    4.18  #define X86EMUL_CMPXCHG_FAILED  2 /* cmpxchg did not see expected value */
    4.19 -struct x86_mem_emulator
    4.20 +struct x86_emulate_ops
    4.21  {
    4.22      /*
    4.23       * read_std: Read bytes of standard (non-emulated/special) memory.
    4.24 @@ -59,7 +61,8 @@ struct x86_mem_emulator
    4.25      int (*read_std)(
    4.26          unsigned long addr,
    4.27          unsigned long *val,
    4.28 -        unsigned int bytes);
    4.29 +        unsigned int bytes,
    4.30 +        struct x86_emulate_ctxt *ctxt);
    4.31  
    4.32      /*
    4.33       * write_std: Write bytes of standard (non-emulated/special) memory.
    4.34 @@ -71,7 +74,8 @@ struct x86_mem_emulator
    4.35      int (*write_std)(
    4.36          unsigned long addr,
    4.37          unsigned long val,
    4.38 -        unsigned int bytes);
    4.39 +        unsigned int bytes,
    4.40 +        struct x86_emulate_ctxt *ctxt);
    4.41  
    4.42      /*
    4.43       * read_emulated: Read bytes from emulated/special memory area.
    4.44 @@ -82,7 +86,8 @@ struct x86_mem_emulator
    4.45      int (*read_emulated)(
    4.46          unsigned long addr,
    4.47          unsigned long *val,
    4.48 -        unsigned int bytes);
    4.49 +        unsigned int bytes,
    4.50 +        struct x86_emulate_ctxt *ctxt);
    4.51  
    4.52      /*
    4.53       * write_emulated: Read bytes from emulated/special memory area.
    4.54 @@ -93,7 +98,8 @@ struct x86_mem_emulator
    4.55      int (*write_emulated)(
    4.56          unsigned long addr,
    4.57          unsigned long val,
    4.58 -        unsigned int bytes);
    4.59 +        unsigned int bytes,
    4.60 +        struct x86_emulate_ctxt *ctxt);
    4.61  
    4.62      /*
    4.63       * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
    4.64 @@ -107,11 +113,12 @@ struct x86_mem_emulator
    4.65          unsigned long addr,
    4.66          unsigned long old,
    4.67          unsigned long new,
    4.68 -        unsigned int bytes);
    4.69 +        unsigned int bytes,
    4.70 +        struct x86_emulate_ctxt *ctxt);
    4.71  
    4.72      /*
    4.73 -     * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
    4.74 -     *                   emulated/special memory area.
    4.75 +     * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
    4.76 +     *                     emulated/special memory area.
    4.77       *  @addr:  [IN ] Linear address to access.
    4.78       *  @old:   [IN ] Value expected to be current at @addr.
    4.79       *  @new:   [IN ] Value to write to @addr.
    4.80 @@ -126,7 +133,8 @@ struct x86_mem_emulator
    4.81          unsigned long old_lo,
    4.82          unsigned long old_hi,
    4.83          unsigned long new_lo,
    4.84 -        unsigned long new_hi);
    4.85 +        unsigned long new_hi,
    4.86 +        struct x86_emulate_ctxt *ctxt);
    4.87  };
    4.88  
    4.89  /* Standard reader/writer functions that callers may wish to use. */
    4.90 @@ -134,15 +142,29 @@ extern int
    4.91  x86_emulate_read_std(
    4.92      unsigned long addr,
    4.93      unsigned long *val,
    4.94 -    unsigned int bytes);
    4.95 +    unsigned int bytes,
    4.96 +    struct x86_emulate_ctxt *ctxt);
    4.97  extern int
    4.98  x86_emulate_write_std(
    4.99      unsigned long addr,
   4.100      unsigned long val,
   4.101 -    unsigned int bytes);
   4.102 +    unsigned int bytes,
   4.103 +    struct x86_emulate_ctxt *ctxt);
   4.104  
   4.105  struct cpu_user_regs;
   4.106  
   4.107 +struct x86_emulate_ctxt
   4.108 +{
   4.109 +    /* Register state before/after emulation. */
   4.110 +    struct cpu_user_regs   *regs;
   4.111 +
   4.112 +    /* Linear faulting address (if emulating a page-faulting instruction). */
   4.113 +    unsigned long           cr2;
   4.114 +
   4.115 +    /* Emulated execution mode, represented by an X86EMUL_MODE value. */
   4.116 +    int                     mode;
   4.117 +};
   4.118 +
   4.119  /* Execution mode, passed to the emulator. */
   4.120  #define X86EMUL_MODE_REAL     0 /* Real mode.             */
   4.121  #define X86EMUL_MODE_PROT16   2 /* 16-bit protected mode. */
   4.122 @@ -159,25 +181,19 @@ struct cpu_user_regs;
   4.123  /*
   4.124   * x86_emulate_memop: Emulate an instruction that faulted attempting to
   4.125   *                    read/write a 'special' memory area.
   4.126 - *  @regs: Register state at time of fault.
   4.127 - *  @cr2:  Linear faulting address within an emulated/special memory area.
   4.128 - *  @ops:  Interface to access special memory.
   4.129 - *  @mode: Emulated execution mode, represented by an X86EMUL_MODE value.
   4.130   * Returns -1 on failure, 0 on success.
   4.131   */
   4.132 -extern int
   4.133 +int
   4.134  x86_emulate_memop(
   4.135 -    struct cpu_user_regs *regs,
   4.136 -    unsigned long cr2,
   4.137 -    struct x86_mem_emulator *ops,
   4.138 -    int mode);
   4.139 +    struct x86_emulate_ctxt *ctxt,
   4.140 +    struct x86_emulate_ops  *ops);
   4.141  
   4.142  /*
   4.143   * Given the 'reg' portion of a ModRM byte, and a register block, return a
   4.144   * pointer into the block that addresses the relevant register.
   4.145   * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
   4.146   */
   4.147 -extern void *
   4.148 +void *
   4.149  decode_register(
   4.150      uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs);
   4.151