aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pat.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/pat.c')
-rw-r--r--arch/x86/mm/pat.c74
1 files changed, 50 insertions, 24 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 8b08fb955274..9127e31c7268 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -30,7 +30,7 @@
30#ifdef CONFIG_X86_PAT 30#ifdef CONFIG_X86_PAT
31int __read_mostly pat_enabled = 1; 31int __read_mostly pat_enabled = 1;
32 32
33void __cpuinit pat_disable(char *reason) 33void __cpuinit pat_disable(const char *reason)
34{ 34{
35 pat_enabled = 0; 35 pat_enabled = 0;
36 printk(KERN_INFO "%s\n", reason); 36 printk(KERN_INFO "%s\n", reason);
@@ -42,6 +42,11 @@ static int __init nopat(char *str)
42 return 0; 42 return 0;
43} 43}
44early_param("nopat", nopat); 44early_param("nopat", nopat);
45#else
46static inline void pat_disable(const char *reason)
47{
48 (void)reason;
49}
45#endif 50#endif
46 51
47 52
@@ -78,16 +83,20 @@ void pat_init(void)
78 if (!pat_enabled) 83 if (!pat_enabled)
79 return; 84 return;
80 85
81 /* Paranoia check. */ 86 if (!cpu_has_pat) {
82 if (!cpu_has_pat && boot_pat_state) { 87 if (!boot_pat_state) {
83 /* 88 pat_disable("PAT not supported by CPU.");
84 * If this happens we are on a secondary CPU, but 89 return;
85 * switched to PAT on the boot CPU. We have no way to 90 } else {
86 * undo PAT. 91 /*
87 */ 92 * If this happens we are on a secondary CPU, but
88 printk(KERN_ERR "PAT enabled, " 93 * switched to PAT on the boot CPU. We have no way to
89 "but not supported by secondary CPU\n"); 94 * undo PAT.
90 BUG(); 95 */
96 printk(KERN_ERR "PAT enabled, "
97 "but not supported by secondary CPU\n");
98 BUG();
99 }
91 } 100 }
92 101
93 /* Set PWT to Write-Combining. All other bits stay the same */ 102 /* Set PWT to Write-Combining. All other bits stay the same */
@@ -333,11 +342,23 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
333 req_type & _PAGE_CACHE_MASK); 342 req_type & _PAGE_CACHE_MASK);
334 } 343 }
335 344
336 is_range_ram = pagerange_is_ram(start, end); 345 if (new_type)
337 if (is_range_ram == 1) 346 *new_type = actual_type;
338 return reserve_ram_pages_type(start, end, req_type, new_type); 347
339 else if (is_range_ram < 0) 348 /*
340 return -EINVAL; 349 * For legacy reasons, some parts of the physical address range in the
350 * legacy 1MB region is treated as non-RAM (even when listed as RAM in
351 * the e820 tables). So we will track the memory attributes of this
352 * legacy 1MB region using the linear memtype_list always.
353 */
354 if (end >= ISA_END_ADDRESS) {
355 is_range_ram = pagerange_is_ram(start, end);
356 if (is_range_ram == 1)
357 return reserve_ram_pages_type(start, end, req_type,
358 new_type);
359 else if (is_range_ram < 0)
360 return -EINVAL;
361 }
341 362
342 new = kmalloc(sizeof(struct memtype), GFP_KERNEL); 363 new = kmalloc(sizeof(struct memtype), GFP_KERNEL);
343 if (!new) 364 if (!new)
@@ -347,9 +368,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
347 new->end = end; 368 new->end = end;
348 new->type = actual_type; 369 new->type = actual_type;
349 370
350 if (new_type)
351 *new_type = actual_type;
352
353 spin_lock(&memtype_lock); 371 spin_lock(&memtype_lock);
354 372
355 if (cached_entry && start >= cached_start) 373 if (cached_entry && start >= cached_start)
@@ -437,11 +455,19 @@ int free_memtype(u64 start, u64 end)
437 if (is_ISA_range(start, end - 1)) 455 if (is_ISA_range(start, end - 1))
438 return 0; 456 return 0;
439 457
440 is_range_ram = pagerange_is_ram(start, end); 458 /*
441 if (is_range_ram == 1) 459 * For legacy reasons, some parts of the physical address range in the
442 return free_ram_pages_type(start, end); 460 * legacy 1MB region is treated as non-RAM (even when listed as RAM in
443 else if (is_range_ram < 0) 461 * the e820 tables). So we will track the memory attributes of this
444 return -EINVAL; 462 * legacy 1MB region using the linear memtype_list always.
463 */
464 if (end >= ISA_END_ADDRESS) {
465 is_range_ram = pagerange_is_ram(start, end);
466 if (is_range_ram == 1)
467 return free_ram_pages_type(start, end);
468 else if (is_range_ram < 0)
469 return -EINVAL;
470 }
445 471
446 spin_lock(&memtype_lock); 472 spin_lock(&memtype_lock);
447 list_for_each_entry(entry, &memtype_list, nd) { 473 list_for_each_entry(entry, &memtype_list, nd) {