]> xenbits.xensource.com Git - xen.git/commitdiff
x86/emul: Support CPUID faulting via a speculative MSR read
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 2 Nov 2016 15:50:23 +0000 (15:50 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 21 Feb 2017 13:49:31 +0000 (13:49 +0000)
This removes the need for every cpuid() emulation hook to individually support
CPUID faulting.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/hvm/emulate.c
xen/arch/x86/traps.c
xen/arch/x86/x86_emulate/x86_emulate.c
xen/arch/x86/x86_emulate/x86_emulate.h

index edcae5e64bdd52c1109e3a74b2cf69b2c922f4ec..f24d289ea67080e21f83d6bdaca0f1604de3d564 100644 (file)
@@ -1575,15 +1575,6 @@ static int hvmemul_wbinvd(
 int hvmemul_cpuid(uint32_t leaf, uint32_t subleaf,
                   struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt)
 {
-    /*
-     * x86_emulate uses this function to query CPU features for its own internal
-     * use. Make sure we're actually emulating CPUID before emulating CPUID
-     * faulting.
-     */
-    if ( ctxt->opcode == X86EMUL_OPC(0x0f, 0xa2) &&
-         hvm_check_cpuid_faulting(current) )
-        return X86EMUL_EXCEPTION;
-
     guest_cpuid(current, leaf, subleaf, res);
     return X86EMUL_OKAY;
 }
index ec8b002f6e5b8d570c64e523e0087034c2f6c9e3..75c89eb5fb6771bcfcec808ce19fe36c333ea68c 100644 (file)
@@ -2884,23 +2884,7 @@ static int priv_op_wbinvd(struct x86_emulate_ctxt *ctxt)
 int pv_emul_cpuid(uint32_t leaf, uint32_t subleaf,
                   struct cpuid_leaf *res, struct x86_emulate_ctxt *ctxt)
 {
-    const struct vcpu *curr = current;
-
-    /*
-     * x86_emulate uses this function to query CPU features for its own
-     * internal use. Make sure we're actually emulating CPUID before checking
-     * for emulated CPUID faulting.
-     */
-    if ( ctxt->opcode == X86EMUL_OPC(0x0f, 0xa2) )
-    {
-
-        /* If cpuid faulting is enabled and CPL>0 leave the #GP untouched. */
-        if ( curr->arch.cpuid_faulting &&
-             !guest_kernel_mode(curr, ctxt->regs) )
-            return X86EMUL_EXCEPTION;
-    }
-
-    guest_cpuid(curr, leaf, subleaf, res);
+    guest_cpuid(current, leaf, subleaf, res);
 
     return X86EMUL_OKAY;
 }
index f339d364eb25bd312061d10486c8fdd1cedd0cd2..a65026a3b60f819f27545fc352ae1dddc94cc6b6 100644 (file)
@@ -5424,10 +5424,25 @@ x86_emulate(
         break;
 
     case X86EMUL_OPC(0x0f, 0xa2): /* cpuid */
+        msr_val = 0;
         fail_if(ops->cpuid == NULL);
+
+        /* Speculatively read MSR_INTEL_MISC_FEATURES_ENABLES. */
+        if ( ops->read_msr && !mode_ring0() &&
+             (rc = ops->read_msr(MSR_INTEL_MISC_FEATURES_ENABLES,
+                                 &msr_val, ctxt)) == X86EMUL_EXCEPTION )
+        {
+            /* Not implemented.  Squash the exception and proceed normally. */
+            x86_emul_reset_event(ctxt);
+            rc = X86EMUL_OKAY;
+        }
+        if ( rc != X86EMUL_OKAY )
+            goto done;
+
+        generate_exception_if((msr_val & MSR_MISC_FEATURES_CPUID_FAULTING),
+                              EXC_GP, 0); /* Faulting active? (Inc. CPL test) */
+
         rc = ops->cpuid(_regs._eax, _regs._ecx, &cpuid_leaf, ctxt);
-        generate_exception_if(rc == X86EMUL_EXCEPTION,
-                              EXC_GP, 0); /* CPUID Faulting? */
         if ( rc != X86EMUL_OKAY )
             goto done;
         _regs.r(ax) = cpuid_leaf.a;
index 071668d8b113618506da57600e5279c5c316486a..c35873ea10dd09965b77744731b47b8453a09482 100644 (file)
@@ -413,12 +413,7 @@ struct x86_emulate_ops
     int (*wbinvd)(
         struct x86_emulate_ctxt *ctxt);
 
-    /*
-     * cpuid: Emulate CPUID via given set of EAX-EDX inputs/outputs.
-     *
-     * May return X86EMUL_EXCEPTION, which causes the emulator to inject
-     * #GP[0].  Used to implement CPUID faulting.
-     */
+    /* cpuid: Emulate CPUID via given set of EAX-EDX inputs/outputs. */
     int (*cpuid)(
         uint32_t leaf,
         uint32_t subleaf,