Skip to content

Commit 918d80a

Browse files
committed
Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 cpu handling changes from Ingo Molnar: "Bigger changes: - Intel CPU hardware-enablement: new vector instructions support (AVX-512), by Fenghua Yu. - Support the clflushopt instruction and use it in appropriate places. clflushopt is similar to clflush but with more relaxed ordering, by Ross Zwisler. - MSR accessor cleanups, by Borislav Petkov. - 'forcepae' boot flag for those who have way too much time to spend on way too old Pentium-M systems and want to live way too dangerously, by Chris Bainbridge" * 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, cpu: Add forcepae parameter for booting PAE kernels on PAE-disabled Pentium M Rename TAINT_UNSAFE_SMP to TAINT_CPU_OUT_OF_SPEC x86, intel: Make MSR_IA32_MISC_ENABLE bit constants systematic x86, Intel: Convert to the new bit access MSR accessors x86, AMD: Convert to the new bit access MSR accessors x86: Add another set of MSR accessor functions x86: Use clflushopt in drm_clflush_virt_range x86: Use clflushopt in drm_clflush_page x86: Use clflushopt in clflush_cache_range x86: Add support for the clflushopt instruction x86, AVX-512: Enable AVX-512 States Context Switch x86, AVX-512: AVX-512 Feature Detection
2 parents 26a5c0d + 69f2366 commit 918d80a

File tree

15 files changed

+248
-101
lines changed

15 files changed

+248
-101
lines changed

Documentation/kernel-parameters.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
10111011
parameter will force ia64_sal_cache_flush to call
10121012
ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
10131013

1014+
forcepae [X86-32]
1015+
Forcefully enable Physical Address Extension (PAE).
1016+
Many Pentium M systems disable PAE but may have a
1017+
functionally usable PAE implementation.
1018+
Warning: use of this parameter will taint the kernel
1019+
and may cause unknown problems.
1020+
10141021
ftrace=[tracer]
10151022
[FTRACE] will set and start the specified tracer
10161023
as early as possible in order to facilitate early

arch/x86/boot/cpucheck.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ static int is_transmeta(void)
6767
cpu_vendor[2] == A32('M', 'x', '8', '6');
6868
}
6969

70+
static int is_intel(void)
71+
{
72+
return cpu_vendor[0] == A32('G', 'e', 'n', 'u') &&
73+
cpu_vendor[1] == A32('i', 'n', 'e', 'I') &&
74+
cpu_vendor[2] == A32('n', 't', 'e', 'l');
75+
}
76+
7077
/* Returns a bitmask of which words we have error bits in */
7178
static int check_cpuflags(void)
7279
{
@@ -153,6 +160,19 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
153160
asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
154161

155162
err = check_cpuflags();
163+
} else if (err == 0x01 &&
164+
!(err_flags[0] & ~(1 << X86_FEATURE_PAE)) &&
165+
is_intel() && cpu.level == 6 &&
166+
(cpu.model == 9 || cpu.model == 13)) {
167+
/* PAE is disabled on this Pentium M but can be forced */
168+
if (cmdline_find_option_bool("forcepae")) {
169+
puts("WARNING: Forcing PAE in CPU flags\n");
170+
set_bit(X86_FEATURE_PAE, cpu.flags);
171+
err = check_cpuflags();
172+
}
173+
else {
174+
puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n");
175+
}
156176
}
157177

158178
if (err_flags_ptr)

arch/x86/include/asm/cpufeature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,14 @@
217217
#define X86_FEATURE_INVPCID (9*32+10) /* Invalidate Processor Context ID */
218218
#define X86_FEATURE_RTM (9*32+11) /* Restricted Transactional Memory */
219219
#define X86_FEATURE_MPX (9*32+14) /* Memory Protection Extension */
220+
#define X86_FEATURE_AVX512F (9*32+16) /* AVX-512 Foundation */
220221
#define X86_FEATURE_RDSEED (9*32+18) /* The RDSEED instruction */
221222
#define X86_FEATURE_ADX (9*32+19) /* The ADCX and ADOX instructions */
222223
#define X86_FEATURE_SMAP (9*32+20) /* Supervisor Mode Access Prevention */
224+
#define X86_FEATURE_CLFLUSHOPT (9*32+23) /* CLFLUSHOPT instruction */
225+
#define X86_FEATURE_AVX512PF (9*32+26) /* AVX-512 Prefetch */
226+
#define X86_FEATURE_AVX512ER (9*32+27) /* AVX-512 Exponential and Reciprocal */
227+
#define X86_FEATURE_AVX512CD (9*32+28) /* AVX-512 Conflict Detection */
223228

224229
/*
225230
* BUG word(s)

arch/x86/include/asm/msr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ do { \
214214

215215
struct msr *msrs_alloc(void);
216216
void msrs_free(struct msr *msrs);
217+
int msr_set_bit(u32 msr, u8 bit);
218+
int msr_clear_bit(u32 msr, u8 bit);
217219

218220
#ifdef CONFIG_SMP
219221
int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);

arch/x86/include/asm/special_insns.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ static inline void clflush(volatile void *__p)
191191
asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
192192
}
193193

194+
static inline void clflushopt(volatile void *__p)
195+
{
196+
alternative_io(".byte " __stringify(NOP_DS_PREFIX) "; clflush %P0",
197+
".byte 0x66; clflush %P0",
198+
X86_FEATURE_CLFLUSHOPT,
199+
"+m" (*(volatile char __force *)__p));
200+
}
201+
194202
#define nop() asm volatile ("nop")
195203

196204

arch/x86/include/asm/xsave.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
#define XSTATE_CPUID 0x0000000d
88

9-
#define XSTATE_FP 0x1
10-
#define XSTATE_SSE 0x2
11-
#define XSTATE_YMM 0x4
12-
#define XSTATE_BNDREGS 0x8
13-
#define XSTATE_BNDCSR 0x10
9+
#define XSTATE_FP 0x1
10+
#define XSTATE_SSE 0x2
11+
#define XSTATE_YMM 0x4
12+
#define XSTATE_BNDREGS 0x8
13+
#define XSTATE_BNDCSR 0x10
14+
#define XSTATE_OPMASK 0x20
15+
#define XSTATE_ZMM_Hi256 0x40
16+
#define XSTATE_Hi16_ZMM 0x80
1417

1518
#define XSTATE_FPSSE (XSTATE_FP | XSTATE_SSE)
1619

@@ -23,7 +26,8 @@
2326
#define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET)
2427

2528
/* Supported features which support lazy state saving */
26-
#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM)
29+
#define XSTATE_LAZY (XSTATE_FP | XSTATE_SSE | XSTATE_YMM \
30+
| XSTATE_OPMASK | XSTATE_ZMM_Hi256 | XSTATE_Hi16_ZMM)
2731

2832
/* Supported features which require eager state saving */
2933
#define XSTATE_EAGER (XSTATE_BNDREGS | XSTATE_BNDCSR)

arch/x86/include/uapi/asm/msr-index.h

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -368,33 +368,58 @@
368368
#define THERM_LOG_THRESHOLD1 (1 << 9)
369369

370370
/* MISC_ENABLE bits: architectural */
371-
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0)
372-
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1)
373-
#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7)
374-
#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11)
375-
#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12)
376-
#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16)
377-
#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18)
378-
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22)
379-
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23)
380-
#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34)
371+
#define MSR_IA32_MISC_ENABLE_FAST_STRING_BIT 0
372+
#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << MSR_IA32_MISC_ENABLE_FAST_STRING_BIT)
373+
#define MSR_IA32_MISC_ENABLE_TCC_BIT 1
374+
#define MSR_IA32_MISC_ENABLE_TCC (1ULL << MSR_IA32_MISC_ENABLE_TCC_BIT)
375+
#define MSR_IA32_MISC_ENABLE_EMON_BIT 7
376+
#define MSR_IA32_MISC_ENABLE_EMON (1ULL << MSR_IA32_MISC_ENABLE_EMON_BIT)
377+
#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT 11
378+
#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT)
379+
#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT 12
380+
#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT)
381+
#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT 16
382+
#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT)
383+
#define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18
384+
#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT)
385+
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22
386+
#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT);
387+
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23
388+
#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT)
389+
#define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34
390+
#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT)
381391

382392
/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
383-
#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2)
384-
#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3)
385-
#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4)
386-
#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6)
387-
#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8)
388-
#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9)
389-
#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10)
390-
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10)
391-
#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13)
392-
#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19)
393-
#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20)
394-
#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24)
395-
#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37)
396-
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38)
397-
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39)
393+
#define MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT 2
394+
#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT)
395+
#define MSR_IA32_MISC_ENABLE_TM1_BIT 3
396+
#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << MSR_IA32_MISC_ENABLE_TM1_BIT)
397+
#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT 4
398+
#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT)
399+
#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT 6
400+
#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT)
401+
#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT 8
402+
#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT)
403+
#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT 9
404+
#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT)
405+
#define MSR_IA32_MISC_ENABLE_FERR_BIT 10
406+
#define MSR_IA32_MISC_ENABLE_FERR (1ULL << MSR_IA32_MISC_ENABLE_FERR_BIT)
407+
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT 10
408+
#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT)
409+
#define MSR_IA32_MISC_ENABLE_TM2_BIT 13
410+
#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << MSR_IA32_MISC_ENABLE_TM2_BIT)
411+
#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT 19
412+
#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT)
413+
#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT 20
414+
#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT)
415+
#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT 24
416+
#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT)
417+
#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT 37
418+
#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT)
419+
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT 38
420+
#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT)
421+
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT 39
422+
#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT)
398423

399424
#define MSR_IA32_TSC_DEADLINE 0x000006E0
400425

arch/x86/kernel/cpu/amd.c

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static void amd_k7_smp_check(struct cpuinfo_x86 *c)
218218
*/
219219
WARN_ONCE(1, "WARNING: This combination of AMD"
220220
" processors is not suitable for SMP.\n");
221-
add_taint(TAINT_UNSAFE_SMP, LOCKDEP_NOW_UNRELIABLE);
221+
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE);
222222
}
223223

224224
static void init_amd_k7(struct cpuinfo_x86 *c)
@@ -233,9 +233,7 @@ static void init_amd_k7(struct cpuinfo_x86 *c)
233233
if (c->x86_model >= 6 && c->x86_model <= 10) {
234234
if (!cpu_has(c, X86_FEATURE_XMM)) {
235235
printk(KERN_INFO "Enabling disabled K7/SSE Support.\n");
236-
rdmsr(MSR_K7_HWCR, l, h);
237-
l &= ~0x00008000;
238-
wrmsr(MSR_K7_HWCR, l, h);
236+
msr_clear_bit(MSR_K7_HWCR, 15);
239237
set_cpu_cap(c, X86_FEATURE_XMM);
240238
}
241239
}
@@ -509,14 +507,8 @@ static void early_init_amd(struct cpuinfo_x86 *c)
509507
#endif
510508

511509
/* F16h erratum 793, CVE-2013-6885 */
512-
if (c->x86 == 0x16 && c->x86_model <= 0xf) {
513-
u64 val;
514-
515-
rdmsrl(MSR_AMD64_LS_CFG, val);
516-
if (!(val & BIT(15)))
517-
wrmsrl(MSR_AMD64_LS_CFG, val | BIT(15));
518-
}
519-
510+
if (c->x86 == 0x16 && c->x86_model <= 0xf)
511+
msr_set_bit(MSR_AMD64_LS_CFG, 15);
520512
}
521513

522514
static const int amd_erratum_383[];
@@ -536,11 +528,8 @@ static void init_amd(struct cpuinfo_x86 *c)
536528
* Errata 63 for SH-B3 steppings
537529
* Errata 122 for all steppings (F+ have it disabled by default)
538530
*/
539-
if (c->x86 == 0xf) {
540-
rdmsrl(MSR_K7_HWCR, value);
541-
value |= 1 << 6;
542-
wrmsrl(MSR_K7_HWCR, value);
543-
}
531+
if (c->x86 == 0xf)
532+
msr_set_bit(MSR_K7_HWCR, 6);
544533
#endif
545534

546535
early_init_amd(c);
@@ -623,14 +612,11 @@ static void init_amd(struct cpuinfo_x86 *c)
623612
(c->x86_model >= 0x10) && (c->x86_model <= 0x1f) &&
624613
!cpu_has(c, X86_FEATURE_TOPOEXT)) {
625614

626-
if (!rdmsrl_safe(0xc0011005, &value)) {
627-
value |= 1ULL << 54;
628-
wrmsrl_safe(0xc0011005, value);
615+
if (msr_set_bit(0xc0011005, 54) > 0) {
629616
rdmsrl(0xc0011005, value);
630-
if (value & (1ULL << 54)) {
617+
if (value & BIT_64(54)) {
631618
set_cpu_cap(c, X86_FEATURE_TOPOEXT);
632-
printk(KERN_INFO FW_INFO "CPU: Re-enabling "
633-
"disabled Topology Extensions Support\n");
619+
pr_info(FW_INFO "CPU: Re-enabling disabled Topology Extensions Support.\n");
634620
}
635621
}
636622
}
@@ -709,19 +695,12 @@ static void init_amd(struct cpuinfo_x86 *c)
709695
* Disable GART TLB Walk Errors on Fam10h. We do this here
710696
* because this is always needed when GART is enabled, even in a
711697
* kernel which has no MCE support built in.
712-
* BIOS should disable GartTlbWlk Errors themself. If
713-
* it doesn't do it here as suggested by the BKDG.
698+
* BIOS should disable GartTlbWlk Errors already. If
699+
* it doesn't, do it here as suggested by the BKDG.
714700
*
715701
* Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012
716702
*/
717-
u64 mask;
718-
int err;
719-
720-
err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask);
721-
if (err == 0) {
722-
mask |= (1 << 10);
723-
wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask);
724-
}
703+
msr_set_bit(MSR_AMD64_MCx_MASK(4), 10);
725704

726705
/*
727706
* On family 10h BIOS may not have properly enabled WC+ support,
@@ -733,10 +712,7 @@ static void init_amd(struct cpuinfo_x86 *c)
733712
* NOTE: we want to use the _safe accessors so as not to #GP kvm
734713
* guests on older kvm hosts.
735714
*/
736-
737-
rdmsrl_safe(MSR_AMD64_BU_CFG2, &value);
738-
value &= ~(1ULL << 24);
739-
wrmsrl_safe(MSR_AMD64_BU_CFG2, value);
715+
msr_clear_bit(MSR_AMD64_BU_CFG2, 24);
740716

741717
if (cpu_has_amd_erratum(c, amd_erratum_383))
742718
set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);

arch/x86/kernel/cpu/intel.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,8 @@ static void early_init_intel(struct cpuinfo_x86 *c)
3131

3232
/* Unmask CPUID levels if masked: */
3333
if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
34-
rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
35-
36-
if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) {
37-
misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
38-
wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
34+
if (msr_clear_bit(MSR_IA32_MISC_ENABLE,
35+
MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0) {
3936
c->cpuid_level = cpuid_eax(0);
4037
get_cpu_cap(c);
4138
}
@@ -129,16 +126,10 @@ static void early_init_intel(struct cpuinfo_x86 *c)
129126
* Ingo Molnar reported a Pentium D (model 6) and a Xeon
130127
* (model 2) with the same problem.
131128
*/
132-
if (c->x86 == 15) {
133-
rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
134-
135-
if (misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING) {
136-
printk(KERN_INFO "kmemcheck: Disabling fast string operations\n");
137-
138-
misc_enable &= ~MSR_IA32_MISC_ENABLE_FAST_STRING;
139-
wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
140-
}
141-
}
129+
if (c->x86 == 15)
130+
if (msr_clear_bit(MSR_IA32_MISC_ENABLE,
131+
MSR_IA32_MISC_ENABLE_FAST_STRING_BIT) > 0)
132+
pr_info("kmemcheck: Disabling fast string operations\n");
142133
#endif
143134

144135
/*
@@ -195,10 +186,16 @@ static void intel_smp_check(struct cpuinfo_x86 *c)
195186
}
196187
}
197188

198-
static void intel_workarounds(struct cpuinfo_x86 *c)
189+
static int forcepae;
190+
static int __init forcepae_setup(char *__unused)
199191
{
200-
unsigned long lo, hi;
192+
forcepae = 1;
193+
return 1;
194+
}
195+
__setup("forcepae", forcepae_setup);
201196

197+
static void intel_workarounds(struct cpuinfo_x86 *c)
198+
{
202199
#ifdef CONFIG_X86_F00F_BUG
203200
/*
204201
* All current models of Pentium and Pentium with MMX technology CPUs
@@ -224,17 +221,27 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
224221
if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
225222
clear_cpu_cap(c, X86_FEATURE_SEP);
226223

224+
/*
225+
* PAE CPUID issue: many Pentium M report no PAE but may have a
226+
* functionally usable PAE implementation.
227+
* Forcefully enable PAE if kernel parameter "forcepae" is present.
228+
*/
229+
if (forcepae) {
230+
printk(KERN_WARNING "PAE forced!\n");
231+
set_cpu_cap(c, X86_FEATURE_PAE);
232+
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE);
233+
}
234+
227235
/*
228236
* P4 Xeon errata 037 workaround.
229237
* Hardware prefetcher may cause stale data to be loaded into the cache.
230238
*/
231239
if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
232-
rdmsr(MSR_IA32_MISC_ENABLE, lo, hi);
233-
if ((lo & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE) == 0) {
234-
printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n");
235-
printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n");
236-
lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE;
237-
wrmsr(MSR_IA32_MISC_ENABLE, lo, hi);
240+
if (msr_set_bit(MSR_IA32_MISC_ENABLE,
241+
MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT)
242+
> 0) {
243+
pr_info("CPU: C0 stepping P4 Xeon detected.\n");
244+
pr_info("CPU: Disabling hardware prefetching (Errata 037)\n");
238245
}
239246
}
240247

0 commit comments

Comments
 (0)