x86, mem, intel: Initialize Enhanced REP MOVSB/STOSB
authorFenghua Yu <fenghua.yu@intel.com>
Tue, 17 May 2011 22:29:11 +0000 (15:29 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Tue, 17 May 2011 22:40:23 +0000 (15:40 -0700)
If kernel intends to use enhanced REP MOVSB/STOSB, it must ensure
IA32_MISC_ENABLE.Fast_String_Enable (bit 0) is set and CPUID.(EAX=07H, ECX=0H):
EBX[bit 9] also reports 1.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: http://lkml.kernel.org/r/1305671358-14478-3-git-send-email-fenghua.yu@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
arch/x86/kernel/cpu/intel.c

index df86bc8c859d6ff8596759e7a54258fd9764d7d6..fc73a34ba8c9c1cb93c1086845090d03782381b5 100644 (file)
 
 static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
 {
+       u64 misc_enable;
+
        /* Unmask CPUID levels if masked: */
        if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
-               u64 misc_enable;
-
                rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 
                if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) {
@@ -118,8 +118,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
         * (model 2) with the same problem.
         */
        if (c->x86 == 15) {
-               u64 misc_enable;
-
                rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 
                if (misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING) {
@@ -130,6 +128,19 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
                }
        }
 #endif
+
+       /*
+        * If fast string is not enabled in IA32_MISC_ENABLE for any reason,
+        * clear the fast string and enhanced fast string CPU capabilities.
+        */
+       if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
+               rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
+               if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) {
+                       printk(KERN_INFO "Disabled fast string operations\n");
+                       setup_clear_cpu_cap(X86_FEATURE_REP_GOOD);
+                       setup_clear_cpu_cap(X86_FEATURE_ERMS);
+               }
+       }
 }
 
 #ifdef CONFIG_X86_32