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 <[email protected]>
---
 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 d174db7..54fb098 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,
-- 
1.6.0.6

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to