From: Avi Kivity <[email protected]>

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 <[email protected]>
Signed-off-by: Marcelo Tosatti <[email protected]>

diff --git a/arch/x86/include/asm/kvm_emulate.h 
b/arch/x86/include/asm/kvm_emulate.h
index daf4477..f397b79 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -185,6 +185,7 @@ struct decode_cache {
        bool has_seg_override;
        u8 seg_override;
        unsigned int d;
+       int (*execute)(struct x86_emulate_ctxt *ctxt);
        unsigned long regs[NR_VCPU_REGS];
        unsigned long eip;
        /* modrm */
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4803976..1d905cb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -106,6 +106,7 @@
 struct opcode {
        u32 flags;
        union {
+               int (*execute)(struct x86_emulate_ctxt *ctxt);
                struct opcode *group;
                struct group_dual *gdual;
        } u;
@@ -120,6 +121,7 @@ struct group_dual {
 #define N    D(0)
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
 #define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
+#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
 
 static struct opcode group1[] = {
        X7(D(Lock)), N
@@ -349,6 +351,7 @@ static struct opcode twobyte_table[256] = {
 #undef N
 #undef G
 #undef GD
+#undef I
 
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
@@ -1070,6 +1073,8 @@ done_prefixes:
                c->d |= opcode.flags;
        }
 
+       c->execute = opcode.u.execute;
+
        /* Unrecognised? */
        if (c->d == 0 || (c->d & Undefined)) {
                DPRINTF("Cannot emulate %02x\n", c->b);
@@ -2706,6 +2711,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 
 special_insn:
 
+       if (c->execute) {
+               rc = c->execute(ctxt);
+               if (rc != X86EMUL_CONTINUE)
+                       goto done;
+               goto writeback;
+       }
+
        if (c->twobyte)
                goto twobyte_insn;
 
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to