x86/mm/pat: Untangle pat_init()
Split it into a BSP and AP version which makes the PAT initialization path actually readable again. Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Toshi Kani <toshi.kani@hp.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Elliott@hp.com Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Luis R. Rodriguez <mcgrof@suse.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: arnd@arndb.de Cc: hch@lst.de Cc: hmh@hmh.eng.br Cc: jgross@suse.com Cc: konrad.wilk@oracle.com Cc: linux-mm <linux-mm@kvack.org> Cc: linux-nvdimm@lists.01.org Cc: stefan.bader@canonical.com Cc: yigal@plexistor.com Link: http://lkml.kernel.org/r/1433436928-31903-2-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
d6472302f2
commit
9dac629094
1 changed files with 40 additions and 29 deletions
|
@ -36,6 +36,8 @@
|
||||||
#undef pr_fmt
|
#undef pr_fmt
|
||||||
#define pr_fmt(fmt) "" fmt
|
#define pr_fmt(fmt) "" fmt
|
||||||
|
|
||||||
|
static bool boot_cpu_done;
|
||||||
|
|
||||||
static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
|
static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
|
||||||
|
|
||||||
static inline void pat_disable(const char *reason)
|
static inline void pat_disable(const char *reason)
|
||||||
|
@ -194,31 +196,47 @@ void pat_init_cache_modes(void)
|
||||||
|
|
||||||
#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
|
#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
|
||||||
|
|
||||||
|
static void pat_bsp_init(u64 pat)
|
||||||
|
{
|
||||||
|
if (!cpu_has_pat) {
|
||||||
|
pat_disable("PAT not supported by CPU.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
|
||||||
|
if (!boot_pat_state) {
|
||||||
|
pat_disable("PAT MSR is 0, disabled.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrmsrl(MSR_IA32_CR_PAT, pat);
|
||||||
|
|
||||||
|
pat_init_cache_modes();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pat_ap_init(u64 pat)
|
||||||
|
{
|
||||||
|
if (!cpu_has_pat) {
|
||||||
|
/*
|
||||||
|
* If this happens we are on a secondary CPU, but switched to
|
||||||
|
* PAT on the boot CPU. We have no way to undo PAT.
|
||||||
|
*/
|
||||||
|
panic("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
wrmsrl(MSR_IA32_CR_PAT, pat);
|
||||||
|
}
|
||||||
|
|
||||||
void pat_init(void)
|
void pat_init(void)
|
||||||
{
|
{
|
||||||
u64 pat;
|
u64 pat;
|
||||||
bool boot_cpu = !boot_pat_state;
|
|
||||||
|
|
||||||
if (!pat_enabled())
|
if (!pat_enabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!cpu_has_pat) {
|
|
||||||
if (!boot_pat_state) {
|
|
||||||
pat_disable("PAT not supported by CPU.");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* If this happens we are on a secondary CPU, but
|
|
||||||
* switched to PAT on the boot CPU. We have no way to
|
|
||||||
* undo PAT.
|
|
||||||
*/
|
|
||||||
pr_err("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set PWT to Write-Combining. All other bits stay the same */
|
|
||||||
/*
|
/*
|
||||||
|
* Set PWT to Write-Combining. All other bits stay the same:
|
||||||
|
*
|
||||||
* PTE encoding used in Linux:
|
* PTE encoding used in Linux:
|
||||||
* PAT
|
* PAT
|
||||||
* |PCD
|
* |PCD
|
||||||
|
@ -233,19 +251,12 @@ void pat_init(void)
|
||||||
pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) |
|
pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) |
|
||||||
PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC);
|
PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC);
|
||||||
|
|
||||||
/* Boot CPU check */
|
if (!boot_cpu_done) {
|
||||||
if (!boot_pat_state) {
|
pat_bsp_init(pat);
|
||||||
rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
|
boot_cpu_done = true;
|
||||||
if (!boot_pat_state) {
|
} else {
|
||||||
pat_disable("PAT read returns always zero, disabled.");
|
pat_ap_init(pat);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wrmsrl(MSR_IA32_CR_PAT, pat);
|
|
||||||
|
|
||||||
if (boot_cpu)
|
|
||||||
pat_init_cache_modes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef PAT
|
#undef PAT
|
||||||
|
|
Loading…
Add table
Reference in a new issue