Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Borislav Petkov and committed by
Ingo Molnar
9dac6290 d6472302

+40 -29
+40 -29
arch/x86/mm/pat.c
··· 36 36 #undef pr_fmt 37 37 #define pr_fmt(fmt) "" fmt 38 38 39 + static bool boot_cpu_done; 40 + 39 41 static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT); 40 42 41 43 static inline void pat_disable(const char *reason) ··· 196 194 197 195 #define PAT(x, y) ((u64)PAT_ ## y << ((x)*8)) 198 196 197 + static void pat_bsp_init(u64 pat) 198 + { 199 + if (!cpu_has_pat) { 200 + pat_disable("PAT not supported by CPU."); 201 + return; 202 + } 203 + 204 + rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); 205 + if (!boot_pat_state) { 206 + pat_disable("PAT MSR is 0, disabled."); 207 + return; 208 + } 209 + 210 + wrmsrl(MSR_IA32_CR_PAT, pat); 211 + 212 + pat_init_cache_modes(); 213 + } 214 + 215 + static void pat_ap_init(u64 pat) 216 + { 217 + if (!cpu_has_pat) { 218 + /* 219 + * If this happens we are on a secondary CPU, but switched to 220 + * PAT on the boot CPU. We have no way to undo PAT. 221 + */ 222 + panic("x86/PAT: PAT enabled, but not supported by secondary CPU\n"); 223 + } 224 + 225 + wrmsrl(MSR_IA32_CR_PAT, pat); 226 + } 227 + 199 228 void pat_init(void) 200 229 { 201 230 u64 pat; 202 - bool boot_cpu = !boot_pat_state; 203 231 204 232 if (!pat_enabled()) 205 233 return; 206 234 207 - if (!cpu_has_pat) { 208 - if (!boot_pat_state) { 209 - pat_disable("PAT not supported by CPU."); 210 - return; 211 - } else { 212 - /* 213 - * If this happens we are on a secondary CPU, but 214 - * switched to PAT on the boot CPU. We have no way to 215 - * undo PAT. 216 - */ 217 - pr_err("x86/PAT: PAT enabled, but not supported by secondary CPU\n"); 218 - BUG(); 219 - } 220 - } 221 - 222 - /* Set PWT to Write-Combining. All other bits stay the same */ 223 235 /* 236 + * Set PWT to Write-Combining. All other bits stay the same: 237 + * 224 238 * PTE encoding used in Linux: 225 239 * PAT 226 240 * |PCD ··· 251 233 pat = PAT(0, WB) | PAT(1, WC) | PAT(2, UC_MINUS) | PAT(3, UC) | 252 234 PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); 253 235 254 - /* Boot CPU check */ 255 - if (!boot_pat_state) { 256 - rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); 257 - if (!boot_pat_state) { 258 - pat_disable("PAT read returns always zero, disabled."); 259 - return; 260 - } 236 + if (!boot_cpu_done) { 237 + pat_bsp_init(pat); 238 + boot_cpu_done = true; 239 + } else { 240 + pat_ap_init(pat); 261 241 } 262 - 263 - wrmsrl(MSR_IA32_CR_PAT, pat); 264 - 265 - if (boot_cpu) 266 - pat_init_cache_modes(); 267 242 } 268 243 269 244 #undef PAT