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 [email protected] https://lists.sourceforge.net/lists/listinfo/kvm-devel
