ia64/xen-unstable

changeset 13331:8a99ebc5f5a4

[XEN] Tweak x86 emulator interface.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Jan 08 18:39:29 2007 +0000 (2007-01-08)
parents 1e7bbecdc0a2
children 6d6a4d5801bd
files tools/tests/test_x86_emulator.c xen/arch/x86/hvm/instrlen.c xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/mm.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/x86_emulate.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/x86_emulate.h
line diff
     1.1 --- a/tools/tests/test_x86_emulator.c	Mon Jan 08 17:38:47 2007 +0000
     1.2 +++ b/tools/tests/test_x86_emulator.c	Mon Jan 08 18:39:29 2007 +0000
     1.3 @@ -102,7 +102,7 @@ int main(int argc, char **argv)
     1.4      int rc;
     1.5  
     1.6      ctxt.regs = &regs;
     1.7 -    ctxt.mode = X86EMUL_MODE_PROT32;
     1.8 +    ctxt.address_bytes = 4;
     1.9  
    1.10      res = mmap((void *)0x100000, 0x1000, PROT_READ|PROT_WRITE,
    1.11                 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
     2.1 --- a/xen/arch/x86/hvm/instrlen.c	Mon Jan 08 17:38:47 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/instrlen.c	Mon Jan 08 18:39:29 2007 +0000
     2.3 @@ -201,7 +201,7 @@ static uint8_t twobyte_table[256] = {
     2.4     if ( inst_copy_from_guest(&_x, pc, 1) != 1 ) {                       \
     2.5         gdprintk(XENLOG_WARNING,                                         \
     2.6                  "Cannot read from address %lx (eip %lx, mode %d)\n",    \
     2.7 -                pc, org_pc, mode);                                      \
     2.8 +                pc, org_pc, address_bytes);                             \
     2.9         return -1;                                                       \
    2.10     }                                                                    \
    2.11     pc += 1;                                                             \
    2.12 @@ -218,30 +218,20 @@ static uint8_t twobyte_table[256] = {
    2.13   * EXTERNAL this routine calculates the length of the current instruction
    2.14   * pointed to by org_pc.  The guest state is _not_ changed by this routine.
    2.15   */
    2.16 -int hvm_instruction_length(unsigned long org_pc, int mode)
    2.17 +int hvm_instruction_length(unsigned long org_pc, int address_bytes)
    2.18  {
    2.19      uint8_t b, d, twobyte = 0, rex_prefix = 0, modrm_reg = 0;
    2.20      unsigned int op_default, op_bytes, ad_default, ad_bytes, tmp;
    2.21      int length = 0;
    2.22      unsigned long pc = org_pc;
    2.23  
    2.24 -    switch ( mode )
    2.25 +    op_bytes = op_default = ad_bytes = ad_default = address_bytes;
    2.26 +    if ( op_bytes == 8 )
    2.27      {
    2.28 -    case X86EMUL_MODE_REAL:
    2.29 -    case X86EMUL_MODE_PROT16:
    2.30 -        op_bytes = op_default = ad_bytes = ad_default = 2;
    2.31 -        break;
    2.32 -    case X86EMUL_MODE_PROT32:
    2.33 -        op_bytes = op_default = ad_bytes = ad_default = 4;
    2.34 -        break;
    2.35 -#ifdef __x86_64__
    2.36 -    case X86EMUL_MODE_PROT64:
    2.37          op_bytes = op_default = 4;
    2.38 -        ad_bytes = ad_default = 8;
    2.39 -        break;
    2.40 +#ifndef __x86_64__
    2.41 +        return -1;
    2.42  #endif
    2.43 -    default:
    2.44 -        return -1;
    2.45      }
    2.46  
    2.47      /* Legacy prefixes. */
    2.48 @@ -253,7 +243,7 @@ int hvm_instruction_length(unsigned long
    2.49              op_bytes = op_default ^ 6;      /* switch between 2/4 bytes */
    2.50              break;
    2.51          case 0x67: /* address-size override */
    2.52 -            if ( mode == X86EMUL_MODE_PROT64 )
    2.53 +            if ( ad_default == 8 )
    2.54                  ad_bytes = ad_default ^ 12; /* switch between 4/8 bytes */
    2.55              else
    2.56                  ad_bytes = ad_default ^ 6;  /* switch between 2/4 bytes */
    2.57 @@ -270,7 +260,7 @@ int hvm_instruction_length(unsigned long
    2.58              break;
    2.59  #ifdef __x86_64__
    2.60          case 0x40 ... 0x4f:
    2.61 -            if ( mode == X86EMUL_MODE_PROT64 )
    2.62 +            if ( ad_default == 8 )
    2.63              {
    2.64                  rex_prefix = b;
    2.65                  continue;
    2.66 @@ -434,7 +424,7 @@ done:
    2.67  
    2.68  cannot_emulate:
    2.69      gdprintk(XENLOG_WARNING,
    2.70 -            "Cannot emulate %02x at address %lx (%lx, mode %d)\n",
    2.71 -            b, pc - 1, org_pc, mode);
    2.72 +            "Cannot emulate %02x at address %lx (%lx, addr_bytes %d)\n",
    2.73 +            b, pc - 1, org_pc, address_bytes);
    2.74      return -1;
    2.75  }
     3.1 --- a/xen/arch/x86/hvm/platform.c	Mon Jan 08 17:38:47 2007 +0000
     3.2 +++ b/xen/arch/x86/hvm/platform.c	Mon Jan 08 18:39:29 2007 +0000
     3.3 @@ -352,7 +352,7 @@ static int reg_mem(unsigned char size, u
     3.4      return DECODE_success;
     3.5  }
     3.6  
     3.7 -static int mmio_decode(int mode, unsigned char *opcode,
     3.8 +static int mmio_decode(int address_bytes, unsigned char *opcode,
     3.9                         struct hvm_io_op *mmio_op,
    3.10                         unsigned char *ad_size, unsigned char *op_size,
    3.11                         unsigned char *seg_sel)
    3.12 @@ -368,9 +368,9 @@ static int mmio_decode(int mode, unsigne
    3.13  
    3.14      opcode = check_prefix(opcode, mmio_op, ad_size, op_size, seg_sel, &rex);
    3.15  
    3.16 -    switch ( mode ) {
    3.17 -    case X86EMUL_MODE_REAL: /* meaning is reversed */
    3.18 -    case X86EMUL_MODE_PROT16:
    3.19 +    switch ( address_bytes )
    3.20 +    {
    3.21 +    case 2:
    3.22          if ( *op_size == WORD )
    3.23              *op_size = LONG;
    3.24          else if ( *op_size == LONG )
    3.25 @@ -384,14 +384,14 @@ static int mmio_decode(int mode, unsigne
    3.26          else if ( *ad_size == 0 )
    3.27              *ad_size = WORD;
    3.28          break;
    3.29 -    case X86EMUL_MODE_PROT32:
    3.30 +    case 4:
    3.31          if ( *op_size == 0 )
    3.32              *op_size = LONG;
    3.33          if ( *ad_size == 0 )
    3.34              *ad_size = LONG;
    3.35          break;
    3.36  #ifdef __x86_64__
    3.37 -    case X86EMUL_MODE_PROT64:
    3.38 +    case 8:
    3.39          if ( *op_size == 0 )
    3.40              *op_size = rex & 0x8 ? QUAD : LONG;
    3.41          if ( *ad_size == 0 )
    3.42 @@ -907,7 +907,7 @@ void handle_mmio(unsigned long gpa)
    3.43      struct hvm_io_op *mmio_op;
    3.44      struct cpu_user_regs *regs;
    3.45      unsigned char inst[MAX_INST_LEN], ad_size, op_size, seg_sel;
    3.46 -    int i, mode, df, inst_len;
    3.47 +    int i, address_bytes, df, inst_len;
    3.48      struct vcpu *v = current;
    3.49  
    3.50      mmio_op = &v->arch.hvm_vcpu.io_op;
    3.51 @@ -919,9 +919,9 @@ void handle_mmio(unsigned long gpa)
    3.52  
    3.53      df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
    3.54  
    3.55 -    mode = hvm_guest_x86_mode(v);
    3.56 +    address_bytes = hvm_guest_x86_mode(v);
    3.57      inst_addr = hvm_get_segment_base(v, x86_seg_cs) + regs->eip;
    3.58 -    inst_len = hvm_instruction_length(inst_addr, mode);
    3.59 +    inst_len = hvm_instruction_length(inst_addr, address_bytes);
    3.60      if ( inst_len <= 0 )
    3.61      {
    3.62          printk("handle_mmio: failed to get instruction length\n");
    3.63 @@ -934,8 +934,8 @@ void handle_mmio(unsigned long gpa)
    3.64          domain_crash_synchronous();
    3.65      }
    3.66  
    3.67 -    if ( mmio_decode(mode, inst, mmio_op, &ad_size, &op_size, &seg_sel)
    3.68 -         == DECODE_failure ) {
    3.69 +    if ( mmio_decode(address_bytes, inst, mmio_op, &ad_size,
    3.70 +                     &op_size, &seg_sel) == DECODE_failure ) {
    3.71          printk("handle_mmio: failed to decode instruction\n");
    3.72          printk("mmio opcode: gpa 0x%lx, len %d:", gpa, inst_len);
    3.73          for ( i = 0; i < inst_len; i++ )
     4.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Jan 08 17:38:47 2007 +0000
     4.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Jan 08 18:39:29 2007 +0000
     4.3 @@ -483,14 +483,12 @@ static int svm_guest_x86_mode(struct vcp
     4.4      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     4.5  
     4.6      if ( vmcb->efer & EFER_LMA )
     4.7 -        return (vmcb->cs.attr.fields.l ?
     4.8 -                X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32);
     4.9 +        return (vmcb->cs.attr.fields.l ? 8 : 4);
    4.10  
    4.11      if ( svm_realmode(v) )
    4.12 -        return X86EMUL_MODE_REAL;
    4.13 -
    4.14 -    return (vmcb->cs.attr.fields.db ?
    4.15 -            X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16);
    4.16 +        return 2;
    4.17 +
    4.18 +    return (vmcb->cs.attr.fields.db ? 4 : 2);
    4.19  }
    4.20  
    4.21  void svm_update_host_cr3(struct vcpu *v)
     5.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Jan 08 17:38:47 2007 +0000
     5.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Jan 08 18:39:29 2007 +0000
     5.3 @@ -695,14 +695,12 @@ static int vmx_guest_x86_mode(struct vcp
     5.4      cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
     5.5  
     5.6      if ( vmx_long_mode_enabled(v) )
     5.7 -        return ((cs_ar_bytes & (1u<<13)) ?
     5.8 -                X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32);
     5.9 +        return ((cs_ar_bytes & (1u<<13)) ? 8 : 4);
    5.10  
    5.11      if ( vmx_realmode(v) )
    5.12 -        return X86EMUL_MODE_REAL;
    5.13 +        return 2;
    5.14  
    5.15 -    return ((cs_ar_bytes & (1u<<14)) ?
    5.16 -            X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16);
    5.17 +    return ((cs_ar_bytes & (1u<<14)) ? 4 : 2);
    5.18  }
    5.19  
    5.20  static int vmx_pae_enabled(struct vcpu *v)
     6.1 --- a/xen/arch/x86/mm.c	Mon Jan 08 17:38:47 2007 +0000
     6.2 +++ b/xen/arch/x86/mm.c	Mon Jan 08 18:39:29 2007 +0000
     6.3 @@ -3379,9 +3379,9 @@ int ptwr_do_page_fault(struct vcpu *v, u
     6.4          goto bail;
     6.5  
     6.6      ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
     6.7 -    ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32;
     6.8 -    ptwr_ctxt.cr2       = addr;
     6.9 -    ptwr_ctxt.pte       = pte;
    6.10 +    ptwr_ctxt.ctxt.address_bytes = IS_COMPAT(d) ? 4 : sizeof(long);
    6.11 +    ptwr_ctxt.cr2 = addr;
    6.12 +    ptwr_ctxt.pte = pte;
    6.13      if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
    6.14          goto bail;
    6.15  
     7.1 --- a/xen/arch/x86/mm/shadow/common.c	Mon Jan 08 17:38:47 2007 +0000
     7.2 +++ b/xen/arch/x86/mm/shadow/common.c	Mon Jan 08 18:39:29 2007 +0000
     7.3 @@ -110,7 +110,7 @@ static int hvm_translate_linear_addr(
     7.4      unsigned long limit, addr = offset;
     7.5      uint32_t last_byte;
     7.6  
     7.7 -    if ( sh_ctxt->ctxt.mode != X86EMUL_MODE_PROT64 )
     7.8 +    if ( sh_ctxt->ctxt.address_bytes != 8 )
     7.9      {
    7.10          /*
    7.11           * COMPATIBILITY MODE: Apply segment checks and add base.
    7.12 @@ -407,7 +407,7 @@ struct x86_emulate_ops *shadow_init_emul
    7.13  
    7.14      if ( !is_hvm_vcpu(v) )
    7.15      {
    7.16 -        sh_ctxt->ctxt.mode = X86EMUL_MODE_HOST;
    7.17 +        sh_ctxt->ctxt.address_bytes = sizeof(long);
    7.18          return &pv_shadow_emulator_ops;
    7.19      }
    7.20  
    7.21 @@ -417,13 +417,11 @@ struct x86_emulate_ops *shadow_init_emul
    7.22  
    7.23      /* Work out the emulation mode. */
    7.24      if ( hvm_long_mode_enabled(v) )
    7.25 -        sh_ctxt->ctxt.mode = creg->attr.fields.l ?
    7.26 -            X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32;
    7.27 +        sh_ctxt->ctxt.address_bytes = creg->attr.fields.l ? 8 : 4;
    7.28      else if ( regs->eflags & X86_EFLAGS_VM )
    7.29 -        sh_ctxt->ctxt.mode = X86EMUL_MODE_REAL;
    7.30 +        sh_ctxt->ctxt.address_bytes = 2;
    7.31      else
    7.32 -        sh_ctxt->ctxt.mode = creg->attr.fields.db ?
    7.33 -            X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
    7.34 +        sh_ctxt->ctxt.address_bytes = creg->attr.fields.db ? 4 : 2;
    7.35  
    7.36      /* Attempt to prefetch whole instruction. */
    7.37      sh_ctxt->insn_buf_bytes =
     8.1 --- a/xen/arch/x86/x86_emulate.c	Mon Jan 08 17:38:47 2007 +0000
     8.2 +++ b/xen/arch/x86/x86_emulate.c	Mon Jan 08 18:39:29 2007 +0000
     8.3 @@ -391,10 +391,10 @@ do{ __asm__ __volatile__ (              
     8.4  /* Fetch next part of the instruction being emulated. */
     8.5  #define insn_fetch_bytes(_size)                                         \
     8.6  ({ unsigned long _x, _eip = _truncate_ea(_regs.eip, def_ad_bytes);      \
     8.7 +   if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
     8.8     rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
     8.9 -   if ( rc != 0 )                                                       \
    8.10 -       goto done;                                                       \
    8.11 -   _register_address_increment(_regs.eip, (_size), def_ad_bytes);       \
    8.12 +   if ( rc ) goto done;                                                 \
    8.13 +   _regs.eip += (_size); /* real hardware doesn't truncate */           \
    8.14     _x;                                                                  \
    8.15  })
    8.16  #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
    8.17 @@ -406,13 +406,15 @@ do{ __asm__ __volatile__ (              
    8.18  })
    8.19  #define truncate_ea(ea) _truncate_ea((ea), ad_bytes)
    8.20  
    8.21 +#define mode_64bit() (def_ad_bytes == 8)
    8.22 +
    8.23  /* Update address held in a register, based on addressing mode. */
    8.24  #define _register_address_increment(reg, inc, byte_width)               \
    8.25  do {                                                                    \
    8.26      int _inc = (inc); /* signed type ensures sign extension to long */  \
    8.27      if ( (byte_width) == sizeof(unsigned long) )                        \
    8.28          (reg) += _inc;                                                  \
    8.29 -    else if ( mode == X86EMUL_MODE_PROT64 )                             \
    8.30 +    else if ( mode_64bit() )                                            \
    8.31          (reg) = ((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1);    \
    8.32      else                                                                \
    8.33          (reg) = ((reg) & ~((1UL << ((byte_width) << 3)) - 1)) |         \
    8.34 @@ -424,7 +426,7 @@ do {                                    
    8.35  #define jmp_rel(rel)                                                    \
    8.36  do {                                                                    \
    8.37      _regs.eip += (int)(rel);                                            \
    8.38 -    if ( mode != X86EMUL_MODE_PROT64 )                                  \
    8.39 +    if ( !mode_64bit() )                                                \
    8.40          _regs.eip = ((op_bytes == 2)                                    \
    8.41                       ? (uint16_t)_regs.eip : (uint32_t)_regs.eip);      \
    8.42  } while (0)
    8.43 @@ -521,7 +523,6 @@ x86_emulate(
    8.44      unsigned int lock_prefix = 0, rep_prefix = 0, i;
    8.45      int rc = 0;
    8.46      struct operand src, dst;
    8.47 -    int mode = ctxt->mode;
    8.48  
    8.49      /* Data operand effective address (usually computed from ModRM). */
    8.50      struct operand ea;
    8.51 @@ -531,27 +532,15 @@ x86_emulate(
    8.52      ea.mem.seg = x86_seg_ds;
    8.53      ea.mem.off = 0;
    8.54  
    8.55 -    switch ( mode )
    8.56 +    op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes;
    8.57 +    if ( op_bytes == 8 )
    8.58      {
    8.59 -    case X86EMUL_MODE_REAL:
    8.60 -    case X86EMUL_MODE_PROT16:
    8.61 -        op_bytes = def_ad_bytes = 2;
    8.62 -        break;
    8.63 -    case X86EMUL_MODE_PROT32:
    8.64 -        op_bytes = def_ad_bytes = 4;
    8.65 -        break;
    8.66 -#ifdef __x86_64__
    8.67 -    case X86EMUL_MODE_PROT64:
    8.68          op_bytes = 4;
    8.69 -        def_ad_bytes = 8;
    8.70 -        break;
    8.71 +#ifndef __x86_64__
    8.72 +        return -1;
    8.73  #endif
    8.74 -    default:
    8.75 -        return -1;
    8.76      }
    8.77  
    8.78 -    ad_bytes = def_ad_bytes;
    8.79 -
    8.80      /* Prefix bytes. */
    8.81      for ( i = 0; i < 8; i++ )
    8.82      {
    8.83 @@ -561,7 +550,7 @@ x86_emulate(
    8.84              op_bytes ^= 6;      /* switch between 2/4 bytes */
    8.85              break;
    8.86          case 0x67: /* address-size override */
    8.87 -            if ( mode == X86EMUL_MODE_PROT64 )
    8.88 +            if ( mode_64bit() )
    8.89                  ad_bytes ^= 12; /* switch between 4/8 bytes */
    8.90              else
    8.91                  ad_bytes ^= 6;  /* switch between 2/4 bytes */
    8.92 @@ -592,7 +581,7 @@ x86_emulate(
    8.93              rep_prefix = 1;
    8.94              break;
    8.95          case 0x40 ... 0x4f: /* REX */
    8.96 -            if ( mode != X86EMUL_MODE_PROT64 )
    8.97 +            if ( !mode_64bit() )
    8.98                  goto done_prefixes;
    8.99              rex_prefix = b;
   8.100              continue;
   8.101 @@ -685,8 +674,7 @@ x86_emulate(
   8.102                  else if ( (sib_base == 4) && !twobyte && (b == 0x8f) )
   8.103                      /* POP <rm> must have its EA calculated post increment. */
   8.104                      ea.mem.off += _regs.esp +
   8.105 -                        (((mode == X86EMUL_MODE_PROT64) && (op_bytes == 4))
   8.106 -                         ? 8 : op_bytes);
   8.107 +                        ((mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes);
   8.108                  else
   8.109                      ea.mem.off += *(long*)decode_register(sib_base, &_regs, 0);
   8.110              }
   8.111 @@ -701,7 +689,7 @@ x86_emulate(
   8.112                  if ( (modrm_rm & 7) != 5 )
   8.113                      break;
   8.114                  ea.mem.off = insn_fetch_type(int32_t);
   8.115 -                if ( mode != X86EMUL_MODE_PROT64 )
   8.116 +                if ( !mode_64bit() )
   8.117                      break;
   8.118                  /* Relative to RIP of next instruction. Argh! */
   8.119                  ea.mem.off += _regs.eip;
   8.120 @@ -935,7 +923,7 @@ x86_emulate(
   8.121          break;
   8.122  
   8.123      case 0x63: /* movsxd */
   8.124 -        if ( mode != X86EMUL_MODE_PROT64 )
   8.125 +        if ( !mode_64bit() )
   8.126              goto cannot_emulate;
   8.127          dst.val = (int32_t)src.val;
   8.128          break;
   8.129 @@ -983,7 +971,7 @@ x86_emulate(
   8.130  
   8.131      case 0x8f: /* pop (sole member of Grp1a) */
   8.132          /* 64-bit mode: POP defaults to a 64-bit operand. */
   8.133 -        if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) )
   8.134 +        if ( mode_64bit() && (dst.bytes == 4) )
   8.135              dst.bytes = 8;
   8.136          if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
   8.137                               &dst.val, dst.bytes, ctxt)) != 0 )
   8.138 @@ -1079,7 +1067,7 @@ x86_emulate(
   8.139              break;
   8.140          case 6: /* push */
   8.141              /* 64-bit mode: PUSH defaults to a 64-bit operand. */
   8.142 -            if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) )
   8.143 +            if ( mode_64bit() && (dst.bytes == 4) )
   8.144              {
   8.145                  dst.bytes = 8;
   8.146                  if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
   8.147 @@ -1168,7 +1156,7 @@ x86_emulate(
   8.148      case 0x50 ... 0x57: /* push reg */
   8.149          dst.type  = OP_MEM;
   8.150          dst.bytes = op_bytes;
   8.151 -        if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) )
   8.152 +        if ( mode_64bit() && (dst.bytes == 4) )
   8.153              dst.bytes = 8;
   8.154          dst.val = *(unsigned long *)decode_register(
   8.155              (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
   8.156 @@ -1182,7 +1170,7 @@ x86_emulate(
   8.157          dst.reg   = decode_register(
   8.158              (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
   8.159          dst.bytes = op_bytes;
   8.160 -        if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) )
   8.161 +        if ( mode_64bit() && (dst.bytes == 4) )
   8.162              dst.bytes = 8;
   8.163          if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
   8.164                               &dst.val, dst.bytes, ctxt)) != 0 )
   8.165 @@ -1278,8 +1266,7 @@ x86_emulate(
   8.166          break;
   8.167  
   8.168      case 0xeb: /* jmp (near) */
   8.169 -        jmp_rel(insn_fetch_bytes(
   8.170 -            (mode == X86EMUL_MODE_PROT64) ? 4 : op_bytes));
   8.171 +        jmp_rel(insn_fetch_bytes(mode_64bit() ? 4 : op_bytes));
   8.172          break;
   8.173  
   8.174      case 0xf5: /* cmc */
   8.175 @@ -1401,8 +1388,7 @@ x86_emulate(
   8.176          break;
   8.177  
   8.178      case 0x80 ... 0x8f: /* jcc (near) */ {
   8.179 -        int rel = insn_fetch_bytes(
   8.180 -            (mode == X86EMUL_MODE_PROT64) ? 4 : op_bytes);
   8.181 +        int rel = insn_fetch_bytes(mode_64bit() ? 4 : op_bytes);
   8.182          if ( test_cc(b, _regs.eflags) )
   8.183              jmp_rel(rel);
   8.184          break;
     9.1 --- a/xen/include/asm-x86/hvm/hvm.h	Mon Jan 08 17:38:47 2007 +0000
     9.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Mon Jan 08 18:39:29 2007 +0000
     9.3 @@ -185,7 +185,7 @@ hvm_guest_x86_mode(struct vcpu *v)
     9.4      return hvm_funcs.guest_x86_mode(v);
     9.5  }
     9.6  
     9.7 -int hvm_instruction_length(unsigned long pc, int mode);
     9.8 +int hvm_instruction_length(unsigned long pc, int address_bytes);
     9.9  
    9.10  static inline void
    9.11  hvm_update_host_cr3(struct vcpu *v)
    10.1 --- a/xen/include/asm-x86/x86_emulate.h	Mon Jan 08 17:38:47 2007 +0000
    10.2 +++ b/xen/include/asm-x86/x86_emulate.h	Mon Jan 08 18:39:29 2007 +0000
    10.3 @@ -134,24 +134,11 @@ struct cpu_user_regs;
    10.4  struct x86_emulate_ctxt
    10.5  {
    10.6      /* Register state before/after emulation. */
    10.7 -    struct cpu_user_regs   *regs;
    10.8 -
    10.9 -    /* Emulated execution mode, represented by an X86EMUL_MODE value. */
   10.10 -    int                     mode;
   10.11 -};
   10.12 +    struct cpu_user_regs *regs;
   10.13  
   10.14 -/* Execution mode, passed to the emulator. */
   10.15 -#define X86EMUL_MODE_REAL     0 /* Real mode.             */
   10.16 -#define X86EMUL_MODE_PROT16   2 /* 16-bit protected mode. */
   10.17 -#define X86EMUL_MODE_PROT32   4 /* 32-bit protected mode. */
   10.18 -#define X86EMUL_MODE_PROT64   8 /* 64-bit (long) mode.    */
   10.19 -
   10.20 -/* Host execution mode. */
   10.21 -#if defined(__i386__)
   10.22 -#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
   10.23 -#elif defined(__x86_64__)
   10.24 -#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
   10.25 -#endif
   10.26 +    /* Default address size in current execution mode (2, 4, or 8). */
   10.27 +    int                   address_bytes;
   10.28 +};
   10.29  
   10.30  /*
   10.31   * x86_emulate: Emulate an instruction.