[PATCH 01/20] x86/mm/pat: Untangle pat_init()

From: Borislav Petkov
Date: Thu Jun 04 2015 - 13:04:59 EST


From: Borislav Petkov <bp@xxxxxxx>

Split it into a BSP and AP version which makes the PAT initialization
path actually readable again.

Signed-off-by: Borislav Petkov <bp@xxxxxxx>
Reviewed-by: Toshi Kani <toshi.kani@xxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxxxxxx>
Cc: arnd@xxxxxxxx
Cc: Elliott@xxxxxx
Cc: hch@xxxxxx
Cc: hmh@xxxxxxxxxx
Cc: H. Peter Anvin <hpa@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: jgross@xxxxxxxx
Cc: konrad.wilk@xxxxxxxxxx
Cc: linux-mm <linux-mm@xxxxxxxxx>
Cc: linux-nvdimm@xxxxxxxxxxxx
Cc: Luis R. Rodriguez <mcgrof@xxxxxxxx>
Cc: stefan.bader@xxxxxxxxxxxxx
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: x86-ml <x86@xxxxxxxxxx>
Cc: yigal@xxxxxxxxxxxxx
---
arch/x86/mm/pat.c | 69 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 40 insertions(+), 29 deletions(-)

diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index a1c96544099d..476d0780560f 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -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)
@@ -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
@@ -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
--
2.3.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/