diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 12 |
1 files changed, 12 insertions, 0 deletions
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 @@ | |||
106 | struct opcode { | 106 | struct 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 | ||
124 | static struct opcode group1[] = { | 126 | static 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 | ||
2706 | special_insn: | 2711 | special_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 | ||