diff options
author | Borislav Petkov <bp@suse.de> | 2015-06-04 12:55:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-06-07 09:28:52 -0400 |
commit | 9dac6290945142e6b87d9f027edfee676dcfbfda (patch) | |
tree | 67c6cb70618147f0662b2922724fca77b8a109ec | |
parent | d6472302f242559d45dcf4ebace62508dc4d8aeb (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.c | 69 |
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 | ||
39 | static bool boot_cpu_done; | ||
40 | |||
39 | static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT); | 41 | static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT); |
40 | 42 | ||
41 | static inline void pat_disable(const char *reason) | 43 | static 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 | ||
197 | void pat_init(void) | 199 | static 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 | |||
217 | static 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 | |||
230 | void 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 |