aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-05-08 03:18:43 -0400
committerIngo Molnar <mingo@elte.hu>2008-05-08 09:43:51 -0400
commit8d4a4300854f3971502e81dacd930704cb88f606 (patch)
treed091b49851e60af1530dd3d7cd54057f98d48ffb /arch/x86/mm
parentcb3f43b22bbb5ddbf6ce3e2bac40ce6eba30aba0 (diff)
x86: cleanup PAT cpu validation
Move the scattered checks for PAT support to a single function. Its moved to addon_cpuid_features.c as this file is shared between 32 and 64 bit. Remove the manipulation of the PAT feature bit and just disable PAT in the PAT layer, based on the PAT bit provided by the CPU and the current CPU version/model white list. Change the boot CPU check so it works on Voyager somewhere in the future as well :) Also panic, when a secondary has PAT disabled but the primary one has alrady switched to PAT. We have no way to undo that. The white list is kept for now to ensure that we can rely on known to work CPU types and concentrate on the software induced problems instead of fighthing CPU erratas and subtle wreckage caused by not yet verified CPUs. Once the PAT code has stabilized enough, we can remove the white list and open the can of worms. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r--arch/x86/mm/pat.c50
1 files changed, 22 insertions, 28 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 277446cd30b6..60adbe22efa0 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -25,31 +25,24 @@
25#include <asm/mtrr.h> 25#include <asm/mtrr.h>
26#include <asm/io.h> 26#include <asm/io.h>
27 27
28int pat_wc_enabled = 1; 28#ifdef CONFIG_X86_PAT
29int __read_mostly pat_wc_enabled = 1;
29 30
30static u64 __read_mostly boot_pat_state; 31void __init pat_disable(char *reason)
31
32static int nopat(char *str)
33{ 32{
34 pat_wc_enabled = 0; 33 pat_wc_enabled = 0;
35 printk(KERN_INFO "x86: PAT support disabled.\n"); 34 printk(KERN_INFO "%s\n", reason);
36
37 return 0;
38} 35}
39early_param("nopat", nopat);
40 36
41static int pat_known_cpu(void) 37static int nopat(char *str)
42{ 38{
43 if (!pat_wc_enabled) 39 pat_disable("PAT support disabled.");
44 return 0;
45
46 if (cpu_has_pat)
47 return 1;
48
49 pat_wc_enabled = 0;
50 printk(KERN_INFO "CPU and/or kernel does not support PAT.\n");
51 return 0; 40 return 0;
52} 41}
42early_param("nopat", nopat);
43#endif
44
45static u64 __read_mostly boot_pat_state;
53 46
54enum { 47enum {
55 PAT_UC = 0, /* uncached */ 48 PAT_UC = 0, /* uncached */
@@ -66,17 +59,19 @@ void pat_init(void)
66{ 59{
67 u64 pat; 60 u64 pat;
68 61
69#ifndef CONFIG_X86_PAT 62 if (!pat_wc_enabled)
70 nopat(NULL);
71#endif
72
73 /* Boot CPU enables PAT based on CPU feature */
74 if (!smp_processor_id() && !pat_known_cpu())
75 return; 63 return;
76 64
77 /* APs enable PAT iff boot CPU has enabled it before */ 65 /* Paranoia check. */
78 if (smp_processor_id() && !pat_wc_enabled) 66 if (!cpu_has_pat) {
79 return; 67 printk(KERN_ERR "PAT enabled, but CPU feature cleared\n");
68 /*
69 * Panic if this happens on the secondary CPU, and we
70 * switched to PAT on the boot CPU. We have no way to
71 * undo PAT.
72 */
73 BUG_ON(boot_pat_state);
74 }
80 75
81 /* Set PWT to Write-Combining. All other bits stay the same */ 76 /* Set PWT to Write-Combining. All other bits stay the same */
82 /* 77 /*
@@ -95,9 +90,8 @@ void pat_init(void)
95 PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC); 90 PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC);
96 91
97 /* Boot CPU check */ 92 /* Boot CPU check */
98 if (!smp_processor_id()) { 93 if (!boot_pat_state)
99 rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); 94 rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
100 }
101 95
102 wrmsrl(MSR_IA32_CR_PAT, pat); 96 wrmsrl(MSR_IA32_CR_PAT, pat);
103 printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n", 97 printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n",