aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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