diff options
author | Avi Kivity <avi@redhat.com> | 2008-12-23 19:46:01 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-24 11:02:51 +0200 |
commit | 2b3d2a206037b1471de6a6dc51427af034cfdb47 (patch) | |
tree | e90379964dff6ff8d578b7f8401dfb3b05ff6111 | |
parent | e2078318042569682d0496cfd7bd962a766e82b1 (diff) | |
download | blackbird-op-linux-2b3d2a206037b1471de6a6dc51427af034cfdb47.tar.gz blackbird-op-linux-2b3d2a206037b1471de6a6dc51427af034cfdb47.zip |
KVM: Fix vmload and friends misinterpreted as lidt
The AMD SVM instruction family all overload the 0f 01 /3 opcode, further
multiplexing on the three r/m bits. But the code decided that anything that
isn't a vmmcall must be an lidt (which shares the 0f 01 /3 opcode, for the
case that mod = 3).
Fix by aborting emulation if this isn't a vmmcall.
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index d174db7a3370..54fb09889a80 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -1908,11 +1908,16 @@ twobyte_insn: c->dst.type = OP_NONE; break; case 3: /* lidt/vmmcall */ - if (c->modrm_mod == 3 && c->modrm_rm == 1) { - rc = kvm_fix_hypercall(ctxt->vcpu); - if (rc) - goto done; - kvm_emulate_hypercall(ctxt->vcpu); + if (c->modrm_mod == 3) { + switch (c->modrm_rm) { + case 1: + rc = kvm_fix_hypercall(ctxt->vcpu); + if (rc) + goto done; + break; + default: + goto cannot_emulate; + } } else { rc = read_descriptor(ctxt, ops, c->src.ptr, &size, &address, |