* [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions
@ 2011-11-22 6:15 Takuya Yoshikawa
2011-11-22 6:16 ` [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT Takuya Yoshikawa
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:15 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
This patch set eats the remaining spaghetti in the emulator and
cleans up the large plate.
After this, only trivial cases will be there.
Passed emulator.flat test:
SUMMARY: 90 tests, 0 failures
Thanks,
Takuya
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
@ 2011-11-22 6:16 ` Takuya Yoshikawa
2011-11-22 10:49 ` Avi Kivity
2011-11-22 6:17 ` [PATCH 2/7] KVM: x86 emulator: Use opcode::execute for BT family Takuya Yoshikawa
` (5 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:16 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
IN : E4, E5, EC, ED
OUT: E6, E7, EE, EF
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 54 ++++++++++++++++++++++++-----------------------
1 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8547958..8ba4ea8 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2776,6 +2776,24 @@ static int em_jcxz(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_in(struct x86_emulate_ctxt *ctxt)
+{
+ if (!pio_in_emulated(ctxt, ctxt->dst.bytes, ctxt->src.val,
+ &ctxt->dst.val))
+ return X86EMUL_IO_NEEDED;
+
+ return X86EMUL_CONTINUE;
+}
+
+static int em_out(struct x86_emulate_ctxt *ctxt)
+{
+ ctxt->ops->pio_out_emulated(ctxt, ctxt->src.bytes, ctxt->dst.val,
+ &ctxt->src.val, 1);
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
+ return X86EMUL_CONTINUE;
+}
+
static int em_cli(struct x86_emulate_ctxt *ctxt)
{
if (emulator_bad_iopl(ctxt))
@@ -3004,6 +3022,8 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
#define D2bv(_f) D((_f) | ByteOp), D(_f)
#define D2bvIP(_f, _i, _p) DIP((_f) | ByteOp, _i, _p), DIP(_f, _i, _p)
#define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e)
+#define I2bvIP(_f, _e, _i, _p) \
+ IIP((_f) | ByteOp, _e, _i, _p), IIP(_f, _e, _i, _p)
#define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e), \
I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \
@@ -3217,13 +3237,13 @@ static struct opcode opcode_table[256] = {
/* 0xE0 - 0xE7 */
X3(I(SrcImmByte, em_loop)),
I(SrcImmByte, em_jcxz),
- D2bvIP(SrcImmUByte | DstAcc, in, check_perm_in),
- D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out),
+ I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in),
+ I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out),
/* 0xE8 - 0xEF */
D(SrcImm | Stack), D(SrcImm | ImplicitOps),
I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps),
- D2bvIP(SrcDX | DstAcc, in, check_perm_in),
- D2bvIP(SrcAcc | DstDX, out, check_perm_out),
+ I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in),
+ I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out),
/* 0xF0 - 0xF7 */
N, DI(ImplicitOps, icebp), N, N,
DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
@@ -3325,6 +3345,7 @@ static struct opcode twobyte_table[256] = {
#undef D2bv
#undef D2bvIP
#undef I2bv
+#undef I2bvIP
#undef I6ALU
static unsigned imm_size(struct x86_emulate_ctxt *ctxt)
@@ -3867,11 +3888,12 @@ special_insn:
case 0x6c: /* insb */
case 0x6d: /* insw/insd */
ctxt->src.val = ctxt->regs[VCPU_REGS_RDX];
- goto do_io_in;
+ rc = em_in(ctxt);
+ break;
case 0x6e: /* outsb */
case 0x6f: /* outsw/outsd */
ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX];
- goto do_io_out;
+ rc = em_out(ctxt);
break;
case 0x70 ... 0x7f: /* jcc (short) */
if (test_cc(ctxt->b, ctxt->eflags))
@@ -3915,12 +3937,6 @@ special_insn:
ctxt->src.val = ctxt->regs[VCPU_REGS_RCX];
rc = em_grp2(ctxt);
break;
- case 0xe4: /* inb */
- case 0xe5: /* in */
- goto do_io_in;
- case 0xe6: /* outb */
- case 0xe7: /* out */
- goto do_io_out;
case 0xe8: /* call (near) */ {
long int rel = ctxt->src.val;
ctxt->src.val = (unsigned long) ctxt->_eip;
@@ -3933,20 +3949,6 @@ special_insn:
jmp_rel(ctxt, ctxt->src.val);
ctxt->dst.type = OP_NONE; /* Disable writeback. */
break;
- case 0xec: /* in al,dx */
- case 0xed: /* in (e/r)ax,dx */
- do_io_in:
- if (!pio_in_emulated(ctxt, ctxt->dst.bytes, ctxt->src.val,
- &ctxt->dst.val))
- goto done; /* IO is needed */
- break;
- case 0xee: /* out dx,al */
- case 0xef: /* out dx,(e/r)ax */
- do_io_out:
- ops->pio_out_emulated(ctxt, ctxt->src.bytes, ctxt->dst.val,
- &ctxt->src.val, 1);
- ctxt->dst.type = OP_NONE; /* Disable writeback. */
- break;
case 0xf4: /* hlt */
ctxt->ops->halt(ctxt);
break;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/7] KVM: x86 emulator: Use opcode::execute for BT family
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
2011-11-22 6:16 ` [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT Takuya Yoshikawa
@ 2011-11-22 6:17 ` Takuya Yoshikawa
2011-11-22 6:18 ` [PATCH 3/7] KVM: x86 emulator: Use opcode::execute for CALL Takuya Yoshikawa
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:17 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
BT : 0F A3
BTS: 0F AB
BTR: 0F B3
BTC: 0F BB
Group 8: 0F BA
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 77 +++++++++++++++++++++++------------------------
1 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8ba4ea8..7a9ce6d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2813,6 +2813,35 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_bt(struct x86_emulate_ctxt *ctxt)
+{
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
+ /* only subword offset */
+ ctxt->src.val &= (ctxt->dst.bytes << 3) - 1;
+
+ emulate_2op_SrcV_nobyte(ctxt, "bt");
+ return X86EMUL_CONTINUE;
+}
+
+static int em_bts(struct x86_emulate_ctxt *ctxt)
+{
+ emulate_2op_SrcV_nobyte(ctxt, "bts");
+ return X86EMUL_CONTINUE;
+}
+
+static int em_btr(struct x86_emulate_ctxt *ctxt)
+{
+ emulate_2op_SrcV_nobyte(ctxt, "btr");
+ return X86EMUL_CONTINUE;
+}
+
+static int em_btc(struct x86_emulate_ctxt *ctxt)
+{
+ emulate_2op_SrcV_nobyte(ctxt, "btc");
+ return X86EMUL_CONTINUE;
+}
+
static bool valid_cr(int nr)
{
switch (nr) {
@@ -3117,10 +3146,10 @@ static struct group_dual group7 = { {
static struct opcode group8[] = {
N, N, N, N,
- D(DstMem | SrcImmByte | ModRM),
- D(DstMem | SrcImmByte | ModRM | Lock | PageTable),
- D(DstMem | SrcImmByte | ModRM | Lock),
- D(DstMem | SrcImmByte | ModRM | Lock | PageTable),
+ I(DstMem | SrcImmByte | ModRM, em_bt),
+ I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_bts),
+ I(DstMem | SrcImmByte | ModRM | Lock, em_btr),
+ I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_btc),
};
static struct group_dual group9 = { {
@@ -3299,26 +3328,27 @@ static struct opcode twobyte_table[256] = {
X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)),
/* 0xA0 - 0xA7 */
I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg),
- DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp),
+ DI(ImplicitOps, cpuid), I(DstMem | SrcReg | ModRM | BitOp, em_bt),
D(DstMem | SrcReg | Src2ImmByte | ModRM),
D(DstMem | SrcReg | Src2CL | ModRM), N, N,
/* 0xA8 - 0xAF */
I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
DI(ImplicitOps, rsm),
- D(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable),
+ I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
D(DstMem | SrcReg | Src2ImmByte | ModRM),
D(DstMem | SrcReg | Src2CL | ModRM),
D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
/* 0xB0 - 0xB7 */
D2bv(DstMem | SrcReg | ModRM | Lock | PageTable),
I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
- D(DstMem | SrcReg | ModRM | BitOp | Lock),
+ I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg),
D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
/* 0xB8 - 0xBF */
N, N,
- G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable),
+ G(BitOp, group8),
+ I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
/* 0xC0 - 0xCF */
@@ -4103,21 +4133,10 @@ twobyte_insn:
case 0x90 ... 0x9f: /* setcc r/m8 */
ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
break;
- case 0xa3:
- bt: /* bt */
- ctxt->dst.type = OP_NONE;
- /* only subword offset */
- ctxt->src.val &= (ctxt->dst.bytes << 3) - 1;
- emulate_2op_SrcV_nobyte(ctxt, "bt");
- break;
case 0xa4: /* shld imm8, r, r/m */
case 0xa5: /* shld cl, r, r/m */
emulate_2op_cl(ctxt, "shld");
break;
- case 0xab:
- bts: /* bts */
- emulate_2op_SrcV_nobyte(ctxt, "bts");
- break;
case 0xac: /* shrd imm8, r, r/m */
case 0xad: /* shrd cl, r, r/m */
emulate_2op_cl(ctxt, "shrd");
@@ -4141,31 +4160,11 @@ twobyte_insn:
ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
}
break;
- case 0xb3:
- btr: /* btr */
- emulate_2op_SrcV_nobyte(ctxt, "btr");
- break;
case 0xb6 ... 0xb7: /* movzx */
ctxt->dst.bytes = ctxt->op_bytes;
ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val
: (u16) ctxt->src.val;
break;
- case 0xba: /* Grp8 */
- switch (ctxt->modrm_reg & 3) {
- case 0:
- goto bt;
- case 1:
- goto bts;
- case 2:
- goto btr;
- case 3:
- goto btc;
- }
- break;
- case 0xbb:
- btc: /* btc */
- emulate_2op_SrcV_nobyte(ctxt, "btc");
- break;
case 0xbc: { /* bsf */
u8 zf;
__asm__ ("bsf %2, %0; setz %1"
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/7] KVM: x86 emulator: Use opcode::execute for CALL
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
2011-11-22 6:16 ` [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT Takuya Yoshikawa
2011-11-22 6:17 ` [PATCH 2/7] KVM: x86 emulator: Use opcode::execute for BT family Takuya Yoshikawa
@ 2011-11-22 6:18 ` Takuya Yoshikawa
2011-11-22 6:19 ` [PATCH 4/7] KVM: x86 emulator: Use opcode::execute for MOV to cr/dr Takuya Yoshikawa
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:18 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
CALL: E8
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 7a9ce6d..6b7a03b 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2482,6 +2482,15 @@ static int em_das(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_call(struct x86_emulate_ctxt *ctxt)
+{
+ long rel = ctxt->src.val;
+
+ ctxt->src.val = (unsigned long)ctxt->_eip;
+ jmp_rel(ctxt, rel);
+ return em_push(ctxt);
+}
+
static int em_call_far(struct x86_emulate_ctxt *ctxt)
{
u16 sel, old_cs;
@@ -3269,7 +3278,7 @@ static struct opcode opcode_table[256] = {
I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in),
I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out),
/* 0xE8 - 0xEF */
- D(SrcImm | Stack), D(SrcImm | ImplicitOps),
+ I(SrcImm | Stack, em_call), D(SrcImm | ImplicitOps),
I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps),
I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in),
I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out),
@@ -3967,13 +3976,6 @@ special_insn:
ctxt->src.val = ctxt->regs[VCPU_REGS_RCX];
rc = em_grp2(ctxt);
break;
- case 0xe8: /* call (near) */ {
- long int rel = ctxt->src.val;
- ctxt->src.val = (unsigned long) ctxt->_eip;
- jmp_rel(ctxt, rel);
- rc = em_push(ctxt);
- break;
- }
case 0xe9: /* jmp rel */
case 0xeb: /* jmp rel short */
jmp_rel(ctxt, ctxt->src.val);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/7] KVM: x86 emulator: Use opcode::execute for MOV to cr/dr
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
` (2 preceding siblings ...)
2011-11-22 6:18 ` [PATCH 3/7] KVM: x86 emulator: Use opcode::execute for CALL Takuya Yoshikawa
@ 2011-11-22 6:19 ` Takuya Yoshikawa
2011-11-22 6:20 ` [PATCH 5/7] KVM: x86 emulator: Use opcode::execute for WRMSR/RDMSR Takuya Yoshikawa
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:19 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
MOV: 0F 22 (move to control registers)
MOV: 0F 23 (move to debug registers)
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 52 +++++++++++++++++++++++++++--------------------
1 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 6b7a03b..7fe5ed1 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2638,6 +2638,34 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_cr_write(struct x86_emulate_ctxt *ctxt)
+{
+ if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
+ return emulate_gp(ctxt, 0);
+
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
+ return X86EMUL_CONTINUE;
+}
+
+static int em_dr_write(struct x86_emulate_ctxt *ctxt)
+{
+ unsigned long val;
+
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
+ val = ctxt->src.val & ~0ULL;
+ else
+ val = ctxt->src.val & ~0U;
+
+ /* #UD condition is already handled. */
+ if (ctxt->ops->set_dr(ctxt, ctxt->modrm_reg, val) < 0)
+ return emulate_gp(ctxt, 0);
+
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
+ return X86EMUL_CONTINUE;
+}
+
static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt)
{
if (ctxt->modrm_reg > VCPU_SREG_GS)
@@ -3304,8 +3332,8 @@ static struct opcode twobyte_table[256] = {
/* 0x20 - 0x2F */
DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read),
DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read),
- DIP(ModRM | SrcMem | Priv | Op3264, cr_write, check_cr_write),
- DIP(ModRM | SrcMem | Priv | Op3264, dr_write, check_dr_write),
+ IIP(ModRM | SrcMem | Priv | Op3264, em_cr_write, cr_write, check_cr_write),
+ IIP(ModRM | SrcMem | Priv | Op3264, em_dr_write, dr_write, check_dr_write),
N, N, N, N,
N, N, N, N, N, N, N, N,
/* 0x30 - 0x3F */
@@ -4080,26 +4108,6 @@ twobyte_insn:
case 0x21: /* mov from dr to reg */
ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val);
break;
- case 0x22: /* mov reg, cr */
- if (ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) {
- emulate_gp(ctxt, 0);
- rc = X86EMUL_PROPAGATE_FAULT;
- goto done;
- }
- ctxt->dst.type = OP_NONE;
- break;
- case 0x23: /* mov from reg to dr */
- if (ops->set_dr(ctxt, ctxt->modrm_reg, ctxt->src.val &
- ((ctxt->mode == X86EMUL_MODE_PROT64) ?
- ~0ULL : ~0U)) < 0) {
- /* #UD condition is already handled by the code above */
- emulate_gp(ctxt, 0);
- rc = X86EMUL_PROPAGATE_FAULT;
- goto done;
- }
-
- ctxt->dst.type = OP_NONE; /* no writeback */
- break;
case 0x30:
/* wrmsr */
msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/7] KVM: x86 emulator: Use opcode::execute for WRMSR/RDMSR
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
` (3 preceding siblings ...)
2011-11-22 6:19 ` [PATCH 4/7] KVM: x86 emulator: Use opcode::execute for MOV to cr/dr Takuya Yoshikawa
@ 2011-11-22 6:20 ` Takuya Yoshikawa
2011-11-22 6:20 ` [PATCH 6/7] KVM: x86 emulator: Use opcode::execute for CMPXCHG Takuya Yoshikawa
2011-11-22 6:21 ` [PATCH 7/7] KVM: x86 emulator: Use opcode::execute for BSF/BSR Takuya Yoshikawa
6 siblings, 0 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:20 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
WRMSR: 0F 30
RDMSR: 0F 32
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 52 ++++++++++++++++++++++++------------------------
1 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 7fe5ed1..906c5eb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2666,6 +2666,30 @@ static int em_dr_write(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_wrmsr(struct x86_emulate_ctxt *ctxt)
+{
+ u64 msr_data;
+
+ msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]
+ | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32);
+ if (ctxt->ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data))
+ return emulate_gp(ctxt, 0);
+
+ return X86EMUL_CONTINUE;
+}
+
+static int em_rdmsr(struct x86_emulate_ctxt *ctxt)
+{
+ u64 msr_data;
+
+ if (ctxt->ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data))
+ return emulate_gp(ctxt, 0);
+
+ ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data;
+ ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32;
+ return X86EMUL_CONTINUE;
+}
+
static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt)
{
if (ctxt->modrm_reg > VCPU_SREG_GS)
@@ -3337,9 +3361,9 @@ static struct opcode twobyte_table[256] = {
N, N, N, N,
N, N, N, N, N, N, N, N,
/* 0x30 - 0x3F */
- DI(ImplicitOps | Priv, wrmsr),
+ II(ImplicitOps | Priv, em_wrmsr, wrmsr),
IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc),
- DI(ImplicitOps | Priv, rdmsr),
+ II(ImplicitOps | Priv, em_rdmsr, rdmsr),
DIP(ImplicitOps | Priv, rdpmc, check_rdpmc),
I(ImplicitOps | VendorSpecific, em_sysenter),
I(ImplicitOps | Priv | VendorSpecific, em_sysexit),
@@ -3818,7 +3842,6 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
{
struct x86_emulate_ops *ops = ctxt->ops;
- u64 msr_data;
int rc = X86EMUL_CONTINUE;
int saved_dst_type = ctxt->dst.type;
@@ -4108,29 +4131,6 @@ twobyte_insn:
case 0x21: /* mov from dr to reg */
ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val);
break;
- case 0x30:
- /* wrmsr */
- msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]
- | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32);
- if (ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data)) {
- emulate_gp(ctxt, 0);
- rc = X86EMUL_PROPAGATE_FAULT;
- goto done;
- }
- rc = X86EMUL_CONTINUE;
- break;
- case 0x32:
- /* rdmsr */
- if (ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data)) {
- emulate_gp(ctxt, 0);
- rc = X86EMUL_PROPAGATE_FAULT;
- goto done;
- } else {
- ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data;
- ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32;
- }
- rc = X86EMUL_CONTINUE;
- break;
case 0x40 ... 0x4f: /* cmov */
ctxt->dst.val = ctxt->dst.orig_val = ctxt->src.val;
if (!test_cc(ctxt->b, ctxt->eflags))
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 6/7] KVM: x86 emulator: Use opcode::execute for CMPXCHG
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
` (4 preceding siblings ...)
2011-11-22 6:20 ` [PATCH 5/7] KVM: x86 emulator: Use opcode::execute for WRMSR/RDMSR Takuya Yoshikawa
@ 2011-11-22 6:20 ` Takuya Yoshikawa
2011-11-22 6:21 ` [PATCH 7/7] KVM: x86 emulator: Use opcode::execute for BSF/BSR Takuya Yoshikawa
6 siblings, 0 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:20 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
CMPXCHG: 0F B0, 0F B1
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 37 +++++++++++++++++++------------------
1 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 906c5eb..799000d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1832,6 +1832,24 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
return rc;
}
+static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
+{
+ /* Save real source value, then compare EAX against destination. */
+ ctxt->src.orig_val = ctxt->src.val;
+ ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
+ emulate_2op_SrcV(ctxt, "cmp");
+
+ if (ctxt->eflags & EFLG_ZF) {
+ /* Success: write back to memory. */
+ ctxt->dst.val = ctxt->src.orig_val;
+ } else {
+ /* Failure: write the value we saw to EAX. */
+ ctxt->dst.type = OP_REG;
+ ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
+ }
+ return X86EMUL_CONTINUE;
+}
+
static int em_lseg(struct x86_emulate_ctxt *ctxt)
{
int seg = ctxt->src2.val;
@@ -3400,7 +3418,7 @@ static struct opcode twobyte_table[256] = {
D(DstMem | SrcReg | Src2CL | ModRM),
D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
/* 0xB0 - 0xB7 */
- D2bv(DstMem | SrcReg | ModRM | Lock | PageTable),
+ I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
@@ -4153,23 +4171,6 @@ twobyte_insn:
break;
case 0xae: /* clflush */
break;
- case 0xb0 ... 0xb1: /* cmpxchg */
- /*
- * Save real source value, then compare EAX against
- * destination.
- */
- ctxt->src.orig_val = ctxt->src.val;
- ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
- emulate_2op_SrcV(ctxt, "cmp");
- if (ctxt->eflags & EFLG_ZF) {
- /* Success: write back to memory. */
- ctxt->dst.val = ctxt->src.orig_val;
- } else {
- /* Failure: write the value we saw to EAX. */
- ctxt->dst.type = OP_REG;
- ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
- }
- break;
case 0xb6 ... 0xb7: /* movzx */
ctxt->dst.bytes = ctxt->op_bytes;
ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 7/7] KVM: x86 emulator: Use opcode::execute for BSF/BSR
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
` (5 preceding siblings ...)
2011-11-22 6:20 ` [PATCH 6/7] KVM: x86 emulator: Use opcode::execute for CMPXCHG Takuya Yoshikawa
@ 2011-11-22 6:21 ` Takuya Yoshikawa
6 siblings, 0 replies; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-22 6:21 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm, takuya.yoshikawa
BSF: 0F BC
BSR: 0F BD
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 60 ++++++++++++++++++++++++++++--------------------
1 files changed, 35 insertions(+), 25 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 799000d..4cd3313 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2921,6 +2921,40 @@ static int em_btc(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_bsf(struct x86_emulate_ctxt *ctxt)
+{
+ u8 zf;
+
+ __asm__ ("bsf %2, %0; setz %1"
+ : "=r"(ctxt->dst.val), "=q"(zf)
+ : "r"(ctxt->src.val));
+
+ ctxt->eflags &= ~X86_EFLAGS_ZF;
+ if (zf) {
+ ctxt->eflags |= X86_EFLAGS_ZF;
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
+ }
+ return X86EMUL_CONTINUE;
+}
+
+static int em_bsr(struct x86_emulate_ctxt *ctxt)
+{
+ u8 zf;
+
+ __asm__ ("bsr %2, %0; setz %1"
+ : "=r"(ctxt->dst.val), "=q"(zf)
+ : "r"(ctxt->src.val));
+
+ ctxt->eflags &= ~X86_EFLAGS_ZF;
+ if (zf) {
+ ctxt->eflags |= X86_EFLAGS_ZF;
+ /* Disable writeback. */
+ ctxt->dst.type = OP_NONE;
+ }
+ return X86EMUL_CONTINUE;
+}
+
static bool valid_cr(int nr)
{
switch (nr) {
@@ -3428,7 +3462,7 @@ static struct opcode twobyte_table[256] = {
N, N,
G(BitOp, group8),
I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
- D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+ I(DstReg | SrcMem | ModRM, em_bsf), I(DstReg | SrcMem | ModRM, em_bsr),
D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
/* 0xC0 - 0xCF */
D2bv(DstMem | SrcReg | ModRM | Lock),
@@ -4176,30 +4210,6 @@ twobyte_insn:
ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val
: (u16) ctxt->src.val;
break;
- case 0xbc: { /* bsf */
- u8 zf;
- __asm__ ("bsf %2, %0; setz %1"
- : "=r"(ctxt->dst.val), "=q"(zf)
- : "r"(ctxt->src.val));
- ctxt->eflags &= ~X86_EFLAGS_ZF;
- if (zf) {
- ctxt->eflags |= X86_EFLAGS_ZF;
- ctxt->dst.type = OP_NONE; /* Disable writeback. */
- }
- break;
- }
- case 0xbd: { /* bsr */
- u8 zf;
- __asm__ ("bsr %2, %0; setz %1"
- : "=r"(ctxt->dst.val), "=q"(zf)
- : "r"(ctxt->src.val));
- ctxt->eflags &= ~X86_EFLAGS_ZF;
- if (zf) {
- ctxt->eflags |= X86_EFLAGS_ZF;
- ctxt->dst.type = OP_NONE; /* Disable writeback. */
- }
- break;
- }
case 0xbe ... 0xbf: /* movsx */
ctxt->dst.bytes = ctxt->op_bytes;
ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val :
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT
2011-11-22 6:16 ` [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT Takuya Yoshikawa
@ 2011-11-22 10:49 ` Avi Kivity
2011-11-22 10:57 ` Avi Kivity
0 siblings, 1 reply; 12+ messages in thread
From: Avi Kivity @ 2011-11-22 10:49 UTC (permalink / raw)
To: Takuya Yoshikawa; +Cc: mtosatti, kvm, takuya.yoshikawa
On 11/22/2011 08:16 AM, Takuya Yoshikawa wrote:
> IN : E4, E5, EC, ED
> OUT: E6, E7, EE, EF
>
> @@ -3867,11 +3888,12 @@ special_insn:
> case 0x6c: /* insb */
> case 0x6d: /* insw/insd */
> ctxt->src.val = ctxt->regs[VCPU_REGS_RDX];
> - goto do_io_in;
> + rc = em_in(ctxt);
> + break;
> case 0x6e: /* outsb */
> case 0x6f: /* outsw/outsd */
> ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX];
> - goto do_io_out;
> + rc = em_out(ctxt);
> break;
> case 0x70 ... 0x7f: /* jcc (short) */
> if (test_cc(ctxt->b, ctxt->eflags))
>
We have SrcDX/DstDX for these.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT
2011-11-22 10:49 ` Avi Kivity
@ 2011-11-22 10:57 ` Avi Kivity
2011-11-23 3:27 ` [PATCH] KVM: x86 emulator: Use opcode::execute for INS/OUTS Takuya Yoshikawa
0 siblings, 1 reply; 12+ messages in thread
From: Avi Kivity @ 2011-11-22 10:57 UTC (permalink / raw)
To: Takuya Yoshikawa; +Cc: mtosatti, kvm, takuya.yoshikawa
On 11/22/2011 12:49 PM, Avi Kivity wrote:
> On 11/22/2011 08:16 AM, Takuya Yoshikawa wrote:
> > IN : E4, E5, EC, ED
> > OUT: E6, E7, EE, EF
> >
> > @@ -3867,11 +3888,12 @@ special_insn:
> > case 0x6c: /* insb */
> > case 0x6d: /* insw/insd */
> > ctxt->src.val = ctxt->regs[VCPU_REGS_RDX];
> > - goto do_io_in;
> > + rc = em_in(ctxt);
> > + break;
> > case 0x6e: /* outsb */
> > case 0x6f: /* outsw/outsd */
> > ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX];
> > - goto do_io_out;
> > + rc = em_out(ctxt);
> > break;
> > case 0x70 ... 0x7f: /* jcc (short) */
> > if (test_cc(ctxt->b, ctxt->eflags))
> >
>
> We have SrcDX/DstDX for these.
>
Everything else looks good; no need to regenerate this, it can be done
as a follow up patch if you like.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] KVM: x86 emulator: Use opcode::execute for INS/OUTS
2011-11-22 10:57 ` Avi Kivity
@ 2011-11-23 3:27 ` Takuya Yoshikawa
2011-11-27 16:35 ` Avi Kivity
0 siblings, 1 reply; 12+ messages in thread
From: Takuya Yoshikawa @ 2011-11-23 3:27 UTC (permalink / raw)
To: Avi Kivity; +Cc: Takuya Yoshikawa, mtosatti, kvm
From: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
INSB : 6C
INSW/INSD : 6D
OUTSB : 6E
OUTSW/OUTSD: 6F
The I/O port address is read from the DX register when we decode the
operand because we see the SrcDX/DstDX flag is set.
Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
arch/x86/kvm/emulate.c | 14 ++------------
1 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4cd3313..ac8e5ed 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3321,8 +3321,8 @@ static struct opcode opcode_table[256] = {
I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
I(SrcImmByte | Mov | Stack, em_push),
I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
- D2bvIP(DstDI | SrcDX | Mov | String, ins, check_perm_in), /* insb, insw/insd */
- D2bvIP(SrcSI | DstDX | String, outs, check_perm_out), /* outsb, outsw/outsd */
+ I2bvIP(DstDI | SrcDX | Mov | String, em_in, ins, check_perm_in), /* insb, insw/insd */
+ I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */
/* 0x70 - 0x7F */
X16(D(SrcImmByte)),
/* 0x80 - 0x87 */
@@ -4027,16 +4027,6 @@ special_insn:
goto cannot_emulate;
ctxt->dst.val = (s32) ctxt->src.val;
break;
- case 0x6c: /* insb */
- case 0x6d: /* insw/insd */
- ctxt->src.val = ctxt->regs[VCPU_REGS_RDX];
- rc = em_in(ctxt);
- break;
- case 0x6e: /* outsb */
- case 0x6f: /* outsw/outsd */
- ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX];
- rc = em_out(ctxt);
- break;
case 0x70 ... 0x7f: /* jcc (short) */
if (test_cc(ctxt->b, ctxt->eflags))
jmp_rel(ctxt, ctxt->src.val);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] KVM: x86 emulator: Use opcode::execute for INS/OUTS
2011-11-23 3:27 ` [PATCH] KVM: x86 emulator: Use opcode::execute for INS/OUTS Takuya Yoshikawa
@ 2011-11-27 16:35 ` Avi Kivity
0 siblings, 0 replies; 12+ messages in thread
From: Avi Kivity @ 2011-11-27 16:35 UTC (permalink / raw)
To: Takuya Yoshikawa; +Cc: Takuya Yoshikawa, mtosatti, kvm
On 11/23/2011 05:27 AM, Takuya Yoshikawa wrote:
> From: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
>
> INSB : 6C
> INSW/INSD : 6D
> OUTSB : 6E
> OUTSW/OUTSD: 6F
>
> The I/O port address is read from the DX register when we decode the
> operand because we see the SrcDX/DstDX flag is set.
>
>
Thanks, applied.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-11-27 16:35 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-22 6:15 [PATCH 0/7] KVM: x86 emulator: Use opcode::execute for some instructions Takuya Yoshikawa
2011-11-22 6:16 ` [PATCH 1/7] KVM: x86 emulator: Use opcode::execute for IN/OUT Takuya Yoshikawa
2011-11-22 10:49 ` Avi Kivity
2011-11-22 10:57 ` Avi Kivity
2011-11-23 3:27 ` [PATCH] KVM: x86 emulator: Use opcode::execute for INS/OUTS Takuya Yoshikawa
2011-11-27 16:35 ` Avi Kivity
2011-11-22 6:17 ` [PATCH 2/7] KVM: x86 emulator: Use opcode::execute for BT family Takuya Yoshikawa
2011-11-22 6:18 ` [PATCH 3/7] KVM: x86 emulator: Use opcode::execute for CALL Takuya Yoshikawa
2011-11-22 6:19 ` [PATCH 4/7] KVM: x86 emulator: Use opcode::execute for MOV to cr/dr Takuya Yoshikawa
2011-11-22 6:20 ` [PATCH 5/7] KVM: x86 emulator: Use opcode::execute for WRMSR/RDMSR Takuya Yoshikawa
2011-11-22 6:20 ` [PATCH 6/7] KVM: x86 emulator: Use opcode::execute for CMPXCHG Takuya Yoshikawa
2011-11-22 6:21 ` [PATCH 7/7] KVM: x86 emulator: Use opcode::execute for BSF/BSR Takuya Yoshikawa
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).