Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, cpu: Add forcepae parameter for booting PAE kernels on PAE-disabled Pentium M

Many Pentium M systems disable PAE but may have a functionally usable PAE
implementation. This adds the "forcepae" parameter which bypasses the boot
check for PAE, and sets the CPU as being PAE capable. Using this parameter
will taint the kernel with TAINT_CPU_OUT_OF_SPEC.

Signed-off-by: Chris Bainbridge <chris.bainbridge@gmail.com>
Link: http://lkml.kernel.org/r/20140307114040.GA4997@localhost
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>

authored by

Chris Bainbridge and committed by
H. Peter Anvin
69f2366c 8c90487c

+46
+7
Documentation/kernel-parameters.txt
··· 1011 1011 parameter will force ia64_sal_cache_flush to call 1012 1012 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH. 1013 1013 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 + 1014 1021 ftrace=[tracer] 1015 1022 [FTRACE] will set and start the specified tracer 1016 1023 as early as possible in order to facilitate early
+20
arch/x86/boot/cpucheck.c
··· 67 67 cpu_vendor[2] == A32('M', 'x', '8', '6'); 68 68 } 69 69 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 + 70 77 /* Returns a bitmask of which words we have error bits in */ 71 78 static int check_cpuflags(void) 72 79 { ··· 160 153 asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); 161 154 162 155 err = check_cpuflags(); 156 + } else if (err == 0x01 && 157 + !(err_flags[0] & ~(1 << X86_FEATURE_PAE)) && 158 + is_intel() && cpu.level == 6 && 159 + (cpu.model == 9 || cpu.model == 13)) { 160 + /* PAE is disabled on this Pentium M but can be forced */ 161 + if (cmdline_find_option_bool("forcepae")) { 162 + puts("WARNING: Forcing PAE in CPU flags\n"); 163 + set_bit(X86_FEATURE_PAE, cpu.flags); 164 + err = check_cpuflags(); 165 + } 166 + else { 167 + puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n"); 168 + } 163 169 } 164 170 165 171 if (err_flags_ptr)
+19
arch/x86/kernel/cpu/intel.c
··· 186 186 } 187 187 } 188 188 189 + static int forcepae; 190 + static int __init forcepae_setup(char *__unused) 191 + { 192 + forcepae = 1; 193 + return 1; 194 + } 195 + __setup("forcepae", forcepae_setup); 196 + 189 197 static void intel_workarounds(struct cpuinfo_x86 *c) 190 198 { 191 199 #ifdef CONFIG_X86_F00F_BUG ··· 220 212 */ 221 213 if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) 222 214 clear_cpu_cap(c, X86_FEATURE_SEP); 215 + 216 + /* 217 + * PAE CPUID issue: many Pentium M report no PAE but may have a 218 + * functionally usable PAE implementation. 219 + * Forcefully enable PAE if kernel parameter "forcepae" is present. 220 + */ 221 + if (forcepae) { 222 + printk(KERN_WARNING "PAE forced!\n"); 223 + set_cpu_cap(c, X86_FEATURE_PAE); 224 + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE); 225 + } 223 226 224 227 /* 225 228 * P4 Xeon errata 037 workaround.