kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] More instruction emulations
@ 2010-08-22 12:18 Avi Kivity
  2010-08-22 12:18 ` [PATCH 01/14] KVM: x86 emulator: pass destination type to ____emulate_2op() Avi Kivity
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Add a bunch of instructions to the emulator.  These are sufficient to make
the BIOS boot.

Avi Kivity (14):
  KVM: x86 emulator: pass destination type to ____emulate_2op()
  KVM: x86 emulator: Use a register for ____emulate_2op() destination
  KVM: x86 emulator: implement DAS (opcode 2F)
  KVM: x86 emulator: implement CALL FAR (FF /3)
  KVM: x86 emulator: add SrcImmU16 operand type
  KVM: x86 emulator: implement RET imm16 (opcode C2)
  KVM: x86 emulator: implement IMUL REG, R/M, imm8 (opcode 6B)
  KVM: x86 emulator: implement IMUL REG, R/M (opcode 0F AF)
  KVM: x86 emulator: remove SrcImplicit
  KVM: x86 emulator: implement RDTSC (opcode 0F 31)
  KVM: x86 emulator: consolidate immediate decode into a function
  KVM: x86 emulator: add Src2Imm decoding
  KVM: x86 emulator: implement IMUL REG, R/M, IMM (opcode 69)
  KVM: x86 emulator: implement CWD (opcode 99)

 arch/x86/kvm/emulate.c |  277 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 220 insertions(+), 57 deletions(-)


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

* [PATCH 01/14] KVM: x86 emulator: pass destination type to ____emulate_2op()
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 02/14] KVM: x86 emulator: Use a register for ____emulate_2op() destination Avi Kivity
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

We'll need it later so we can use a register for the destination.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c37fb01..49bfcc7 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -194,13 +194,13 @@ struct group_dual {
 #define ON64(x)
 #endif
 
-#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix)	\
+#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix, _dsttype) \
 	do {								\
 		__asm__ __volatile__ (					\
 			_PRE_EFLAGS("0", "4", "2")			\
 			_op _suffix " %"_x"3,%1; "			\
 			_POST_EFLAGS("0", "4", "2")			\
-			: "=m" (_eflags), "=m" ((_dst).val),		\
+			: "=m" (_eflags), "=m" (*(_dsttype*)&(_dst).val),\
 			  "=&r" (_tmp)					\
 			: _y ((_src).val), "i" (EFLAGS_MASK));		\
 	} while (0)
@@ -213,13 +213,13 @@ struct group_dual {
 									\
 		switch ((_dst).bytes) {					\
 		case 2:							\
-			____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
+			____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w",u16);\
 			break;						\
 		case 4:							\
-			____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
+			____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l",u32);\
 			break;						\
 		case 8:							\
-			ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
+			ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q",u64)); \
 			break;						\
 		}							\
 	} while (0)
@@ -229,7 +229,7 @@ struct group_dual {
 		unsigned long _tmp;					     \
 		switch ((_dst).bytes) {				             \
 		case 1:							     \
-			____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b");  \
+			____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b",u8); \
 			break;						     \
 		default:						     \
 			__emulate_2op_nobyte(_op, _src, _dst, _eflags,	     \
-- 
1.7.1


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

* [PATCH 02/14] KVM: x86 emulator: Use a register for ____emulate_2op() destination
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
  2010-08-22 12:18 ` [PATCH 01/14] KVM: x86 emulator: pass destination type to ____emulate_2op() Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 03/14] KVM: x86 emulator: implement DAS (opcode 2F) Avi Kivity
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Most x86 two operand instructions allow the destination to be a memory operand,
but IMUL (for example) requires that the destination be a register.  Change
____emulate_2op() to take a register for both source and destination so we
can invoke IMUL.

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 49bfcc7..f6f93b9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -200,7 +200,7 @@ struct group_dual {
 			_PRE_EFLAGS("0", "4", "2")			\
 			_op _suffix " %"_x"3,%1; "			\
 			_POST_EFLAGS("0", "4", "2")			\
-			: "=m" (_eflags), "=m" (*(_dsttype*)&(_dst).val),\
+			: "=m" (_eflags), "+q" (*(_dsttype*)&(_dst).val),\
 			  "=&r" (_tmp)					\
 			: _y ((_src).val), "i" (EFLAGS_MASK));		\
 	} while (0)
-- 
1.7.1


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

* [PATCH 03/14] KVM: x86 emulator: implement DAS (opcode 2F)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
  2010-08-22 12:18 ` [PATCH 01/14] KVM: x86 emulator: pass destination type to ____emulate_2op() Avi Kivity
  2010-08-22 12:18 ` [PATCH 02/14] KVM: x86 emulator: Use a register for ____emulate_2op() destination Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:21   ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 04/14] KVM: x86 emulator: implement CALL FAR (FF /3) Avi Kivity
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index f6f93b9..4cbc884 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2176,6 +2176,40 @@ static int em_push(struct x86_emulate_ctxt *ctxt)
 	return X86EMUL_CONTINUE;
 }
 
+static int em_das(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u8 al, old_al;
+	bool af, cf, old_cf;
+
+	cf = ctxt->eflags & X86_EFLAGS_CF;
+	al = c->dst.val;
+
+	old_al = al;
+	old_cf = cf;
+	cf = false;
+	af = ctxt->eflags & X86_EFLAGS_AF;
+	if ((al & 0x0f) > 9 || af) {
+		al -= 6;
+		cf = old_cf | (al >= 250);
+		af = true;
+	} else {
+		af = false;
+	}
+	if (old_al > 0x99 || old_cf) {
+		al -= 0x60;
+		cf = true;
+	}
+
+	c->dst.val = al;
+	ctxt->eflags &= ~(X86_EFLAGS_AF | X86_EFLAGS_CF);
+	if (cf)
+		ctxt->eflags |= X86_EFLAGS_CF;
+	if (af)
+		ctxt->eflags |= X86_EFLAGS_AF;
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2259,7 +2293,8 @@ static struct opcode opcode_table[256] = {
 	/* 0x28 - 0x2F */
 	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
 	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm), N, N,
+	D(ByteOp | DstAcc | SrcImmByte), D(DstAcc | SrcImm),
+	N, I(ByteOp | DstAcc | No64, em_das),
 	/* 0x30 - 0x37 */
 	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
 	D(ByteOp | DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
-- 
1.7.1


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

* [PATCH 04/14] KVM: x86 emulator: implement CALL FAR (FF /3)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (2 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 03/14] KVM: x86 emulator: implement DAS (opcode 2F) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 05/14] KVM: x86 emulator: add SrcImmU16 operand type Avi Kivity
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4cbc884..34c4196 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2210,6 +2210,40 @@ static int em_das(struct x86_emulate_ctxt *ctxt)
 	return X86EMUL_CONTINUE;
 }
 
+static int em_call_far(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u16 sel, old_cs;
+	ulong old_eip;
+	int rc;
+
+	old_cs = ctxt->ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
+	old_eip = c->eip;
+
+	memcpy(&sel, c->src.valptr + c->op_bytes, 2);
+	if (load_segment_descriptor(ctxt, ctxt->ops, sel, VCPU_SREG_CS))
+		return X86EMUL_CONTINUE;
+
+	c->eip = 0;
+	memcpy(&c->eip, c->src.valptr, c->op_bytes);
+
+	c->src.val = old_cs;
+	emulate_push(ctxt, ctxt->ops);
+	rc = writeback(ctxt, ctxt->ops);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+
+	c->src.val = old_eip;
+	emulate_push(ctxt, ctxt->ops);
+	rc = writeback(ctxt, ctxt->ops);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+
+	c->dst.type = OP_NONE;
+
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2237,7 +2271,8 @@ static struct opcode group4[] = {
 
 static struct opcode group5[] = {
 	D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock),
-	D(SrcMem | ModRM | Stack), N,
+	D(SrcMem | ModRM | Stack),
+	I(SrcMemFAddr | ModRM | ImplicitOps | Stack, em_call_far),
 	D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps),
 	D(SrcMem | ModRM | Stack), N,
 };
-- 
1.7.1


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

* [PATCH 05/14] KVM: x86 emulator: add SrcImmU16 operand type
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (3 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 04/14] KVM: x86 emulator: implement CALL FAR (FF /3) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 06/14] KVM: x86 emulator: implement RET imm16 (opcode C2) Avi Kivity
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Used for RET NEAR instructions.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 34c4196..67e8eed 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -72,6 +72,7 @@
 #define SrcImmFAddr (0xb<<4)	/* Source is immediate far address */
 #define SrcMemFAddr (0xc<<4)	/* Source is far address in memory */
 #define SrcAcc      (0xd<<4)	/* Source Accumulator */
+#define SrcImmU16   (0xe<<4)    /* Immediate operand, unsigned, 16 bits */
 #define SrcMask     (0xf<<4)
 /* Generic ModRM decode. */
 #define ModRM       (1<<8)
@@ -2674,13 +2675,17 @@ done_prefixes:
 	srcmem_common:
 		c->src = memop;
 		break;
+	case SrcImmU16:
+		c->src.bytes = 2;
+		goto srcimm;
 	case SrcImm:
 	case SrcImmU:
-		c->src.type = OP_IMM;
-		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;
+	srcimm:
+		c->src.type = OP_IMM;
+		c->src.addr.mem = c->eip;
 		/* NB. Immediates are sign-extended as necessary. */
 		switch (c->src.bytes) {
 		case 1:
@@ -2693,7 +2698,8 @@ done_prefixes:
 			c->src.val = insn_fetch(s32, 4, c->eip);
 			break;
 		}
-		if ((c->d & SrcMask) == SrcImmU) {
+		if ((c->d & SrcMask) == SrcImmU
+		    || (c->d & SrcMask) == SrcImmU16) {
 			switch (c->src.bytes) {
 			case 1:
 				c->src.val &= 0xff;
-- 
1.7.1


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

* [PATCH 06/14] KVM: x86 emulator: implement RET imm16 (opcode C2)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (4 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 05/14] KVM: x86 emulator: add SrcImmU16 operand type Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 07/14] KVM: x86 emulator: implement IMUL REG, R/M, imm8 (opcode 6B) Avi Kivity
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 67e8eed..6ef4b22 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2245,6 +2245,21 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
 	return X86EMUL_CONTINUE;
 }
 
+static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	c->dst.type = OP_REG;
+	c->dst.addr.reg = &c->eip;
+	c->dst.bytes = c->op_bytes;
+	rc = emulate_pop(ctxt, ctxt->ops, &c->dst.val, c->op_bytes);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->src.val);
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2390,7 +2405,9 @@ static struct opcode opcode_table[256] = {
 	X8(D(DstReg | SrcImm | Mov)),
 	/* 0xC0 - 0xC7 */
 	D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM),
-	N, D(ImplicitOps | Stack), N, N,
+	I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
+	D(ImplicitOps | Stack),
+	N, N,
 	D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov),
 	/* 0xC8 - 0xCF */
 	N, N, N, D(ImplicitOps | Stack),
-- 
1.7.1


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

* [PATCH 07/14] KVM: x86 emulator: implement IMUL REG, R/M, imm8 (opcode 6B)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (5 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 06/14] KVM: x86 emulator: implement RET imm16 (opcode C2) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 08/14] KVM: x86 emulator: implement IMUL REG, R/M (opcode 0F AF) Avi Kivity
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 6ef4b22..ae72835 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2260,6 +2260,15 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
 	return X86EMUL_CONTINUE;
 }
 
+static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.val = c->src2.val;
+	emulate_2op_SrcV_nobyte("imul", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2367,7 +2376,8 @@ static struct opcode opcode_table[256] = {
 	N, N, N, N,
 	/* 0x68 - 0x6F */
 	I(SrcImm | Mov | Stack, em_push), N,
-	I(SrcImmByte | Mov | Stack, em_push), N,
+	I(SrcImmByte | Mov | Stack, em_push),
+	I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
 	D(DstDI | ByteOp | Mov | String), D(DstDI | Mov | String), /* insb, insw/insd */
 	D(SrcSI | ByteOp | ImplicitOps | String), D(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
 	/* 0x70 - 0x7F */
-- 
1.7.1


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

* [PATCH 08/14] KVM: x86 emulator: implement IMUL REG, R/M (opcode 0F AF)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (6 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 07/14] KVM: x86 emulator: implement IMUL REG, R/M, imm8 (opcode 6B) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 09/14] KVM: x86 emulator: remove SrcImplicit Avi Kivity
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ae72835..7574d1e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2260,15 +2260,22 @@ static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
 	return X86EMUL_CONTINUE;
 }
 
-static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
+static int em_imul(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 
-	c->dst.val = c->src2.val;
 	emulate_2op_SrcV_nobyte("imul", c->src, c->dst, ctxt->eflags);
 	return X86EMUL_CONTINUE;
 }
 
+static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.val = c->src2.val;
+	return em_imul(ctxt);
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2484,7 +2491,7 @@ static struct opcode twobyte_table[256] = {
 	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
 	D(DstMem | SrcReg | Src2ImmByte | ModRM),
 	D(DstMem | SrcReg | Src2CL | ModRM),
-	D(ModRM), N,
+	D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
 	/* 0xB0 - 0xB7 */
 	D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
 	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
-- 
1.7.1


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

* [PATCH 09/14] KVM: x86 emulator: remove SrcImplicit
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (7 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 08/14] KVM: x86 emulator: implement IMUL REG, R/M (opcode 0F AF) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 10/14] KVM: x86 emulator: implement RDTSC (opcode 0F 31) Avi Kivity
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Useless.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 7574d1e..e83b9fc 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -58,7 +58,6 @@
 #define DstMask     (7<<1)
 /* Source operand type. */
 #define SrcNone     (0<<4)	/* No source operand. */
-#define SrcImplicit (0<<4)	/* Source operand is implicit in the opcode. */
 #define SrcReg      (1<<4)	/* Register operand. */
 #define SrcMem      (2<<4)	/* Memory operand. */
 #define SrcMem16    (3<<4)	/* Memory operand (16-bit). */
@@ -2431,7 +2430,7 @@ static struct opcode opcode_table[256] = {
 	D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
 	/* 0xD0 - 0xD7 */
 	D(ByteOp | DstMem | SrcOne | ModRM), D(DstMem | SrcOne | ModRM),
-	D(ByteOp | DstMem | SrcImplicit | ModRM), D(DstMem | SrcImplicit | ModRM),
+	D(ByteOp | DstMem | ModRM), D(DstMem | ModRM),
 	N, N, N, N,
 	/* 0xD8 - 0xDF */
 	N, N, N, N, N, N, N, N,
-- 
1.7.1


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

* [PATCH 10/14] KVM: x86 emulator: implement RDTSC (opcode 0F 31)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (8 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 09/14] KVM: x86 emulator: remove SrcImplicit Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 11/14] KVM: x86 emulator: consolidate immediate decode into a function Avi Kivity
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index e83b9fc..09bec0c 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2275,6 +2275,22 @@ static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
 	return em_imul(ctxt);
 }
 
+static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
+{
+	unsigned cpl = ctxt->ops->cpl(ctxt->vcpu);
+	struct decode_cache *c = &ctxt->decode;
+	u64 tsc = 0;
+
+	if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD)) {
+		emulate_gp(ctxt, 0);
+		return X86EMUL_PROPAGATE_FAULT;
+	}
+	ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc);
+	c->regs[VCPU_REGS_RAX] = (u32)tsc;
+	c->regs[VCPU_REGS_RDX] = tsc >> 32;
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
@@ -2465,7 +2481,8 @@ static struct opcode twobyte_table[256] = {
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
-	D(ImplicitOps | Priv), N, D(ImplicitOps | Priv), N,
+	D(ImplicitOps | Priv), I(ImplicitOps, em_rdtsc),
+	D(ImplicitOps | Priv), N,
 	D(ImplicitOps), D(ImplicitOps | Priv), N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x40 - 0x4F */
-- 
1.7.1


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

* [PATCH 11/14] KVM: x86 emulator: consolidate immediate decode into a function
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (9 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 10/14] KVM: x86 emulator: implement RDTSC (opcode 0F 31) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 12/14] KVM: x86 emulator: add Src2Imm decoding Avi Kivity
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 09bec0c..3cf9c02 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2537,6 +2537,55 @@ static struct opcode twobyte_table[256] = {
 #undef GD
 #undef I
 
+static unsigned imm_size(struct decode_cache *c)
+{
+	unsigned size;
+
+	size = (c->d & ByteOp) ? 1 : c->op_bytes;
+	if (size == 8)
+		size = 4;
+	return size;
+}
+
+static int decode_imm(struct x86_emulate_ctxt *ctxt, struct operand *op,
+		      unsigned size, bool sign_extension)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct x86_emulate_ops *ops = ctxt->ops;
+	int rc = X86EMUL_CONTINUE;
+
+	op->type = OP_IMM;
+	op->bytes = size;
+	op->addr.mem = c->eip;
+	/* NB. Immediates are sign-extended as necessary. */
+	switch (op->bytes) {
+	case 1:
+		op->val = insn_fetch(s8, 1, c->eip);
+		break;
+	case 2:
+		op->val = insn_fetch(s16, 2, c->eip);
+		break;
+	case 4:
+		op->val = insn_fetch(s32, 4, c->eip);
+		break;
+	}
+	if (!sign_extension) {
+		switch (op->bytes) {
+		case 1:
+			op->val &= 0xff;
+			break;
+		case 2:
+			op->val &= 0xffff;
+			break;
+		case 4:
+			op->val &= 0xffffffff;
+			break;
+		}
+	}
+done:
+	return rc;
+}
+
 int
 x86_decode_insn(struct x86_emulate_ctxt *ctxt)
 {
@@ -2726,52 +2775,19 @@ done_prefixes:
 		c->src = memop;
 		break;
 	case SrcImmU16:
-		c->src.bytes = 2;
-		goto srcimm;
+		rc = decode_imm(ctxt, &c->src, 2, false);
+		break;
 	case SrcImm:
+		rc = decode_imm(ctxt, &c->src, imm_size(c), true);
+		break;
 	case SrcImmU:
-		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		if (c->src.bytes == 8)
-			c->src.bytes = 4;
-	srcimm:
-		c->src.type = OP_IMM;
-		c->src.addr.mem = c->eip;
-		/* NB. Immediates are sign-extended as necessary. */
-		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;
-		}
-		if ((c->d & SrcMask) == SrcImmU
-		    || (c->d & SrcMask) == SrcImmU16) {
-			switch (c->src.bytes) {
-			case 1:
-				c->src.val &= 0xff;
-				break;
-			case 2:
-				c->src.val &= 0xffff;
-				break;
-			case 4:
-				c->src.val &= 0xffffffff;
-				break;
-			}
-		}
+		rc = decode_imm(ctxt, &c->src, imm_size(c), false);
 		break;
 	case SrcImmByte:
+		rc = decode_imm(ctxt, &c->src, 1, true);
+		break;
 	case SrcImmUByte:
-		c->src.type = OP_IMM;
-		c->src.addr.mem = c->eip;
-		c->src.bytes = 1;
-		if ((c->d & SrcMask) == SrcImmByte)
-			c->src.val = insn_fetch(s8, 1, c->eip);
-		else
-			c->src.val = insn_fetch(u8, 1, c->eip);
+		rc = decode_imm(ctxt, &c->src, 1, false);
 		break;
 	case SrcAcc:
 		c->src.type = OP_REG;
@@ -2803,6 +2819,9 @@ done_prefixes:
 		break;
 	}
 
+	if (rc != X86EMUL_CONTINUE)
+		goto done;
+
 	/*
 	 * Decode and fetch the second source operand: register, memory
 	 * or immediate.
@@ -2815,10 +2834,7 @@ done_prefixes:
 		c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
 		break;
 	case Src2ImmByte:
-		c->src2.type = OP_IMM;
-		c->src2.addr.mem = c->eip;
-		c->src2.bytes = 1;
-		c->src2.val = insn_fetch(u8, 1, c->eip);
+		rc = decode_imm(ctxt, &c->src2, 1, true);
 		break;
 	case Src2One:
 		c->src2.bytes = 1;
@@ -2826,6 +2842,9 @@ done_prefixes:
 		break;
 	}
 
+	if (rc != X86EMUL_CONTINUE)
+		goto done;
+
 	/* Decode and fetch the destination operand: register or memory. */
 	switch (c->d & DstMask) {
 	case DstReg:
-- 
1.7.1


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

* [PATCH 12/14] KVM: x86 emulator: add Src2Imm decoding
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (10 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 11/14] KVM: x86 emulator: consolidate immediate decode into a function Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 13/14] KVM: x86 emulator: implement IMUL REG, R/M, IMM (opcode 69) Avi Kivity
  2010-08-22 12:18 ` [PATCH 14/14] KVM: x86 emulator: implement CWD (opcode 99) Avi Kivity
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

Needed for 3-operand IMUL.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 3cf9c02..3365511 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -95,6 +95,7 @@
 #define Src2CL      (1<<29)
 #define Src2ImmByte (2<<29)
 #define Src2One     (3<<29)
+#define Src2Imm     (4<<29)
 #define Src2Mask    (7<<29)
 
 #define X2(x...) x, x
@@ -2840,6 +2841,9 @@ done_prefixes:
 		c->src2.bytes = 1;
 		c->src2.val = 1;
 		break;
+	case Src2Imm:
+		rc = decode_imm(ctxt, &c->src2, imm_size(c), true);
+		break;
 	}
 
 	if (rc != X86EMUL_CONTINUE)
-- 
1.7.1


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

* [PATCH 13/14] KVM: x86 emulator: implement IMUL REG, R/M, IMM (opcode 69)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (11 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 12/14] KVM: x86 emulator: add Src2Imm decoding Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  2010-08-22 12:18 ` [PATCH 14/14] KVM: x86 emulator: implement CWD (opcode 99) Avi Kivity
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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 3365511..d4ec010 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2398,7 +2398,8 @@ static struct opcode opcode_table[256] = {
 	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
 	N, N, N, N,
 	/* 0x68 - 0x6F */
-	I(SrcImm | Mov | Stack, em_push), N,
+	I(SrcImm | Mov | Stack, em_push),
+	I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
 	I(SrcImmByte | Mov | Stack, em_push),
 	I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
 	D(DstDI | ByteOp | Mov | String), D(DstDI | Mov | String), /* insb, insw/insd */
-- 
1.7.1


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

* [PATCH 14/14] KVM: x86 emulator: implement CWD (opcode 99)
  2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
                   ` (12 preceding siblings ...)
  2010-08-22 12:18 ` [PATCH 13/14] KVM: x86 emulator: implement IMUL REG, R/M, IMM (opcode 69) Avi Kivity
@ 2010-08-22 12:18 ` Avi Kivity
  13 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:18 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d4ec010..f512ba7 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2276,6 +2276,18 @@ static int em_imul_3op(struct x86_emulate_ctxt *ctxt)
 	return em_imul(ctxt);
 }
 
+static int em_cwd(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.type = OP_REG;
+	c->dst.bytes = c->src.bytes;
+	c->dst.addr.reg = &c->regs[VCPU_REGS_RDX];
+	c->dst.val = ~((c->src.val >> (c->src.bytes * 8 - 1)) - 1);
+
+	return X86EMUL_CONTINUE;
+}
+
 static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
 {
 	unsigned cpl = ctxt->ops->cpl(ctxt->vcpu);
@@ -2421,7 +2433,8 @@ static struct opcode opcode_table[256] = {
 	/* 0x90 - 0x97 */
 	X8(D(SrcAcc | DstReg)),
 	/* 0x98 - 0x9F */
-	D(DstAcc | SrcNone), N, D(SrcImmFAddr | No64), N,
+	D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd),
+	D(SrcImmFAddr | No64), N,
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
 	/* 0xA0 - 0xA7 */
 	D(ByteOp | DstAcc | SrcMem | Mov | MemAbs), D(DstAcc | SrcMem | Mov | MemAbs),
-- 
1.7.1


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

* Re: [PATCH 03/14] KVM: x86 emulator: implement DAS (opcode 2F)
  2010-08-22 12:18 ` [PATCH 03/14] KVM: x86 emulator: implement DAS (opcode 2F) Avi Kivity
@ 2010-08-22 12:21   ` Avi Kivity
  0 siblings, 0 replies; 16+ messages in thread
From: Avi Kivity @ 2010-08-22 12:21 UTC (permalink / raw)
  To: Marcelo Tosatti, kvm

  On 08/22/2010 03:18 PM, Avi Kivity wrote:
> Signed-off-by: Avi Kivity<avi@redhat.com>
> ---
>   arch/x86/kvm/emulate.c |   37 ++++++++++++++++++++++++++++++++++++-
>   1 files changed, 36 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index f6f93b9..4cbc884 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -2176,6 +2176,40 @@ static int em_push(struct x86_emulate_ctxt *ctxt)
>   	return X86EMUL_CONTINUE;
>   }
>
> +static int em_das(struct x86_emulate_ctxt *ctxt)
> +{
> +	struct decode_cache *c =&ctxt->decode;
> +	u8 al, old_al;
> +	bool af, cf, old_cf;
> +
> +	cf = ctxt->eflags&  X86_EFLAGS_CF;
> +	al = c->dst.val;
> +
> +	old_al = al;
> +	old_cf = cf;
> +	cf = false;
> +	af = ctxt->eflags&  X86_EFLAGS_AF;
> +	if ((al&  0x0f)>  9 || af) {
> +		al -= 6;
> +		cf = old_cf | (al>= 250);
> +		af = true;
> +	} else {
> +		af = false;
> +	}
> +	if (old_al>  0x99 || old_cf) {
> +		al -= 0x60;
> +		cf = true;
> +	}
> +
> +	c->dst.val = al;
> +	ctxt->eflags&= ~(X86_EFLAGS_AF | X86_EFLAGS_CF);
> +	if (cf)
> +		ctxt->eflags |= X86_EFLAGS_CF;
> +	if (af)
> +		ctxt->eflags |= X86_EFLAGS_AF;
> +	return X86EMUL_CONTINUE;
> +}
> +

Missing the following hunk:

      }

      c->dst.val = al;
+    /* Set PF, ZF, SF */
+    c->src.type = OP_IMM;
+    c->src.val = 0;
+    c->src.bytes = 1;
+    emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
      ctxt->eflags &= ~(X86_EFLAGS_AF | X86_EFLAGS_CF);
      if (cf)
          ctxt->eflags |= X86_EFLAGS_CF;


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


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

end of thread, other threads:[~2010-08-22 12:21 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-22 12:18 [PATCH 00/14] More instruction emulations Avi Kivity
2010-08-22 12:18 ` [PATCH 01/14] KVM: x86 emulator: pass destination type to ____emulate_2op() Avi Kivity
2010-08-22 12:18 ` [PATCH 02/14] KVM: x86 emulator: Use a register for ____emulate_2op() destination Avi Kivity
2010-08-22 12:18 ` [PATCH 03/14] KVM: x86 emulator: implement DAS (opcode 2F) Avi Kivity
2010-08-22 12:21   ` Avi Kivity
2010-08-22 12:18 ` [PATCH 04/14] KVM: x86 emulator: implement CALL FAR (FF /3) Avi Kivity
2010-08-22 12:18 ` [PATCH 05/14] KVM: x86 emulator: add SrcImmU16 operand type Avi Kivity
2010-08-22 12:18 ` [PATCH 06/14] KVM: x86 emulator: implement RET imm16 (opcode C2) Avi Kivity
2010-08-22 12:18 ` [PATCH 07/14] KVM: x86 emulator: implement IMUL REG, R/M, imm8 (opcode 6B) Avi Kivity
2010-08-22 12:18 ` [PATCH 08/14] KVM: x86 emulator: implement IMUL REG, R/M (opcode 0F AF) Avi Kivity
2010-08-22 12:18 ` [PATCH 09/14] KVM: x86 emulator: remove SrcImplicit Avi Kivity
2010-08-22 12:18 ` [PATCH 10/14] KVM: x86 emulator: implement RDTSC (opcode 0F 31) Avi Kivity
2010-08-22 12:18 ` [PATCH 11/14] KVM: x86 emulator: consolidate immediate decode into a function Avi Kivity
2010-08-22 12:18 ` [PATCH 12/14] KVM: x86 emulator: add Src2Imm decoding Avi Kivity
2010-08-22 12:18 ` [PATCH 13/14] KVM: x86 emulator: implement IMUL REG, R/M, IMM (opcode 69) Avi Kivity
2010-08-22 12:18 ` [PATCH 14/14] KVM: x86 emulator: implement CWD (opcode 99) Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).