public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Make some cleanup in x86_emulate.c
@ 2007-09-21 11:28 Laurent Vivier
  0 siblings, 0 replies; 6+ messages in thread
From: Laurent Vivier @ 2007-09-21 11:28 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

This patch series makes some cleanups in x86_emulate.c

[PATCH 1/3] move some parts of x86_decode_insn() into functions.
[PATCH 2/3] remove _eflags and use directly ctxt->eflags
[PATCH 3/3] remove no_wb



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 0/3] Make some cleanup in x86_emulate.c
@ 2007-09-24  9:10 Laurent Vivier
       [not found] ` <11906250562300-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Laurent Vivier @ 2007-09-24  9:10 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f; +Cc: Laurent Vivier

This patch series makes some cleanups in x86_emulate.c

[PATCH 1/3] move some parts of x86_decode_insn() into functions.
[PATCH 2/3] remove _eflags and use directly ctxt->eflags
[PATCH 3/3] remove no_wb

It has been rebased to current master.

Signed-off-by: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] move grp decoding into functions to make x86_emulate_insn() clearer
       [not found] ` <11906250562300-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
@ 2007-09-24  9:10   ` Laurent Vivier
       [not found]     ` <1190625056943-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
  2007-09-24 13:20   ` [PATCH 0/3] Make some cleanup in x86_emulate.c Avi Kivity
  1 sibling, 1 reply; 6+ messages in thread
From: Laurent Vivier @ 2007-09-24  9:10 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f; +Cc: Laurent Vivier

To improve readability, move push, writeback, and grp 1a/2/3/4/5/9 emulation 
parts into functions.

Signed-off-by: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
---
 drivers/kvm/x86_emulate.c |  451 ++++++++++++++++++++++++++------------------
 1 files changed, 266 insertions(+), 185 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index f294a49..64e8e03 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -896,6 +896,244 @@ done:
 	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
 }
 
+static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.type  = OP_MEM;
+	c->dst.bytes = c->op_bytes;
+	c->dst.val = c->src.val;
+	register_address_increment(c->regs[VCPU_REGS_RSP], -c->op_bytes);
+	c->dst.ptr = (void *) register_address(ctxt->ss_base,
+					       c->regs[VCPU_REGS_RSP]);
+}
+
+static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
+				struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	/* 64-bit mode: POP always pops a 64-bit operand. */
+
+	if (ctxt->mode == X86EMUL_MODE_PROT64)
+		c->dst.bytes = 8;
+
+	rc = ops->read_std(register_address(ctxt->ss_base,
+					    c->regs[VCPU_REGS_RSP]),
+			   &c->dst.val, c->dst.bytes, ctxt->vcpu);
+	if (rc != 0)
+		return rc;
+
+	register_address_increment(c->regs[VCPU_REGS_RSP], c->dst.bytes);
+
+	return 0;
+}
+
+static inline void emulate_grp2(struct decode_cache *c, unsigned long *_eflags)
+{
+	switch (c->modrm_reg) {
+	case 0:	/* rol */
+		emulate_2op_SrcB("rol", c->src, c->dst, *_eflags);
+		break;
+	case 1:	/* ror */
+		emulate_2op_SrcB("ror", c->src, c->dst, *_eflags);
+		break;
+	case 2:	/* rcl */
+		emulate_2op_SrcB("rcl", c->src, c->dst, *_eflags);
+		break;
+	case 3:	/* rcr */
+		emulate_2op_SrcB("rcr", c->src, c->dst, *_eflags);
+		break;
+	case 4:	/* sal/shl */
+	case 6:	/* sal/shl */
+		emulate_2op_SrcB("sal", c->src, c->dst, *_eflags);
+		break;
+	case 5:	/* shr */
+		emulate_2op_SrcB("shr", c->src, c->dst, *_eflags);
+		break;
+	case 7:	/* sar */
+		emulate_2op_SrcB("sar", c->src, c->dst, *_eflags);
+		break;
+	}
+}
+
+static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
+			       struct x86_emulate_ops *ops,
+			       unsigned long *_eflags)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc = 0;
+
+	switch (c->modrm_reg) {
+	case 0 ... 1:	/* test */
+		/*
+		 * Special case in Grp3: test has an immediate
+		 * source operand.
+		 */
+		c->src.type = OP_IMM;
+		c->src.ptr = (unsigned long *)c->eip;
+		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		if (c->src.bytes == 8)
+			c->src.bytes = 4;
+		switch (c->src.bytes) {
+		case 1:
+			c->src.val = insn_fetch(s8, 1, c->eip);
+			break;
+		case 2:
+			c->src.val = insn_fetch(s16, 2, c->eip);
+			break;
+		case 4:
+			c->src.val = insn_fetch(s32, 4, c->eip);
+			break;
+		}
+		emulate_2op_SrcV("test", c->src, c->dst, *_eflags);
+		break;
+	case 2:	/* not */
+		c->dst.val = ~c->dst.val;
+		break;
+	case 3:	/* neg */
+		emulate_1op("neg", c->dst, *_eflags);
+		break;
+	default:
+		DPRINTF("Cannot emulate %02x\n", c->b);
+		rc = X86EMUL_UNHANDLEABLE;
+		break;
+	}
+done:
+	return rc;
+}
+
+static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
+			       struct x86_emulate_ops *ops,
+			       unsigned long *_eflags,
+			       int *no_wb)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	switch (c->modrm_reg) {
+	case 0:	/* inc */
+		emulate_1op("inc", c->dst, *_eflags);
+		break;
+	case 1:	/* dec */
+		emulate_1op("dec", c->dst, *_eflags);
+		break;
+	case 4: /* jmp abs */
+		if (c->b == 0xff)
+			c->eip = c->dst.val;
+		else {
+			DPRINTF("Cannot emulate %02x\n", c->b);
+			return X86EMUL_UNHANDLEABLE;
+		}
+		break;
+	case 6:	/* push */
+
+		/* 64-bit mode: PUSH always pushes a 64-bit operand. */
+
+		if (ctxt->mode == X86EMUL_MODE_PROT64) {
+			c->dst.bytes = 8;
+			rc = ops->read_std((unsigned long)c->dst.ptr,
+					   &c->dst.val, 8, ctxt->vcpu);
+			if (rc != 0)
+				return rc;
+		}
+		register_address_increment(c->regs[VCPU_REGS_RSP],
+					   -c->dst.bytes);
+		rc = ops->write_std(register_address(ctxt->ss_base,
+				    c->regs[VCPU_REGS_RSP]), &c->dst.val,
+				    c->dst.bytes, ctxt->vcpu);
+		if (rc != 0)
+			return rc;
+		*no_wb = 1;
+		break;
+	default:
+		DPRINTF("Cannot emulate %02x\n", c->b);
+		return X86EMUL_UNHANDLEABLE;
+	}
+	return 0;
+}
+
+static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
+			       struct x86_emulate_ops *ops,
+			       unsigned long *_eflags,
+			       unsigned long cr2)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u64 old, new;
+	int rc;
+
+	rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu);
+	if (rc != 0)
+		return rc;
+
+	if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
+	    ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
+
+		c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
+		c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
+		*_eflags &= ~EFLG_ZF;
+
+	} else {
+		new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
+		       (u32) c->regs[VCPU_REGS_RBX];
+
+		rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu);
+		if (rc != 0)
+			return rc;
+		*_eflags |= EFLG_ZF;
+	}
+	return 0;
+}
+
+static inline int writeback(struct x86_emulate_ctxt *ctxt,
+			    struct x86_emulate_ops *ops)
+{
+	int rc;
+	struct decode_cache *c = &ctxt->decode;
+
+	switch (c->dst.type) {
+	case OP_REG:
+		/* The 4-byte case *is* correct:
+		 * in 64-bit mode we zero-extend.
+		 */
+		switch (c->dst.bytes) {
+		case 1:
+			*(u8 *)c->dst.ptr = (u8)c->dst.val;
+			break;
+		case 2:
+			*(u16 *)c->dst.ptr = (u16)c->dst.val;
+			break;
+		case 4:
+			*c->dst.ptr = (u32)c->dst.val;
+			break;	/* 64b: zero-ext */
+		case 8:
+			*c->dst.ptr = c->dst.val;
+			break;
+		}
+		break;
+	case OP_MEM:
+		if (c->lock_prefix)
+			rc = ops->cmpxchg_emulated(
+					(unsigned long)c->dst.ptr,
+					&c->dst.orig_val,
+					&c->dst.val,
+					c->dst.bytes,
+					ctxt->vcpu);
+		else
+			rc = ops->write_emulated(
+					(unsigned long)c->dst.ptr,
+					&c->dst.val,
+					c->dst.bytes,
+					ctxt->vcpu);
+		if (rc != 0)
+			return rc;
+	default:
+		break;
+	}
+	return 0;
+}
+
 int
 x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 {
@@ -1005,14 +1243,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	case 0x6a: /* push imm8 */
 		c->src.val = 0L;
 		c->src.val = insn_fetch(s8, 1, c->eip);
-push:
-		c->dst.type  = OP_MEM;
-		c->dst.bytes = c->op_bytes;
-		c->dst.val = c->src.val;
-		register_address_increment(c->regs[VCPU_REGS_RSP],
-					   -c->op_bytes);
-		c->dst.ptr = (void *) register_address(ctxt->ss_base,
-						       c->regs[VCPU_REGS_RSP]);
+		emulate_push(ctxt);
 		break;
 	case 0x80 ... 0x83:	/* Grp1 */
 		switch (c->modrm_reg) {
@@ -1035,7 +1266,6 @@ push:
 		}
 		break;
 	case 0x84 ... 0x85:
-	      test:		/* test */
 		emulate_2op_SrcV("test", c->src, c->dst, _eflags);
 		break;
 	case 0x86 ... 0x87:	/* xchg */
@@ -1067,18 +1297,9 @@ push:
 		c->dst.val = c->modrm_val;
 		break;
 	case 0x8f:		/* pop (sole member of Grp1a) */
-		/* 64-bit mode: POP always pops a 64-bit operand. */
-		if (ctxt->mode == X86EMUL_MODE_PROT64)
-			c->dst.bytes = 8;
-		if ((rc = ops->read_std(register_address(
-						   ctxt->ss_base,
-						   c->regs[VCPU_REGS_RSP]),
-						   &c->dst.val,
-						   c->dst.bytes,
-						   ctxt->vcpu)) != 0)
+		rc = emulate_grp1a(ctxt, ops);
+		if (rc != 0)
 			goto done;
-		register_address_increment(c->regs[VCPU_REGS_RSP],
-					   c->dst.bytes);
 		break;
 	case 0xa0 ... 0xa1:	/* mov */
 		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
@@ -1092,31 +1313,7 @@ push:
 		c->eip += c->ad_bytes;
 		break;
 	case 0xc0 ... 0xc1:
-	      grp2:		/* Grp2 */
-		switch (c->modrm_reg) {
-		case 0:	/* rol */
-			emulate_2op_SrcB("rol", c->src, c->dst, _eflags);
-			break;
-		case 1:	/* ror */
-			emulate_2op_SrcB("ror", c->src, c->dst, _eflags);
-			break;
-		case 2:	/* rcl */
-			emulate_2op_SrcB("rcl", c->src, c->dst, _eflags);
-			break;
-		case 3:	/* rcr */
-			emulate_2op_SrcB("rcr", c->src, c->dst, _eflags);
-			break;
-		case 4:	/* sal/shl */
-		case 6:	/* sal/shl */
-			emulate_2op_SrcB("sal", c->src, c->dst, _eflags);
-			break;
-		case 5:	/* shr */
-			emulate_2op_SrcB("shr", c->src, c->dst, _eflags);
-			break;
-		case 7:	/* sar */
-			emulate_2op_SrcB("sar", c->src, c->dst, _eflags);
-			break;
-		}
+		emulate_grp2(c, &_eflags);
 		break;
 	case 0xc6 ... 0xc7:	/* mov (sole member of Grp11) */
 	mov:
@@ -1124,126 +1321,29 @@ push:
 		break;
 	case 0xd0 ... 0xd1:	/* Grp2 */
 		c->src.val = 1;
-		goto grp2;
+		emulate_grp2(c, &_eflags);
+		break;
 	case 0xd2 ... 0xd3:	/* Grp2 */
 		c->src.val = c->regs[VCPU_REGS_RCX];
-		goto grp2;
+		emulate_grp2(c, &_eflags);
+		break;
 	case 0xf6 ... 0xf7:	/* Grp3 */
-		switch (c->modrm_reg) {
-		case 0 ... 1:	/* test */
-			/*
-			 * Special case in Grp3: test has an immediate
-			 * source operand.
-			 */
-			c->src.type = OP_IMM;
-			c->src.ptr = (unsigned long *)c->eip;
-			c->src.bytes = (c->d & ByteOp) ? 1 :
-							       c->op_bytes;
-			if (c->src.bytes == 8)
-				c->src.bytes = 4;
-			switch (c->src.bytes) {
-			case 1:
-				c->src.val = insn_fetch(s8, 1, c->eip);
-				break;
-			case 2:
-				c->src.val = insn_fetch(s16, 2, c->eip);
-				break;
-			case 4:
-				c->src.val = insn_fetch(s32, 4, c->eip);
-				break;
-			}
-			goto test;
-		case 2:	/* not */
-			c->dst.val = ~c->dst.val;
-			break;
-		case 3:	/* neg */
-			emulate_1op("neg", c->dst, _eflags);
-			break;
-		default:
-			goto cannot_emulate;
-		}
+		rc = emulate_grp3(ctxt, ops, &_eflags);
+		if (rc != 0)
+			goto done;
 		break;
 	case 0xfe ... 0xff:	/* Grp4/Grp5 */
-		switch (c->modrm_reg) {
-		case 0:	/* inc */
-			emulate_1op("inc", c->dst, _eflags);
-			break;
-		case 1:	/* dec */
-			emulate_1op("dec", c->dst, _eflags);
-			break;
-		case 4: /* jmp abs */
-			if (c->b == 0xff)
-				c->eip = c->dst.val;
-			else
-				goto cannot_emulate;
-			break;
-		case 6:	/* push */
-			/* 64-bit mode: PUSH always pushes a 64-bit operand. */
-			if (ctxt->mode == X86EMUL_MODE_PROT64) {
-				c->dst.bytes = 8;
-				if ((rc = ops->read_std(
-						 (unsigned long)c->dst.ptr,
-						 &c->dst.val, 8,
-						 ctxt->vcpu)) != 0)
-					goto done;
-			}
-			register_address_increment(c->regs[VCPU_REGS_RSP],
-						   -c->dst.bytes);
-			if ((rc = ops->write_std(
-				     register_address(ctxt->ss_base,
-					  c->regs[VCPU_REGS_RSP]),
-					  &c->dst.val,
-					   c->dst.bytes, ctxt->vcpu)) != 0)
-				goto done;
-			no_wb = 1;
-			break;
-		default:
-			goto cannot_emulate;
-		}
+		rc = emulate_grp45(ctxt, ops, &_eflags, &no_wb);
+		if (rc != 0)
+			goto done;
 		break;
 	}
 
 writeback:
 	if (!no_wb) {
-		switch (c->dst.type) {
-		case OP_REG:
-			/* The 4-byte case *is* correct:
-			 * in 64-bit mode we zero-extend.
-			 */
-			switch (c->dst.bytes) {
-			case 1:
-				*(u8 *)c->dst.ptr = (u8)c->dst.val;
-				break;
-			case 2:
-				*(u16 *)c->dst.ptr = (u16)c->dst.val;
-				break;
-			case 4:
-				*c->dst.ptr = (u32)c->dst.val;
-				break;	/* 64b: zero-ext */
-			case 8:
-				*c->dst.ptr = c->dst.val;
-				break;
-			}
-			break;
-		case OP_MEM:
-			if (c->lock_prefix)
-				rc = ops->cmpxchg_emulated(
-						(unsigned long)c->dst.ptr,
-						&c->dst.orig_val,
-						&c->dst.val,
-						c->dst.bytes,
-						ctxt->vcpu);
-			else
-				rc = ops->write_emulated(
-						(unsigned long)c->dst.ptr,
-						&c->dst.val,
-						c->dst.bytes,
-						ctxt->vcpu);
-			if (rc != 0)
-				goto done;
-		default:
-			break;
-		}
+		rc = writeback(ctxt, ops);
+		if (rc != 0)
+			goto done;
 	}
 
 	/* Commit shadow register state. */
@@ -1272,8 +1372,7 @@ special_insn:
 			ctxt->ss_base, c->regs[VCPU_REGS_RSP]);
 		break;
 	case 0x58 ... 0x5f: /* pop reg */
-		c->dst.ptr =
-				(unsigned long *)&c->regs[c->b & 0x7];
+		c->dst.ptr = (unsigned long *)&c->regs[c->b & 0x7];
 	pop_instruction:
 		if ((rc = ops->read_std(register_address(ctxt->ss_base,
 			c->regs[VCPU_REGS_RSP]), c->dst.ptr,
@@ -1328,7 +1427,8 @@ special_insn:
 	}
 	case 0x9c: /* pushf */
 		c->src.val =  (unsigned long) _eflags;
-		goto push;
+		emulate_push(ctxt);
+		break;
 	case 0x9d: /* popf */
 		c->dst.ptr = (unsigned long *) &_eflags;
 		goto pop_instruction;
@@ -1425,7 +1525,8 @@ special_insn:
 		}
 		c->src.val = (unsigned long) c->eip;
 		JMP_REL(rel);
-		goto push;
+		emulate_push(ctxt);
+		break;
 	}
 	case 0xe9: /* jmp rel */
 	case 0xeb: /* jmp rel short */
@@ -1500,8 +1601,7 @@ twobyte_insn:
 		no_wb = 1;
 		if (c->modrm_mod != 3)
 			goto cannot_emulate;
-		rc = emulator_get_dr(ctxt, c->modrm_reg,
-				     &c->regs[c->modrm_rm]);
+		rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
 		break;
 	case 0x23: /* mov from reg to dr */
 		no_wb = 1;
@@ -1650,8 +1750,7 @@ twobyte_special_insn:
 		break;
 	case 0x32:
 		/* rdmsr */
-		rc = kvm_get_msr(ctxt->vcpu,
-				 c->regs[VCPU_REGS_RCX], &msr_data);
+		rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
 		if (rc) {
 			kvm_x86_ops->inject_gp(ctxt->vcpu, 0);
 			c->eip = ctxt->vcpu->rip;
@@ -1683,28 +1782,10 @@ twobyte_special_insn:
 		break;
 	}
 	case 0xc7:		/* Grp9 (cmpxchg8b) */
-		{
-			u64 old, new;
-			if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu))
-									!= 0)
-				goto done;
-			if (((u32) (old >> 0) !=
-					(u32) c->regs[VCPU_REGS_RAX]) ||
-			    ((u32) (old >> 32) !=
-					(u32) c->regs[VCPU_REGS_RDX])) {
-				c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
-				c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
-				_eflags &= ~EFLG_ZF;
-			} else {
-				new = ((u64)c->regs[VCPU_REGS_RCX] << 32)
-					| (u32) c->regs[VCPU_REGS_RBX];
-				if ((rc = ops->cmpxchg_emulated(cr2, &old,
-							  &new, 8, ctxt->vcpu)) != 0)
-					goto done;
-				_eflags |= EFLG_ZF;
-			}
-			break;
-		}
+		rc = emulate_grp9(ctxt, ops, &_eflags, cr2);
+		if (rc != 0)
+			goto done;
+		break;
 	}
 	goto writeback;
 
-- 
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] remove _eflags and use directly ctxt->eflags.
       [not found]     ` <1190625056943-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
@ 2007-09-24  9:10       ` Laurent Vivier
       [not found]         ` <11906250573823-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Laurent Vivier @ 2007-09-24  9:10 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f; +Cc: Laurent Vivier

Remove _eflags and use directly ctxt->eflags. Caching eflags is not needed as 
it is restored to vcpu by kvm_main.c:emulate_instruction() from ctxt->eflags 
only if emulation doesn't fail.

Signed-off-by: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
---
 drivers/kvm/x86_emulate.c |  121 ++++++++++++++++++++++-----------------------
 1 files changed, 59 insertions(+), 62 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 64e8e03..d1dec3e 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -930,37 +930,37 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
 	return 0;
 }
 
-static inline void emulate_grp2(struct decode_cache *c, unsigned long *_eflags)
+static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt)
 {
+	struct decode_cache *c = &ctxt->decode;
 	switch (c->modrm_reg) {
 	case 0:	/* rol */
-		emulate_2op_SrcB("rol", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("rol", c->src, c->dst, ctxt->eflags);
 		break;
 	case 1:	/* ror */
-		emulate_2op_SrcB("ror", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("ror", c->src, c->dst, ctxt->eflags);
 		break;
 	case 2:	/* rcl */
-		emulate_2op_SrcB("rcl", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("rcl", c->src, c->dst, ctxt->eflags);
 		break;
 	case 3:	/* rcr */
-		emulate_2op_SrcB("rcr", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("rcr", c->src, c->dst, ctxt->eflags);
 		break;
 	case 4:	/* sal/shl */
 	case 6:	/* sal/shl */
-		emulate_2op_SrcB("sal", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("sal", c->src, c->dst, ctxt->eflags);
 		break;
 	case 5:	/* shr */
-		emulate_2op_SrcB("shr", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("shr", c->src, c->dst, ctxt->eflags);
 		break;
 	case 7:	/* sar */
-		emulate_2op_SrcB("sar", c->src, c->dst, *_eflags);
+		emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags);
 		break;
 	}
 }
 
 static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops,
-			       unsigned long *_eflags)
+			       struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
 	int rc = 0;
@@ -987,13 +987,13 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
 			c->src.val = insn_fetch(s32, 4, c->eip);
 			break;
 		}
-		emulate_2op_SrcV("test", c->src, c->dst, *_eflags);
+		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
 		break;
 	case 2:	/* not */
 		c->dst.val = ~c->dst.val;
 		break;
 	case 3:	/* neg */
-		emulate_1op("neg", c->dst, *_eflags);
+		emulate_1op("neg", c->dst, ctxt->eflags);
 		break;
 	default:
 		DPRINTF("Cannot emulate %02x\n", c->b);
@@ -1006,7 +1006,6 @@ done:
 
 static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
 			       struct x86_emulate_ops *ops,
-			       unsigned long *_eflags,
 			       int *no_wb)
 {
 	struct decode_cache *c = &ctxt->decode;
@@ -1014,10 +1013,10 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
 
 	switch (c->modrm_reg) {
 	case 0:	/* inc */
-		emulate_1op("inc", c->dst, *_eflags);
+		emulate_1op("inc", c->dst, ctxt->eflags);
 		break;
 	case 1:	/* dec */
-		emulate_1op("dec", c->dst, *_eflags);
+		emulate_1op("dec", c->dst, ctxt->eflags);
 		break;
 	case 4: /* jmp abs */
 		if (c->b == 0xff)
@@ -1056,7 +1055,6 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
 
 static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
 			       struct x86_emulate_ops *ops,
-			       unsigned long *_eflags,
 			       unsigned long cr2)
 {
 	struct decode_cache *c = &ctxt->decode;
@@ -1072,7 +1070,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
 
 		c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
 		c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
-		*_eflags &= ~EFLG_ZF;
+		ctxt->eflags &= ~EFLG_ZF;
 
 	} else {
 		new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
@@ -1081,7 +1079,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
 		rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu);
 		if (rc != 0)
 			return rc;
-		*_eflags |= EFLG_ZF;
+		ctxt->eflags |= EFLG_ZF;
 	}
 	return 0;
 }
@@ -1141,7 +1139,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	int no_wb = 0;
 	u64 msr_data;
 	unsigned long saved_rcx = 0, saved_eip = 0;
-	unsigned long _eflags = ctxt->eflags;
 	struct decode_cache *c = &ctxt->decode;
 	int rc = 0;
 
@@ -1188,23 +1185,23 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	switch (c->b) {
 	case 0x00 ... 0x05:
 	      add:		/* add */
-		emulate_2op_SrcV("add", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x08 ... 0x0d:
 	      or:		/* or */
-		emulate_2op_SrcV("or", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x10 ... 0x15:
 	      adc:		/* adc */
-		emulate_2op_SrcV("adc", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x18 ... 0x1d:
 	      sbb:		/* sbb */
-		emulate_2op_SrcV("sbb", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x20 ... 0x23:
 	      and:		/* and */
-		emulate_2op_SrcV("and", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x24:              /* and al imm8 */
 		c->dst.type = OP_REG;
@@ -1225,15 +1222,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 		goto and;
 	case 0x28 ... 0x2d:
 	      sub:		/* sub */
-		emulate_2op_SrcV("sub", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x30 ... 0x35:
 	      xor:		/* xor */
-		emulate_2op_SrcV("xor", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x38 ... 0x3d:
 	      cmp:		/* cmp */
-		emulate_2op_SrcV("cmp", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x63:		/* movsxd */
 		if (ctxt->mode != X86EMUL_MODE_PROT64)
@@ -1266,7 +1263,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 		}
 		break;
 	case 0x84 ... 0x85:
-		emulate_2op_SrcV("test", c->src, c->dst, _eflags);
+		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0x86 ... 0x87:	/* xchg */
 		/* Write back the register source. */
@@ -1313,7 +1310,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 		c->eip += c->ad_bytes;
 		break;
 	case 0xc0 ... 0xc1:
-		emulate_grp2(c, &_eflags);
+		emulate_grp2(ctxt);
 		break;
 	case 0xc6 ... 0xc7:	/* mov (sole member of Grp11) */
 	mov:
@@ -1321,19 +1318,19 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 		break;
 	case 0xd0 ... 0xd1:	/* Grp2 */
 		c->src.val = 1;
-		emulate_grp2(c, &_eflags);
+		emulate_grp2(ctxt);
 		break;
 	case 0xd2 ... 0xd3:	/* Grp2 */
 		c->src.val = c->regs[VCPU_REGS_RCX];
-		emulate_grp2(c, &_eflags);
+		emulate_grp2(ctxt);
 		break;
 	case 0xf6 ... 0xf7:	/* Grp3 */
-		rc = emulate_grp3(ctxt, ops, &_eflags);
+		rc = emulate_grp3(ctxt, ops);
 		if (rc != 0)
 			goto done;
 		break;
 	case 0xfe ... 0xff:	/* Grp4/Grp5 */
-		rc = emulate_grp45(ctxt, ops, &_eflags, &no_wb);
+		rc = emulate_grp45(ctxt, ops, &no_wb);
 		if (rc != 0)
 			goto done;
 		break;
@@ -1348,7 +1345,6 @@ writeback:
 
 	/* Commit shadow register state. */
 	memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs);
-	ctxt->eflags = _eflags;
 	ctxt->vcpu->rip = c->eip;
 
 done:
@@ -1395,7 +1391,7 @@ special_insn:
 				(c->d & ByteOp) ? 1 : c->op_bytes,
 				c->rep_prefix ?
 				address_mask(c->regs[VCPU_REGS_RCX]) : 1,
-				(_eflags & EFLG_DF),
+				(ctxt->eflags & EFLG_DF),
 				register_address(ctxt->es_base,
 						 c->regs[VCPU_REGS_RDI]),
 				c->rep_prefix,
@@ -1409,7 +1405,7 @@ special_insn:
 				(c->d & ByteOp) ? 1 : c->op_bytes,
 				c->rep_prefix ?
 				address_mask(c->regs[VCPU_REGS_RCX]) : 1,
-				(_eflags & EFLG_DF),
+				(ctxt->eflags & EFLG_DF),
 				register_address(c->override_base ?
 							*c->override_base :
 							ctxt->ds_base,
@@ -1421,16 +1417,16 @@ special_insn:
 	case 0x70 ... 0x7f: /* jcc (short) */ {
 		int rel = insn_fetch(s8, 1, c->eip);
 
-		if (test_cc(c->b, _eflags))
+		if (test_cc(c->b, ctxt->eflags))
 		JMP_REL(rel);
 		break;
 	}
 	case 0x9c: /* pushf */
-		c->src.val =  (unsigned long) _eflags;
+		c->src.val =  (unsigned long) ctxt->eflags;
 		emulate_push(ctxt);
 		break;
 	case 0x9d: /* popf */
-		c->dst.ptr = (unsigned long *) &_eflags;
+		c->dst.ptr = (unsigned long *) &ctxt->eflags;
 		goto pop_instruction;
 	case 0xc3: /* ret */
 		c->dst.ptr = &c->eip;
@@ -1469,10 +1465,10 @@ special_insn:
 			goto done;
 		}
 		register_address_increment(c->regs[VCPU_REGS_RSI],
-				       (_eflags & EFLG_DF) ? -c->dst.bytes
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
 							   : c->dst.bytes);
 		register_address_increment(c->regs[VCPU_REGS_RDI],
-				       (_eflags & EFLG_DF) ? -c->dst.bytes
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
 							   : c->dst.bytes);
 		break;
 	case 0xa6 ... 0xa7:	/* cmps */
@@ -1484,7 +1480,7 @@ special_insn:
 		c->dst.ptr = (unsigned long *)cr2;
 		c->dst.val = c->regs[VCPU_REGS_RAX];
 		register_address_increment(c->regs[VCPU_REGS_RDI],
-				       (_eflags & EFLG_DF) ? -c->dst.bytes
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
 							   : c->dst.bytes);
 		break;
 	case 0xac ... 0xad:	/* lods */
@@ -1501,7 +1497,7 @@ special_insn:
 			goto done;
 		}
 		register_address_increment(c->regs[VCPU_REGS_RSI],
-				       (_eflags & EFLG_DF) ? -c->dst.bytes
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
 							   : c->dst.bytes);
 		break;
 	case 0xae ... 0xaf:	/* scas */
@@ -1588,7 +1584,8 @@ twobyte_insn:
 		case 6: /* lmsw */
 			if (c->modrm_mod != 3)
 				goto cannot_emulate;
-			realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val, &_eflags);
+			realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val,
+						  &ctxt->eflags);
 			break;
 		case 7: /* invlpg*/
 			emulate_invlpg(ctxt->vcpu, cr2);
@@ -1619,29 +1616,29 @@ twobyte_insn:
 		 */
 		switch ((c->b & 15) >> 1) {
 		case 0:	/* cmovo */
-			no_wb = (_eflags & EFLG_OF) ? 0 : 1;
+			no_wb = (ctxt->eflags & EFLG_OF) ? 0 : 1;
 			break;
 		case 1:	/* cmovb/cmovc/cmovnae */
-			no_wb = (_eflags & EFLG_CF) ? 0 : 1;
+			no_wb = (ctxt->eflags & EFLG_CF) ? 0 : 1;
 			break;
 		case 2:	/* cmovz/cmove */
-			no_wb = (_eflags & EFLG_ZF) ? 0 : 1;
+			no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1;
 			break;
 		case 3:	/* cmovbe/cmovna */
-			no_wb = (_eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1;
+			no_wb = (ctxt->eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1;
 			break;
 		case 4:	/* cmovs */
-			no_wb = (_eflags & EFLG_SF) ? 0 : 1;
+			no_wb = (ctxt->eflags & EFLG_SF) ? 0 : 1;
 			break;
 		case 5:	/* cmovp/cmovpe */
-			no_wb = (_eflags & EFLG_PF) ? 0 : 1;
+			no_wb = (ctxt->eflags & EFLG_PF) ? 0 : 1;
 			break;
 		case 7:	/* cmovle/cmovng */
-			no_wb = (_eflags & EFLG_ZF) ? 0 : 1;
+			no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1;
 			/* fall through */
 		case 6:	/* cmovl/cmovnge */
-			no_wb &= (!(_eflags & EFLG_SF) !=
-			      !(_eflags & EFLG_OF)) ? 0 : 1;
+			no_wb &= (!(ctxt->eflags & EFLG_SF) !=
+			      !(ctxt->eflags & EFLG_OF)) ? 0 : 1;
 			break;
 		}
 		/* Odd cmov opcodes (lsb == 1) have inverted sense. */
@@ -1651,13 +1648,13 @@ twobyte_insn:
 	      bt:		/* bt */
 		/* only subword offset */
 		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("bt", c->src, c->dst, _eflags);
+		emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0xab:
 	      bts:		/* bts */
 		/* only subword offset */
 		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("bts", c->src, c->dst, _eflags);
+		emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0xb0 ... 0xb1:	/* cmpxchg */
 		/*
@@ -1666,8 +1663,8 @@ twobyte_insn:
 		 */
 		c->src.orig_val = c->src.val;
 		c->src.val = c->regs[VCPU_REGS_RAX];
-		emulate_2op_SrcV("cmp", c->src, c->dst, _eflags);
-		if (_eflags & EFLG_ZF) {
+		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
+		if (ctxt->eflags & EFLG_ZF) {
 			/* Success: write back to memory. */
 			c->dst.val = c->src.orig_val;
 		} else {
@@ -1680,7 +1677,7 @@ twobyte_insn:
 	      btr:		/* btr */
 		/* only subword offset */
 		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("btr", c->src, c->dst, _eflags);
+		emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0xb6 ... 0xb7:	/* movzx */
 		c->dst.bytes = c->op_bytes;
@@ -1703,7 +1700,7 @@ twobyte_insn:
 	      btc:		/* btc */
 		/* only subword offset */
 		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, _eflags);
+		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
 		break;
 	case 0xbe ... 0xbf:	/* movsx */
 		c->dst.bytes = c->op_bytes;
@@ -1735,7 +1732,7 @@ twobyte_special_insn:
 		if (c->modrm_mod != 3)
 			goto cannot_emulate;
 		realmode_set_cr(ctxt->vcpu,
-				c->modrm_reg, c->modrm_val, &_eflags);
+				c->modrm_reg, c->modrm_val, &ctxt->eflags);
 		break;
 	case 0x30:
 		/* wrmsr */
@@ -1777,12 +1774,12 @@ twobyte_special_insn:
 			DPRINTF("jnz: Invalid op_bytes\n");
 			goto cannot_emulate;
 		}
-		if (test_cc(c->b, _eflags))
+		if (test_cc(c->b, ctxt->eflags))
 			JMP_REL(rel);
 		break;
 	}
 	case 0xc7:		/* Grp9 (cmpxchg8b) */
-		rc = emulate_grp9(ctxt, ops, &_eflags, cr2);
+		rc = emulate_grp9(ctxt, ops, cr2);
 		if (rc != 0)
 			goto done;
 		break;
-- 
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] Remove no_wb, use dst.type = OP_NONE instead, idea stollen from xen-3.1
       [not found]         ` <11906250573823-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
@ 2007-09-24  9:10           ` Laurent Vivier
  0 siblings, 0 replies; 6+ messages in thread
From: Laurent Vivier @ 2007-09-24  9:10 UTC (permalink / raw)
  To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f; +Cc: Laurent Vivier

Remove no_wb, use dst.type = OP_NONE instead, idea stollen from xen-3.1

Signed-off-by: Laurent Vivier <Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
---
 drivers/kvm/x86_emulate.c |   76 ++++++++++++++------------------------------
 drivers/kvm/x86_emulate.h |    2 +-
 2 files changed, 25 insertions(+), 53 deletions(-)

diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index d1dec3e..14160f0 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1005,8 +1005,7 @@ done:
 }
 
 static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops,
-			       int *no_wb)
+			       struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
 	int rc;
@@ -1044,7 +1043,7 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
 				    c->dst.bytes, ctxt->vcpu);
 		if (rc != 0)
 			return rc;
-		*no_wb = 1;
+		c->dst.type = OP_NONE;
 		break;
 	default:
 		DPRINTF("Cannot emulate %02x\n", c->b);
@@ -1126,6 +1125,10 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
 					ctxt->vcpu);
 		if (rc != 0)
 			return rc;
+		break;
+	case OP_NONE:
+		/* no writeback */
+		break;
 	default:
 		break;
 	}
@@ -1136,7 +1139,6 @@ int
 x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 {
 	unsigned long cr2 = ctxt->cr2;
-	int no_wb = 0;
 	u64 msr_data;
 	unsigned long saved_rcx = 0, saved_eip = 0;
 	struct decode_cache *c = &ctxt->decode;
@@ -1330,18 +1332,16 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 			goto done;
 		break;
 	case 0xfe ... 0xff:	/* Grp4/Grp5 */
-		rc = emulate_grp45(ctxt, ops, &no_wb);
+		rc = emulate_grp45(ctxt, ops);
 		if (rc != 0)
 			goto done;
 		break;
 	}
 
 writeback:
-	if (!no_wb) {
-		rc = writeback(ctxt, ops);
-		if (rc != 0)
-			goto done;
-	}
+	rc = writeback(ctxt, ops);
+	if (rc != 0)
+		goto done;
 
 	/* Commit shadow register state. */
 	memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs);
@@ -1382,7 +1382,7 @@ special_insn:
 
 		register_address_increment(c->regs[VCPU_REGS_RSP],
 					   c->op_bytes);
-		no_wb = 1; /* Disable writeback. */
+		c->dst.type = OP_NONE;	/* Disable writeback. */
 		break;
 	case 0x6c:		/* insb */
 	case 0x6d:		/* insw/insd */
@@ -1527,7 +1527,7 @@ special_insn:
 	case 0xe9: /* jmp rel */
 	case 0xeb: /* jmp rel short */
 		JMP_REL(c->src.val);
-		no_wb = 1; /* Disable writeback. */
+		c->dst.type = OP_NONE; /* Disable writeback. */
 		break;
 
 
@@ -1537,8 +1537,6 @@ special_insn:
 twobyte_insn:
 	switch (c->b) {
 	case 0x01: /* lgdt, lidt, lmsw */
-		/* Disable writeback. */
-		no_wb = 1;
 		switch (c->modrm_reg) {
 			u16 size;
 			unsigned long address;
@@ -1593,56 +1591,30 @@ twobyte_insn:
 		default:
 			goto cannot_emulate;
 		}
+		/* Disable writeback. */
+		c->dst.type = OP_NONE;
 		break;
 	case 0x21: /* mov from dr to reg */
-		no_wb = 1;
 		if (c->modrm_mod != 3)
 			goto cannot_emulate;
 		rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
+		if (rc)
+			goto cannot_emulate;
+		c->dst.type = OP_NONE;	/* no writeback */
 		break;
 	case 0x23: /* mov from reg to dr */
-		no_wb = 1;
 		if (c->modrm_mod != 3)
 			goto cannot_emulate;
 		rc = emulator_set_dr(ctxt, c->modrm_reg,
 				     c->regs[c->modrm_rm]);
+		if (rc)
+			goto cannot_emulate;
+		c->dst.type = OP_NONE;	/* no writeback */
 		break;
 	case 0x40 ... 0x4f:	/* cmov */
 		c->dst.val = c->dst.orig_val = c->src.val;
-		no_wb = 1;
-		/*
-		 * First, assume we're decoding an even cmov opcode
-		 * (lsb == 0).
-		 */
-		switch ((c->b & 15) >> 1) {
-		case 0:	/* cmovo */
-			no_wb = (ctxt->eflags & EFLG_OF) ? 0 : 1;
-			break;
-		case 1:	/* cmovb/cmovc/cmovnae */
-			no_wb = (ctxt->eflags & EFLG_CF) ? 0 : 1;
-			break;
-		case 2:	/* cmovz/cmove */
-			no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1;
-			break;
-		case 3:	/* cmovbe/cmovna */
-			no_wb = (ctxt->eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1;
-			break;
-		case 4:	/* cmovs */
-			no_wb = (ctxt->eflags & EFLG_SF) ? 0 : 1;
-			break;
-		case 5:	/* cmovp/cmovpe */
-			no_wb = (ctxt->eflags & EFLG_PF) ? 0 : 1;
-			break;
-		case 7:	/* cmovle/cmovng */
-			no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1;
-			/* fall through */
-		case 6:	/* cmovl/cmovnge */
-			no_wb &= (!(ctxt->eflags & EFLG_SF) !=
-			      !(ctxt->eflags & EFLG_OF)) ? 0 : 1;
-			break;
-		}
-		/* Odd cmov opcodes (lsb == 1) have inverted sense. */
-		no_wb ^= c->b & 1;
+		if (!test_cc(c->b, ctxt->eflags))
+			c->dst.type = OP_NONE; /* no writeback */
 		break;
 	case 0xa3:
 	      bt:		/* bt */
@@ -1711,8 +1683,6 @@ twobyte_insn:
 	goto writeback;
 
 twobyte_special_insn:
-	/* Disable writeback. */
-	no_wb = 1;
 	switch (c->b) {
 	case 0x06:
 		emulate_clts(ctxt->vcpu);
@@ -1784,6 +1754,8 @@ twobyte_special_insn:
 			goto done;
 		break;
 	}
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
 	goto writeback;
 
 cannot_emulate:
diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h
index 28acad4..f03b128 100644
--- a/drivers/kvm/x86_emulate.h
+++ b/drivers/kvm/x86_emulate.h
@@ -114,7 +114,7 @@ struct x86_emulate_ops {
 
 /* Type, address-of, and value of an instruction's operand. */
 struct operand {
-	enum { OP_REG, OP_MEM, OP_IMM } type;
+	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
 	unsigned int bytes;
 	unsigned long val, orig_val, *ptr;
 };
-- 
1.5.2.4


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] Make some cleanup in x86_emulate.c
       [not found] ` <11906250562300-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
  2007-09-24  9:10   ` [PATCH 1/3] move grp decoding into functions to make x86_emulate_insn() clearer Laurent Vivier
@ 2007-09-24 13:20   ` Avi Kivity
  1 sibling, 0 replies; 6+ messages in thread
From: Avi Kivity @ 2007-09-24 13:20 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

Laurent Vivier wrote:
> This patch series makes some cleanups in x86_emulate.c
>
> [PATCH 1/3] move some parts of x86_decode_insn() into functions.
> [PATCH 2/3] remove _eflags and use directly ctxt->eflags
> [PATCH 3/3] remove no_wb
>
> It has been rebased to current master.
>
>   

Applied all, thanks.


-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2007-09-24 13:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-24  9:10 [PATCH 0/3] Make some cleanup in x86_emulate.c Laurent Vivier
     [not found] ` <11906250562300-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
2007-09-24  9:10   ` [PATCH 1/3] move grp decoding into functions to make x86_emulate_insn() clearer Laurent Vivier
     [not found]     ` <1190625056943-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
2007-09-24  9:10       ` [PATCH 2/3] remove _eflags and use directly ctxt->eflags Laurent Vivier
     [not found]         ` <11906250573823-git-send-email-Laurent.Vivier-6ktuUTfB/bM@public.gmane.org>
2007-09-24  9:10           ` [PATCH 3/3] Remove no_wb, use dst.type = OP_NONE instead, idea stollen from xen-3.1 Laurent Vivier
2007-09-24 13:20   ` [PATCH 0/3] Make some cleanup in x86_emulate.c Avi Kivity
  -- strict thread matches above, loose matches on Subject: below --
2007-09-21 11:28 Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox