aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2015-06-04 12:55:09 -0400
committerIngo Molnar <mingo@kernel.org>2015-06-07 09:28:52 -0400
commit9dac6290945142e6b87d9f027edfee676dcfbfda (patch)
tree67c6cb70618147f0662b2922724fca77b8a109ec
parentd6472302f242559d45dcf4ebace62508dc4d8aeb (diff)
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>
-rw-r--r--arch/x86/mm/pat.c69
1 files 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 @@
36#undef pr_fmt 36#undef pr_fmt
37#define pr_fmt(fmt) "" fmt 37#define pr_fmt(fmt) "" fmt
38 38
39static bool boot_cpu_done;
40
39static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT); 41static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
40 42
41static inline void pat_disable(const char *reason) 43static inline void pat_disable(const char *reason)
@@ -194,31 +196,47 @@ void pat_init_cache_modes(void)
194 196
195#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8)) 197#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
196 198
197void pat_init(void) 199static void pat_bsp_init(u64 pat)
198{ 200{
199 u64 pat; 201 if (!cpu_has_pat) {
200 bool boot_cpu = !boot_pat_state; 202 pat_disable("PAT not supported by CPU.");
203 return;
204 }
201 205
202 if (!pat_enabled()) 206 rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
207 if (!boot_pat_state) {
208 pat_disable("PAT MSR is 0, disabled.");
203 return; 209 return;
210 }
204 211
212 wrmsrl(MSR_IA32_CR_PAT, pat);
213
214 pat_init_cache_modes();
215}
216
217static void pat_ap_init(u64 pat)
218{
205 if (!cpu_has_pat) { 219 if (!cpu_has_pat) {
206 if (!boot_pat_state) { 220 /*
207 pat_disable("PAT not supported by CPU."); 221 * If this happens we are on a secondary CPU, but switched to
208 return; 222 * PAT on the boot CPU. We have no way to undo PAT.
209 } else { 223 */
210 /* 224 panic("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
211 * If this happens we are on a secondary CPU, but
212 * switched to PAT on the boot CPU. We have no way to
213 * undo PAT.
214 */
215 pr_err("x86/PAT: PAT enabled, but not supported by secondary CPU\n");
216 BUG();
217 }
218 } 225 }
219 226
220 /* Set PWT to Write-Combining. All other bits stay the same */ 227 wrmsrl(MSR_IA32_CR_PAT, pat);
228}
229
230void pat_init(void)
231{
232 u64 pat;
233
234 if (!pat_enabled())
235 return;
236
221 /* 237 /*
238 * Set PWT to Write-Combining. All other bits stay the same:
239 *
222 * PTE encoding used in Linux: 240 * PTE encoding used in Linux:
223 * PAT 241 * PAT
224 * |PCD 242 * |PCD
@@ -233,19 +251,12 @@ void pat_init(void)
233 pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) | 251 pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) |
234 PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); 252 PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC);
235 253
236 /* Boot CPU check */ 254 if (!boot_cpu_done) {
237 if (!boot_pat_state) { 255 pat_bsp_init(pat);
238 rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); 256 boot_cpu_done = true;
239 if (!boot_pat_state) { 257 } else {
240 pat_disable("PAT read returns always zero, disabled."); 258 pat_ap_init(pat);
241 return;
242 }
243 } 259 }
244
245 wrmsrl(MSR_IA32_CR_PAT, pat);
246
247 if (boot_cpu)
248 pat_init_cache_modes();
249} 260}
250 261
251#undef PAT 262#undef PAT