Commit 75a04811 authored by H. Peter Anvin's avatar H. Peter Anvin

x86: handle PAT more like other CPU features

Impact: Cleanup

When PAT was originally introduced, it was handled specially for a few
reasons:

- PAT bugs are hard to track down, so we wanted to maintain a
  whitelist of CPUs.
- The i386 and x86-64 CPUID code was not yet unified.

Both of these are now obsolete, so handle PAT like any other features,
including ordinary feature blacklisting due to known bugs.
Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent b1882e68
...@@ -5,10 +5,8 @@ ...@@ -5,10 +5,8 @@
#ifdef CONFIG_X86_PAT #ifdef CONFIG_X86_PAT
extern int pat_enabled; extern int pat_enabled;
extern void validate_pat_support(struct cpuinfo_x86 *c);
#else #else
static const int pat_enabled; static const int pat_enabled;
static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
#endif #endif
extern void pat_init(void); extern void pat_init(void);
...@@ -17,6 +15,4 @@ extern int reserve_memtype(u64 start, u64 end, ...@@ -17,6 +15,4 @@ extern int reserve_memtype(u64 start, u64 end,
unsigned long req_type, unsigned long *ret_type); unsigned long req_type, unsigned long *ret_type);
extern int free_memtype(u64 start, u64 end); extern int free_memtype(u64 start, u64 end);
extern void pat_disable(char *reason);
#endif /* _ASM_X86_PAT_H */ #endif /* _ASM_X86_PAT_H */
...@@ -143,37 +143,3 @@ void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c) ...@@ -143,37 +143,3 @@ void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c)
return; return;
#endif #endif
} }
#ifdef CONFIG_X86_PAT
void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
{
if (!cpu_has_pat)
pat_disable("PAT not supported by CPU.");
switch (c->x86_vendor) {
case X86_VENDOR_INTEL:
/*
* There is a known erratum on Pentium III and Core Solo
* and Core Duo CPUs.
* " Page with PAT set to WC while associated MTRR is UC
* may consolidate to UC "
* Because of this erratum, it is better to stick with
* setting WC in MTRR rather than using PAT on these CPUs.
*
* Enable PAT WC only on P4, Core 2 or later CPUs.
*/
if (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 15))
return;
pat_disable("PAT WC disabled due to known CPU erratum.");
return;
case X86_VENDOR_AMD:
case X86_VENDOR_CENTAUR:
case X86_VENDOR_TRANSMETA:
return;
}
pat_disable("PAT disabled. Not yet verified on this CPU type.");
}
#endif
...@@ -570,8 +570,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) ...@@ -570,8 +570,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
if (this_cpu->c_early_init) if (this_cpu->c_early_init)
this_cpu->c_early_init(c); this_cpu->c_early_init(c);
validate_pat_support(c);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
c->cpu_index = boot_cpu_id; c->cpu_index = boot_cpu_id;
#endif #endif
......
...@@ -50,6 +50,18 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) ...@@ -50,6 +50,18 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
} }
/*
* There is a known erratum on Pentium III and Core Solo
* and Core Duo CPUs.
* " Page with PAT set to WC while associated MTRR is UC
* may consolidate to UC "
* Because of this erratum, it is better to stick with
* setting WC in MTRR rather than using PAT on these CPUs.
*
* Enable PAT WC only on P4, Core 2 or later CPUs.
*/
if (c->x86 == 6 && c->x86_model < 15)
clear_cpu_cap(c, X86_FEATURE_PAT);
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#ifdef CONFIG_X86_PAT #ifdef CONFIG_X86_PAT
int __read_mostly pat_enabled = 1; int __read_mostly pat_enabled = 1;
void __cpuinit pat_disable(char *reason) void __cpuinit pat_disable(const char *reason)
{ {
pat_enabled = 0; pat_enabled = 0;
printk(KERN_INFO "%s\n", reason); printk(KERN_INFO "%s\n", reason);
...@@ -42,6 +42,11 @@ static int __init nopat(char *str) ...@@ -42,6 +42,11 @@ static int __init nopat(char *str)
return 0; return 0;
} }
early_param("nopat", nopat); early_param("nopat", nopat);
#else
static inline void pat_disable(const char *reason)
{
(void)reason;
}
#endif #endif
...@@ -78,8 +83,11 @@ void pat_init(void) ...@@ -78,8 +83,11 @@ void pat_init(void)
if (!pat_enabled) if (!pat_enabled)
return; return;
/* Paranoia check. */ if (!cpu_has_pat) {
if (!cpu_has_pat && boot_pat_state) { if (!boot_pat_state) {
pat_disable("PAT not supported by CPU.");
return;
} else {
/* /*
* If this happens we are on a secondary CPU, but * If this happens we are on a secondary CPU, but
* switched to PAT on the boot CPU. We have no way to * switched to PAT on the boot CPU. We have no way to
...@@ -89,6 +97,7 @@ void pat_init(void) ...@@ -89,6 +97,7 @@ void pat_init(void)
"but not supported by secondary CPU\n"); "but not supported by secondary CPU\n");
BUG(); BUG();
} }
}
/* Set PWT to Write-Combining. All other bits stay the same */ /* Set PWT to Write-Combining. All other bits stay the same */
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment