aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Bainbridge <chris.bainbridge@gmail.com>2014-03-07 06:40:42 -0500
committerH. Peter Anvin <hpa@zytor.com>2014-03-20 19:31:54 -0400
commit69f2366c9456d0ce784cf5aba87ee77eeadc1d5e (patch)
tree3e4405ced0145cbcbbf303106965cad9075cb4a4
parent8c90487cdc64847b4fdd812ab3047f426fec4d13 (diff)
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>
-rw-r--r--Documentation/kernel-parameters.txt7
-rw-r--r--arch/x86/boot/cpucheck.c20
-rw-r--r--arch/x86/kernel/cpu/intel.c19
3 files changed, 46 insertions, 0 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 7116fda7077f..06600cc9a26c 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1011,6 +1011,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1011 parameter will force ia64_sal_cache_flush to call 1011 parameter will force ia64_sal_cache_flush to call
1012 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH. 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 ftrace=[tracer] 1021 ftrace=[tracer]
1015 [FTRACE] will set and start the specified tracer 1022 [FTRACE] will set and start the specified tracer
1016 as early as possible in order to facilitate early 1023 as early as possible in order to facilitate early
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 100a9a10076a..f0d0b20fe149 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -67,6 +67,13 @@ static int is_transmeta(void)
67 cpu_vendor[2] == A32('M', 'x', '8', '6'); 67 cpu_vendor[2] == A32('M', 'x', '8', '6');
68} 68}
69 69
70static 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/* Returns a bitmask of which words we have error bits in */ 77/* Returns a bitmask of which words we have error bits in */
71static int check_cpuflags(void) 78static int check_cpuflags(void)
72{ 79{
@@ -153,6 +160,19 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
153 asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); 160 asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
154 161
155 err = check_cpuflags(); 162 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 }
156 } 176 }
157 177
158 if (err_flags_ptr) 178 if (err_flags_ptr)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 34bbb555e269..897d6201ef10 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -186,6 +186,14 @@ static void intel_smp_check(struct cpuinfo_x86 *c)
186 } 186 }
187} 187}
188 188
189static int forcepae;
190static int __init forcepae_setup(char *__unused)
191{
192 forcepae = 1;
193 return 1;
194}
195__setup("forcepae", forcepae_setup);
196
189static void intel_workarounds(struct cpuinfo_x86 *c) 197static void intel_workarounds(struct cpuinfo_x86 *c)
190{ 198{
191#ifdef CONFIG_X86_F00F_BUG 199#ifdef CONFIG_X86_F00F_BUG
@@ -214,6 +222,17 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
214 clear_cpu_cap(c, X86_FEATURE_SEP); 222 clear_cpu_cap(c, X86_FEATURE_SEP);
215 223
216 /* 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
235 /*
217 * P4 Xeon errata 037 workaround. 236 * P4 Xeon errata 037 workaround.
218 * Hardware prefetcher may cause stale data to be loaded into the cache. 237 * Hardware prefetcher may cause stale data to be loaded into the cache.
219 */ 238 */