ia64/xen-unstable

changeset 11620:e0db5a3a2ef6

[HVM] Use AMD's isntruction-length decoder for VMX as well as SVM
MMIO decode. The VMX-defined instruction-length info field is not
valid for use during most page faults. Hence we have to obtain the
instruction length the slow-and-stupid way.

This *will* go away when we throw away the wretched MMIO emulator.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Sep 25 10:22:17 2006 +0100 (2006-09-25)
parents 807fbfb0a0dc
children f052ccc0cc26
files xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/instrlen.c xen/arch/x86/hvm/platform.c xen/arch/x86/hvm/svm/Makefile xen/arch/x86/hvm/svm/instrlen.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/vmx/vmx.h
line diff
     1.1 --- a/xen/arch/x86/hvm/Makefile	Mon Sep 25 09:36:11 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/Makefile	Mon Sep 25 10:22:17 2006 +0100
     1.3 @@ -4,6 +4,7 @@ subdir-y += vmx
     1.4  obj-y += hvm.o
     1.5  obj-y += i8254.o
     1.6  obj-y += i8259.o
     1.7 +obj-y += instrlen.o
     1.8  obj-y += intercept.o
     1.9  obj-y += io.o
    1.10  obj-y += platform.o
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/x86/hvm/instrlen.c	Mon Sep 25 10:22:17 2006 +0100
     2.3 @@ -0,0 +1,474 @@
     2.4 +/*
     2.5 + * instrlen.c - calculates the instruction length for all operating modes
     2.6 + * 
     2.7 + * Travis Betak, travis.betak@amd.com
     2.8 + * Copyright (c) 2005,2006 AMD
     2.9 + * Copyright (c) 2005 Keir Fraser
    2.10 + *
    2.11 + * Essentially a very, very stripped version of Keir Fraser's work in
    2.12 + * x86_emulate.c.  Used for MMIO.
    2.13 + */
    2.14 +
    2.15 +/*
    2.16 + * TODO: The way in which we use hvm_instruction_length is very inefficient as
    2.17 + * it now stands. It will be worthwhile to return the actual instruction buffer
    2.18 + * along with the instruction length since one of the reasons we are getting
    2.19 + * the instruction length is to know how many instruction bytes we need to
    2.20 + * fetch.
    2.21 + */
    2.22 +
    2.23 +#include <xen/config.h>
    2.24 +#include <xen/sched.h>
    2.25 +#include <xen/mm.h>
    2.26 +#include <asm/regs.h>
    2.27 +#include <asm-x86/x86_emulate.h>
    2.28 +
    2.29 +/* read from guest memory */
    2.30 +extern int inst_copy_from_guest(unsigned char *buf, unsigned long eip,
    2.31 +        int length);
    2.32 +
    2.33 +/*
    2.34 + * Opcode effective-address decode tables.
    2.35 + * Note that we only emulate instructions that have at least one memory
    2.36 + * operand (excluding implicit stack references). We assume that stack
    2.37 + * references and instruction fetches will never occur in special memory
    2.38 + * areas that require emulation. So, for example, 'mov <imm>,<reg>' need
    2.39 + * not be handled.
    2.40 + */
    2.41 +
    2.42 +/* Operand sizes: 8-bit operands or specified/overridden size. */
    2.43 +#define ByteOp      (1<<0) /* 8-bit operands. */
    2.44 +/* Destination operand type. */
    2.45 +#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
    2.46 +#define DstReg      (2<<1) /* Register operand. */
    2.47 +#define DstMem      (3<<1) /* Memory operand. */
    2.48 +#define DstMask     (3<<1)
    2.49 +/* Source operand type. */
    2.50 +#define SrcNone     (0<<3) /* No source operand. */
    2.51 +#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
    2.52 +#define SrcReg      (1<<3) /* Register operand. */
    2.53 +#define SrcMem      (2<<3) /* Memory operand. */
    2.54 +#define SrcMem16    (3<<3) /* Memory operand (16-bit). */
    2.55 +#define SrcMem32    (4<<3) /* Memory operand (32-bit). */
    2.56 +#define SrcImm      (5<<3) /* Immediate operand. */
    2.57 +#define SrcImmByte  (6<<3) /* 8-bit sign-extended immediate operand. */
    2.58 +#define SrcMask     (7<<3)
    2.59 +/* Generic ModRM decode. */
    2.60 +#define ModRM       (1<<6)
    2.61 +/* Destination is only written; never read. */
    2.62 +#define Mov         (1<<7)
    2.63 +
    2.64 +static uint8_t opcode_table[256] = {
    2.65 +    /* 0x00 - 0x07 */
    2.66 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.67 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.68 +    0, 0, 0, 0,
    2.69 +    /* 0x08 - 0x0F */
    2.70 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.71 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.72 +    0, 0, 0, 0,
    2.73 +    /* 0x10 - 0x17 */
    2.74 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.75 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.76 +    0, 0, 0, 0,
    2.77 +    /* 0x18 - 0x1F */
    2.78 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.79 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.80 +    0, 0, 0, 0,
    2.81 +    /* 0x20 - 0x27 */
    2.82 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.83 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.84 +    0, 0, 0, 0,
    2.85 +    /* 0x28 - 0x2F */
    2.86 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.87 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.88 +    0, 0, 0, 0,
    2.89 +    /* 0x30 - 0x37 */
    2.90 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.91 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.92 +    0, 0, 0, 0,
    2.93 +    /* 0x38 - 0x3F */
    2.94 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    2.95 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    2.96 +    0, 0, 0, 0,
    2.97 +    /* 0x40 - 0x4F */
    2.98 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    2.99 +    /* 0x50 - 0x5F */
   2.100 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.101 +    /* 0x60 - 0x6F */
   2.102 +    0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */,
   2.103 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.104 +    /* 0x70 - 0x7F */
   2.105 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.106 +    /* 0x80 - 0x87 */
   2.107 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
   2.108 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
   2.109 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   2.110 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   2.111 +    /* 0x88 - 0x8F */
   2.112 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   2.113 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
   2.114 +    0, 0, 0, DstMem|SrcNone|ModRM|Mov,
   2.115 +    /* 0x90 - 0x9F */
   2.116 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.117 +    /* 0xA0 - 0xA7 */
   2.118 +    ByteOp|DstReg|SrcMem|Mov, DstReg|SrcMem|Mov,
   2.119 +    ByteOp|DstMem|SrcReg|Mov, DstMem|SrcReg|Mov,
   2.120 +    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   2.121 +    ByteOp|ImplicitOps, ImplicitOps,
   2.122 +    /* 0xA8 - 0xAF */
   2.123 +    0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   2.124 +    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   2.125 +    ByteOp|ImplicitOps, ImplicitOps,
   2.126 +    /* 0xB0 - 0xBF */
   2.127 +    SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, 
   2.128 +    SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, 
   2.129 +    0, 0, 0, 0, 0, 0, 0, 0,
   2.130 +    /* 0xC0 - 0xC7 */
   2.131 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
   2.132 +    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
   2.133 +    /* 0xC8 - 0xCF */
   2.134 +    0, 0, 0, 0, 0, 0, 0, 0,
   2.135 +    /* 0xD0 - 0xD7 */
   2.136 +    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
   2.137 +    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
   2.138 +    0, 0, 0, 0,
   2.139 +    /* 0xD8 - 0xDF */
   2.140 +    0, 0, 0, 0, 0, 0, 0, 0,
   2.141 +    /* 0xE0 - 0xEF */
   2.142 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.143 +    /* 0xF0 - 0xF7 */
   2.144 +    0, 0, 0, 0,
   2.145 +    0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
   2.146 +    /* 0xF8 - 0xFF */
   2.147 +    0, 0, 0, 0,
   2.148 +    0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
   2.149 +};
   2.150 +
   2.151 +static uint8_t twobyte_table[256] = {
   2.152 +    /* 0x00 - 0x0F */
   2.153 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
   2.154 +    /* 0x10 - 0x1F */
   2.155 +    0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0,
   2.156 +    /* 0x20 - 0x2F */
   2.157 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.158 +    /* 0x30 - 0x3F */
   2.159 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.160 +    /* 0x40 - 0x47 */
   2.161 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.162 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.163 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.164 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.165 +    /* 0x48 - 0x4F */
   2.166 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.167 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.168 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.169 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   2.170 +    /* 0x50 - 0x5F */
   2.171 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.172 +    /* 0x60 - 0x6F */
   2.173 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.174 +    /* 0x70 - 0x7F */
   2.175 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.176 +    /* 0x80 - 0x8F */
   2.177 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.178 +    /* 0x90 - 0x9F */
   2.179 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.180 +    /* 0xA0 - 0xA7 */
   2.181 +    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0, 
   2.182 +    /* 0xA8 - 0xAF */
   2.183 +    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
   2.184 +    /* 0xB0 - 0xB7 */
   2.185 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstMem|SrcReg|ModRM,
   2.186 +    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
   2.187 +    /* 0xB8 - 0xBF */
   2.188 +    0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM,
   2.189 +    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
   2.190 +    /* 0xC0 - 0xCF */
   2.191 +    0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
   2.192 +    /* 0xD0 - 0xDF */
   2.193 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.194 +    /* 0xE0 - 0xEF */
   2.195 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   2.196 +    /* 0xF0 - 0xFF */
   2.197 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   2.198 +};
   2.199 +
   2.200 +/* 
   2.201 + * insn_fetch - fetch the next 1 to 4 bytes from instruction stream 
   2.202 + * 
   2.203 + * @_type:   u8, u16, u32, s8, s16, or s32
   2.204 + * @_size:   1, 2, or 4 bytes
   2.205 + * @_eip:    address to fetch from guest memory
   2.206 + * @_length: increments the current instruction length counter by _size
   2.207 + *
   2.208 + * This is used internally by hvm_instruction_length to fetch the next byte,
   2.209 + * word, or dword from guest memory at location _eip.  we currently use a local
   2.210 + * unsigned long as the storage buffer since the most bytes we're gonna get
   2.211 + * is limited to 4.
   2.212 + */
   2.213 +#define insn_fetch(_type, _size, _eip, _length)                         \
   2.214 +({  unsigned long _x;                                                   \
   2.215 +        if ((rc = inst_copy_from_guest((unsigned char *)(&(_x)),        \
   2.216 +                (unsigned long)(_eip), _size))                          \
   2.217 +                    != _size)                                           \
   2.218 +        goto done;                                                      \
   2.219 +    (_eip) += (_size);                                                  \
   2.220 +    (_length) += (_size);                                               \
   2.221 +    (_type)_x;                                                          \
   2.222 +})
   2.223 +
   2.224 +/**
   2.225 + * hvm_instruction_length - returns the current instructions length
   2.226 + *
   2.227 + * @regs: guest register state
   2.228 + * @mode: guest operating mode
   2.229 + *
   2.230 + * EXTERNAL this routine calculates the length of the current instruction
   2.231 + * pointed to by eip.  The guest state is _not_ changed by this routine.
   2.232 + */
   2.233 +int hvm_instruction_length(struct cpu_user_regs *regs, int mode)
   2.234 +{
   2.235 +    uint8_t b, d, twobyte = 0, rex_prefix = 0;
   2.236 +    uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   2.237 +    unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
   2.238 +    int rc = 0;
   2.239 +    int length = 0;
   2.240 +    unsigned int tmp;
   2.241 +
   2.242 +    /* Shadow copy of register state. Committed on successful emulation. */
   2.243 +    struct cpu_user_regs _regs = *regs;
   2.244 +
   2.245 +    /* include CS for 16-bit modes */
   2.246 +    if (mode == X86EMUL_MODE_REAL || mode == X86EMUL_MODE_PROT16)
   2.247 +        _regs.eip += (_regs.cs << 4);
   2.248 +
   2.249 +    switch ( mode )
   2.250 +    {
   2.251 +    case X86EMUL_MODE_REAL:
   2.252 +    case X86EMUL_MODE_PROT16:
   2.253 +        op_bytes = ad_bytes = 2;
   2.254 +        break;
   2.255 +    case X86EMUL_MODE_PROT32:
   2.256 +        op_bytes = ad_bytes = 4;
   2.257 +        break;
   2.258 +#ifdef __x86_64__
   2.259 +    case X86EMUL_MODE_PROT64:
   2.260 +        op_bytes = 4;
   2.261 +        ad_bytes = 8;
   2.262 +        break;
   2.263 +#endif
   2.264 +    default:
   2.265 +        return -1;
   2.266 +    }
   2.267 +
   2.268 +    /* Legacy prefixes. */
   2.269 +    for ( i = 0; i < 8; i++ )
   2.270 +    {
   2.271 +        switch ( b = insn_fetch(uint8_t, 1, _regs.eip, length) )
   2.272 +        {
   2.273 +        case 0x66: /* operand-size override */
   2.274 +            op_bytes ^= 6;      /* switch between 2/4 bytes */
   2.275 +            break;
   2.276 +        case 0x67: /* address-size override */
   2.277 +            if ( mode == X86EMUL_MODE_PROT64 )
   2.278 +                ad_bytes ^= 12; /* switch between 4/8 bytes */
   2.279 +            else
   2.280 +                ad_bytes ^= 6;  /* switch between 2/4 bytes */
   2.281 +            break;
   2.282 +        case 0x2e: /* CS override */
   2.283 +        case 0x3e: /* DS override */
   2.284 +        case 0x26: /* ES override */
   2.285 +        case 0x64: /* FS override */
   2.286 +        case 0x65: /* GS override */
   2.287 +        case 0x36: /* SS override */
   2.288 +            break;
   2.289 +        case 0xf0: /* LOCK */
   2.290 +            lock_prefix = 1;
   2.291 +            break;
   2.292 +        case 0xf3: /* REP/REPE/REPZ */
   2.293 +            rep_prefix = 1;
   2.294 +            break;
   2.295 +        case 0xf2: /* REPNE/REPNZ */
   2.296 +            break;
   2.297 +        default:
   2.298 +            goto done_prefixes;
   2.299 +        }
   2.300 +    }
   2.301 +done_prefixes:
   2.302 +
   2.303 +    /* Note quite the same as 80386 real mode, but hopefully good enough. */
   2.304 +    if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) ) {
   2.305 +        printf("sonofabitch!! we don't support 32-bit addresses in realmode\n");
   2.306 +        goto cannot_emulate;
   2.307 +    }
   2.308 +
   2.309 +    /* REX prefix. */
   2.310 +    if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
   2.311 +    {
   2.312 +        rex_prefix = b;
   2.313 +        if ( b & 8 )
   2.314 +            op_bytes = 8;          /* REX.W */
   2.315 +        modrm_reg = (b & 4) << 1;  /* REX.R */
   2.316 +        /* REX.B and REX.X do not need to be decoded. */
   2.317 +        b = insn_fetch(uint8_t, 1, _regs.eip, length);
   2.318 +    }
   2.319 +
   2.320 +    /* Opcode byte(s). */
   2.321 +    d = opcode_table[b];
   2.322 +    if ( d == 0 )
   2.323 +    {
   2.324 +        /* Two-byte opcode? */
   2.325 +        if ( b == 0x0f )
   2.326 +        {
   2.327 +            twobyte = 1;
   2.328 +            b = insn_fetch(uint8_t, 1, _regs.eip, length);
   2.329 +            d = twobyte_table[b];
   2.330 +        }
   2.331 +
   2.332 +        /* Unrecognised? */
   2.333 +        if ( d == 0 )
   2.334 +            goto cannot_emulate;
   2.335 +    }
   2.336 +
   2.337 +    /* ModRM and SIB bytes. */
   2.338 +    if ( d & ModRM )
   2.339 +    {
   2.340 +        modrm = insn_fetch(uint8_t, 1, _regs.eip, length);
   2.341 +        modrm_mod |= (modrm & 0xc0) >> 6;
   2.342 +        modrm_reg |= (modrm & 0x38) >> 3;
   2.343 +        modrm_rm  |= (modrm & 0x07);
   2.344 +
   2.345 +        if ( modrm_mod == 3 )
   2.346 +        {
   2.347 +            DPRINTK("Cannot parse ModRM.mod == 3.\n");
   2.348 +            goto cannot_emulate;
   2.349 +        }
   2.350 +
   2.351 +        if ( ad_bytes == 2 )
   2.352 +        {
   2.353 +            /* 16-bit ModR/M decode. */
   2.354 +            switch ( modrm_mod )
   2.355 +            {
   2.356 +            case 0:
   2.357 +                if ( modrm_rm == 6 ) 
   2.358 +                {
   2.359 +                    length += 2;
   2.360 +                    _regs.eip += 2; /* skip disp16 */
   2.361 +                }
   2.362 +                break;
   2.363 +            case 1:
   2.364 +                length += 1;
   2.365 +                _regs.eip += 1; /* skip disp8 */
   2.366 +                break;
   2.367 +            case 2:
   2.368 +                length += 2;
   2.369 +                _regs.eip += 2; /* skip disp16 */
   2.370 +                break;
   2.371 +            }
   2.372 +        }
   2.373 +        else
   2.374 +        {
   2.375 +            /* 32/64-bit ModR/M decode. */
   2.376 +            switch ( modrm_mod )
   2.377 +            {
   2.378 +            case 0:
   2.379 +                if ( (modrm_rm == 4) && 
   2.380 +                     (((insn_fetch(uint8_t, 1, _regs.eip, length)) & 7) 
   2.381 +                        == 5) )
   2.382 +                {
   2.383 +                    length += 4;
   2.384 +                    _regs.eip += 4; /* skip disp32 specified by SIB.base */
   2.385 +                }
   2.386 +                else if ( modrm_rm == 5 )
   2.387 +                {
   2.388 +                    length += 4;
   2.389 +                    _regs.eip += 4; /* skip disp32 */
   2.390 +                }
   2.391 +                break;
   2.392 +            case 1:
   2.393 +                if ( modrm_rm == 4 )
   2.394 +                {
   2.395 +                    insn_fetch(uint8_t, 1, _regs.eip, length);
   2.396 +                }
   2.397 +                length += 1;
   2.398 +                _regs.eip += 1; /* skip disp8 */
   2.399 +                break;
   2.400 +            case 2:
   2.401 +                if ( modrm_rm == 4 )
   2.402 +                {
   2.403 +                    insn_fetch(uint8_t, 1, _regs.eip, length);
   2.404 +                }
   2.405 +                length += 4;
   2.406 +                _regs.eip += 4; /* skip disp32 */
   2.407 +                break;
   2.408 +            }
   2.409 +        }
   2.410 +    }
   2.411 +
   2.412 +    /* Decode and fetch the destination operand: register or memory. */
   2.413 +    switch ( d & DstMask )
   2.414 +    {
   2.415 +    case ImplicitOps:
   2.416 +        /* Special instructions do their own operand decoding. */
   2.417 +        goto done;
   2.418 +    }
   2.419 +
   2.420 +    /* Decode and fetch the source operand: register, memory or immediate. */
   2.421 +    switch ( d & SrcMask )
   2.422 +    {
   2.423 +    case SrcImm:
   2.424 +        tmp = (d & ByteOp) ? 1 : op_bytes;
   2.425 +        if ( tmp == 8 ) tmp = 4;
   2.426 +        /* NB. Immediates are sign-extended as necessary. */
   2.427 +        switch ( tmp )
   2.428 +        {
   2.429 +        case 1: insn_fetch(int8_t,  1, _regs.eip, length); break;
   2.430 +        case 2: insn_fetch(int16_t, 2, _regs.eip, length); break;
   2.431 +        case 4: insn_fetch(int32_t, 4, _regs.eip, length); break;
   2.432 +        }
   2.433 +        break;
   2.434 +    case SrcImmByte:
   2.435 +        insn_fetch(int8_t,  1, _regs.eip, length);
   2.436 +        break;
   2.437 +    }
   2.438 +
   2.439 +    if ( twobyte )
   2.440 +        goto done;
   2.441 +
   2.442 +    switch ( b )
   2.443 +    {
   2.444 +    case 0xa0 ... 0xa1: /* mov */
   2.445 +        length += ad_bytes;
   2.446 +        _regs.eip += ad_bytes; /* skip src displacement */
   2.447 +        break;
   2.448 +    case 0xa2 ... 0xa3: /* mov */
   2.449 +        length += ad_bytes;
   2.450 +        _regs.eip += ad_bytes; /* skip dst displacement */
   2.451 +        break;
   2.452 +    case 0xf6 ... 0xf7: /* Grp3 */
   2.453 +        switch ( modrm_reg )
   2.454 +        {
   2.455 +        case 0 ... 1: /* test */
   2.456 +            /* Special case in Grp3: test has an immediate source operand. */
   2.457 +            tmp = (d & ByteOp) ? 1 : op_bytes;
   2.458 +            if ( tmp == 8 ) tmp = 4;
   2.459 +            switch ( tmp )
   2.460 +            {
   2.461 +            case 1: insn_fetch(int8_t,  1, _regs.eip, length); break;
   2.462 +            case 2: insn_fetch(int16_t, 2, _regs.eip, length); break;
   2.463 +            case 4: insn_fetch(int32_t, 4, _regs.eip, length); break;
   2.464 +            }
   2.465 +            goto done;
   2.466 +        }
   2.467 +        break;
   2.468 +    }
   2.469 +
   2.470 +done:
   2.471 +    return length;
   2.472 +
   2.473 +cannot_emulate:
   2.474 +    DPRINTK("Cannot emulate %02x at address %lx (eip %lx, mode %d)\n",
   2.475 +            b, (unsigned long)_regs.eip, (unsigned long)regs->eip, mode);
   2.476 +    return -1;
   2.477 +}
     3.1 --- a/xen/arch/x86/hvm/platform.c	Mon Sep 25 09:36:11 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/platform.c	Mon Sep 25 10:22:17 2006 +0100
     3.3 @@ -52,7 +52,7 @@ static inline long __get_reg_value(unsig
     3.4      case QUAD:
     3.5          return (long)(reg);
     3.6      default:
     3.7 -        printf("Error: (__get_reg_value) Invalid reg size\n");
     3.8 +        printk("Error: (__get_reg_value) Invalid reg size\n");
     3.9          domain_crash_synchronous();
    3.10      }
    3.11  }
    3.12 @@ -78,7 +78,7 @@ long get_reg_value(int size, int index, 
    3.13          case 7: /* %bh */
    3.14              return (char)((regs->rbx & 0xFF00) >> 8);
    3.15          default:
    3.16 -            printf("Error: (get_reg_value) Invalid index value\n");
    3.17 +            printk("Error: (get_reg_value) Invalid index value\n");
    3.18              domain_crash_synchronous();
    3.19          }
    3.20          /* NOTREACHED */
    3.21 @@ -102,7 +102,7 @@ long get_reg_value(int size, int index, 
    3.22      case 14: return __get_reg_value(regs->r14, size);
    3.23      case 15: return __get_reg_value(regs->r15, size);
    3.24      default:
    3.25 -        printf("Error: (get_reg_value) Invalid index value\n");
    3.26 +        printk("Error: (get_reg_value) Invalid index value\n");
    3.27          domain_crash_synchronous();
    3.28      }
    3.29  }
    3.30 @@ -115,7 +115,7 @@ static inline long __get_reg_value(unsig
    3.31      case LONG:
    3.32          return (int)(reg & 0xFFFFFFFF);
    3.33      default:
    3.34 -        printf("Error: (__get_reg_value) Invalid reg size\n");
    3.35 +        printk("Error: (__get_reg_value) Invalid reg size\n");
    3.36          domain_crash_synchronous();
    3.37      }
    3.38  }
    3.39 @@ -141,7 +141,7 @@ long get_reg_value(int size, int index, 
    3.40          case 7: /* %bh */
    3.41              return (char)((regs->ebx & 0xFF00) >> 8);
    3.42          default:
    3.43 -            printf("Error: (get_reg_value) Invalid index value\n");
    3.44 +            printk("Error: (get_reg_value) Invalid index value\n");
    3.45              domain_crash_synchronous();
    3.46          }
    3.47      }
    3.48 @@ -156,7 +156,7 @@ long get_reg_value(int size, int index, 
    3.49      case 6: return __get_reg_value(regs->esi, size);
    3.50      case 7: return __get_reg_value(regs->edi, size);
    3.51      default:
    3.52 -        printf("Error: (get_reg_value) Invalid index value\n");
    3.53 +        printk("Error: (get_reg_value) Invalid index value\n");
    3.54          domain_crash_synchronous();
    3.55      }
    3.56  }
    3.57 @@ -464,7 +464,7 @@ static int hvm_decode(int realmode, unsi
    3.58                      return DECODE_success;
    3.59  
    3.60                  default:
    3.61 -                    printf("%x/%x, This opcode isn't handled yet!\n",
    3.62 +                    printk("%x/%x, This opcode isn't handled yet!\n",
    3.63                             *opcode, ins_subtype);
    3.64                      return DECODE_failure;
    3.65              }
    3.66 @@ -614,7 +614,7 @@ static int hvm_decode(int realmode, unsi
    3.67          break;
    3.68  
    3.69      default:
    3.70 -        printf("%x, This opcode isn't handled yet!\n", *opcode);
    3.71 +        printk("%x, This opcode isn't handled yet!\n", *opcode);
    3.72          return DECODE_failure;
    3.73      }
    3.74  
    3.75 @@ -675,12 +675,12 @@ static int hvm_decode(int realmode, unsi
    3.76          }
    3.77          else
    3.78          {
    3.79 -            printf("0f %x, This opcode subtype isn't handled yet\n", *opcode);
    3.80 +            printk("0f %x, This opcode subtype isn't handled yet\n", *opcode);
    3.81              return DECODE_failure;
    3.82          }
    3.83  
    3.84      default:
    3.85 -        printf("0f %x, This opcode isn't handled yet\n", *opcode);
    3.86 +        printk("0f %x, This opcode isn't handled yet\n", *opcode);
    3.87          return DECODE_failure;
    3.88      }
    3.89  }
    3.90 @@ -702,7 +702,7 @@ static void hvm_send_assist_req(struct v
    3.91      if ( unlikely(p->state != STATE_INVALID) ) {
    3.92          /* This indicates a bug in the device model.  Crash the
    3.93             domain. */
    3.94 -        printf("Device model set bad IO state %d.\n", p->state);
    3.95 +        printk("Device model set bad IO state %d.\n", p->state);
    3.96          domain_crash(v->domain);
    3.97          return;
    3.98      }
    3.99 @@ -733,7 +733,7 @@ void send_pio_req(struct cpu_user_regs *
   3.100  
   3.101      p = &vio->vp_ioreq;
   3.102      if ( p->state != STATE_INVALID )
   3.103 -        printf("WARNING: send pio with something already pending (%d)?\n",
   3.104 +        printk("WARNING: send pio with something already pending (%d)?\n",
   3.105                 p->state);
   3.106      p->dir = dir;
   3.107      p->pdata_valid = pvalid;
   3.108 @@ -776,14 +776,14 @@ void send_mmio_req(
   3.109  
   3.110      vio = get_vio(v->domain, v->vcpu_id);
   3.111      if (vio == NULL) {
   3.112 -        printf("bad shared page\n");
   3.113 +        printk("bad shared page\n");
   3.114          domain_crash_synchronous();
   3.115      }
   3.116  
   3.117      p = &vio->vp_ioreq;
   3.118  
   3.119      if ( p->state != STATE_INVALID )
   3.120 -        printf("WARNING: send mmio with something already pending (%d)?\n",
   3.121 +        printk("WARNING: send mmio with something already pending (%d)?\n",
   3.122                 p->state);
   3.123      p->dir = dir;
   3.124      p->pdata_valid = pvalid;
   3.125 @@ -841,7 +841,7 @@ static void mmio_operands(int type, unsi
   3.126          else
   3.127              send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0);
   3.128      } else {
   3.129 -        printf("mmio_operands: invalid operand\n");
   3.130 +        printk("mmio_operands: invalid operand\n");
   3.131          domain_crash_synchronous();
   3.132      }
   3.133  }
   3.134 @@ -866,8 +866,10 @@ void handle_mmio(unsigned long va, unsig
   3.135      memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES);
   3.136      hvm_store_cpu_guest_regs(v, regs, NULL);
   3.137  
   3.138 -    if ((inst_len = hvm_instruction_length(v)) <= 0) {
   3.139 -        printf("handle_mmio: failed to get instruction length\n");
   3.140 +    inst_len = hvm_instruction_length(regs, hvm_guest_x86_mode(v));
   3.141 +    if ( inst_len <= 0 )
   3.142 +    {
   3.143 +        printk("handle_mmio: failed to get instruction length\n");
   3.144          domain_crash_synchronous();
   3.145      }
   3.146  
   3.147 @@ -880,19 +882,19 @@ void handle_mmio(unsigned long va, unsig
   3.148      memset(inst, 0, MAX_INST_LEN);
   3.149      ret = inst_copy_from_guest(inst, inst_addr, inst_len);
   3.150      if (ret != inst_len) {
   3.151 -        printf("handle_mmio: failed to copy instruction\n");
   3.152 +        printk("handle_mmio: failed to copy instruction\n");
   3.153          domain_crash_synchronous();
   3.154      }
   3.155  
   3.156      init_instruction(&mmio_inst);
   3.157  
   3.158      if (hvm_decode(realmode, inst, &mmio_inst) == DECODE_failure) {
   3.159 -        printf("handle_mmio: failed to decode instruction\n");
   3.160 -        printf("mmio opcode: va 0x%lx, gpa 0x%lx, len %d:",
   3.161 +        printk("handle_mmio: failed to decode instruction\n");
   3.162 +        printk("mmio opcode: va 0x%lx, gpa 0x%lx, len %d:",
   3.163                 va, gpa, inst_len);
   3.164          for (i = 0; i < inst_len; i++)
   3.165 -            printf(" %02x", inst[i] & 0xFF);
   3.166 -        printf("\n");
   3.167 +            printk(" %02x", inst[i] & 0xFF);
   3.168 +        printk("\n");
   3.169          domain_crash_synchronous();
   3.170      }
   3.171  
   3.172 @@ -1073,7 +1075,7 @@ void handle_mmio(unsigned long va, unsig
   3.173          break;
   3.174  
   3.175      default:
   3.176 -        printf("Unhandled MMIO instruction\n");
   3.177 +        printk("Unhandled MMIO instruction\n");
   3.178          domain_crash_synchronous();
   3.179      }
   3.180  }
     4.1 --- a/xen/arch/x86/hvm/svm/Makefile	Mon Sep 25 09:36:11 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/svm/Makefile	Mon Sep 25 10:22:17 2006 +0100
     4.3 @@ -2,7 +2,6 @@ subdir-$(x86_32) += x86_32
     4.4  subdir-$(x86_64) += x86_64
     4.5  
     4.6  obj-y += emulate.o
     4.7 -obj-y += instrlen.o
     4.8  obj-y += intr.o
     4.9  obj-y += svm.o
    4.10  obj-y += vmcb.o
     5.1 --- a/xen/arch/x86/hvm/svm/instrlen.c	Mon Sep 25 09:36:11 2006 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,479 +0,0 @@
     5.4 -/*
     5.5 - * instrlen.c - calculates the instruction length for all operating modes
     5.6 - * 
     5.7 - * Travis Betak, travis.betak@amd.com
     5.8 - * Copyright (c) 2005,2006 AMD
     5.9 - * Copyright (c) 2005 Keir Fraser
    5.10 - *
    5.11 - * Essentially a very, very stripped version of Keir Fraser's work in
    5.12 - * x86_emulate.c.  Used for MMIO.
    5.13 - */
    5.14 -
    5.15 -/*
    5.16 - * TODO: the way in which we use svm_instrlen is very inefficient as is now
    5.17 - * stands.  It will be worth while to return the actual instruction buffer
    5.18 - * along with the instruction length since one of the reasons we are getting
    5.19 - * the instruction length is to know how many instruction bytes we need to
    5.20 - * fetch.
    5.21 - */
    5.22 -
    5.23 -#include <xen/config.h>
    5.24 -#include <xen/types.h>
    5.25 -#include <xen/lib.h>
    5.26 -#include <xen/mm.h>
    5.27 -#include <asm/regs.h>
    5.28 -#define DPRINTF DPRINTK
    5.29 -#include <asm-x86/x86_emulate.h>
    5.30 -
    5.31 -/* read from guest memory */
    5.32 -extern int inst_copy_from_guest(unsigned char *buf, unsigned long eip,
    5.33 -        int length);
    5.34 -extern void svm_dump_inst(unsigned long eip);
    5.35 -
    5.36 -/*
    5.37 - * Opcode effective-address decode tables.
    5.38 - * Note that we only emulate instructions that have at least one memory
    5.39 - * operand (excluding implicit stack references). We assume that stack
    5.40 - * references and instruction fetches will never occur in special memory
    5.41 - * areas that require emulation. So, for example, 'mov <imm>,<reg>' need
    5.42 - * not be handled.
    5.43 - */
    5.44 -
    5.45 -/* Operand sizes: 8-bit operands or specified/overridden size. */
    5.46 -#define ByteOp      (1<<0) /* 8-bit operands. */
    5.47 -/* Destination operand type. */
    5.48 -#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
    5.49 -#define DstReg      (2<<1) /* Register operand. */
    5.50 -#define DstMem      (3<<1) /* Memory operand. */
    5.51 -#define DstMask     (3<<1)
    5.52 -/* Source operand type. */
    5.53 -#define SrcNone     (0<<3) /* No source operand. */
    5.54 -#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
    5.55 -#define SrcReg      (1<<3) /* Register operand. */
    5.56 -#define SrcMem      (2<<3) /* Memory operand. */
    5.57 -#define SrcMem16    (3<<3) /* Memory operand (16-bit). */
    5.58 -#define SrcMem32    (4<<3) /* Memory operand (32-bit). */
    5.59 -#define SrcImm      (5<<3) /* Immediate operand. */
    5.60 -#define SrcImmByte  (6<<3) /* 8-bit sign-extended immediate operand. */
    5.61 -#define SrcMask     (7<<3)
    5.62 -/* Generic ModRM decode. */
    5.63 -#define ModRM       (1<<6)
    5.64 -/* Destination is only written; never read. */
    5.65 -#define Mov         (1<<7)
    5.66 -
    5.67 -static uint8_t opcode_table[256] = {
    5.68 -    /* 0x00 - 0x07 */
    5.69 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.70 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.71 -    0, 0, 0, 0,
    5.72 -    /* 0x08 - 0x0F */
    5.73 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.74 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.75 -    0, 0, 0, 0,
    5.76 -    /* 0x10 - 0x17 */
    5.77 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.78 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.79 -    0, 0, 0, 0,
    5.80 -    /* 0x18 - 0x1F */
    5.81 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.82 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.83 -    0, 0, 0, 0,
    5.84 -    /* 0x20 - 0x27 */
    5.85 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.86 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.87 -    0, 0, 0, 0,
    5.88 -    /* 0x28 - 0x2F */
    5.89 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.90 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.91 -    0, 0, 0, 0,
    5.92 -    /* 0x30 - 0x37 */
    5.93 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.94 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.95 -    0, 0, 0, 0,
    5.96 -    /* 0x38 - 0x3F */
    5.97 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    5.98 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    5.99 -    0, 0, 0, 0,
   5.100 -    /* 0x40 - 0x4F */
   5.101 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.102 -    /* 0x50 - 0x5F */
   5.103 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.104 -    /* 0x60 - 0x6F */
   5.105 -    0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */,
   5.106 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.107 -    /* 0x70 - 0x7F */
   5.108 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.109 -    /* 0x80 - 0x87 */
   5.110 -    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
   5.111 -    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
   5.112 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   5.113 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   5.114 -    /* 0x88 - 0x8F */
   5.115 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   5.116 -    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
   5.117 -    0, 0, 0, DstMem|SrcNone|ModRM|Mov,
   5.118 -    /* 0x90 - 0x9F */
   5.119 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.120 -    /* 0xA0 - 0xA7 */
   5.121 -    ByteOp|DstReg|SrcMem|Mov, DstReg|SrcMem|Mov,
   5.122 -    ByteOp|DstMem|SrcReg|Mov, DstMem|SrcReg|Mov,
   5.123 -    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   5.124 -    ByteOp|ImplicitOps, ImplicitOps,
   5.125 -    /* 0xA8 - 0xAF */
   5.126 -    0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   5.127 -    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   5.128 -    ByteOp|ImplicitOps, ImplicitOps,
   5.129 -    /* 0xB0 - 0xBF */
   5.130 -    SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, 
   5.131 -    SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, 
   5.132 -    0, 0, 0, 0, 0, 0, 0, 0,
   5.133 -    /* 0xC0 - 0xC7 */
   5.134 -    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
   5.135 -    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
   5.136 -    /* 0xC8 - 0xCF */
   5.137 -    0, 0, 0, 0, 0, 0, 0, 0,
   5.138 -    /* 0xD0 - 0xD7 */
   5.139 -    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
   5.140 -    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
   5.141 -    0, 0, 0, 0,
   5.142 -    /* 0xD8 - 0xDF */
   5.143 -    0, 0, 0, 0, 0, 0, 0, 0,
   5.144 -    /* 0xE0 - 0xEF */
   5.145 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.146 -    /* 0xF0 - 0xF7 */
   5.147 -    0, 0, 0, 0,
   5.148 -    0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
   5.149 -    /* 0xF8 - 0xFF */
   5.150 -    0, 0, 0, 0,
   5.151 -    0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
   5.152 -};
   5.153 -
   5.154 -static uint8_t twobyte_table[256] = {
   5.155 -    /* 0x00 - 0x0F */
   5.156 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
   5.157 -    /* 0x10 - 0x1F */
   5.158 -    0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0,
   5.159 -    /* 0x20 - 0x2F */
   5.160 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.161 -    /* 0x30 - 0x3F */
   5.162 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.163 -    /* 0x40 - 0x47 */
   5.164 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.165 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.166 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.167 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.168 -    /* 0x48 - 0x4F */
   5.169 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.170 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.171 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.172 -    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   5.173 -    /* 0x50 - 0x5F */
   5.174 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.175 -    /* 0x60 - 0x6F */
   5.176 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.177 -    /* 0x70 - 0x7F */
   5.178 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.179 -    /* 0x80 - 0x8F */
   5.180 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.181 -    /* 0x90 - 0x9F */
   5.182 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.183 -    /* 0xA0 - 0xA7 */
   5.184 -    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0, 
   5.185 -    /* 0xA8 - 0xAF */
   5.186 -    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
   5.187 -    /* 0xB0 - 0xB7 */
   5.188 -    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstMem|SrcReg|ModRM,
   5.189 -    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
   5.190 -    /* 0xB8 - 0xBF */
   5.191 -    0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM,
   5.192 -    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
   5.193 -    /* 0xC0 - 0xCF */
   5.194 -    0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
   5.195 -    /* 0xD0 - 0xDF */
   5.196 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.197 -    /* 0xE0 - 0xEF */
   5.198 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   5.199 -    /* 0xF0 - 0xFF */
   5.200 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   5.201 -};
   5.202 -
   5.203 -/* 
   5.204 - * insn_fetch - fetch the next 1 to 4 bytes from instruction stream 
   5.205 - * 
   5.206 - * @_type:   u8, u16, u32, s8, s16, or s32
   5.207 - * @_size:   1, 2, or 4 bytes
   5.208 - * @_eip:    address to fetch from guest memory
   5.209 - * @_length: updated! increments the current instruction length counter by _size
   5.210 - *
   5.211 - * INTERNAL this is used internally by svm_instrlen to fetch the next byte,
   5.212 - * word, or dword from guest memory at location _eip.  we currently use a local
   5.213 - * unsigned long as the storage buffer since the most bytes we're gonna get
   5.214 - * is limited to 4.
   5.215 - */
   5.216 -#define insn_fetch(_type, _size, _eip, _length) \
   5.217 -({  unsigned long _x; \
   5.218 -        if ((rc = inst_copy_from_guest((unsigned char *)(&(_x)), \
   5.219 -                (unsigned long)(_eip), _size)) \
   5.220 -                    != _size) \
   5.221 -        goto done; \
   5.222 -    (_eip) += (_size); \
   5.223 -    (_length) += (_size); \
   5.224 -    (_type)_x; \
   5.225 -})
   5.226 -
   5.227 -
   5.228 -/**
   5.229 - * svn_instrlen - returns the current instructions length
   5.230 - *
   5.231 - * @regs: guest register state
   5.232 - * @mode: guest operating mode
   5.233 - *
   5.234 - * EXTERNAL this routine calculates the length of the current instruction
   5.235 - * pointed to by eip.  The guest state is _not_ changed by this routine.
   5.236 - */
   5.237 -int svm_instrlen(struct cpu_user_regs *regs, int mode)
   5.238 -{
   5.239 -    uint8_t b, d, twobyte = 0, rex_prefix = 0;
   5.240 -    uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   5.241 -    unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
   5.242 -    int rc = 0;
   5.243 -    int length = 0;
   5.244 -    unsigned int tmp;
   5.245 -
   5.246 -    /* Shadow copy of register state. Committed on successful emulation. */
   5.247 -    struct cpu_user_regs _regs = *regs;
   5.248 -
   5.249 -    /* include CS for 16-bit modes */
   5.250 -    if (mode == X86EMUL_MODE_REAL || mode == X86EMUL_MODE_PROT16)
   5.251 -        _regs.eip += (_regs.cs << 4);
   5.252 -
   5.253 -    switch ( mode )
   5.254 -    {
   5.255 -    case X86EMUL_MODE_REAL:
   5.256 -    case X86EMUL_MODE_PROT16:
   5.257 -        op_bytes = ad_bytes = 2;
   5.258 -        break;
   5.259 -    case X86EMUL_MODE_PROT32:
   5.260 -        op_bytes = ad_bytes = 4;
   5.261 -        break;
   5.262 -#ifdef __x86_64__
   5.263 -    case X86EMUL_MODE_PROT64:
   5.264 -        op_bytes = 4;
   5.265 -        ad_bytes = 8;
   5.266 -        break;
   5.267 -#endif
   5.268 -    default:
   5.269 -        return -1;
   5.270 -    }
   5.271 -
   5.272 -    /* Legacy prefixes. */
   5.273 -    for ( i = 0; i < 8; i++ )
   5.274 -    {
   5.275 -        switch ( b = insn_fetch(uint8_t, 1, _regs.eip, length) )
   5.276 -        {
   5.277 -        case 0x66: /* operand-size override */
   5.278 -            op_bytes ^= 6;      /* switch between 2/4 bytes */
   5.279 -            break;
   5.280 -        case 0x67: /* address-size override */
   5.281 -            if ( mode == X86EMUL_MODE_PROT64 )
   5.282 -                ad_bytes ^= 12; /* switch between 4/8 bytes */
   5.283 -            else
   5.284 -                ad_bytes ^= 6;  /* switch between 2/4 bytes */
   5.285 -            break;
   5.286 -        case 0x2e: /* CS override */
   5.287 -        case 0x3e: /* DS override */
   5.288 -        case 0x26: /* ES override */
   5.289 -        case 0x64: /* FS override */
   5.290 -        case 0x65: /* GS override */
   5.291 -        case 0x36: /* SS override */
   5.292 -            break;
   5.293 -        case 0xf0: /* LOCK */
   5.294 -            lock_prefix = 1;
   5.295 -            break;
   5.296 -        case 0xf3: /* REP/REPE/REPZ */
   5.297 -            rep_prefix = 1;
   5.298 -            break;
   5.299 -        case 0xf2: /* REPNE/REPNZ */
   5.300 -            break;
   5.301 -        default:
   5.302 -            goto done_prefixes;
   5.303 -        }
   5.304 -    }
   5.305 -done_prefixes:
   5.306 -
   5.307 -    /* Note quite the same as 80386 real mode, but hopefully good enough. */
   5.308 -    if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) ) {
   5.309 -        printf("sonofabitch!! we don't support 32-bit addresses in realmode\n");
   5.310 -        goto cannot_emulate;
   5.311 -    }
   5.312 -
   5.313 -    /* REX prefix. */
   5.314 -    if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
   5.315 -    {
   5.316 -        rex_prefix = b;
   5.317 -        if ( b & 8 )
   5.318 -            op_bytes = 8;          /* REX.W */
   5.319 -        modrm_reg = (b & 4) << 1;  /* REX.R */
   5.320 -        /* REX.B and REX.X do not need to be decoded. */
   5.321 -        b = insn_fetch(uint8_t, 1, _regs.eip, length);
   5.322 -    }
   5.323 -
   5.324 -    /* Opcode byte(s). */
   5.325 -    d = opcode_table[b];
   5.326 -    if ( d == 0 )
   5.327 -    {
   5.328 -        /* Two-byte opcode? */
   5.329 -        if ( b == 0x0f )
   5.330 -        {
   5.331 -            twobyte = 1;
   5.332 -            b = insn_fetch(uint8_t, 1, _regs.eip, length);
   5.333 -            d = twobyte_table[b];
   5.334 -        }
   5.335 -
   5.336 -        /* Unrecognised? */
   5.337 -        if ( d == 0 )
   5.338 -            goto cannot_emulate;
   5.339 -    }
   5.340 -
   5.341 -    /* ModRM and SIB bytes. */
   5.342 -    if ( d & ModRM )
   5.343 -    {
   5.344 -        modrm = insn_fetch(uint8_t, 1, _regs.eip, length);
   5.345 -        modrm_mod |= (modrm & 0xc0) >> 6;
   5.346 -        modrm_reg |= (modrm & 0x38) >> 3;
   5.347 -        modrm_rm  |= (modrm & 0x07);
   5.348 -
   5.349 -        if ( modrm_mod == 3 )
   5.350 -        {
   5.351 -            DPRINTF("Cannot parse ModRM.mod == 3.\n");
   5.352 -            goto cannot_emulate;
   5.353 -        }
   5.354 -
   5.355 -        if ( ad_bytes == 2 )
   5.356 -        {
   5.357 -            /* 16-bit ModR/M decode. */
   5.358 -            switch ( modrm_mod )
   5.359 -            {
   5.360 -            case 0:
   5.361 -                if ( modrm_rm == 6 ) 
   5.362 -                {
   5.363 -                    length += 2;
   5.364 -                    _regs.eip += 2; /* skip disp16 */
   5.365 -                }
   5.366 -                break;
   5.367 -            case 1:
   5.368 -                length += 1;
   5.369 -                _regs.eip += 1; /* skip disp8 */
   5.370 -                break;
   5.371 -            case 2:
   5.372 -                length += 2;
   5.373 -                _regs.eip += 2; /* skip disp16 */
   5.374 -                break;
   5.375 -            }
   5.376 -        }
   5.377 -        else
   5.378 -        {
   5.379 -            /* 32/64-bit ModR/M decode. */
   5.380 -            switch ( modrm_mod )
   5.381 -            {
   5.382 -            case 0:
   5.383 -                if ( (modrm_rm == 4) && 
   5.384 -                     (((insn_fetch(uint8_t, 1, _regs.eip, length)) & 7) 
   5.385 -                        == 5) )
   5.386 -                {
   5.387 -                    length += 4;
   5.388 -                    _regs.eip += 4; /* skip disp32 specified by SIB.base */
   5.389 -                }
   5.390 -                else if ( modrm_rm == 5 )
   5.391 -                {
   5.392 -                    length += 4;
   5.393 -                    _regs.eip += 4; /* skip disp32 */
   5.394 -                }
   5.395 -                break;
   5.396 -            case 1:
   5.397 -                if ( modrm_rm == 4 )
   5.398 -                {
   5.399 -                    insn_fetch(uint8_t, 1, _regs.eip, length);
   5.400 -                }
   5.401 -                length += 1;
   5.402 -                _regs.eip += 1; /* skip disp8 */
   5.403 -                break;
   5.404 -            case 2:
   5.405 -                if ( modrm_rm == 4 )
   5.406 -                {
   5.407 -                    insn_fetch(uint8_t, 1, _regs.eip, length);
   5.408 -                }
   5.409 -                length += 4;
   5.410 -                _regs.eip += 4; /* skip disp32 */
   5.411 -                break;
   5.412 -            }
   5.413 -        }
   5.414 -    }
   5.415 -
   5.416 -    /* Decode and fetch the destination operand: register or memory. */
   5.417 -    switch ( d & DstMask )
   5.418 -    {
   5.419 -    case ImplicitOps:
   5.420 -        /* Special instructions do their own operand decoding. */
   5.421 -        goto done;
   5.422 -    }
   5.423 -
   5.424 -    /* Decode and fetch the source operand: register, memory or immediate. */
   5.425 -    switch ( d & SrcMask )
   5.426 -    {
   5.427 -    case SrcImm:
   5.428 -        tmp = (d & ByteOp) ? 1 : op_bytes;
   5.429 -        if ( tmp == 8 ) tmp = 4;
   5.430 -        /* NB. Immediates are sign-extended as necessary. */
   5.431 -        switch ( tmp )
   5.432 -        {
   5.433 -        case 1: insn_fetch(int8_t,  1, _regs.eip, length); break;
   5.434 -        case 2: insn_fetch(int16_t, 2, _regs.eip, length); break;
   5.435 -        case 4: insn_fetch(int32_t, 4, _regs.eip, length); break;
   5.436 -        }
   5.437 -        break;
   5.438 -    case SrcImmByte:
   5.439 -        insn_fetch(int8_t,  1, _regs.eip, length);
   5.440 -        break;
   5.441 -    }
   5.442 -
   5.443 -    if ( twobyte )
   5.444 -        goto done;
   5.445 -
   5.446 -    switch ( b )
   5.447 -    {
   5.448 -    case 0xa0 ... 0xa1: /* mov */
   5.449 -        length += ad_bytes;
   5.450 -        _regs.eip += ad_bytes; /* skip src displacement */
   5.451 -        break;
   5.452 -    case 0xa2 ... 0xa3: /* mov */
   5.453 -        length += ad_bytes;
   5.454 -        _regs.eip += ad_bytes; /* skip dst displacement */
   5.455 -        break;
   5.456 -    case 0xf6 ... 0xf7: /* Grp3 */
   5.457 -        switch ( modrm_reg )
   5.458 -        {
   5.459 -        case 0 ... 1: /* test */
   5.460 -            /* Special case in Grp3: test has an immediate source operand. */
   5.461 -            tmp = (d & ByteOp) ? 1 : op_bytes;
   5.462 -            if ( tmp == 8 ) tmp = 4;
   5.463 -            switch ( tmp )
   5.464 -            {
   5.465 -            case 1: insn_fetch(int8_t,  1, _regs.eip, length); break;
   5.466 -            case 2: insn_fetch(int16_t, 2, _regs.eip, length); break;
   5.467 -            case 4: insn_fetch(int32_t, 4, _regs.eip, length); break;
   5.468 -            }
   5.469 -            goto done;
   5.470 -        }
   5.471 -        break;
   5.472 -    }
   5.473 -
   5.474 -done:
   5.475 -    return length;
   5.476 -
   5.477 -cannot_emulate:
   5.478 -    DPRINTF("Cannot emulate %02x at address %lx (eip %lx, mode %d)\n",
   5.479 -            b, (unsigned long)_regs.eip, (unsigned long)regs->eip, mode);
   5.480 -    svm_dump_inst(_regs.eip);
   5.481 -    return -1;
   5.482 -}
     6.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Sep 25 09:36:11 2006 +0100
     6.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Sep 25 10:22:17 2006 +0100
     6.3 @@ -44,6 +44,7 @@
     6.4  #include <asm/hvm/svm/emulate.h>
     6.5  #include <asm/hvm/svm/vmmcall.h>
     6.6  #include <asm/hvm/svm/intr.h>
     6.7 +#include <asm/x86_emulate.h>
     6.8  #include <public/sched.h>
     6.9  
    6.10  #define SVM_EXTRA_DEBUG
    6.11 @@ -60,7 +61,6 @@ extern int inst_copy_from_guest(unsigned
    6.12  extern asmlinkage void do_IRQ(struct cpu_user_regs *);
    6.13  extern void send_pio_req(struct cpu_user_regs *regs, unsigned long port,
    6.14                           unsigned long count, int size, long value, int dir, int pvalid);
    6.15 -extern int svm_instrlen(struct cpu_user_regs *regs, int mode);
    6.16  extern void svm_dump_inst(unsigned long eip);
    6.17  extern int svm_dbg_on;
    6.18  void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
    6.19 @@ -468,21 +468,19 @@ static int svm_realmode(struct vcpu *v)
    6.20      return (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE);
    6.21  }
    6.22  
    6.23 -int svm_guest_x86_mode(struct vcpu *v)
    6.24 +static int svm_guest_x86_mode(struct vcpu *v)
    6.25  {
    6.26      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    6.27 -    unsigned long cr0 = vmcb->cr0, eflags = vmcb->rflags, mode;
    6.28 -    /* check which operating mode the guest is running */
    6.29 -    if( vmcb->efer & EFER_LMA )
    6.30 -        mode = vmcb->cs.attributes.fields.l ? 8 : 4;
    6.31 -    else
    6.32 -        mode = (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE) ? 2 : 4;
    6.33 -    return mode;
    6.34 -}
    6.35 -
    6.36 -int svm_instruction_length(struct vcpu *v)
    6.37 -{
    6.38 -    return svm_instrlen(guest_cpu_user_regs(), svm_guest_x86_mode(v));
    6.39 +
    6.40 +    if ( vmcb->efer & EFER_LMA )
    6.41 +        return (vmcb->cs.attributes.fields.l ?
    6.42 +                X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32);
    6.43 +
    6.44 +    if ( svm_realmode(v) )
    6.45 +        return X86EMUL_MODE_REAL;
    6.46 +
    6.47 +    return (vmcb->cs.attributes.fields.db ?
    6.48 +            X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16);
    6.49  }
    6.50  
    6.51  void svm_update_host_cr3(struct vcpu *v)
    6.52 @@ -878,7 +876,6 @@ int start_svm(void)
    6.53      hvm_funcs.long_mode_enabled = svm_long_mode_enabled;
    6.54      hvm_funcs.pae_enabled = svm_pae_enabled;
    6.55      hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
    6.56 -    hvm_funcs.instruction_length = svm_instruction_length;
    6.57      hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
    6.58  
    6.59      hvm_funcs.update_host_cr3 = svm_update_host_cr3;
     7.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Sep 25 09:36:11 2006 +0100
     7.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Sep 25 10:22:17 2006 +0100
     7.3 @@ -45,6 +45,7 @@
     7.4  #include <public/hvm/ioreq.h>
     7.5  #include <asm/hvm/vpic.h>
     7.6  #include <asm/hvm/vlapic.h>
     7.7 +#include <asm/x86_emulate.h>
     7.8  
     7.9  extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
    7.10  
    7.11 @@ -593,15 +594,6 @@ static void vmx_load_cpu_guest_regs(stru
    7.12      vmx_vmcs_exit(v);
    7.13  }
    7.14  
    7.15 -static int vmx_instruction_length(struct vcpu *v)
    7.16 -{
    7.17 -    unsigned long inst_len;
    7.18 -
    7.19 -    if ( __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len) ) /* XXX Unsafe XXX */
    7.20 -        return 0;
    7.21 -    return inst_len;
    7.22 -}
    7.23 -
    7.24  static unsigned long vmx_get_ctrl_reg(struct vcpu *v, unsigned int num)
    7.25  {
    7.26      switch ( num )
    7.27 @@ -729,6 +721,35 @@ static void vmx_init_hypercall_page(stru
    7.28      *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
    7.29  }
    7.30  
    7.31 +static int vmx_realmode(struct vcpu *v)
    7.32 +{
    7.33 +    unsigned long rflags;
    7.34 +
    7.35 +    ASSERT(v == current);
    7.36 +
    7.37 +    __vmread(GUEST_RFLAGS, &rflags);
    7.38 +    return rflags & X86_EFLAGS_VM;
    7.39 +}
    7.40 +
    7.41 +static int vmx_guest_x86_mode(struct vcpu *v)
    7.42 +{
    7.43 +    unsigned long cs_ar_bytes;
    7.44 +
    7.45 +    ASSERT(v == current);
    7.46 +
    7.47 +    __vmread(GUEST_CS_AR_BYTES, &cs_ar_bytes);
    7.48 +
    7.49 +    if ( vmx_long_mode_enabled(v) )
    7.50 +        return ((cs_ar_bytes & (1u<<13)) ?
    7.51 +                X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32);
    7.52 +
    7.53 +    if ( vmx_realmode(v) )
    7.54 +        return X86EMUL_MODE_REAL;
    7.55 +
    7.56 +    return ((cs_ar_bytes & (1u<<14)) ?
    7.57 +            X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16);
    7.58 +}
    7.59 +
    7.60  /* Setup HVM interfaces */
    7.61  static void vmx_setup_hvm_funcs(void)
    7.62  {
    7.63 @@ -748,7 +769,6 @@ static void vmx_setup_hvm_funcs(void)
    7.64      hvm_funcs.long_mode_enabled = vmx_long_mode_enabled;
    7.65      hvm_funcs.pae_enabled = vmx_pae_enabled;
    7.66      hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
    7.67 -    hvm_funcs.instruction_length = vmx_instruction_length;
    7.68      hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
    7.69  
    7.70      hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
     8.1 --- a/xen/include/asm-x86/hvm/hvm.h	Mon Sep 25 09:36:11 2006 +0100
     8.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Mon Sep 25 10:22:17 2006 +0100
     8.3 @@ -51,15 +51,13 @@ struct hvm_function_table {
     8.4       * Examine specifics of the guest state:
     8.5       * 1) determine whether the guest is in real or vm8086 mode,
     8.6       * 2) determine whether paging is enabled,
     8.7 -     * 3) return the length of the instruction that caused an exit.
     8.8 -     * 4) return the current guest control-register value
     8.9 +     * 3) return the current guest control-register value
    8.10       */
    8.11      int (*realmode)(struct vcpu *v);
    8.12      int (*paging_enabled)(struct vcpu *v);
    8.13      int (*long_mode_enabled)(struct vcpu *v);
    8.14      int (*pae_enabled)(struct vcpu *v);
    8.15      int (*guest_x86_mode)(struct vcpu *v);
    8.16 -    int (*instruction_length)(struct vcpu *v);
    8.17      unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
    8.18  
    8.19      /* 
    8.20 @@ -159,11 +157,7 @@ hvm_guest_x86_mode(struct vcpu *v)
    8.21      return hvm_funcs.guest_x86_mode(v);
    8.22  }
    8.23  
    8.24 -static inline int
    8.25 -hvm_instruction_length(struct vcpu *v)
    8.26 -{
    8.27 -    return hvm_funcs.instruction_length(v);
    8.28 -}
    8.29 +int hvm_instruction_length(struct cpu_user_regs *regs, int mode);
    8.30  
    8.31  static inline void
    8.32  hvm_update_host_cr3(struct vcpu *v)
    8.33 @@ -182,9 +176,9 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u
    8.34      return 0;                   /* force to fail */
    8.35  }
    8.36  
    8.37 -extern void hvm_stts(struct vcpu *v);
    8.38 -extern void hvm_set_guest_time(struct vcpu *v, u64 gtime);
    8.39 -extern void hvm_do_resume(struct vcpu *v);
    8.40 +void hvm_stts(struct vcpu *v);
    8.41 +void hvm_set_guest_time(struct vcpu *v, u64 gtime);
    8.42 +void hvm_do_resume(struct vcpu *v);
    8.43  
    8.44  static inline void
    8.45  hvm_init_ap_context(struct vcpu_guest_context *ctxt,
    8.46 @@ -193,6 +187,6 @@ hvm_init_ap_context(struct vcpu_guest_co
    8.47      return hvm_funcs.init_ap_context(ctxt, vcpuid, trampoline_vector);
    8.48  }
    8.49  
    8.50 -extern int hvm_bringup_ap(int vcpuid, int trampoline_vector);
    8.51 +int hvm_bringup_ap(int vcpuid, int trampoline_vector);
    8.52  
    8.53  #endif /* __ASM_X86_HVM_HVM_H__ */
     9.1 --- a/xen/include/asm-x86/hvm/vmx/vmx.h	Mon Sep 25 09:36:11 2006 +0100
     9.2 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h	Mon Sep 25 10:22:17 2006 +0100
     9.3 @@ -425,38 +425,12 @@ static inline int vmx_pae_enabled(struct
     9.4  }
     9.5  
     9.6  /* Works only for vcpu == current */
     9.7 -static inline int vmx_realmode(struct vcpu *v)
     9.8 -{
     9.9 -    unsigned long rflags;
    9.10 -    ASSERT(v == current);
    9.11 -
    9.12 -    __vmread(GUEST_RFLAGS, &rflags);
    9.13 -    return rflags & X86_EFLAGS_VM;
    9.14 -}
    9.15 -
    9.16 -/* Works only for vcpu == current */
    9.17  static inline void vmx_update_host_cr3(struct vcpu *v)
    9.18  {
    9.19      ASSERT(v == current);
    9.20      __vmwrite(HOST_CR3, v->arch.cr3);
    9.21  }
    9.22  
    9.23 -static inline int vmx_guest_x86_mode(struct vcpu *v)
    9.24 -{
    9.25 -    unsigned long cs_ar_bytes;
    9.26 -    ASSERT(v == current);
    9.27 -
    9.28 -    if ( vmx_long_mode_enabled(v) )
    9.29 -    {
    9.30 -        __vmread(GUEST_CS_AR_BYTES, &cs_ar_bytes);
    9.31 -        return (cs_ar_bytes & (1u<<13)) ? 8 : 4;
    9.32 -    }
    9.33 -    if ( vmx_realmode(v) )
    9.34 -        return 2;
    9.35 -    __vmread(GUEST_CS_AR_BYTES, &cs_ar_bytes);
    9.36 -    return (cs_ar_bytes & (1u<<14)) ? 4 : 2;
    9.37 -}
    9.38 -
    9.39  static inline int vmx_pgbit_test(struct vcpu *v)
    9.40  {
    9.41      unsigned long cr0;