Before we start actually adjusting behavior when ERMS is available,
follow Linux commit 161ec53c702c ("x86, mem, intel: Initialize Enhanced
REP MOVSB/STOSB") and zap the CPUID-derived feature flag when the MSR
bit is clear. Don't extend the artificial clearing to guest view,
though: Guests can take their own decision in this regard, as they can
read (most of) MISC_ENABLE.

Signed-off-by: Jan Beulich <jbeul...@suse.com>
---
TBD: Would be nice if "cpuid=no-erms" propagated to guest view (for
     "cpuid=" generally meaning to affect guests as well as Xen), but
     since both disabling paths use setup_clear_cpu_cap() they're
     indistinguishable in guest_common_feature_adjustments(). A separate
     boolean could take care of this, but would look clumsy to me.
---
v5: Correct guest_common_max_feature_adjustments() addition.
v4: Also adjust guest_common_max_feature_adjustments().
v3: New.

--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -366,8 +366,18 @@ static void cf_check early_init_intel(st
                paddr_bits = 36;
 
        if (c == &boot_cpu_data) {
+               uint64_t misc_enable;
+
                check_memory_type_self_snoop_errata();
 
+               /*
+                * If fast string is not enabled in IA32_MISC_ENABLE for any 
reason,
+                * clear the enhanced fast string CPU capability.
+                */
+               rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
+               if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING))
+                       setup_clear_cpu_cap(X86_FEATURE_ERMS);
+
                intel_init_levelling();
        }
 
--- a/xen/arch/x86/cpu-policy.c
+++ b/xen/arch/x86/cpu-policy.c
@@ -487,6 +487,12 @@ static void __init guest_common_max_feat
      */
     if ( test_bit(X86_FEATURE_RTM, fs) )
         __set_bit(X86_FEATURE_RTM_ALWAYS_ABORT, fs);
+
+    /*
+     * We expose MISC_ENABLE to guests, so our internal clearing of ERMS when
+     * FAST_STRING is not set should not affect the view of migrating-in 
guests.
+     */
+    __set_bit(X86_FEATURE_ERMS, fs);
 }
 
 static void __init guest_common_default_feature_adjustments(uint32_t *fs)
@@ -567,6 +573,16 @@ static void __init guest_common_default_
         __clear_bit(X86_FEATURE_RTM, fs);
         __set_bit(X86_FEATURE_RTM_ALWAYS_ABORT, fs);
     }
+
+    /*
+     * We expose MISC_ENABLE to guests, so our internal clearing of ERMS when
+     * FAST_STRING is not set should not propagate to guest view.  Guests can
+     * judge on their own whether to ignore the CPUID bit when the MSR bit is
+     * clear.  The bit being uniformly set in the max policies, we only need
+     * to clear it here (if hardware doesn't have it).
+     */
+    if ( !raw_cpu_policy.feat.erms )
+        __clear_bit(X86_FEATURE_ERMS, fs);
 }
 
 static void __init guest_common_feature_adjustments(uint32_t *fs)
--- a/xen/arch/x86/include/asm/msr-index.h
+++ b/xen/arch/x86/include/asm/msr-index.h
@@ -493,6 +493,7 @@
 #define MSR_IA32_THERM_INTERRUPT       0x0000019b
 #define MSR_IA32_THERM_STATUS          0x0000019c
 #define MSR_IA32_MISC_ENABLE           0x000001a0
+#define MSR_IA32_MISC_ENABLE_FAST_STRING  (1<<0)
 #define MSR_IA32_MISC_ENABLE_PERF_AVAIL   (1<<7)
 #define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL  (1<<11)
 #define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1<<12)


Reply via email to