Some latest Intel CPU models support cpuid feature mask. CPUID.1.EAX>0x00010674.CPUID mask feature is intended to be used to limit the feature flags reported by CPUID.1.EDX:ECX. This patch add CPUID feature mask support in XEN by using boot options in GRUB entry. For detailed information, please refer to the related documents. Signed-off-by:Liping Ke Jun Nakajima Yunhong Jiang diff -r 5cd4fe68b6c2 -r f0a3d8da8ef4 xen/arch/x86/cpu/intel.c --- a/xen/arch/x86/cpu/intel.c Tue Jul 08 17:25:04 2008 +0100 +++ b/xen/arch/x86/cpu/intel.c Tue Jul 08 10:02:01 2008 +0800 @@ -18,12 +18,40 @@ extern int trap_init_f00f_bug(void); +/*opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask*/ +static unsigned int opt_cpuid_mask_ecx = 0; +static unsigned int opt_cpuid_mask_edx = 0; +static int flag_cpuid_mask = 0; +integer_param("cpuid_mask_ecx", opt_cpuid_mask_ecx); +integer_param("cpuid_mask_edx", opt_cpuid_mask_edx); + #ifdef CONFIG_X86_INTEL_USERCOPY /* * Alignment at which movsl is preferred for bulk memory copies. */ struct movsl_mask movsl_mask __read_mostly; #endif + +static void __devinit set_cpuidmask(struct cpuinfo_x86 *c) +{ + if (!flag_cpuid_mask && + (opt_cpuid_mask_ecx || opt_cpuid_mask_edx) ) + panic("Does not support cpuid feature mask!\n"); + + if ( flag_cpuid_mask && + (opt_cpuid_mask_ecx || opt_cpuid_mask_edx) ) + { + + unsigned int low = 0xFFFFFFFF, high = 0xFFFFFFFF; + if ( opt_cpuid_mask_ecx ) + low = opt_cpuid_mask_ecx; + if ( opt_cpuid_mask_edx ) + high = opt_cpuid_mask_edx; + wrmsr(MSR_IA32_CPUID_FEATURE_MASK1, low, high); + printk(KERN_INFO "set cpu feature mask ecx %x, edx %x\n", low, high); + } + +} void __devinit early_intel_workaround(struct cpuinfo_x86 *c) { @@ -53,6 +81,27 @@ int __devinit ppro_with_ram_bug(void) return 0; } +static void detect_cpuidmask(struct cpuinfo_x86 *c) +{ + unsigned int eax, ebx, ecx, edx; + + /*Not support multi-stepping configuration. + *if there's one cpu does not support cpuid feature mask, + *we will not set cpuid_mask msr for all of them, + *directly panic after we find it*/ + cpuid(0x00000001, &eax, &ebx, &ecx, &edx); + if ( eax >= 0x00010674 ) + { + printk(KERN_INFO "This Cpu supports cpuid_mask.\n"); + flag_cpuid_mask = 1; + } + else + { + /*some cpu suport cpuid feature mask*/ + printk(KERN_INFO "This Cpu not support cpuid_mask.\n"); + flag_cpuid_mask = 0; + } +} /* * P4 Xeon errata 037 workaround. @@ -157,7 +206,8 @@ static void __devinit init_intel(struct c->x86_max_cores = num_cpu_cores(c); detect_ht(c); - + detect_cpuidmask(c); + set_cpuidmask(c); /* Work around errata */ Intel_errata_workarounds(c); diff -r 5cd4fe68b6c2 -r f0a3d8da8ef4 xen/include/asm-x86/msr-index.h --- a/xen/include/asm-x86/msr-index.h Tue Jul 08 17:25:04 2008 +0100 +++ b/xen/include/asm-x86/msr-index.h Tue Jul 08 10:02:01 2008 +0800 @@ -122,6 +122,9 @@ #define MSR_P6_PERFCTR1 0x000000c2 #define MSR_P6_EVNTSEL0 0x00000186 #define MSR_P6_EVNTSEL1 0x00000187 + +/*MSR for cpuid feature mask*/ +#define MSR_IA32_CPUID_FEATURE_MASK1 0x478 /* MSRs & bits used for VMX enabling */ #define MSR_IA32_VMX_BASIC 0x480