| From joe.korty@ccur.com Fri Mar 20 11:05:59 2009 |
| From: Joe Korty <joe.korty@ccur.com> |
| Date: Thu, 19 Mar 2009 13:28:58 -0400 |
| Subject: Fix misreporting of #cores as #hyperthreads for Q9550 |
| To: stable@kernel.org |
| Cc: Ingo Molnar <mingo@elte.hu>, "H. Peter Anvin" <hpa@linux.intel.com> |
| Message-ID: <20090319172858.GA2629@tsunami.ccur.com> |
| Content-Disposition: inline |
| |
| From: Joe Korty <joe.korty@ccur.com> |
| |
| For the Q9550, in x86_64 mode, /proc/cpuinfo mistakenly |
| thinks the #cores present is the #hyperthreads present. |
| i386 mode was not examined but is assumed to have the |
| same problem. |
| |
| A backport of the following three 2.6.29-rc1 patches |
| fixes the problem: |
| |
| 066941bd4eeb159307a5d7d795100d0887c00442: |
| [PATCH] x86: unmask CPUID levels on Intel CPUs |
| 99fb4d349db7e7dacb2099c5cc320a9e2d31c1ef: |
| [PATCH] x86: unmask CPUID levels on Intel CPUs, fix |
| bdf21a49bab28f0d9613e8d8724ef9c9168b61b9: |
| [PATCH] x86: add MSR_IA32_MISC_ENABLE bits to <asm/msr-index.h> |
| |
| From the first patch: "If the CPUID limit bit in |
| MSR_IA32_MISC_ENABLE is set, clear it to make all CPUID |
| information available. This is required for some features |
| to work, in particular XSAVE." |
| |
| Originally-Developed-by: H. Peter Anvin <hpa@linux.intel.com> |
| Backported-by: Joe Korty <joe.korty@ccur.com> |
| Signed-off-by: Joe Korty <joe.korty@ccur.com> |
| Cc: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/include/asm/msr-index.h | 29 +++++++++++++++++++++++++++++ |
| arch/x86/kernel/cpu/intel.c | 13 +++++++++++++ |
| 2 files changed, 42 insertions(+) |
| |
| --- a/arch/x86/include/asm/msr-index.h |
| +++ b/arch/x86/include/asm/msr-index.h |
| @@ -200,6 +200,35 @@ |
| #define MSR_IA32_THERM_STATUS 0x0000019c |
| #define MSR_IA32_MISC_ENABLE 0x000001a0 |
| |
| +/* MISC_ENABLE bits: architectural */ |
| +#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) |
| +#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) |
| +#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) |
| +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) |
| +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) |
| +#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) |
| +#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) |
| +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) |
| +#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) |
| +#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) |
| + |
| +/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ |
| +#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) |
| +#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) |
| +#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) |
| +#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) |
| +#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) |
| +#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) |
| +#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) |
| +#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) |
| +#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) |
| +#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) |
| +#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) |
| +#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) |
| +#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) |
| +#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) |
| +#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) |
| + |
| /* Intel Model 6 */ |
| #define MSR_P6_EVNTSEL0 0x00000186 |
| #define MSR_P6_EVNTSEL1 0x00000187 |
| --- a/arch/x86/kernel/cpu/intel.c |
| +++ b/arch/x86/kernel/cpu/intel.c |
| @@ -30,6 +30,19 @@ |
| |
| static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) |
| { |
| + /* Unmask CPUID levels if masked: */ |
| + if (c->x86 == 6 && c->x86_model >= 15) { |
| + u64 misc_enable; |
| + |
| + rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); |
| + |
| + if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) { |
| + misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; |
| + wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); |
| + c->cpuid_level = cpuid_eax(0); |
| + } |
| + } |
| + |
| if ((c->x86 == 0xf && c->x86_model >= 0x03) || |
| (c->x86 == 0x6 && c->x86_model >= 0x0e)) |
| set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |