]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
x86/emul: Fix the emulation of invlpga
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 2 Feb 2018 16:10:17 +0000 (16:10 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 5 Feb 2018 18:17:22 +0000 (18:17 +0000)
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>
xen/arch/x86/x86_emulate/x86_emulate.c

index bc8fa1d1b1282cca54220482eaa5dcf895d7eb1b..d192280c4dfa3411cc209413c512bf828705692d 100644 (file)
@@ -5120,8 +5120,15 @@ x86_emulate(
             break;
 
         case 0xdf: /* invlpga */
-            generate_exception_if(!in_protmode(ctxt, ops), EXC_UD);
+            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);
             generate_exception_if(!mode_ring0(), EXC_GP, 0);
+            generate_exception_if(_regs.ecx, EXC_UD); /* TODO: Support ASIDs. */
             fail_if(ops->invlpg == NULL);
             if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.r(ax)),
                                    ctxt)) )