aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-07-29 08:11:51 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:50:22 -0400
commitef65c88912cafe56de2737c440aefc764fd8f202 (patch)
treef9e3ec543228d18234bb2304d0ebd17da39a5364 /arch
parent9aabc88fc8687ba3a520e2ec459821d05f72474e (diff)
KVM: x86 emulator: allow storing emulator execution function in decode tables
Instead of looking up the opcode twice (once for decode flags, once for the big execution switch) look up both flags and function in the decode tables. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_emulate.h1
-rw-r--r--arch/x86/kvm/emulate.c12
2 files changed, 13 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 9ddfa5ed2289..0f901c16cf1c 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -190,6 +190,7 @@ struct decode_cache {
190 bool has_seg_override; 190 bool has_seg_override;
191 u8 seg_override; 191 u8 seg_override;
192 unsigned int d; 192 unsigned int d;
193 int (*execute)(struct x86_emulate_ctxt *ctxt);
193 unsigned long regs[NR_VCPU_REGS]; 194 unsigned long regs[NR_VCPU_REGS];
194 unsigned long eip; 195 unsigned long eip;
195 /* modrm */ 196 /* modrm */
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 3689f34a303a..799e895fb08e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -106,6 +106,7 @@
106struct opcode { 106struct opcode {
107 u32 flags; 107 u32 flags;
108 union { 108 union {
109 int (*execute)(struct x86_emulate_ctxt *ctxt);
109 struct opcode *group; 110 struct opcode *group;
110 struct group_dual *gdual; 111 struct group_dual *gdual;
111 } u; 112 } u;
@@ -120,6 +121,7 @@ struct group_dual {
120#define N D(0) 121#define N D(0)
121#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) } 122#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
122#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) } 123#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
124#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
123 125
124static struct opcode group1[] = { 126static struct opcode group1[] = {
125 X7(D(Lock)), N 127 X7(D(Lock)), N
@@ -349,6 +351,7 @@ static struct opcode twobyte_table[256] = {
349#undef N 351#undef N
350#undef G 352#undef G
351#undef GD 353#undef GD
354#undef I
352 355
353/* EFLAGS bit definitions. */ 356/* EFLAGS bit definitions. */
354#define EFLG_ID (1<<21) 357#define EFLG_ID (1<<21)
@@ -1070,6 +1073,8 @@ done_prefixes:
1070 c->d |= opcode.flags; 1073 c->d |= opcode.flags;
1071 } 1074 }
1072 1075
1076 c->execute = opcode.u.execute;
1077
1073 /* Unrecognised? */ 1078 /* Unrecognised? */
1074 if (c->d == 0 || (c->d & Undefined)) { 1079 if (c->d == 0 || (c->d & Undefined)) {
1075 DPRINTF("Cannot emulate %02x\n", c->b); 1080 DPRINTF("Cannot emulate %02x\n", c->b);
@@ -2705,6 +2710,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
2705 2710
2706special_insn: 2711special_insn:
2707 2712
2713 if (c->execute) {
2714 rc = c->execute(ctxt);
2715 if (rc != X86EMUL_CONTINUE)
2716 goto done;
2717 goto writeback;
2718 }
2719
2708 if (c->twobyte) 2720 if (c->twobyte)
2709 goto twobyte_insn; 2721 goto twobyte_insn;
2710 2722