Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 96347
b: refs/heads/master
c: 8d4a430
h: refs/heads/master
i:
  96345: 9258bbe
  96343: a3a99ef
v: v3
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed May 8, 2008
1 parent 1456ed1 commit 9cb607e
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 61 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cb3f43b22bbb5ddbf6ce3e2bac40ce6eba30aba0
refs/heads/master: 8d4a4300854f3971502e81dacd930704cb88f606
21 changes: 21 additions & 0 deletions trunk/arch/x86/kernel/cpu/addon_cpuid_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <linux/cpu.h>

#include <asm/pat.h>
#include <asm/processor.h>

struct cpuid_bit {
Expand Down Expand Up @@ -48,3 +49,23 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
set_cpu_cap(c, cb->feature);
}
}

#ifdef CONFIG_X86_PAT
void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
{
switch (c->x86_vendor) {
case X86_VENDOR_AMD:
if (c->x86 >= 0xf && c->x86 <= 0x11)
return;
break;
case X86_VENDOR_INTEL:
if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
return;
break;
}

pat_disable(cpu_has_pat ?
"PAT disabled. Not yet verified on this CPU type." :
"PAT not supported by CPU.");
}
#endif
27 changes: 2 additions & 25 deletions trunk/arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <asm/mmu_context.h>
#include <asm/mtrr.h>
#include <asm/mce.h>
#include <asm/pat.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/mpspec.h>
#include <asm/apic.h>
Expand Down Expand Up @@ -308,19 +309,6 @@ static void __cpuinit early_get_cap(struct cpuinfo_x86 *c)

}

clear_cpu_cap(c, X86_FEATURE_PAT);

switch (c->x86_vendor) {
case X86_VENDOR_AMD:
if (c->x86 >= 0xf && c->x86 <= 0x11)
set_cpu_cap(c, X86_FEATURE_PAT);
break;
case X86_VENDOR_INTEL:
if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
set_cpu_cap(c, X86_FEATURE_PAT);
break;
}

}

/*
Expand Down Expand Up @@ -409,18 +397,6 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
init_scattered_cpuid_features(c);
}

clear_cpu_cap(c, X86_FEATURE_PAT);

switch (c->x86_vendor) {
case X86_VENDOR_AMD:
if (c->x86 >= 0xf && c->x86 <= 0x11)
set_cpu_cap(c, X86_FEATURE_PAT);
break;
case X86_VENDOR_INTEL:
if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
set_cpu_cap(c, X86_FEATURE_PAT);
break;
}
}

static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
Expand Down Expand Up @@ -651,6 +627,7 @@ void __init early_cpu_init(void)
cpu_devs[cvdev->vendor] = cvdev->cpu_dev;

early_cpu_detect();
validate_pat_support(&boot_cpu_data);
}

/* Make sure %fs is initialized properly in idle threads */
Expand Down
9 changes: 2 additions & 7 deletions trunk/arch/x86/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include <asm/ds.h>
#include <asm/topology.h>
#include <asm/trampoline.h>
#include <asm/pat.h>

#include <mach_apic.h>
#ifdef CONFIG_PARAVIRT
Expand Down Expand Up @@ -1063,25 +1064,19 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
if (c->extended_cpuid_level >= 0x80000007)
c->x86_power = cpuid_edx(0x80000007);


clear_cpu_cap(c, X86_FEATURE_PAT);

switch (c->x86_vendor) {
case X86_VENDOR_AMD:
early_init_amd(c);
if (c->x86 >= 0xf && c->x86 <= 0x11)
set_cpu_cap(c, X86_FEATURE_PAT);
break;
case X86_VENDOR_INTEL:
early_init_intel(c);
if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
set_cpu_cap(c, X86_FEATURE_PAT);
break;
case X86_VENDOR_CENTAUR:
early_init_centaur(c);
break;
}

validate_pat_support(c);
}

/*
Expand Down
50 changes: 22 additions & 28 deletions trunk/arch/x86/mm/pat.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,24 @@
#include <asm/mtrr.h>
#include <asm/io.h>

int pat_wc_enabled = 1;
#ifdef CONFIG_X86_PAT
int __read_mostly pat_wc_enabled = 1;

static u64 __read_mostly boot_pat_state;

static int nopat(char *str)
void __init pat_disable(char *reason)
{
pat_wc_enabled = 0;
printk(KERN_INFO "x86: PAT support disabled.\n");

return 0;
printk(KERN_INFO "%s\n", reason);
}
early_param("nopat", nopat);

static int pat_known_cpu(void)
static int nopat(char *str)
{
if (!pat_wc_enabled)
return 0;

if (cpu_has_pat)
return 1;

pat_wc_enabled = 0;
printk(KERN_INFO "CPU and/or kernel does not support PAT.\n");
pat_disable("PAT support disabled.");
return 0;
}
early_param("nopat", nopat);
#endif

static u64 __read_mostly boot_pat_state;

enum {
PAT_UC = 0, /* uncached */
Expand All @@ -66,17 +59,19 @@ void pat_init(void)
{
u64 pat;

#ifndef CONFIG_X86_PAT
nopat(NULL);
#endif

/* Boot CPU enables PAT based on CPU feature */
if (!smp_processor_id() && !pat_known_cpu())
if (!pat_wc_enabled)
return;

/* APs enable PAT iff boot CPU has enabled it before */
if (smp_processor_id() && !pat_wc_enabled)
return;
/* Paranoia check. */
if (!cpu_has_pat) {
printk(KERN_ERR "PAT enabled, but CPU feature cleared\n");
/*
* Panic if this happens on the secondary CPU, and we
* switched to PAT on the boot CPU. We have no way to
* undo PAT.
*/
BUG_ON(boot_pat_state);
}

/* Set PWT to Write-Combining. All other bits stay the same */
/*
Expand All @@ -95,9 +90,8 @@ void pat_init(void)
PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC);

/* Boot CPU check */
if (!smp_processor_id()) {
if (!boot_pat_state)
rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
}

wrmsrl(MSR_IA32_CR_PAT, pat);
printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n",
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/asm-x86/pat.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@

#include <linux/types.h>

#ifdef CONFIG_X86_PAT
extern int pat_wc_enabled;
extern void validate_pat_support(struct cpuinfo_x86 *c);
#else
static const int pat_wc_enabled = 0;
static inline void validate_pat_support(struct cpuinfo_x86 *c) { }
#endif

extern void pat_init(void);

extern int reserve_memtype(u64 start, u64 end,
unsigned long req_type, unsigned long *ret_type);
extern int free_memtype(u64 start, u64 end);

extern void pat_disable(char *reason);

#endif

0 comments on commit 9cb607e

Please sign in to comment.