[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 17/25] x86emul: emulate {MONITOR, MWAIT}{, X} as no-op



As mentioned in Linux commit 87c00572ba ("kvm: x86: emulate monitor and
mwait instructions as nop"), older OS X versions (for example) may make
use of the insns without checking CPUID flags (presumably implying
availability from family/model).

While the instruction prefix check appears to contradict the SDM,
Intel's XED project has the insns marked "no_refining_prefix", which
also matches up with neighboring insns in this group. The latter fact
also is what explains why MONITORX/MWAITX do _not_ have such a check.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v3: New.

--- a/xen/arch/x86/cpu/mcheck/x86_mca.h
+++ b/xen/arch/x86/cpu/mcheck/x86_mca.h
@@ -89,9 +89,6 @@
 /* reserved bits */
 #define MCi_STATUS_OTHER_RESERVED2      0x0180000000000000ULL
 
-/* Bitfield of MSR_K8_HWCR register */
-#define K8_HWCR_MCi_STATUS_WREN                (1ULL << 18)
-
 /*Intel Specific bitfield*/
 #define MCi_MISC_ADDRMOD_MASK (0x7UL << 6)
 #define MCi_MISC_PHYSMOD    (0x2UL << 6)
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1712,6 +1712,7 @@ static bool vcpu_has(
 #define vcpu_has_xop()         vcpu_has(0x80000001, X, ECX, 12, ctxt, ops)
 #define vcpu_has_fma4()        vcpu_has(0x80000001, X, ECX, 16, ctxt, ops)
 #define vcpu_has_tbm()         vcpu_has(0x80000001, X, ECX, 21, ctxt, ops)
+#define vcpu_has_monitorx()    vcpu_has(0x80000001, X, ECX, 29, ctxt, ops)
 #define vcpu_has_bmi1()        vcpu_has(         7, 0, EBX,  3, ctxt, ops)
 #define vcpu_has_hle()         vcpu_has(         7, 0, EBX,  4, ctxt, ops)
 #define vcpu_has_avx2()        vcpu_has(         7, 0, EBX,  5, ctxt, ops)
@@ -4979,6 +4980,43 @@ x86_emulate(
 
         switch( modrm )
         {
+        case 0xc8: /* monitor */
+        case 0xc9: /* mwait */
+        {
+            bool user = false;
+
+            generate_exception_if(vex.pfx, EXC_UD);
+            /* There is intentionally no feature flag check here. */
+            if ( ops->read_msr )
+            {
+                switch ( ctxt->vendor )
+                {
+                case X86_VENDOR_AMD:
+                    if ( ops->read_msr(MSR_K8_HWCR, &msr_val,
+                                       ctxt) == X86EMUL_OKAY &&
+                         (msr_val & K8_HWCR_MON_MWAIT_USER_EN) )
+                        user = true;
+                    break;
+
+                case X86_VENDOR_INTEL:
+                    if ( ops->read_msr(MSR_INTEL_MISC_FEATURES_ENABLES,
+                                       &msr_val, ctxt) == X86EMUL_OKAY &&
+                         (msr_val & MSR_MISC_FEATURES_RING3MWAIT) )
+                        user = true;
+                    break;
+                }
+            }
+            generate_exception_if(!user && !mode_ring0(), EXC_UD);
+            if ( modrm & 1 )
+                break;
+        monitor:
+            /* Zero-byte read to perform segmentation checks. */
+            rc = ops->read(ea.mem.seg, truncate_ea(_regs.r(ax)), NULL, 0, 
ctxt);
+            if ( rc != X86EMUL_OKAY )
+                goto done;
+            break;
+        }
+
         case 0xca: /* clac */
         case 0xcb: /* stac */
             vcpu_must_have(smap);
@@ -5073,6 +5111,14 @@ x86_emulate(
             _regs.r(cx) = (uint32_t)msr_val;
             goto rdtsc;
 
+        case 0xfa: /* monitorx */
+            vcpu_must_have(monitorx);
+            goto monitor;
+
+        case 0xfb: /* mwaitx */
+            vcpu_must_have(monitorx);
+            break;
+
         case 0xfc: /* clzero */
         {
             unsigned long zero = 0;
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -161,6 +161,9 @@
 
 #define MSR_K7_HWCR                    0xc0010015
 #define MSR_K8_HWCR                    0xc0010015
+#define K8_HWCR_MON_MWAIT_USER_EN      (1ULL << 10)
+#define K8_HWCR_MCi_STATUS_WREN                (1ULL << 18)
+
 #define MSR_K7_FID_VID_CTL             0xc0010041
 #define MSR_K7_FID_VID_STATUS          0xc0010042
 #define MSR_K8_PSTATE_LIMIT            0xc0010061
@@ -516,6 +519,8 @@
 #define MSR_INTEL_MISC_FEATURES_ENABLES        0x00000140
 #define _MSR_MISC_FEATURES_CPUID_FAULTING      0
 #define MSR_MISC_FEATURES_CPUID_FAULTING       (1ULL << 
_MSR_MISC_FEATURES_CPUID_FAULTING)
+#define _MSR_MISC_FEATURES_RING3MWAIT          1
+#define MSR_MISC_FEATURES_RING3MWAIT           (1ULL << 
_MSR_MISC_FEATURES_RING3MWAIT)
 
 #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668
 #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.