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