All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] More emulator cleanups
@ 2010-08-01 14:23 Avi Kivity
  2010-08-01 14:23 ` [PATCH 01/15] KVM: x86 emulator: push segment override out of decode_modrm() Avi Kivity
                   ` (14 more replies)
  0 siblings, 15 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

This patchset further cleans up the emulator.  The goal is to push
segment decoding into 'struct operand', but a few things stood in
the way.

Avi Kivity (15):
  KVM: x86 emulator: push segment override out of decode_modrm()
  KVM: x86 emulator: use correct type for memory address in operands
  KVM: x86 emulator: simplify xchg decode tables
  KVM: x86 emulator: use SrcAcc to simplify xchg decoding
  KVM: x86 emulator: put register operand fetch into a function
  KVM: x86 emulator: drop use_modrm_ea
  KVM: x86 emulator: simplify REX.W check
  KVM: x86 emulator: introduce Force64 for forcing operand size to 64
    bits
  KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in
    long mode
  KVM: x86 emulator: use struct operand for mov reg,cr and mov cr,reg
    for reg op
  KVM: x86 emulator: use struct operand for mov reg,dr and mov dr,reg
    for reg op
  KVM: x86 emulator: add NoAccess flag for memory instructions that
    skip access
  KVM: x86 emulator: switch LEA to use SrcMem decoding
  KVM: x86 emulator: change invlpg emulation to use src.mem.addr
  KVM: x86 emulator: Decode memory operands directly into a 'struct
    operand'

 arch/x86/include/asm/kvm_emulate.h |   11 +-
 arch/x86/kvm/emulate.c             |  321 ++++++++++++++++--------------------
 2 files changed, 147 insertions(+), 185 deletions(-)


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

* [PATCH 01/15] KVM: x86 emulator: push segment override out of decode_modrm()
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 02/15] KVM: x86 emulator: use correct type for memory address in operands Avi Kivity
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Let it compute modrm_seg instead, and have the caller apply it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    1 +
 arch/x86/kvm/emulate.c             |   10 ++++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index f397b79..ecb2653 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -193,6 +193,7 @@ struct decode_cache {
 	u8 modrm_mod;
 	u8 modrm_reg;
 	u8 modrm_rm;
+	u8 modrm_seg;
 	u8 use_modrm_ea;
 	bool rip_relative;
 	unsigned long modrm_ea;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index dc1ecff..2ed6c67 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -593,6 +593,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 	c->modrm_rm |= (c->modrm & 0x07);
 	c->modrm_ea = 0;
 	c->use_modrm_ea = 1;
+	c->modrm_seg = VCPU_SREG_DS;
 
 	if (c->modrm_mod == 3) {
 		c->modrm_ptr = decode_register(c->modrm_rm,
@@ -649,8 +650,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 		}
 		if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
 		    (c->modrm_rm == 6 && c->modrm_mod != 0))
-			if (!c->has_seg_override)
-				set_seg_override(c, VCPU_SREG_SS);
+			c->modrm_seg = VCPU_SREG_SS;
 		c->modrm_ea = (u16)c->modrm_ea;
 	} else {
 		/* 32/64-bit ModR/M decode. */
@@ -2400,9 +2400,11 @@ done_prefixes:
 		c->op_bytes = 8;
 
 	/* ModRM and SIB bytes. */
-	if (c->d & ModRM)
+	if (c->d & ModRM) {
 		rc = decode_modrm(ctxt, ops);
-	else if (c->d & MemAbs)
+		if (!c->has_seg_override)
+			set_seg_override(c, c->modrm_seg);
+	} else if (c->d & MemAbs)
 		rc = decode_abs(ctxt, ops);
 	if (rc != X86EMUL_CONTINUE)
 		goto done;
-- 
1.7.1


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

* [PATCH 02/15] KVM: x86 emulator: use correct type for memory address in operands
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
  2010-08-01 14:23 ` [PATCH 01/15] KVM: x86 emulator: push segment override out of decode_modrm() Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 03/15] KVM: x86 emulator: simplify xchg decode tables Avi Kivity
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Currently we use a void pointer for memory addresses.  That's wrong since
these are guest virtual addresses which are not directly dereferencable by
the host.

Use the correct type, unsigned long.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    6 ++-
 arch/x86/kvm/emulate.c             |  117 +++++++++++++++++------------------
 2 files changed, 62 insertions(+), 61 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index ecb2653..bbf0e81 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -152,7 +152,11 @@ struct x86_emulate_ops {
 struct operand {
 	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
 	unsigned int bytes;
-	unsigned long orig_val, *ptr;
+	unsigned long orig_val;
+	union {
+		unsigned long *reg;
+		unsigned long mem;
+	} addr;
 	union {
 		unsigned long val;
 		char valptr[sizeof(unsigned long) + 2];
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 2ed6c67..61d728d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -489,7 +489,7 @@ static void *decode_register(u8 modrm_reg, unsigned long *regs,
 
 static int read_descriptor(struct x86_emulate_ctxt *ctxt,
 			   struct x86_emulate_ops *ops,
-			   void *ptr,
+			   ulong addr,
 			   u16 *size, unsigned long *address, int op_bytes)
 {
 	int rc;
@@ -497,12 +497,10 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
 	if (op_bytes == 2)
 		op_bytes = 3;
 	*address = 0;
-	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
-			   ctxt->vcpu, NULL);
+	rc = ops->read_std(addr, (unsigned long *)size, 2, ctxt->vcpu, NULL);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
-	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
-			   ctxt->vcpu, NULL);
+	rc = ops->read_std(addr + 2, address, op_bytes, ctxt->vcpu, NULL);
 	return rc;
 }
 
@@ -552,21 +550,21 @@ static void decode_register_operand(struct operand *op,
 		reg = (c->b & 7) | ((c->rex_prefix & 1) << 3);
 	op->type = OP_REG;
 	if ((c->d & ByteOp) && !inhibit_bytereg) {
-		op->ptr = decode_register(reg, c->regs, highbyte_regs);
-		op->val = *(u8 *)op->ptr;
+		op->addr.reg = decode_register(reg, c->regs, highbyte_regs);
+		op->val = *(u8 *)op->addr.reg;
 		op->bytes = 1;
 	} else {
-		op->ptr = decode_register(reg, c->regs, 0);
+		op->addr.reg = decode_register(reg, c->regs, 0);
 		op->bytes = c->op_bytes;
 		switch (op->bytes) {
 		case 2:
-			op->val = *(u16 *)op->ptr;
+			op->val = *(u16 *)op->addr.reg;
 			break;
 		case 4:
-			op->val = *(u32 *)op->ptr;
+			op->val = *(u32 *)op->addr.reg;
 			break;
 		case 8:
-			op->val = *(u64 *) op->ptr;
+			op->val = *(u64 *) op->addr.reg;
 			break;
 		}
 	}
@@ -976,23 +974,23 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
 		 */
 		switch (c->dst.bytes) {
 		case 1:
-			*(u8 *)c->dst.ptr = (u8)c->dst.val;
+			*(u8 *)c->dst.addr.reg = (u8)c->dst.val;
 			break;
 		case 2:
-			*(u16 *)c->dst.ptr = (u16)c->dst.val;
+			*(u16 *)c->dst.addr.reg = (u16)c->dst.val;
 			break;
 		case 4:
-			*c->dst.ptr = (u32)c->dst.val;
+			*c->dst.addr.reg = (u32)c->dst.val;
 			break;	/* 64b: zero-ext */
 		case 8:
-			*c->dst.ptr = c->dst.val;
+			*c->dst.addr.reg = c->dst.val;
 			break;
 		}
 		break;
 	case OP_MEM:
 		if (c->lock_prefix)
 			rc = ops->cmpxchg_emulated(
-					(unsigned long)c->dst.ptr,
+					c->dst.addr.mem,
 					&c->dst.orig_val,
 					&c->dst.val,
 					c->dst.bytes,
@@ -1000,14 +998,13 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
 					ctxt->vcpu);
 		else
 			rc = ops->write_emulated(
-					(unsigned long)c->dst.ptr,
+					c->dst.addr.mem,
 					&c->dst.val,
 					c->dst.bytes,
 					&err,
 					ctxt->vcpu);
 		if (rc == X86EMUL_PROPAGATE_FAULT)
-			emulate_pf(ctxt,
-					      (unsigned long)c->dst.ptr, err);
+			emulate_pf(ctxt, c->dst.addr.mem, err);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		break;
@@ -1029,8 +1026,8 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt,
 	c->dst.bytes = c->op_bytes;
 	c->dst.val = c->src.val;
 	register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes);
-	c->dst.ptr = (void *) register_address(c, ss_base(ctxt, ops),
-					       c->regs[VCPU_REGS_RSP]);
+	c->dst.addr.mem = register_address(c, ss_base(ctxt, ops),
+					   c->regs[VCPU_REGS_RSP]);
 }
 
 static int emulate_pop(struct x86_emulate_ctxt *ctxt,
@@ -2014,7 +2011,7 @@ static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
 	int df = (ctxt->eflags & EFLG_DF) ? -1 : 1;
 
 	register_address_increment(c, &c->regs[reg], df * op->bytes);
-	op->ptr = (unsigned long *)register_address(c,  base, c->regs[reg]);
+	op->addr.mem = register_address(c,  base, c->regs[reg]);
 }
 
 static int em_push(struct x86_emulate_ctxt *ctxt)
@@ -2451,17 +2448,17 @@ done_prefixes:
 		if ((c->d & ModRM) && c->modrm_mod == 3) {
 			c->src.type = OP_REG;
 			c->src.val = c->modrm_val;
-			c->src.ptr = c->modrm_ptr;
+			c->src.addr.reg = c->modrm_ptr;
 			break;
 		}
 		c->src.type = OP_MEM;
-		c->src.ptr = (unsigned long *)c->modrm_ea;
+		c->src.addr.mem = c->modrm_ea;
 		c->src.val = 0;
 		break;
 	case SrcImm:
 	case SrcImmU:
 		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
+		c->src.addr.mem = c->eip;
 		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		if (c->src.bytes == 8)
 			c->src.bytes = 4;
@@ -2494,7 +2491,7 @@ done_prefixes:
 	case SrcImmByte:
 	case SrcImmUByte:
 		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
+		c->src.addr.mem = c->eip;
 		c->src.bytes = 1;
 		if ((c->d & SrcMask) == SrcImmByte)
 			c->src.val = insn_fetch(s8, 1, c->eip);
@@ -2504,19 +2501,19 @@ done_prefixes:
 	case SrcAcc:
 		c->src.type = OP_REG;
 		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->src.ptr = &c->regs[VCPU_REGS_RAX];
+		c->src.addr.reg = &c->regs[VCPU_REGS_RAX];
 		switch (c->src.bytes) {
 			case 1:
-				c->src.val = *(u8 *)c->src.ptr;
+				c->src.val = *(u8 *)c->src.addr.reg;
 				break;
 			case 2:
-				c->src.val = *(u16 *)c->src.ptr;
+				c->src.val = *(u16 *)c->src.addr.reg;
 				break;
 			case 4:
-				c->src.val = *(u32 *)c->src.ptr;
+				c->src.val = *(u32 *)c->src.addr.reg;
 				break;
 			case 8:
-				c->src.val = *(u64 *)c->src.ptr;
+				c->src.val = *(u64 *)c->src.addr.reg;
 				break;
 		}
 		break;
@@ -2527,20 +2524,20 @@ done_prefixes:
 	case SrcSI:
 		c->src.type = OP_MEM;
 		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->src.ptr = (unsigned long *)
+		c->src.addr.mem =
 			register_address(c,  seg_override_base(ctxt, ops, c),
 					 c->regs[VCPU_REGS_RSI]);
 		c->src.val = 0;
 		break;
 	case SrcImmFAddr:
 		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
+		c->src.addr.mem = c->eip;
 		c->src.bytes = c->op_bytes + 2;
 		insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
 		break;
 	case SrcMemFAddr:
 		c->src.type = OP_MEM;
-		c->src.ptr = (unsigned long *)c->modrm_ea;
+		c->src.addr.mem = c->modrm_ea;
 		c->src.bytes = c->op_bytes + 2;
 		break;
 	}
@@ -2558,7 +2555,7 @@ done_prefixes:
 		break;
 	case Src2ImmByte:
 		c->src2.type = OP_IMM;
-		c->src2.ptr = (unsigned long *)c->eip;
+		c->src2.addr.mem = c->eip;
 		c->src2.bytes = 1;
 		c->src2.val = insn_fetch(u8, 1, c->eip);
 		break;
@@ -2583,11 +2580,11 @@ done_prefixes:
 			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 			c->dst.type = OP_REG;
 			c->dst.val = c->dst.orig_val = c->modrm_val;
-			c->dst.ptr = c->modrm_ptr;
+			c->dst.addr.reg = c->modrm_ptr;
 			break;
 		}
 		c->dst.type = OP_MEM;
-		c->dst.ptr = (unsigned long *)c->modrm_ea;
+		c->dst.addr.mem = c->modrm_ea;
 		if ((c->d & DstMask) == DstMem64)
 			c->dst.bytes = 8;
 		else
@@ -2596,26 +2593,26 @@ done_prefixes:
 		if (c->d & BitOp) {
 			unsigned long mask = ~(c->dst.bytes * 8 - 1);
 
-			c->dst.ptr = (void *)c->dst.ptr +
+			c->dst.addr.mem = c->dst.addr.mem +
 						   (c->src.val & mask) / 8;
 		}
 		break;
 	case DstAcc:
 		c->dst.type = OP_REG;
 		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = &c->regs[VCPU_REGS_RAX];
+		c->dst.addr.reg = &c->regs[VCPU_REGS_RAX];
 		switch (c->dst.bytes) {
 			case 1:
-				c->dst.val = *(u8 *)c->dst.ptr;
+				c->dst.val = *(u8 *)c->dst.addr.reg;
 				break;
 			case 2:
-				c->dst.val = *(u16 *)c->dst.ptr;
+				c->dst.val = *(u16 *)c->dst.addr.reg;
 				break;
 			case 4:
-				c->dst.val = *(u32 *)c->dst.ptr;
+				c->dst.val = *(u32 *)c->dst.addr.reg;
 				break;
 			case 8:
-				c->dst.val = *(u64 *)c->dst.ptr;
+				c->dst.val = *(u64 *)c->dst.addr.reg;
 				break;
 		}
 		c->dst.orig_val = c->dst.val;
@@ -2623,7 +2620,7 @@ done_prefixes:
 	case DstDI:
 		c->dst.type = OP_MEM;
 		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = (unsigned long *)
+		c->dst.addr.mem =
 			register_address(c, es_base(ctxt, ops),
 					 c->regs[VCPU_REGS_RDI]);
 		c->dst.val = 0;
@@ -2691,7 +2688,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 	}
 
 	if (c->src.type == OP_MEM) {
-		rc = read_emulated(ctxt, ops, (unsigned long)c->src.ptr,
+		rc = read_emulated(ctxt, ops, c->src.addr.mem,
 					c->src.valptr, c->src.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
@@ -2699,7 +2696,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 	}
 
 	if (c->src2.type == OP_MEM) {
-		rc = read_emulated(ctxt, ops, (unsigned long)c->src2.ptr,
+		rc = read_emulated(ctxt, ops, c->src2.addr.mem,
 					&c->src2.val, c->src2.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
@@ -2711,7 +2708,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 
 	if ((c->dst.type == OP_MEM) && !(c->d & Mov)) {
 		/* optimisation - avoid slow emulated read if Mov */
-		rc = read_emulated(ctxt, ops, (unsigned long)c->dst.ptr,
+		rc = read_emulated(ctxt, ops, c->dst.addr.mem,
 				   &c->dst.val, c->dst.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
@@ -2875,16 +2872,16 @@ special_insn:
 		/* Write back the register source. */
 		switch (c->dst.bytes) {
 		case 1:
-			*(u8 *) c->src.ptr = (u8) c->dst.val;
+			*(u8 *) c->src.addr.reg = (u8) c->dst.val;
 			break;
 		case 2:
-			*(u16 *) c->src.ptr = (u16) c->dst.val;
+			*(u16 *) c->src.addr.reg = (u16) c->dst.val;
 			break;
 		case 4:
-			*c->src.ptr = (u32) c->dst.val;
+			*c->src.addr.reg = (u32) c->dst.val;
 			break;	/* 64b reg: zero-extend */
 		case 8:
-			*c->src.ptr = c->dst.val;
+			*c->src.addr.reg = c->dst.val;
 			break;
 		}
 		/*
@@ -2931,15 +2928,15 @@ special_insn:
 			goto done;
 		break;
 	case 0x90: /* nop / xchg r8,rax */
-		if (c->dst.ptr == (unsigned long *)&c->regs[VCPU_REGS_RAX]) {
+		if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX]) {
 			c->dst.type = OP_NONE;  /* nop */
 			break;
 		}
 	case 0x91 ... 0x97: /* xchg reg,rax */
 		c->src.type = OP_REG;
 		c->src.bytes = c->op_bytes;
-		c->src.ptr = (unsigned long *) &c->regs[VCPU_REGS_RAX];
-		c->src.val = *(c->src.ptr);
+		c->src.addr.reg = &c->regs[VCPU_REGS_RAX];
+		c->src.val = *(c->src.addr.reg);
 		goto xchg;
 	case 0x9c: /* pushf */
 		c->src.val =  (unsigned long) ctxt->eflags;
@@ -2947,7 +2944,7 @@ special_insn:
 		break;
 	case 0x9d: /* popf */
 		c->dst.type = OP_REG;
-		c->dst.ptr = (unsigned long *) &ctxt->eflags;
+		c->dst.addr.reg = &ctxt->eflags;
 		c->dst.bytes = c->op_bytes;
 		rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes);
 		if (rc != X86EMUL_CONTINUE)
@@ -2958,7 +2955,7 @@ special_insn:
 		goto mov;
 	case 0xa6 ... 0xa7:	/* cmps */
 		c->dst.type = OP_NONE; /* Disable writeback. */
-		DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
+		DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.addr.mem, c->dst.addr.mem);
 		goto cmp;
 	case 0xa8 ... 0xa9:	/* test ax, imm */
 		goto test;
@@ -2977,7 +2974,7 @@ special_insn:
 		break;
 	case 0xc3: /* ret */
 		c->dst.type = OP_REG;
-		c->dst.ptr = &c->eip;
+		c->dst.addr.reg = &c->eip;
 		c->dst.bytes = c->op_bytes;
 		goto pop_instruction;
 	case 0xc6 ... 0xc7:	/* mov (sole member of Grp11) */
@@ -3179,7 +3176,7 @@ twobyte_insn:
 			c->dst.type = OP_NONE;
 			break;
 		case 2: /* lgdt */
-			rc = read_descriptor(ctxt, ops, c->src.ptr,
+			rc = read_descriptor(ctxt, ops, c->src.addr.mem,
 					     &size, &address, c->op_bytes);
 			if (rc != X86EMUL_CONTINUE)
 				goto done;
@@ -3199,7 +3196,7 @@ twobyte_insn:
 					goto cannot_emulate;
 				}
 			} else {
-				rc = read_descriptor(ctxt, ops, c->src.ptr,
+				rc = read_descriptor(ctxt, ops, c->src.addr.mem,
 						     &size, &address,
 						     c->op_bytes);
 				if (rc != X86EMUL_CONTINUE)
@@ -3394,7 +3391,7 @@ twobyte_insn:
 		} else {
 			/* Failure: write the value we saw to EAX. */
 			c->dst.type = OP_REG;
-			c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
+			c->dst.addr.reg = (unsigned long *)&c->regs[VCPU_REGS_RAX];
 		}
 		break;
 	case 0xb3:
-- 
1.7.1


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

* [PATCH 03/15] KVM: x86 emulator: simplify xchg decode tables
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
  2010-08-01 14:23 ` [PATCH 01/15] KVM: x86 emulator: push segment override out of decode_modrm() Avi Kivity
  2010-08-01 14:23 ` [PATCH 02/15] KVM: x86 emulator: use correct type for memory address in operands Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 04/15] KVM: x86 emulator: use SrcAcc to simplify xchg decoding Avi Kivity
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Use X8() to avoid repetition.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 61d728d..745353e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2142,7 +2142,7 @@ static struct opcode opcode_table[256] = {
 	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
 	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
 	/* 0x90 - 0x97 */
-	D(DstReg), D(DstReg), D(DstReg), D(DstReg),	D(DstReg), D(DstReg), D(DstReg), D(DstReg),
+	X8(D(DstReg)),
 	/* 0x98 - 0x9F */
 	N, N, D(SrcImmFAddr | No64), N,
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
-- 
1.7.1


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

* [PATCH 04/15] KVM: x86 emulator: use SrcAcc to simplify xchg decoding
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (2 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 03/15] KVM: x86 emulator: simplify xchg decode tables Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 05/15] KVM: x86 emulator: put register operand fetch into a function Avi Kivity
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   15 ++++-----------
 1 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 745353e..4d510c3 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2142,7 +2142,7 @@ static struct opcode opcode_table[256] = {
 	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
 	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
 	/* 0x90 - 0x97 */
-	X8(D(DstReg)),
+	X8(D(SrcAcc | DstReg)),
 	/* 0x98 - 0x9F */
 	N, N, D(SrcImmFAddr | No64), N,
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
@@ -2927,16 +2927,9 @@ special_insn:
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
-	case 0x90: /* nop / xchg r8,rax */
-		if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX]) {
-			c->dst.type = OP_NONE;  /* nop */
-			break;
-		}
-	case 0x91 ... 0x97: /* xchg reg,rax */
-		c->src.type = OP_REG;
-		c->src.bytes = c->op_bytes;
-		c->src.addr.reg = &c->regs[VCPU_REGS_RAX];
-		c->src.val = *(c->src.addr.reg);
+	case 0x90 ... 0x97: /* nop / xchg reg, rax */
+		if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX])
+			goto done;
 		goto xchg;
 	case 0x9c: /* pushf */
 		c->src.val =  (unsigned long) ctxt->eflags;
-- 
1.7.1


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

* [PATCH 05/15] KVM: x86 emulator: put register operand fetch into a function
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (3 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 04/15] KVM: x86 emulator: use SrcAcc to simplify xchg decoding Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 06/15] KVM: x86 emulator: drop use_modrm_ea Avi Kivity
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

The code is repeated three times, put it into fetch_register_operand()

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |   61 ++++++++++++++++-------------------------------
 1 files changed, 21 insertions(+), 40 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4d510c3..063c96a 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -539,6 +539,24 @@ static int test_cc(unsigned int condition, unsigned int flags)
 	return (!!rc ^ (condition & 1));
 }
 
+static void fetch_register_operand(struct operand *op)
+{
+	switch (op->bytes) {
+	case 1:
+		op->val = *(u8 *)op->addr.reg;
+		break;
+	case 2:
+		op->val = *(u16 *)op->addr.reg;
+		break;
+	case 4:
+		op->val = *(u32 *)op->addr.reg;
+		break;
+	case 8:
+		op->val = *(u64 *)op->addr.reg;
+		break;
+	}
+}
+
 static void decode_register_operand(struct operand *op,
 				    struct decode_cache *c,
 				    int inhibit_bytereg)
@@ -551,23 +569,12 @@ static void decode_register_operand(struct operand *op,
 	op->type = OP_REG;
 	if ((c->d & ByteOp) && !inhibit_bytereg) {
 		op->addr.reg = decode_register(reg, c->regs, highbyte_regs);
-		op->val = *(u8 *)op->addr.reg;
 		op->bytes = 1;
 	} else {
 		op->addr.reg = decode_register(reg, c->regs, 0);
 		op->bytes = c->op_bytes;
-		switch (op->bytes) {
-		case 2:
-			op->val = *(u16 *)op->addr.reg;
-			break;
-		case 4:
-			op->val = *(u32 *)op->addr.reg;
-			break;
-		case 8:
-			op->val = *(u64 *) op->addr.reg;
-			break;
-		}
 	}
+	fetch_register_operand(op);
 	op->orig_val = op->val;
 }
 
@@ -2502,20 +2509,7 @@ done_prefixes:
 		c->src.type = OP_REG;
 		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		c->src.addr.reg = &c->regs[VCPU_REGS_RAX];
-		switch (c->src.bytes) {
-			case 1:
-				c->src.val = *(u8 *)c->src.addr.reg;
-				break;
-			case 2:
-				c->src.val = *(u16 *)c->src.addr.reg;
-				break;
-			case 4:
-				c->src.val = *(u32 *)c->src.addr.reg;
-				break;
-			case 8:
-				c->src.val = *(u64 *)c->src.addr.reg;
-				break;
-		}
+		fetch_register_operand(&c->src);
 		break;
 	case SrcOne:
 		c->src.bytes = 1;
@@ -2601,20 +2595,7 @@ done_prefixes:
 		c->dst.type = OP_REG;
 		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		c->dst.addr.reg = &c->regs[VCPU_REGS_RAX];
-		switch (c->dst.bytes) {
-			case 1:
-				c->dst.val = *(u8 *)c->dst.addr.reg;
-				break;
-			case 2:
-				c->dst.val = *(u16 *)c->dst.addr.reg;
-				break;
-			case 4:
-				c->dst.val = *(u32 *)c->dst.addr.reg;
-				break;
-			case 8:
-				c->dst.val = *(u64 *)c->dst.addr.reg;
-				break;
-		}
+		fetch_register_operand(&c->dst);
 		c->dst.orig_val = c->dst.val;
 		break;
 	case DstDI:
-- 
1.7.1


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

* [PATCH 06/15] KVM: x86 emulator: drop use_modrm_ea
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (4 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 05/15] KVM: x86 emulator: put register operand fetch into a function Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 07/15] KVM: x86 emulator: simplify REX.W check Avi Kivity
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Unused (and has never been).

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    1 -
 arch/x86/kvm/emulate.c             |    1 -
 2 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index bbf0e81..db4a248 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -198,7 +198,6 @@ struct decode_cache {
 	u8 modrm_reg;
 	u8 modrm_rm;
 	u8 modrm_seg;
-	u8 use_modrm_ea;
 	bool rip_relative;
 	unsigned long modrm_ea;
 	void *modrm_ptr;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 063c96a..2ae2e54 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -597,7 +597,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 	c->modrm_reg |= (c->modrm & 0x38) >> 3;
 	c->modrm_rm |= (c->modrm & 0x07);
 	c->modrm_ea = 0;
-	c->use_modrm_ea = 1;
 	c->modrm_seg = VCPU_SREG_DS;
 
 	if (c->modrm_mod == 3) {
-- 
1.7.1


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

* [PATCH 07/15] KVM: x86 emulator: simplify REX.W check
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (5 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 06/15] KVM: x86 emulator: drop use_modrm_ea Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 08/15] KVM: x86 emulator: introduce Force64 for forcing operand size to 64 bits Avi Kivity
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

(x && (x & y)) == (x & y)

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 2ae2e54..a114fa9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2353,9 +2353,8 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt)
 done_prefixes:
 
 	/* REX prefix. */
-	if (c->rex_prefix)
-		if (c->rex_prefix & 8)
-			c->op_bytes = 8;	/* REX.W */
+	if (c->rex_prefix & 8)
+		c->op_bytes = 8;	/* REX.W */
 
 	/* Opcode byte(s). */
 	opcode = opcode_table[c->b];
-- 
1.7.1


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

* [PATCH 08/15] KVM: x86 emulator: introduce Force64 for forcing operand size to 64 bits
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (6 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 07/15] KVM: x86 emulator: simplify REX.W check Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 09/15] KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in long mode Avi Kivity
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index a114fa9..d7d95de 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -83,6 +83,7 @@
 #define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
 #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
 /* Misc flags */
+#define Force64     (1<<24) /* Force operand size to 64 bits in 64-bit mode */
 #define Undefined   (1<<25) /* No Such Instruction */
 #define Lock        (1<<26) /* lock prefix is allowed for the instruction */
 #define Priv        (1<<27) /* instruction generates #GP if current CPL != 0 */
@@ -2398,7 +2399,7 @@ done_prefixes:
 		return -1;
 	}
 
-	if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
+	if (mode == X86EMUL_MODE_PROT64 && (c->d & (Stack | Force64)))
 		c->op_bytes = 8;
 
 	/* ModRM and SIB bytes. */
-- 
1.7.1


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

* [PATCH 09/15] KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in long mode
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (7 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 08/15] KVM: x86 emulator: introduce Force64 for forcing operand size to 64 bits Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-02  7:37   ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 10/15] KVM: x86 emulator: use struct operand for mov reg,cr and mov cr,reg for reg op Avi Kivity
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d7d95de..d1a6cd7 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2205,8 +2205,8 @@ static struct opcode twobyte_table[256] = {
 	/* 0x10 - 0x1F */
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
-	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
-	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
+	D(ModRM | ImplicitOps | Priv | Force64), D(ModRM | Priv | Force64),
+	D(ModRM | ImplicitOps | Priv | Force64), D(ModRM | Priv | Force64),
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
-- 
1.7.1


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

* [PATCH 10/15] KVM: x86 emulator: use struct operand for mov reg,cr and mov cr,reg for reg op
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (8 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 09/15] KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in long mode Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 11/15] KVM: x86 emulator: use struct operand for mov reg,dr and mov dr,reg " Avi Kivity
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

This is an ordinary modrm source or destination; use the standard structure
representing it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d1a6cd7..53e5c60 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2205,8 +2205,8 @@ static struct opcode twobyte_table[256] = {
 	/* 0x10 - 0x1F */
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
-	D(ModRM | ImplicitOps | Priv | Force64), D(ModRM | Priv | Force64),
-	D(ModRM | ImplicitOps | Priv | Force64), D(ModRM | Priv | Force64),
+	D(ModRM | DstMem | Priv | Force64), D(ModRM | Priv | Force64),
+	D(ModRM | SrcMem | Priv | Force64), D(ModRM | Priv | Force64),
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
@@ -3228,8 +3228,7 @@ twobyte_insn:
 			emulate_ud(ctxt);
 			goto done;
 		}
-		c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu);
-		c->dst.type = OP_NONE;	/* no writeback */
+		c->dst.val = ops->get_cr(c->modrm_reg, ctxt->vcpu);
 		break;
 	case 0x21: /* mov from dr to reg */
 		if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) &&
@@ -3241,7 +3240,7 @@ twobyte_insn:
 		c->dst.type = OP_NONE;	/* no writeback */
 		break;
 	case 0x22: /* mov reg, cr */
-		if (ops->set_cr(c->modrm_reg, c->modrm_val, ctxt->vcpu)) {
+		if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) {
 			emulate_gp(ctxt, 0);
 			goto done;
 		}
-- 
1.7.1


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

* [PATCH 11/15] KVM: x86 emulator: use struct operand for mov reg,dr and mov dr,reg for reg op
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (9 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 10/15] KVM: x86 emulator: use struct operand for mov reg,cr and mov cr,reg for reg op Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 12/15] KVM: x86 emulator: add NoAccess flag for memory instructions that skip access Avi Kivity
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

This is an ordinary modrm source or destination; use the standard structure
representing it.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 53e5c60..5bc62f2 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2205,8 +2205,8 @@ static struct opcode twobyte_table[256] = {
 	/* 0x10 - 0x1F */
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
-	D(ModRM | DstMem | Priv | Force64), D(ModRM | Priv | Force64),
-	D(ModRM | SrcMem | Priv | Force64), D(ModRM | Priv | Force64),
+	D(ModRM | DstMem | Priv | Force64), D(ModRM | DstMem | Priv | Force64),
+	D(ModRM | SrcMem | Priv | Force64), D(ModRM | SrcMem | Priv | Force64),
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
@@ -3236,8 +3236,7 @@ twobyte_insn:
 			emulate_ud(ctxt);
 			goto done;
 		}
-		ops->get_dr(c->modrm_reg, &c->regs[c->modrm_rm], ctxt->vcpu);
-		c->dst.type = OP_NONE;	/* no writeback */
+		ops->get_dr(c->modrm_reg, &c->dst.val, ctxt->vcpu);
 		break;
 	case 0x22: /* mov reg, cr */
 		if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) {
@@ -3253,7 +3252,7 @@ twobyte_insn:
 			goto done;
 		}
 
-		if (ops->set_dr(c->modrm_reg, c->regs[c->modrm_rm] &
+		if (ops->set_dr(c->modrm_reg, c->src.val &
 				((ctxt->mode == X86EMUL_MODE_PROT64) ?
 				 ~0ULL : ~0U), ctxt->vcpu) < 0) {
 			/* #UD condition is already handled by the code above */
-- 
1.7.1


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

* [PATCH 12/15] KVM: x86 emulator: add NoAccess flag for memory instructions that skip access
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (10 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 11/15] KVM: x86 emulator: use struct operand for mov reg,dr and mov dr,reg " Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 13/15] KVM: x86 emulator: switch LEA to use SrcMem decoding Avi Kivity
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Use for INVLPG, which accesses the tlb, not memory.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 5bc62f2..29312a0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -83,6 +83,7 @@
 #define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
 #define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
 /* Misc flags */
+#define NoAccess    (1<<23) /* Don't access memory (lea/invlpg/verr etc) */
 #define Force64     (1<<24) /* Force operand size to 64 bits in 64-bit mode */
 #define Undefined   (1<<25) /* No Such Instruction */
 #define Lock        (1<<26) /* lock prefix is allowed for the instruction */
@@ -2062,7 +2063,8 @@ static struct opcode group5[] = {
 static struct group_dual group7 = { {
 	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
 	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), D(SrcMem | ModRM | ByteOp | Priv),
+	D(SrcMem16 | ModRM | Mov | Priv),
+	D(SrcMem | ModRM | ByteOp | Priv | NoAccess),
 }, {
 	D(SrcNone | ModRM | Priv), N, N, D(SrcNone | ModRM | Priv),
 	D(SrcNone | ModRM | DstMem | Mov), N,
@@ -2444,7 +2446,7 @@ done_prefixes:
 		c->src.bytes = (c->d & ByteOp) ? 1 :
 							   c->op_bytes;
 		/* Don't fetch the address for invlpg: it could be unmapped. */
-		if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
+		if (c->d & NoAccess)
 			break;
 	srcmem_common:
 		/*
-- 
1.7.1


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

* [PATCH 13/15] KVM: x86 emulator: switch LEA to use SrcMem decoding
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (11 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 12/15] KVM: x86 emulator: add NoAccess flag for memory instructions that skip access Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 14/15] KVM: x86 emulator: change invlpg emulation to use src.mem.addr Avi Kivity
  2010-08-01 14:23 ` [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand' Avi Kivity
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

The NoAccess flag will prevent memory from being accessed.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 29312a0..46a5d75 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2148,7 +2148,7 @@ static struct opcode opcode_table[256] = {
 	/* 0x88 - 0x8F */
 	D(ByteOp | DstMem | SrcReg | ModRM | Mov), D(DstMem | SrcReg | ModRM | Mov),
 	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem | ModRM | Mov),
-	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | DstReg),
+	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | SrcMem | NoAccess | DstReg),
 	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
 	/* 0x90 - 0x97 */
 	X8(D(SrcAcc | DstReg)),
@@ -2883,7 +2883,7 @@ special_insn:
 		c->dst.val = ops->get_segment_selector(c->modrm_reg, ctxt->vcpu);
 		break;
 	case 0x8d: /* lea r16/r32, m */
-		c->dst.val = c->modrm_ea;
+		c->dst.val = c->src.addr.mem;
 		break;
 	case 0x8e: { /* mov seg, r/m16 */
 		uint16_t sel;
-- 
1.7.1


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

* [PATCH 14/15] KVM: x86 emulator: change invlpg emulation to use src.mem.addr
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (12 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 13/15] KVM: x86 emulator: switch LEA to use SrcMem decoding Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-01 14:23 ` [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand' Avi Kivity
  14 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Instead of using modrm_ea, which will soon be gone.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/kvm/emulate.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 46a5d75..de1ed94 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3194,7 +3194,7 @@ twobyte_insn:
 			emulate_ud(ctxt);
 			goto done;
 		case 7: /* invlpg*/
-			emulate_invlpg(ctxt->vcpu, c->modrm_ea);
+			emulate_invlpg(ctxt->vcpu, c->src.addr.mem);
 			/* Disable writeback. */
 			c->dst.type = OP_NONE;
 			break;
-- 
1.7.1


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

* [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand'
  2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
                   ` (13 preceding siblings ...)
  2010-08-01 14:23 ` [PATCH 14/15] KVM: x86 emulator: change invlpg emulation to use src.mem.addr Avi Kivity
@ 2010-08-01 14:23 ` Avi Kivity
  2010-08-02  7:28   ` Paolo Bonzini
  14 siblings, 1 reply; 19+ messages in thread
From: Avi Kivity @ 2010-08-01 14:23 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

Since modrm operand can be either register or memory, decoding it into
a 'struct operand', which can represent both, is simpler.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 arch/x86/include/asm/kvm_emulate.h |    3 -
 arch/x86/kvm/emulate.c             |  125 ++++++++++++++++-------------------
 2 files changed, 57 insertions(+), 71 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index db4a248..99c1c57 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -199,9 +199,6 @@ struct decode_cache {
 	u8 modrm_rm;
 	u8 modrm_seg;
 	bool rip_relative;
-	unsigned long modrm_ea;
-	void *modrm_ptr;
-	unsigned long modrm_val;
 	struct fetch_cache fetch;
 	struct read_cache io_read;
 	struct read_cache mem_read;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index de1ed94..49a174f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -581,12 +581,14 @@ static void decode_register_operand(struct operand *op,
 }
 
 static int decode_modrm(struct x86_emulate_ctxt *ctxt,
-			struct x86_emulate_ops *ops)
+			struct x86_emulate_ops *ops,
+			struct operand *op)
 {
 	struct decode_cache *c = &ctxt->decode;
 	u8 sib;
 	int index_reg = 0, base_reg = 0, scale;
 	int rc = X86EMUL_CONTINUE;
+	ulong modrm_ea = 0;
 
 	if (c->rex_prefix) {
 		c->modrm_reg = (c->rex_prefix & 4) << 1;	/* REX.R */
@@ -598,16 +600,19 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 	c->modrm_mod |= (c->modrm & 0xc0) >> 6;
 	c->modrm_reg |= (c->modrm & 0x38) >> 3;
 	c->modrm_rm |= (c->modrm & 0x07);
-	c->modrm_ea = 0;
 	c->modrm_seg = VCPU_SREG_DS;
 
 	if (c->modrm_mod == 3) {
-		c->modrm_ptr = decode_register(c->modrm_rm,
+		op->type = OP_REG;
+		op->bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		op->addr.reg = decode_register(c->modrm_rm,
 					       c->regs, c->d & ByteOp);
-		c->modrm_val = *(unsigned long *)c->modrm_ptr;
+		fetch_register_operand(op);
 		return rc;
 	}
 
+	op->type = OP_MEM;
+
 	if (c->ad_bytes == 2) {
 		unsigned bx = c->regs[VCPU_REGS_RBX];
 		unsigned bp = c->regs[VCPU_REGS_RBP];
@@ -618,46 +623,46 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 		switch (c->modrm_mod) {
 		case 0:
 			if (c->modrm_rm == 6)
-				c->modrm_ea += insn_fetch(u16, 2, c->eip);
+				modrm_ea += insn_fetch(u16, 2, c->eip);
 			break;
 		case 1:
-			c->modrm_ea += insn_fetch(s8, 1, c->eip);
+			modrm_ea += insn_fetch(s8, 1, c->eip);
 			break;
 		case 2:
-			c->modrm_ea += insn_fetch(u16, 2, c->eip);
+			modrm_ea += insn_fetch(u16, 2, c->eip);
 			break;
 		}
 		switch (c->modrm_rm) {
 		case 0:
-			c->modrm_ea += bx + si;
+			modrm_ea += bx + si;
 			break;
 		case 1:
-			c->modrm_ea += bx + di;
+			modrm_ea += bx + di;
 			break;
 		case 2:
-			c->modrm_ea += bp + si;
+			modrm_ea += bp + si;
 			break;
 		case 3:
-			c->modrm_ea += bp + di;
+			modrm_ea += bp + di;
 			break;
 		case 4:
-			c->modrm_ea += si;
+			modrm_ea += si;
 			break;
 		case 5:
-			c->modrm_ea += di;
+			modrm_ea += di;
 			break;
 		case 6:
 			if (c->modrm_mod != 0)
-				c->modrm_ea += bp;
+				modrm_ea += bp;
 			break;
 		case 7:
-			c->modrm_ea += bx;
+			modrm_ea += bx;
 			break;
 		}
 		if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
 		    (c->modrm_rm == 6 && c->modrm_mod != 0))
 			c->modrm_seg = VCPU_SREG_SS;
-		c->modrm_ea = (u16)c->modrm_ea;
+		modrm_ea = (u16)modrm_ea;
 	} else {
 		/* 32/64-bit ModR/M decode. */
 		if ((c->modrm_rm & 7) == 4) {
@@ -667,48 +672,51 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 			scale = sib >> 6;
 
 			if ((base_reg & 7) == 5 && c->modrm_mod == 0)
-				c->modrm_ea += insn_fetch(s32, 4, c->eip);
+				modrm_ea += insn_fetch(s32, 4, c->eip);
 			else
-				c->modrm_ea += c->regs[base_reg];
+				modrm_ea += c->regs[base_reg];
 			if (index_reg != 4)
-				c->modrm_ea += c->regs[index_reg] << scale;
+				modrm_ea += c->regs[index_reg] << scale;
 		} else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) {
 			if (ctxt->mode == X86EMUL_MODE_PROT64)
 				c->rip_relative = 1;
 		} else
-			c->modrm_ea += c->regs[c->modrm_rm];
+			modrm_ea += c->regs[c->modrm_rm];
 		switch (c->modrm_mod) {
 		case 0:
 			if (c->modrm_rm == 5)
-				c->modrm_ea += insn_fetch(s32, 4, c->eip);
+				modrm_ea += insn_fetch(s32, 4, c->eip);
 			break;
 		case 1:
-			c->modrm_ea += insn_fetch(s8, 1, c->eip);
+			modrm_ea += insn_fetch(s8, 1, c->eip);
 			break;
 		case 2:
-			c->modrm_ea += insn_fetch(s32, 4, c->eip);
+			modrm_ea += insn_fetch(s32, 4, c->eip);
 			break;
 		}
 	}
+	op->addr.mem = modrm_ea;
 done:
 	return rc;
 }
 
 static int decode_abs(struct x86_emulate_ctxt *ctxt,
-		      struct x86_emulate_ops *ops)
+		      struct x86_emulate_ops *ops,
+		      struct operand *op)
 {
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
 
+	op->type = OP_MEM;
 	switch (c->ad_bytes) {
 	case 2:
-		c->modrm_ea = insn_fetch(u16, 2, c->eip);
+		op->addr.mem = insn_fetch(u16, 2, c->eip);
 		break;
 	case 4:
-		c->modrm_ea = insn_fetch(u32, 4, c->eip);
+		op->addr.mem = insn_fetch(u32, 4, c->eip);
 		break;
 	case 8:
-		c->modrm_ea = insn_fetch(u64, 8, c->eip);
+		op->addr.mem = insn_fetch(u64, 8, c->eip);
 		break;
 	}
 done:
@@ -2275,6 +2283,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt)
 	int mode = ctxt->mode;
 	int def_op_bytes, def_ad_bytes, dual, goffset;
 	struct opcode opcode, *g_mod012, *g_mod3;
+	struct operand memop = { .type = OP_NONE };
 
 	/* we cannot decode insn before we complete previous rep insn */
 	WARN_ON(ctxt->restart);
@@ -2406,25 +2415,25 @@ done_prefixes:
 
 	/* ModRM and SIB bytes. */
 	if (c->d & ModRM) {
-		rc = decode_modrm(ctxt, ops);
+		rc = decode_modrm(ctxt, ops, &memop);
 		if (!c->has_seg_override)
 			set_seg_override(c, c->modrm_seg);
 	} else if (c->d & MemAbs)
-		rc = decode_abs(ctxt, ops);
+		rc = decode_abs(ctxt, ops, &memop);
 	if (rc != X86EMUL_CONTINUE)
 		goto done;
 
 	if (!c->has_seg_override)
 		set_seg_override(c, VCPU_SREG_DS);
 
-	if (!(!c->twobyte && c->b == 0x8d))
-		c->modrm_ea += seg_override_base(ctxt, ops, c);
+	if (memop.type == OP_MEM && !(!c->twobyte && c->b == 0x8d))
+		memop.addr.mem += seg_override_base(ctxt, ops, c);
 
-	if (c->ad_bytes != 8)
-		c->modrm_ea = (u32)c->modrm_ea;
+	if (memop.type == OP_MEM && c->ad_bytes != 8)
+		memop.addr.mem = (u32)memop.addr.mem;
 
-	if (c->rip_relative)
-		c->modrm_ea += c->eip;
+	if (memop.type == OP_MEM && c->rip_relative)
+		memop.addr.mem += c->eip;
 
 	/*
 	 * Decode and fetch the source operand: register, memory
@@ -2437,31 +2446,16 @@ done_prefixes:
 		decode_register_operand(&c->src, c, 0);
 		break;
 	case SrcMem16:
-		c->src.bytes = 2;
+		memop.bytes = 2;
 		goto srcmem_common;
 	case SrcMem32:
-		c->src.bytes = 4;
+		memop.bytes = 4;
 		goto srcmem_common;
 	case SrcMem:
-		c->src.bytes = (c->d & ByteOp) ? 1 :
+		memop.bytes = (c->d & ByteOp) ? 1 :
 							   c->op_bytes;
-		/* Don't fetch the address for invlpg: it could be unmapped. */
-		if (c->d & NoAccess)
-			break;
 	srcmem_common:
-		/*
-		 * For instructions with a ModR/M byte, switch to register
-		 * access if Mod = 3.
-		 */
-		if ((c->d & ModRM) && c->modrm_mod == 3) {
-			c->src.type = OP_REG;
-			c->src.val = c->modrm_val;
-			c->src.addr.reg = c->modrm_ptr;
-			break;
-		}
-		c->src.type = OP_MEM;
-		c->src.addr.mem = c->modrm_ea;
-		c->src.val = 0;
+		c->src = memop;
 		break;
 	case SrcImm:
 	case SrcImmU:
@@ -2531,9 +2525,8 @@ done_prefixes:
 		insn_fetch_arr(c->src.valptr, c->src.bytes, c->eip);
 		break;
 	case SrcMemFAddr:
-		c->src.type = OP_MEM;
-		c->src.addr.mem = c->modrm_ea;
-		c->src.bytes = c->op_bytes + 2;
+		memop.bytes = c->op_bytes + 2;
+		goto srcmem_common;
 		break;
 	}
 
@@ -2571,26 +2564,18 @@ done_prefixes:
 		break;
 	case DstMem:
 	case DstMem64:
-		if ((c->d & ModRM) && c->modrm_mod == 3) {
-			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-			c->dst.type = OP_REG;
-			c->dst.val = c->dst.orig_val = c->modrm_val;
-			c->dst.addr.reg = c->modrm_ptr;
-			break;
-		}
-		c->dst.type = OP_MEM;
-		c->dst.addr.mem = c->modrm_ea;
+		c->dst = memop;
 		if ((c->d & DstMask) == DstMem64)
 			c->dst.bytes = 8;
 		else
 			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.val = 0;
-		if (c->d & BitOp) {
+		if (c->dst.type == OP_MEM && (c->d & BitOp)) {
 			unsigned long mask = ~(c->dst.bytes * 8 - 1);
 
 			c->dst.addr.mem = c->dst.addr.mem +
 						   (c->src.val & mask) / 8;
 		}
+		c->dst.orig_val = c->dst.val;
 		break;
 	case DstAcc:
 		c->dst.type = OP_REG;
@@ -2670,11 +2655,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 	}
 
 	if (c->src.type == OP_MEM) {
+		if (c->d & NoAccess)
+			goto no_fetch;
 		rc = read_emulated(ctxt, ops, c->src.addr.mem,
 					c->src.valptr, c->src.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		c->src.orig_val = c->src.val;
+	no_fetch:
+		;
 	}
 
 	if (c->src2.type == OP_MEM) {
-- 
1.7.1


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

* Re: [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand'
  2010-08-01 14:23 ` [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand' Avi Kivity
@ 2010-08-02  7:28   ` Paolo Bonzini
  2010-08-02  7:36     ` Avi Kivity
  0 siblings, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2010-08-02  7:28 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm, Marcelo Tosatti

On 08/01/2010 04:23 PM, Avi Kivity wrote:
>   	if (c->src.type == OP_MEM) {
> +		if (c->d & NoAccess)
> +			goto no_fetch;
>   		rc = read_emulated(ctxt, ops, c->src.addr.mem,
>   					c->src.valptr, c->src.bytes);
>   		if (rc != X86EMUL_CONTINUE)
>   			goto done;
>   		c->src.orig_val = c->src.val;
> +	no_fetch:
> +		;
>   	}

Maybe remove the goto?

	if (c->src.type == OP_MEM && !(c->d & NoAccess)) {
		rc = read_emulated(ctxt, ops, c->src.addr.mem,
				   c->src.valptr, c->src.bytes);
		if (rc != X86EMUL_CONTINUE)
			goto done;
		c->src.orig_val = c->src.val;
	}

Or do you have other plans for it? :)

Thanks,

Paolo

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

* Re: [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand'
  2010-08-02  7:28   ` Paolo Bonzini
@ 2010-08-02  7:36     ` Avi Kivity
  0 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-02  7:36 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kvm, Marcelo Tosatti

  On 08/02/2010 10:28 AM, Paolo Bonzini wrote:
> On 08/01/2010 04:23 PM, Avi Kivity wrote:
>>       if (c->src.type == OP_MEM) {
>> +        if (c->d & NoAccess)
>> +            goto no_fetch;
>>           rc = read_emulated(ctxt, ops, c->src.addr.mem,
>>                       c->src.valptr, c->src.bytes);
>>           if (rc != X86EMUL_CONTINUE)
>>               goto done;
>>           c->src.orig_val = c->src.val;
>> +    no_fetch:
>> +        ;
>>       }
>
> Maybe remove the goto?
>
>     if (c->src.type == OP_MEM && !(c->d & NoAccess)) {
>         rc = read_emulated(ctxt, ops, c->src.addr.mem,
>                    c->src.valptr, c->src.bytes);
>         if (rc != X86EMUL_CONTINUE)
>             goto done;
>         c->src.orig_val = c->src.val;
>     }
>
> Or do you have other plans for it? :)
>

Mostly, keeping the patch as small as possible.  I'll definitely do a 
cleanup pass later.

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


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

* Re: [PATCH 09/15] KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in long mode
  2010-08-01 14:23 ` [PATCH 09/15] KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in long mode Avi Kivity
@ 2010-08-02  7:37   ` Avi Kivity
  0 siblings, 0 replies; 19+ messages in thread
From: Avi Kivity @ 2010-08-02  7:37 UTC (permalink / raw)
  To: kvm, Marcelo Tosatti

  On 08/01/2010 05:23 PM, Avi Kivity wrote:
> Signed-off-by: Avi Kivity<avi@redhat.com>
> ---
>   arch/x86/kvm/emulate.c |    4 ++--
>   1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index d7d95de..d1a6cd7 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -2205,8 +2205,8 @@ static struct opcode twobyte_table[256] = {
>   	/* 0x10 - 0x1F */
>   	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
>   	/* 0x20 - 0x2F */
> -	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
> -	D(ModRM | ImplicitOps | Priv), D(ModRM | Priv),
> +	D(ModRM | ImplicitOps | Priv | Force64), D(ModRM | Priv | Force64),
> +	D(ModRM | ImplicitOps | Priv | Force64), D(ModRM | Priv | Force64),
>   	N, N, N, N,

This is incorrect.  These instructions are either 32 or 64 bit, while 
Force64 is 64-bit in long mode, and 32/16 bits in other modes, depending 
on default operand size and operand size override.

With this fixed, the whole thing passes autotest.

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


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

end of thread, other threads:[~2010-08-02  7:37 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-01 14:23 [PATCH 00/15] More emulator cleanups Avi Kivity
2010-08-01 14:23 ` [PATCH 01/15] KVM: x86 emulator: push segment override out of decode_modrm() Avi Kivity
2010-08-01 14:23 ` [PATCH 02/15] KVM: x86 emulator: use correct type for memory address in operands Avi Kivity
2010-08-01 14:23 ` [PATCH 03/15] KVM: x86 emulator: simplify xchg decode tables Avi Kivity
2010-08-01 14:23 ` [PATCH 04/15] KVM: x86 emulator: use SrcAcc to simplify xchg decoding Avi Kivity
2010-08-01 14:23 ` [PATCH 05/15] KVM: x86 emulator: put register operand fetch into a function Avi Kivity
2010-08-01 14:23 ` [PATCH 06/15] KVM: x86 emulator: drop use_modrm_ea Avi Kivity
2010-08-01 14:23 ` [PATCH 07/15] KVM: x86 emulator: simplify REX.W check Avi Kivity
2010-08-01 14:23 ` [PATCH 08/15] KVM: x86 emulator: introduce Force64 for forcing operand size to 64 bits Avi Kivity
2010-08-01 14:23 ` [PATCH 09/15] KVM: x86 emulator: mark mov cr and mov dr as 64-bit instructions in long mode Avi Kivity
2010-08-02  7:37   ` Avi Kivity
2010-08-01 14:23 ` [PATCH 10/15] KVM: x86 emulator: use struct operand for mov reg,cr and mov cr,reg for reg op Avi Kivity
2010-08-01 14:23 ` [PATCH 11/15] KVM: x86 emulator: use struct operand for mov reg,dr and mov dr,reg " Avi Kivity
2010-08-01 14:23 ` [PATCH 12/15] KVM: x86 emulator: add NoAccess flag for memory instructions that skip access Avi Kivity
2010-08-01 14:23 ` [PATCH 13/15] KVM: x86 emulator: switch LEA to use SrcMem decoding Avi Kivity
2010-08-01 14:23 ` [PATCH 14/15] KVM: x86 emulator: change invlpg emulation to use src.mem.addr Avi Kivity
2010-08-01 14:23 ` [PATCH 15/15] KVM: x86 emulator: Decode memory operands directly into a 'struct operand' Avi Kivity
2010-08-02  7:28   ` Paolo Bonzini
2010-08-02  7:36     ` Avi Kivity

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.