]> xenbits.xensource.com Git - xen.git/commitdiff
x86/emul: Fix the emulation of invlpga
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 6 Mar 2018 15:08:54 +0000 (16:08 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 6 Mar 2018 15:08:54 +0000 (16:08 +0100)
The instruction requires EFER.SVME set to be usable in the first place.

Furthermore, the emulation doesn't handle ASIDs, so avoid giving the
impression that they work.  Permit ASID 0 which is reserved for non-root
mode (in which case the instruction is identical to invlpg), but raise #UD for
any other ASID.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: a91b2ec337a45d5d98e5a4387aa6563bc5cdc4c9
master date: 2018-02-05 18:17:22 +0000

xen/arch/x86/x86_emulate/x86_emulate.c

index bfabec06ba1012ed2d5761508c88badcadc43b43..5340d5c5d57901531d2e75931c0746f3e6ee6daa 100644 (file)
@@ -4419,14 +4419,24 @@ x86_emulate(
             _regs.eflags |= EFLG_ZF;
             break;
 
-        case 0xdf: /* invlpga */
-            generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
+        case 0xdf: /* invlpga */ {
+            uint64_t msr_val;
+
+            fail_if(!ops->read_msr);
+            if ( (rc = ops->read_msr(MSR_EFER,
+                                     &msr_val, ctxt)) != X86EMUL_OKAY )
+                goto done;
+            /* Finding SVME set implies vcpu_has_svm(). */
+            generate_exception_if(!(msr_val & EFER_SVME) ||
+                                  !in_protmode(ctxt, ops), EXC_UD, -1);
             generate_exception_if(!mode_ring0(), EXC_GP, 0);
+            generate_exception_if((uint32_t)_regs.ecx, EXC_UD, -1); /* TODO: Support ASIDs. */
             fail_if(ops->invlpg == NULL);
             if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax),
                                    ctxt)) )
                 goto done;
             break;
+        }
 
         case 0xf9: /* rdtscp */
         {