Extract prefix decoding part from x86_emulate_memop() to x86_decode_prefix().
Signed-off-by: Laurent Vivier <[EMAIL PROTECTED]> -- ------------- [EMAIL PROTECTED] -------------- "Software is hard" - Donald Knuth
Index: kvm/drivers/kvm/x86_emulate.c =================================================================== --- kvm.orig/drivers/kvm/x86_emulate.c 2007-07-31 17:44:35.000000000 +0200 +++ kvm/drivers/kvm/x86_emulate.c 2007-07-31 18:23:39.000000000 +0200 @@ -480,43 +480,24 @@ } int -x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) +x86_decode_prefix(int mode, u8 *inst, struct x86_prefix *prefix) { - unsigned d; - u8 b, sib, twobyte = 0; - u8 modrm, modrm_mod = 0; - unsigned int i; - int rc = 0; - struct operand src, dst; - unsigned long cr2 = ctxt->cr2; - int mode = ctxt->mode; - unsigned long modrm_ea; - int use_modrm_ea, scale, rip_relative = 0; - int no_wb = 0; - u64 msr_data; - struct x86_prefix prefix; - - /* Shadow copy of register state. Committed on successful emulation. */ - unsigned long _regs[NR_VCPU_REGS]; - unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags; - unsigned long modrm_val = 0; - - memcpy(_regs, ctxt->vcpu->regs, sizeof _regs); - memset(&prefix, 0, sizeof(prefix)); - prefix.override_base = -1; + unsigned int op_bytes, ad_bytes; + int i; + u8 b; switch (mode) { case X86EMUL_MODE_REAL: case X86EMUL_MODE_PROT16: - prefix.op_bytes = prefix.ad_bytes = 2; + op_bytes = ad_bytes = 2; break; case X86EMUL_MODE_PROT32: - prefix.op_bytes = prefix.ad_bytes = 4; + op_bytes = ad_bytes = 4; break; #ifdef CONFIG_X86_64 case X86EMUL_MODE_PROT64: - prefix.op_bytes = 4; - prefix.ad_bytes = 8; + op_bytes = 4; + ad_bytes = 8; break; #endif default: @@ -525,39 +506,39 @@ /* Legacy prefixes. */ for (i = 0; i < 8; i++) { - switch (b = insn_fetch(u8, 1, _eip)) { + switch (b = inst[i]) { case 0x66: /* operand-size override */ - prefix.op_bytes ^= 6; /* switch between 2/4 bytes */ + op_bytes ^= 6; /* switch between 2/4 bytes */ break; case 0x67: /* address-size override */ if (mode == X86EMUL_MODE_PROT64) - prefix.ad_bytes ^= 12; /* switch between 4/8 bytes */ + ad_bytes ^= 12; /* switch between 4/8 bytes */ else - prefix.ad_bytes ^= 6; /* switch between 2/4 bytes */ + ad_bytes ^= 6; /* switch between 2/4 bytes */ break; case 0x2e: /* CS override */ - prefix.override_base = X86EMUL_BASE_CS; + prefix->override_base = X86EMUL_BASE_CS; break; case 0x3e: /* DS override */ - prefix.override_base = X86EMUL_BASE_DS; + prefix->override_base = X86EMUL_BASE_DS; break; case 0x26: /* ES override */ - prefix.override_base = X86EMUL_BASE_ES; + prefix->override_base = X86EMUL_BASE_ES; break; case 0x64: /* FS override */ - prefix.override_base = X86EMUL_BASE_FS; + prefix->override_base = X86EMUL_BASE_FS; break; case 0x65: /* GS override */ - prefix.override_base = X86EMUL_BASE_GS; + prefix->override_base = X86EMUL_BASE_GS; break; case 0x36: /* SS override */ - prefix.override_base = X86EMUL_BASE_SS; + prefix->override_base = X86EMUL_BASE_SS; break; case 0xf0: /* LOCK */ - prefix.lock = 1; + prefix->lock = 1; break; case 0xf3: /* REP/REPE/REPZ */ - prefix.rep = 1; + prefix->rep = 1; break; case 0xf2: /* REPNE/REPNZ */ break; @@ -570,15 +551,62 @@ /* REX prefix. */ if ((mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40)) { - prefix.rex = b; + prefix->rex = b; if (b & 8) - prefix.op_bytes = 8; /* REX.W */ - prefix.modrm_reg = (b & 4) << 1; /* REX.R */ - prefix.index_reg = (b & 2) << 2; /* REX.X */ - prefix.modrm_rm = prefix.base_reg = (b & 1) << 3; /* REG.B */ - b = insn_fetch(u8, 1, _eip); + op_bytes = 8; /* REX.W */ + prefix->modrm_reg = (b & 4) << 1; /* REX.R */ + prefix->index_reg = (b & 2) << 2; /* REX.X */ + prefix->modrm_rm = prefix->base_reg = (b & 1) << 3; /* REG.B */ + i++; } + prefix->op_bytes = op_bytes; + prefix->ad_bytes = ad_bytes; + + return i; +} +EXPORT_SYMBOL_GPL(x86_decode_prefix); + +int +x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) +{ + unsigned d; + u8 b, sib, twobyte = 0; + u8 modrm, modrm_mod = 0; + int rc = 0; + struct operand src, dst; + unsigned long cr2 = ctxt->cr2; + int mode = ctxt->mode; + unsigned long modrm_ea; + int use_modrm_ea, scale, rip_relative = 0; + int no_wb = 0; + u64 msr_data, inst; + struct x86_prefix prefix; + int count; + + /* Shadow copy of register state. Committed on successful emulation. */ + unsigned long _regs[NR_VCPU_REGS]; + unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags; + unsigned long modrm_val = 0; + + memcpy(_regs, ctxt->vcpu->regs, sizeof _regs); + + /* decode prefixes */ + + rc = ops->read_std(_eip + ctxt->base[X86EMUL_BASE_CS], + &inst, sizeof(inst), ctxt->vcpu); + if ( rc != 0 ) + goto done; + + memset(&prefix, 0, sizeof(prefix)); + prefix.override_base = -1; + + count = x86_decode_prefix(mode, (u8*)&inst, &prefix); + if (count == -1) + return -1; + _eip += count; + b = insn_fetch(u8, 1, _eip); + /* Opcode byte(s). */ d = opcode_table[b]; if (d == 0) { Index: kvm/drivers/kvm/x86_emulate.h =================================================================== --- kvm.orig/drivers/kvm/x86_emulate.h 2007-07-31 18:00:51.000000000 +0200 +++ kvm/drivers/kvm/x86_emulate.h 2007-07-31 18:01:53.000000000 +0200 @@ -164,6 +164,13 @@ #endif /* + * x86_decode_prefix: Decode instruction prefixes + * Returns -1 on failure, 0 on success. + */ +int +x86_decode_prefix(int mode, u8 *inst, struct x86_prefix *prefix); + +/* * x86_emulate_memop: Emulate an instruction that faulted attempting to * read/write a 'special' memory area. * Returns -1 on failure, 0 on success.
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel