diff options
author | Avi Kivity <avi@redhat.com> | 2011-04-21 12:21:50 +0300 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-05-22 08:39:35 -0400 |
commit | 5ef39c71d8398115245a5974b488f8703ba3a6b0 (patch) | |
tree | a668bd0b429fcce29a19911f099316aaaed95e9c /arch | |
parent | 68152d88122b24fad0f5910f74efcd19120a19a8 (diff) |
KVM: x86 emulator: Use opcode::execute for 0F 01 opcode
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/emulate.c | 56 |
1 files changed, 13 insertions, 43 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 2132fab188b..252f28348cf 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2625,18 +2625,13 @@ static int em_lgdt(struct x86_emulate_ctxt *ctxt) return X86EMUL_CONTINUE; } -static int em_svm(struct x86_emulate_ctxt *ctxt) +static int em_vmmcall(struct x86_emulate_ctxt *ctxt) { struct decode_cache *c = &ctxt->decode; int rc; - switch (c->modrm_rm) { - case 1: - rc = ctxt->ops->fix_hypercall(ctxt); - break; - default: - return X86EMUL_UNHANDLEABLE; - } + rc = ctxt->ops->fix_hypercall(ctxt); + /* Disable writeback. */ c->dst.type = OP_NONE; return rc; @@ -2909,7 +2904,7 @@ static struct opcode group7_rm1[] = { static struct opcode group7_rm3[] = { DIP(SrcNone | ModRM | Prot | Priv, vmrun, check_svme_pa), - DI(SrcNone | ModRM | Prot | VendorSpecific, vmmcall), + II(SrcNone | ModRM | Prot | VendorSpecific, em_vmmcall, vmmcall), DIP(SrcNone | ModRM | Prot | Priv, vmload, check_svme_pa), DIP(SrcNone | ModRM | Prot | Priv, vmsave, check_svme_pa), DIP(SrcNone | ModRM | Prot | Priv, stgi, check_svme), @@ -2961,15 +2956,17 @@ static struct opcode group6[] = { static struct group_dual group7 = { { DI(ModRM | Mov | DstMem | Priv, sgdt), DI(ModRM | Mov | DstMem | Priv, sidt), - DI(ModRM | SrcMem | Priv, lgdt), DI(ModRM | SrcMem | Priv, lidt), - DI(SrcNone | ModRM | DstMem | Mov, smsw), N, - DI(SrcMem16 | ModRM | Mov | Priv, lmsw), - DI(SrcMem | ModRM | ByteOp | Priv | NoAccess, invlpg), + II(ModRM | SrcMem | Priv, em_lgdt, lgdt), + II(ModRM | SrcMem | Priv, em_lidt, lidt), + II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N, + II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw), + II(SrcMem | ModRM | ByteOp | Priv | NoAccess, em_invlpg, invlpg), }, { - D(SrcNone | ModRM | Priv | VendorSpecific), EXT(0, group7_rm1), + I(SrcNone | ModRM | Priv | VendorSpecific, em_vmcall), + EXT(0, group7_rm1), N, EXT(0, group7_rm3), - DI(SrcNone | ModRM | DstMem | Mov, smsw), N, - DI(SrcMem16 | ModRM | Mov | Priv, lmsw), EXT(0, group7_rm7), + II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N, + II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw), EXT(0, group7_rm7), } }; static struct opcode group8[] = { @@ -4107,33 +4104,6 @@ done: twobyte_insn: switch (c->b) { - case 0x01: /* lgdt, lidt, lmsw */ - switch (c->modrm_reg) { - case 0: /* vmcall */ - rc = em_vmcall(ctxt); - break; - case 2: /* lgdt */ - rc = em_lgdt(ctxt); - break; - case 3: /* lidt/vmmcall */ - if (c->modrm_mod == 3) - return em_svm(ctxt); - else - return em_lidt(ctxt); - break; - case 4: /* smsw */ - rc = em_smsw(ctxt); - break; - case 6: /* lmsw */ - rc = em_lmsw(ctxt); - break; - case 7: /* invlpg*/ - rc = em_invlpg(ctxt); - break; - default: - goto cannot_emulate; - } - break; case 0x05: /* syscall */ rc = emulate_syscall(ctxt, ops); break; |