Skip to content

Commit

Permalink
x86/mm/pat: Untangle pat_init()
Browse files Browse the repository at this point in the history
Split it into a BSP and AP version which makes the PAT
initialization path actually readable again.

Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Toshi Kani <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: [email protected]
Cc: H. Peter Anvin <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Luis R. Rodriguez <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: linux-mm <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
suryasaimadhu authored and Ingo Molnar committed Jun 7, 2015
1 parent d647230 commit 9dac629
Showing 1 changed file with 40 additions and 29 deletions.
69 changes: 40 additions & 29 deletions arch/x86/mm/pat.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#undef pr_fmt
#define pr_fmt(fmt) "" fmt

static bool boot_cpu_done;

static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);

static inline void pat_disable(const char *reason)
Expand Down Expand Up @@ -194,31 +196,47 @@ void pat_init_cache_modes(void)

#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))

void pat_init(void)
static void pat_bsp_init(u64 pat)
{
u64 pat;
bool boot_cpu = !boot_pat_state;
if (!cpu_has_pat) {
pat_disable("PAT not supported by CPU.");
return;
}

if (!pat_enabled())
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 (!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();
}
/*
* 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");
}

/* Set PWT to Write-Combining. All other bits stay the same */
wrmsrl(MSR_IA32_CR_PAT, pat);
}

void pat_init(void)
{
u64 pat;

if (!pat_enabled())
return;

/*
* Set PWT to Write-Combining. All other bits stay the same:
*
* PTE encoding used in Linux:
* PAT
* |PCD
Expand All @@ -233,19 +251,12 @@ void pat_init(void)
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);

/* Boot CPU check */
if (!boot_pat_state) {
rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
if (!boot_pat_state) {
pat_disable("PAT read returns always zero, disabled.");
return;
}
if (!boot_cpu_done) {
pat_bsp_init(pat);
boot_cpu_done = true;
} else {
pat_ap_init(pat);
}

wrmsrl(MSR_IA32_CR_PAT, pat);

if (boot_cpu)
pat_init_cache_modes();
}

#undef PAT
Expand Down

0 comments on commit 9dac629

Please sign in to comment.