diff options
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/fault.c | 5 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 12 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 6 | ||||
-rw-r--r-- | arch/x86/mm/ioremap.c | 5 | ||||
-rw-r--r-- | arch/x86/mm/pat.c | 57 | ||||
-rw-r--r-- | arch/x86/mm/srat_64.c | 27 |
6 files changed, 40 insertions, 72 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index fd7e1798c75a..8bcb6f40ccb6 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -497,6 +497,11 @@ static int vmalloc_fault(unsigned long address) | |||
497 | unsigned long pgd_paddr; | 497 | unsigned long pgd_paddr; |
498 | pmd_t *pmd_k; | 498 | pmd_t *pmd_k; |
499 | pte_t *pte_k; | 499 | pte_t *pte_k; |
500 | |||
501 | /* Make sure we are in vmalloc area */ | ||
502 | if (!(address >= VMALLOC_START && address < VMALLOC_END)) | ||
503 | return -1; | ||
504 | |||
500 | /* | 505 | /* |
501 | * Synchronize this task's top level page-table | 506 | * Synchronize this task's top level page-table |
502 | * with the 'reference' page table. | 507 | * with the 'reference' page table. |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index de236e419cb5..ec30d10154b6 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -438,8 +438,6 @@ void zap_low_mappings(void) | |||
438 | { | 438 | { |
439 | int i; | 439 | int i; |
440 | 440 | ||
441 | save_pg_dir(); | ||
442 | |||
443 | /* | 441 | /* |
444 | * Zap initial low-memory mappings. | 442 | * Zap initial low-memory mappings. |
445 | * | 443 | * |
@@ -663,16 +661,8 @@ void __init mem_init(void) | |||
663 | test_wp_bit(); | 661 | test_wp_bit(); |
664 | 662 | ||
665 | cpa_init(); | 663 | cpa_init(); |
666 | 664 | save_pg_dir(); | |
667 | /* | ||
668 | * Subtle. SMP is doing it's boot stuff late (because it has to | ||
669 | * fork idle threads) - but it also needs low mappings for the | ||
670 | * protected-mode entry to work. We zap these entries only after | ||
671 | * the WP-bit has been tested. | ||
672 | */ | ||
673 | #ifndef CONFIG_SMP | ||
674 | zap_low_mappings(); | 665 | zap_low_mappings(); |
675 | #endif | ||
676 | } | 666 | } |
677 | 667 | ||
678 | #ifdef CONFIG_MEMORY_HOTPLUG | 668 | #ifdef CONFIG_MEMORY_HOTPLUG |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 32ba13b0f818..156e6d7b0e32 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -206,7 +206,7 @@ void __init cleanup_highmap(void) | |||
206 | pmd_t *last_pmd = pmd + PTRS_PER_PMD; | 206 | pmd_t *last_pmd = pmd + PTRS_PER_PMD; |
207 | 207 | ||
208 | for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { | 208 | for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { |
209 | if (!pmd_present(*pmd)) | 209 | if (pmd_none(*pmd)) |
210 | continue; | 210 | continue; |
211 | if (vaddr < (unsigned long) _text || vaddr > end) | 211 | if (vaddr < (unsigned long) _text || vaddr > end) |
212 | set_pmd(pmd, __pmd(0)); | 212 | set_pmd(pmd, __pmd(0)); |
@@ -506,7 +506,7 @@ early_param("memtest", parse_memtest); | |||
506 | 506 | ||
507 | static void __init early_memtest(unsigned long start, unsigned long end) | 507 | static void __init early_memtest(unsigned long start, unsigned long end) |
508 | { | 508 | { |
509 | unsigned long t_start, t_size; | 509 | u64 t_start, t_size; |
510 | unsigned pattern; | 510 | unsigned pattern; |
511 | 511 | ||
512 | if (!memtest_pattern) | 512 | if (!memtest_pattern) |
@@ -525,7 +525,7 @@ static void __init early_memtest(unsigned long start, unsigned long end) | |||
525 | if (t_start + t_size > end) | 525 | if (t_start + t_size > end) |
526 | t_size = end - t_start; | 526 | t_size = end - t_start; |
527 | 527 | ||
528 | printk(KERN_CONT "\n %016lx - %016lx pattern %d", | 528 | printk(KERN_CONT "\n %016llx - %016llx pattern %d", |
529 | t_start, t_start + t_size, pattern); | 529 | t_start, t_start + t_size, pattern); |
530 | 530 | ||
531 | memtest(t_start, t_size, pattern); | 531 | memtest(t_start, t_size, pattern); |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 71bb3159031a..2b2bb3f9b683 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -593,10 +593,11 @@ void __init early_iounmap(void *addr, unsigned long size) | |||
593 | unsigned long offset; | 593 | unsigned long offset; |
594 | unsigned int nrpages; | 594 | unsigned int nrpages; |
595 | enum fixed_addresses idx; | 595 | enum fixed_addresses idx; |
596 | unsigned int nesting; | 596 | int nesting; |
597 | 597 | ||
598 | nesting = --early_ioremap_nested; | 598 | nesting = --early_ioremap_nested; |
599 | WARN_ON(nesting < 0); | 599 | if (WARN_ON(nesting < 0)) |
600 | return; | ||
600 | 601 | ||
601 | if (early_ioremap_debug) { | 602 | if (early_ioremap_debug) { |
602 | printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, | 603 | printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 60adbe22efa0..06b7a1c90fb8 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -28,13 +28,13 @@ | |||
28 | #ifdef CONFIG_X86_PAT | 28 | #ifdef CONFIG_X86_PAT |
29 | int __read_mostly pat_wc_enabled = 1; | 29 | int __read_mostly pat_wc_enabled = 1; |
30 | 30 | ||
31 | void __init pat_disable(char *reason) | 31 | void __cpuinit pat_disable(char *reason) |
32 | { | 32 | { |
33 | pat_wc_enabled = 0; | 33 | pat_wc_enabled = 0; |
34 | printk(KERN_INFO "%s\n", reason); | 34 | printk(KERN_INFO "%s\n", reason); |
35 | } | 35 | } |
36 | 36 | ||
37 | static int nopat(char *str) | 37 | static int __init nopat(char *str) |
38 | { | 38 | { |
39 | pat_disable("PAT support disabled."); | 39 | pat_disable("PAT support disabled."); |
40 | return 0; | 40 | return 0; |
@@ -151,32 +151,33 @@ static int pat_x_mtrr_type(u64 start, u64 end, unsigned long prot, | |||
151 | unsigned long pat_type; | 151 | unsigned long pat_type; |
152 | u8 mtrr_type; | 152 | u8 mtrr_type; |
153 | 153 | ||
154 | mtrr_type = mtrr_type_lookup(start, end); | ||
155 | if (mtrr_type == 0xFF) { /* MTRR not enabled */ | ||
156 | *ret_prot = prot; | ||
157 | return 0; | ||
158 | } | ||
159 | if (mtrr_type == 0xFE) { /* MTRR match error */ | ||
160 | *ret_prot = _PAGE_CACHE_UC; | ||
161 | return -1; | ||
162 | } | ||
163 | if (mtrr_type != MTRR_TYPE_UNCACHABLE && | ||
164 | mtrr_type != MTRR_TYPE_WRBACK && | ||
165 | mtrr_type != MTRR_TYPE_WRCOMB) { /* MTRR type unhandled */ | ||
166 | *ret_prot = _PAGE_CACHE_UC; | ||
167 | return -1; | ||
168 | } | ||
169 | |||
170 | pat_type = prot & _PAGE_CACHE_MASK; | 154 | pat_type = prot & _PAGE_CACHE_MASK; |
171 | prot &= (~_PAGE_CACHE_MASK); | 155 | prot &= (~_PAGE_CACHE_MASK); |
172 | 156 | ||
173 | /* Currently doing intersection by hand. Optimize it later. */ | 157 | /* |
158 | * We return the PAT request directly for types where PAT takes | ||
159 | * precedence with respect to MTRR and for UC_MINUS. | ||
160 | * Consistency checks with other PAT requests is done later | ||
161 | * while going through memtype list. | ||
162 | */ | ||
174 | if (pat_type == _PAGE_CACHE_WC) { | 163 | if (pat_type == _PAGE_CACHE_WC) { |
175 | *ret_prot = prot | _PAGE_CACHE_WC; | 164 | *ret_prot = prot | _PAGE_CACHE_WC; |
165 | return 0; | ||
176 | } else if (pat_type == _PAGE_CACHE_UC_MINUS) { | 166 | } else if (pat_type == _PAGE_CACHE_UC_MINUS) { |
177 | *ret_prot = prot | _PAGE_CACHE_UC_MINUS; | 167 | *ret_prot = prot | _PAGE_CACHE_UC_MINUS; |
178 | } else if (pat_type == _PAGE_CACHE_UC || | 168 | return 0; |
179 | mtrr_type == MTRR_TYPE_UNCACHABLE) { | 169 | } else if (pat_type == _PAGE_CACHE_UC) { |
170 | *ret_prot = prot | _PAGE_CACHE_UC; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * Look for MTRR hint to get the effective type in case where PAT | ||
176 | * request is for WB. | ||
177 | */ | ||
178 | mtrr_type = mtrr_type_lookup(start, end); | ||
179 | |||
180 | if (mtrr_type == MTRR_TYPE_UNCACHABLE) { | ||
180 | *ret_prot = prot | _PAGE_CACHE_UC; | 181 | *ret_prot = prot | _PAGE_CACHE_UC; |
181 | } else if (mtrr_type == MTRR_TYPE_WRCOMB) { | 182 | } else if (mtrr_type == MTRR_TYPE_WRCOMB) { |
182 | *ret_prot = prot | _PAGE_CACHE_WC; | 183 | *ret_prot = prot | _PAGE_CACHE_WC; |
@@ -233,14 +234,12 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, | |||
233 | 234 | ||
234 | if (req_type == -1) { | 235 | if (req_type == -1) { |
235 | /* | 236 | /* |
236 | * Special case where caller wants to inherit from mtrr or | 237 | * Call mtrr_lookup to get the type hint. This is an |
237 | * existing pat mapping, defaulting to UC_MINUS in case of | 238 | * optimization for /dev/mem mmap'ers into WB memory (BIOS |
238 | * no match. | 239 | * tools and ACPI tools). Use WB request for WB memory and use |
240 | * UC_MINUS otherwise. | ||
239 | */ | 241 | */ |
240 | u8 mtrr_type = mtrr_type_lookup(start, end); | 242 | u8 mtrr_type = mtrr_type_lookup(start, end); |
241 | if (mtrr_type == 0xFE) { /* MTRR match error */ | ||
242 | err = -1; | ||
243 | } | ||
244 | 243 | ||
245 | if (mtrr_type == MTRR_TYPE_WRBACK) { | 244 | if (mtrr_type == MTRR_TYPE_WRBACK) { |
246 | req_type = _PAGE_CACHE_WB; | 245 | req_type = _PAGE_CACHE_WB; |
@@ -555,7 +554,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | |||
555 | "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", | 554 | "%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n", |
556 | current->comm, current->pid, | 555 | current->comm, current->pid, |
557 | cattr_name(flags), | 556 | cattr_name(flags), |
558 | offset, offset + size); | 557 | offset, (unsigned long long)(offset + size)); |
559 | return 0; | 558 | return 0; |
560 | } | 559 | } |
561 | 560 | ||
@@ -576,7 +575,7 @@ void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot) | |||
576 | "%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n", | 575 | "%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n", |
577 | current->comm, current->pid, | 576 | current->comm, current->pid, |
578 | cattr_name(want_flags), | 577 | cattr_name(want_flags), |
579 | addr, addr + size, | 578 | addr, (unsigned long long)(addr + size), |
580 | cattr_name(flags)); | 579 | cattr_name(flags)); |
581 | } | 580 | } |
582 | } | 581 | } |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 3890234e5b26..99649dccad28 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -97,36 +97,9 @@ static __init inline int srat_disabled(void) | |||
97 | return numa_off || acpi_numa < 0; | 97 | return numa_off || acpi_numa < 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | /* | ||
101 | * A lot of BIOS fill in 10 (= no distance) everywhere. This messes | ||
102 | * up the NUMA heuristics which wants the local node to have a smaller | ||
103 | * distance than the others. | ||
104 | * Do some quick checks here and only use the SLIT if it passes. | ||
105 | */ | ||
106 | static __init int slit_valid(struct acpi_table_slit *slit) | ||
107 | { | ||
108 | int i, j; | ||
109 | int d = slit->locality_count; | ||
110 | for (i = 0; i < d; i++) { | ||
111 | for (j = 0; j < d; j++) { | ||
112 | u8 val = slit->entry[d*i + j]; | ||
113 | if (i == j) { | ||
114 | if (val != LOCAL_DISTANCE) | ||
115 | return 0; | ||
116 | } else if (val <= LOCAL_DISTANCE) | ||
117 | return 0; | ||
118 | } | ||
119 | } | ||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | /* Callback for SLIT parsing */ | 100 | /* Callback for SLIT parsing */ |
124 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | 101 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) |
125 | { | 102 | { |
126 | if (!slit_valid(slit)) { | ||
127 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); | ||
128 | return; | ||
129 | } | ||
130 | acpi_slit = slit; | 103 | acpi_slit = slit; |
131 | } | 104 | } |
132 | 105 | ||