KVM: Fix vmload and friends misinterpreted as lidt
authorAvi Kivity <avi@redhat.com>
Tue, 23 Dec 2008 17:46:01 +0000 (19:46 +0200)
committerAvi Kivity <avi@redhat.com>
Tue, 24 Mar 2009 09:02:51 +0000 (11:02 +0200)
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>
arch/x86/kvm/x86_emulate.c

index d174db7a3370d9e80f6c1b93f2960a40b5b1cc43..54fb09889a80e33831797e25e8895ba901fc5192 100644 (file)
@@ -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,