* [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).