Skip to content

Commit

Permalink
x86, cpu: Add forcepae parameter for booting PAE kernels on PAE-disab…
Browse files Browse the repository at this point in the history
…led 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>
  • Loading branch information
Chris Bainbridge authored and H. Peter Anvin committed Mar 20, 2014
1 parent 8c90487 commit 69f2366
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
parameter will force ia64_sal_cache_flush to call
ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.

forcepae [X86-32]
Forcefully enable Physical Address Extension (PAE).
Many Pentium M systems disable PAE but may have a
functionally usable PAE implementation.
Warning: use of this parameter will taint the kernel
and may cause unknown problems.

ftrace=[tracer]
[FTRACE] will set and start the specified tracer
as early as possible in order to facilitate early
Expand Down
20 changes: 20 additions & 0 deletions arch/x86/boot/cpucheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ static int is_transmeta(void)
cpu_vendor[2] == A32('M', 'x', '8', '6');
}

static int is_intel(void)
{
return cpu_vendor[0] == A32('G', 'e', 'n', 'u') &&
cpu_vendor[1] == A32('i', 'n', 'e', 'I') &&
cpu_vendor[2] == A32('n', 't', 'e', 'l');
}

/* Returns a bitmask of which words we have error bits in */
static int check_cpuflags(void)
{
Expand Down Expand Up @@ -153,6 +160,19 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));

err = check_cpuflags();
} else if (err == 0x01 &&
!(err_flags[0] & ~(1 << X86_FEATURE_PAE)) &&
is_intel() && cpu.level == 6 &&
(cpu.model == 9 || cpu.model == 13)) {
/* PAE is disabled on this Pentium M but can be forced */
if (cmdline_find_option_bool("forcepae")) {
puts("WARNING: Forcing PAE in CPU flags\n");
set_bit(X86_FEATURE_PAE, cpu.flags);
err = check_cpuflags();
}
else {
puts("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n");
}
}

if (err_flags_ptr)
Expand Down
19 changes: 19 additions & 0 deletions arch/x86/kernel/cpu/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ static void intel_smp_check(struct cpuinfo_x86 *c)
}
}

static int forcepae;
static int __init forcepae_setup(char *__unused)
{
forcepae = 1;
return 1;
}
__setup("forcepae", forcepae_setup);

static void intel_workarounds(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_X86_F00F_BUG
Expand Down Expand Up @@ -213,6 +221,17 @@ static void intel_workarounds(struct cpuinfo_x86 *c)
if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
clear_cpu_cap(c, X86_FEATURE_SEP);

/*
* PAE CPUID issue: many Pentium M report no PAE but may have a
* functionally usable PAE implementation.
* Forcefully enable PAE if kernel parameter "forcepae" is present.
*/
if (forcepae) {
printk(KERN_WARNING "PAE forced!\n");
set_cpu_cap(c, X86_FEATURE_PAE);
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_NOW_UNRELIABLE);
}

/*
* P4 Xeon errata 037 workaround.
* Hardware prefetcher may cause stale data to be loaded into the cache.
Expand Down

0 comments on commit 69f2366

Please sign in to comment.