* [PATCH 0/3] Random emulator improvements
@ 2010-08-30 14:14 Avi Kivity
2010-08-30 14:14 ` [PATCH 1/3] KVM: x86 emulator: use single stage decoding for mov instructions Avi Kivity
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Avi Kivity @ 2010-08-30 14:14 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
Three patches with no underlying motive.
Avi Kivity (3):
KVM: x86 emulator: use single stage decoding for mov instructions
KVM: x86 emulator: fix group 11 decoding for reg != 0
KVM: x86 emulator: clean up control flow in x86_emulate_insn()
arch/x86/kvm/emulate.c | 110 +++++++++++++-----------------------------------
1 files changed, 29 insertions(+), 81 deletions(-)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] KVM: x86 emulator: use single stage decoding for mov instructions
2010-08-30 14:14 [PATCH 0/3] Random emulator improvements Avi Kivity
@ 2010-08-30 14:14 ` Avi Kivity
2010-08-30 14:14 ` [PATCH 2/3] KVM: x86 emulator: fix group 11 decoding for reg != 0 Avi Kivity
2010-08-30 14:14 ` [PATCH 3/3] KVM: x86 emulator: clean up control flow in x86_emulate_insn() Avi Kivity
2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2010-08-30 14:14 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/emulate.c | 42 ++++++++++++++++++------------------------
1 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8bfa3e3..c0715ae 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2378,6 +2378,13 @@ static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
+static int em_mov(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+ c->dst.val = 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) }
@@ -2489,8 +2496,8 @@ static struct opcode opcode_table[256] = {
G(DstMem | SrcImmByte | ModRM | Group, group1),
D2bv(DstMem | SrcReg | ModRM), D2bv(DstMem | SrcReg | ModRM | Lock),
/* 0x88 - 0x8F */
- D2bv(DstMem | SrcReg | ModRM | Mov),
- D2bv(DstReg | SrcMem | ModRM | Mov),
+ I2bv(DstMem | SrcReg | ModRM | Mov, em_mov),
+ I2bv(DstReg | SrcMem | ModRM | Mov, em_mov),
D(DstMem | SrcNone | ModRM | Mov), D(ModRM | SrcMem | NoAccess | DstReg),
D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
/* 0x90 - 0x97 */
@@ -2500,24 +2507,25 @@ static struct opcode opcode_table[256] = {
I(SrcImmFAddr | No64, em_call_far), N,
D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
/* 0xA0 - 0xA7 */
- D2bv(DstAcc | SrcMem | Mov | MemAbs),
- D2bv(DstMem | SrcAcc | Mov | MemAbs),
- D2bv(SrcSI | DstDI | Mov | String), D2bv(SrcSI | DstDI | String),
+ I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
+ I2bv(DstMem | SrcAcc | Mov | MemAbs, em_mov),
+ I2bv(SrcSI | DstDI | Mov | String, em_mov),
+ D2bv(SrcSI | DstDI | String),
/* 0xA8 - 0xAF */
D2bv(DstAcc | SrcImm),
- D2bv(SrcAcc | DstDI | Mov | String),
- D2bv(SrcSI | DstAcc | Mov | String),
+ I2bv(SrcAcc | DstDI | Mov | String, em_mov),
+ I2bv(SrcSI | DstAcc | Mov | String, em_mov),
D2bv(SrcAcc | DstDI | String),
/* 0xB0 - 0xB7 */
- X8(D(ByteOp | DstReg | SrcImm | Mov)),
+ X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)),
/* 0xB8 - 0xBF */
- X8(D(DstReg | SrcImm | Mov)),
+ X8(I(DstReg | SrcImm | Mov, em_mov)),
/* 0xC0 - 0xC7 */
D2bv(DstMem | SrcImmByte | ModRM),
I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
D(ImplicitOps | Stack),
D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64),
- D2bv(DstMem | SrcImm | ModRM | Mov),
+ I2bv(DstMem | SrcImm | ModRM | Mov, em_mov),
/* 0xC8 - 0xCF */
N, N, N, D(ImplicitOps | Stack),
D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
@@ -3212,8 +3220,6 @@ special_insn:
c->dst.val = c->src.orig_val;
c->lock_prefix = 1;
break;
- case 0x88 ... 0x8b: /* mov */
- goto mov;
case 0x8c: /* mov r/m, sreg */
if (c->modrm_reg > VCPU_SREG_GS) {
emulate_ud(ctxt);
@@ -3271,22 +3277,14 @@ special_insn:
if (rc != X86EMUL_CONTINUE)
goto done;
break;
- case 0xa0 ... 0xa3: /* mov */
- case 0xa4 ... 0xa5: /* movs */
- goto mov;
case 0xa6 ... 0xa7: /* cmps */
c->dst.type = OP_NONE; /* Disable writeback. */
DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.addr.mem, c->dst.addr.mem);
goto cmp;
case 0xa8 ... 0xa9: /* test ax, imm */
goto test;
- case 0xaa ... 0xab: /* stos */
- case 0xac ... 0xad: /* lods */
- goto mov;
case 0xae ... 0xaf: /* scas */
goto cmp;
- case 0xb0 ... 0xbf: /* mov r, imm */
- goto mov;
case 0xc0 ... 0xc1:
emulate_grp2(ctxt);
break;
@@ -3305,10 +3303,6 @@ special_insn:
if (rc != X86EMUL_CONTINUE)
goto done;
break;
- case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
- mov:
- c->dst.val = c->src.val;
- break;
case 0xcb: /* ret far */
rc = emulate_ret_far(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] KVM: x86 emulator: fix group 11 decoding for reg != 0
2010-08-30 14:14 [PATCH 0/3] Random emulator improvements Avi Kivity
2010-08-30 14:14 ` [PATCH 1/3] KVM: x86 emulator: use single stage decoding for mov instructions Avi Kivity
@ 2010-08-30 14:14 ` Avi Kivity
2010-08-30 14:14 ` [PATCH 3/3] KVM: x86 emulator: clean up control flow in x86_emulate_insn() Avi Kivity
2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2010-08-30 14:14 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
These are all undefined.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/emulate.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c0715ae..9940d16 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2449,6 +2449,10 @@ static struct group_dual group9 = { {
N, N, N, N, N, N, N, N,
} };
+static struct opcode group11[] = {
+ I(DstMem | SrcImm | ModRM | Mov, em_mov), X7(D(Undefined)),
+};
+
static struct opcode opcode_table[256] = {
/* 0x00 - 0x07 */
D6ALU(Lock),
@@ -2525,7 +2529,7 @@ static struct opcode opcode_table[256] = {
I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
D(ImplicitOps | Stack),
D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64),
- I2bv(DstMem | SrcImm | ModRM | Mov, em_mov),
+ G(ByteOp, group11), G(0, group11),
/* 0xC8 - 0xCF */
N, N, N, D(ImplicitOps | Stack),
D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] KVM: x86 emulator: clean up control flow in x86_emulate_insn()
2010-08-30 14:14 [PATCH 0/3] Random emulator improvements Avi Kivity
2010-08-30 14:14 ` [PATCH 1/3] KVM: x86 emulator: use single stage decoding for mov instructions Avi Kivity
2010-08-30 14:14 ` [PATCH 2/3] KVM: x86 emulator: fix group 11 decoding for reg != 0 Avi Kivity
@ 2010-08-30 14:14 ` Avi Kivity
2 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2010-08-30 14:14 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
x86_emulate_insn() is full of things like
if (rc != X86EMUL_CONTINUE)
goto done;
break;
consolidate all of those at the end of the switch statement.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/emulate.c | 64 +++++------------------------------------------
1 files changed, 7 insertions(+), 57 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 9940d16..27d2c22 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3098,8 +3098,6 @@ special_insn:
break;
case 0x07: /* pop es */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x08 ... 0x0d:
or: /* or */
@@ -3117,8 +3115,6 @@ special_insn:
break;
case 0x17: /* pop ss */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x18 ... 0x1d:
sbb: /* sbb */
@@ -3129,8 +3125,6 @@ special_insn:
break;
case 0x1f: /* pop ds */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x20 ... 0x25:
and: /* and */
@@ -3157,18 +3151,12 @@ special_insn:
case 0x58 ... 0x5f: /* pop reg */
pop_instruction:
rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x60: /* pusha */
rc = emulate_pusha(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x61: /* popa */
rc = emulate_popa(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x63: /* movsxd */
if (ctxt->mode != X86EMUL_MODE_PROT64)
@@ -3255,8 +3243,6 @@ special_insn:
}
case 0x8f: /* pop (sole member of Grp1a) */
rc = emulate_grp1a(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0x90 ... 0x97: /* nop / xchg reg, rax */
if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX])
@@ -3278,8 +3264,6 @@ special_insn:
c->dst.addr.reg = &ctxt->eflags;
c->dst.bytes = c->op_bytes;
rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xa6 ... 0xa7: /* cmps */
c->dst.type = OP_NONE; /* Disable writeback. */
@@ -3299,18 +3283,12 @@ special_insn:
goto pop_instruction;
case 0xc4: /* les */
rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xc5: /* lds */
rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xcb: /* ret far */
rc = emulate_ret_far(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xcc: /* int3 */
irq = 3;
@@ -3319,8 +3297,6 @@ special_insn:
irq = c->src.val;
do_interrupt:
rc = emulate_int(ctxt, ops, irq);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xce: /* into */
if (ctxt->eflags & EFLG_OF) {
@@ -3330,9 +3306,6 @@ special_insn:
break;
case 0xcf: /* iret */
rc = emulate_iret(ctxt, ops);
-
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xd0 ... 0xd1: /* Grp2 */
emulate_grp2(ctxt);
@@ -3419,8 +3392,6 @@ special_insn:
break;
case 0xf6 ... 0xf7: /* Grp3 */
rc = emulate_grp3(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xf8: /* clc */
ctxt->eflags &= ~EFLG_CF;
@@ -3453,8 +3424,6 @@ special_insn:
case 0xfe: /* Grp4 */
grp45:
rc = emulate_grp45(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xff: /* Grp5 */
if (c->modrm_reg == 5)
@@ -3464,6 +3433,9 @@ special_insn:
goto cannot_emulate;
}
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
writeback:
rc = writeback(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
@@ -3545,8 +3517,6 @@ twobyte_insn:
switch (c->modrm_rm) {
case 1:
rc = kvm_fix_hypercall(ctxt->vcpu);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
default:
goto cannot_emulate;
@@ -3585,10 +3555,6 @@ twobyte_insn:
break;
case 0x05: /* syscall */
rc = emulate_syscall(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
- else
- goto writeback;
break;
case 0x06:
emulate_clts(ctxt->vcpu);
@@ -3665,17 +3631,9 @@ twobyte_insn:
break;
case 0x34: /* sysenter */
rc = emulate_sysenter(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
- else
- goto writeback;
break;
case 0x35: /* sysexit */
rc = emulate_sysexit(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
- else
- goto writeback;
break;
case 0x40 ... 0x4f: /* cmov */
c->dst.val = c->dst.orig_val = c->src.val;
@@ -3694,8 +3652,6 @@ twobyte_insn:
break;
case 0xa1: /* pop fs */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xa3:
bt: /* bt */
@@ -3713,8 +3669,6 @@ twobyte_insn:
break;
case 0xa9: /* pop gs */
rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xab:
bts: /* bts */
@@ -3745,8 +3699,6 @@ twobyte_insn:
break;
case 0xb2: /* lss */
rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xb3:
btr: /* btr */
@@ -3754,13 +3706,9 @@ twobyte_insn:
break;
case 0xb4: /* lfs */
rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xb5: /* lgs */
rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
case 0xb6 ... 0xb7: /* movzx */
c->dst.bytes = c->op_bytes;
@@ -3825,12 +3773,14 @@ twobyte_insn:
break;
case 0xc7: /* Grp9 (cmpxchg8b) */
rc = emulate_grp9(ctxt, ops);
- if (rc != X86EMUL_CONTINUE)
- goto done;
break;
default:
goto cannot_emulate;
}
+
+ if (rc != X86EMUL_CONTINUE)
+ goto done;
+
goto writeback;
cannot_emulate:
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-08-30 14:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-30 14:14 [PATCH 0/3] Random emulator improvements Avi Kivity
2010-08-30 14:14 ` [PATCH 1/3] KVM: x86 emulator: use single stage decoding for mov instructions Avi Kivity
2010-08-30 14:14 ` [PATCH 2/3] KVM: x86 emulator: fix group 11 decoding for reg != 0 Avi Kivity
2010-08-30 14:14 ` [PATCH 3/3] KVM: x86 emulator: clean up control flow in x86_emulate_insn() 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).