diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2013-02-01 05:25:06 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-02-01 05:28:36 -0500 |
commit | 68d00bbebb5a48b7a9056a8c03476a71ecbc30a6 (patch) | |
tree | 95af63041b79c43be37d734da6073fc82070f769 | |
parent | ac2cbab21f318e19bc176a7f38a120cec835220f (diff) | |
parent | 07f4207a305c834f528d08428df4531744e25678 (diff) |
Merge remote-tracking branch 'origin/x86/mm' into x86/mm2
Explicitly merging these two branches due to nontrivial conflicts and
to allow further work.
Resolved Conflicts:
arch/x86/kernel/head32.c
arch/x86/kernel/head64.c
arch/x86/mm/init_64.c
arch/x86/realmode/init.c
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
29 files changed, 199 insertions, 287 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 79795af59810..108efcb21c9e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1253,10 +1253,6 @@ config NODES_SHIFT | |||
1253 | Specify the maximum number of NUMA Nodes available on the target | 1253 | Specify the maximum number of NUMA Nodes available on the target |
1254 | system. Increases memory reserved to accommodate various tables. | 1254 | system. Increases memory reserved to accommodate various tables. |
1255 | 1255 | ||
1256 | config HAVE_ARCH_ALLOC_REMAP | ||
1257 | def_bool y | ||
1258 | depends on X86_32 && NUMA | ||
1259 | |||
1260 | config ARCH_HAVE_MEMORY_PRESENT | 1256 | config ARCH_HAVE_MEMORY_PRESENT |
1261 | def_bool y | 1257 | def_bool y |
1262 | depends on X86_32 && DISCONTIGMEM | 1258 | depends on X86_32 && DISCONTIGMEM |
diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index eb05fb3b02fb..8a9b3e288cb4 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h | |||
@@ -14,12 +14,6 @@ extern struct pglist_data *node_data[]; | |||
14 | 14 | ||
15 | #include <asm/numaq.h> | 15 | #include <asm/numaq.h> |
16 | 16 | ||
17 | extern void resume_map_numa_kva(pgd_t *pgd); | ||
18 | |||
19 | #else /* !CONFIG_NUMA */ | ||
20 | |||
21 | static inline void resume_map_numa_kva(pgd_t *pgd) {} | ||
22 | |||
23 | #endif /* CONFIG_NUMA */ | 17 | #endif /* CONFIG_NUMA */ |
24 | 18 | ||
25 | #ifdef CONFIG_DISCONTIGMEM | 19 | #ifdef CONFIG_DISCONTIGMEM |
diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 100a20c7b98d..c87892442e53 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h | |||
@@ -48,7 +48,8 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, | |||
48 | * case properly. Once all supported versions of gcc understand it, we can | 48 | * case properly. Once all supported versions of gcc understand it, we can |
49 | * remove this Voodoo magic stuff. (i.e. once gcc3.x is deprecated) | 49 | * remove this Voodoo magic stuff. (i.e. once gcc3.x is deprecated) |
50 | */ | 50 | */ |
51 | #define __pa_symbol(x) __pa(__phys_reloc_hide((unsigned long)(x))) | 51 | #define __pa_symbol(x) \ |
52 | __phys_addr_symbol(__phys_reloc_hide((unsigned long)(x))) | ||
52 | 53 | ||
53 | #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) | 54 | #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) |
54 | 55 | ||
diff --git a/arch/x86/include/asm/page_32.h b/arch/x86/include/asm/page_32.h index da4e762406f7..4d550d04b609 100644 --- a/arch/x86/include/asm/page_32.h +++ b/arch/x86/include/asm/page_32.h | |||
@@ -15,6 +15,7 @@ extern unsigned long __phys_addr(unsigned long); | |||
15 | #else | 15 | #else |
16 | #define __phys_addr(x) __phys_addr_nodebug(x) | 16 | #define __phys_addr(x) __phys_addr_nodebug(x) |
17 | #endif | 17 | #endif |
18 | #define __phys_addr_symbol(x) __phys_addr(x) | ||
18 | #define __phys_reloc_hide(x) RELOC_HIDE((x), 0) | 19 | #define __phys_reloc_hide(x) RELOC_HIDE((x), 0) |
19 | 20 | ||
20 | #ifdef CONFIG_FLATMEM | 21 | #ifdef CONFIG_FLATMEM |
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 072694ed81a5..0f1ddee6a0ce 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h | |||
@@ -3,4 +3,40 @@ | |||
3 | 3 | ||
4 | #include <asm/page_64_types.h> | 4 | #include <asm/page_64_types.h> |
5 | 5 | ||
6 | #ifndef __ASSEMBLY__ | ||
7 | |||
8 | /* duplicated to the one in bootmem.h */ | ||
9 | extern unsigned long max_pfn; | ||
10 | extern unsigned long phys_base; | ||
11 | |||
12 | static inline unsigned long __phys_addr_nodebug(unsigned long x) | ||
13 | { | ||
14 | unsigned long y = x - __START_KERNEL_map; | ||
15 | |||
16 | /* use the carry flag to determine if x was < __START_KERNEL_map */ | ||
17 | x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET)); | ||
18 | |||
19 | return x; | ||
20 | } | ||
21 | |||
22 | #ifdef CONFIG_DEBUG_VIRTUAL | ||
23 | extern unsigned long __phys_addr(unsigned long); | ||
24 | extern unsigned long __phys_addr_symbol(unsigned long); | ||
25 | #else | ||
26 | #define __phys_addr(x) __phys_addr_nodebug(x) | ||
27 | #define __phys_addr_symbol(x) \ | ||
28 | ((unsigned long)(x) - __START_KERNEL_map + phys_base) | ||
29 | #endif | ||
30 | |||
31 | #define __phys_reloc_hide(x) (x) | ||
32 | |||
33 | #ifdef CONFIG_FLATMEM | ||
34 | #define pfn_valid(pfn) ((pfn) < max_pfn) | ||
35 | #endif | ||
36 | |||
37 | void clear_page(void *page); | ||
38 | void copy_page(void *to, void *from); | ||
39 | |||
40 | #endif /* !__ASSEMBLY__ */ | ||
41 | |||
6 | #endif /* _ASM_X86_PAGE_64_H */ | 42 | #endif /* _ASM_X86_PAGE_64_H */ |
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 320f7bb95f76..8b491e66eaa8 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h | |||
@@ -50,26 +50,4 @@ | |||
50 | #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) | 50 | #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) |
51 | #define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) | 51 | #define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) |
52 | 52 | ||
53 | #ifndef __ASSEMBLY__ | ||
54 | void clear_page(void *page); | ||
55 | void copy_page(void *to, void *from); | ||
56 | |||
57 | /* duplicated to the one in bootmem.h */ | ||
58 | extern unsigned long max_pfn; | ||
59 | extern unsigned long phys_base; | ||
60 | |||
61 | extern unsigned long __phys_addr(unsigned long); | ||
62 | #define __phys_reloc_hide(x) (x) | ||
63 | |||
64 | #define vmemmap ((struct page *)VMEMMAP_START) | ||
65 | |||
66 | extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); | ||
67 | extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); | ||
68 | |||
69 | #endif /* !__ASSEMBLY__ */ | ||
70 | |||
71 | #ifdef CONFIG_FLATMEM | ||
72 | #define pfn_valid(pfn) ((pfn) < max_pfn) | ||
73 | #endif | ||
74 | |||
75 | #endif /* _ASM_X86_PAGE_64_DEFS_H */ | 53 | #endif /* _ASM_X86_PAGE_64_DEFS_H */ |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 3c7c6985045d..b6e41b8cd659 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -390,6 +390,7 @@ pte_t *populate_extra_pte(unsigned long vaddr); | |||
390 | 390 | ||
391 | #ifndef __ASSEMBLY__ | 391 | #ifndef __ASSEMBLY__ |
392 | #include <linux/mm_types.h> | 392 | #include <linux/mm_types.h> |
393 | #include <linux/log2.h> | ||
393 | 394 | ||
394 | static inline int pte_none(pte_t pte) | 395 | static inline int pte_none(pte_t pte) |
395 | { | 396 | { |
@@ -783,6 +784,19 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) | |||
783 | memcpy(dst, src, count * sizeof(pgd_t)); | 784 | memcpy(dst, src, count * sizeof(pgd_t)); |
784 | } | 785 | } |
785 | 786 | ||
787 | #define PTE_SHIFT ilog2(PTRS_PER_PTE) | ||
788 | static inline int page_level_shift(enum pg_level level) | ||
789 | { | ||
790 | return (PAGE_SHIFT - PTE_SHIFT) + level * PTE_SHIFT; | ||
791 | } | ||
792 | static inline unsigned long page_level_size(enum pg_level level) | ||
793 | { | ||
794 | return 1UL << page_level_shift(level); | ||
795 | } | ||
796 | static inline unsigned long page_level_mask(enum pg_level level) | ||
797 | { | ||
798 | return ~(page_level_size(level) - 1); | ||
799 | } | ||
786 | 800 | ||
787 | #include <asm-generic/pgtable.h> | 801 | #include <asm-generic/pgtable.h> |
788 | #endif /* __ASSEMBLY__ */ | 802 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 47356f9df82e..b5d30ad39022 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h | |||
@@ -183,6 +183,11 @@ extern void cleanup_highmap(void); | |||
183 | 183 | ||
184 | #define __HAVE_ARCH_PTE_SAME | 184 | #define __HAVE_ARCH_PTE_SAME |
185 | 185 | ||
186 | #define vmemmap ((struct page *)VMEMMAP_START) | ||
187 | |||
188 | extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); | ||
189 | extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); | ||
190 | |||
186 | #endif /* !__ASSEMBLY__ */ | 191 | #endif /* !__ASSEMBLY__ */ |
187 | 192 | ||
188 | #endif /* _ASM_X86_PGTABLE_64_H */ | 193 | #endif /* _ASM_X86_PGTABLE_64_H */ |
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 696fa7eafb1d..e6423002c10b 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h | |||
@@ -330,7 +330,7 @@ extern void native_pagetable_init(void); | |||
330 | struct seq_file; | 330 | struct seq_file; |
331 | extern void arch_report_meminfo(struct seq_file *m); | 331 | extern void arch_report_meminfo(struct seq_file *m); |
332 | 332 | ||
333 | enum { | 333 | enum pg_level { |
334 | PG_LEVEL_NONE, | 334 | PG_LEVEL_NONE, |
335 | PG_LEVEL_4K, | 335 | PG_LEVEL_4K, |
336 | PG_LEVEL_2M, | 336 | PG_LEVEL_2M, |
@@ -351,6 +351,7 @@ static inline void update_page_count(int level, unsigned long pages) { } | |||
351 | * as a pte too. | 351 | * as a pte too. |
352 | */ | 352 | */ |
353 | extern pte_t *lookup_address(unsigned long address, unsigned int *level); | 353 | extern pte_t *lookup_address(unsigned long address, unsigned int *level); |
354 | extern phys_addr_t slow_virt_to_phys(void *__address); | ||
354 | 355 | ||
355 | #endif /* !__ASSEMBLY__ */ | 356 | #endif /* !__ASSEMBLY__ */ |
356 | 357 | ||
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index d5e0d717005a..0532f5d6e4ef 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -69,7 +69,7 @@ int acpi_suspend_lowlevel(void) | |||
69 | 69 | ||
70 | #ifndef CONFIG_64BIT | 70 | #ifndef CONFIG_64BIT |
71 | header->pmode_entry = (u32)&wakeup_pmode_return; | 71 | header->pmode_entry = (u32)&wakeup_pmode_return; |
72 | header->pmode_cr3 = (u32)__pa(&initial_page_table); | 72 | header->pmode_cr3 = (u32)__pa_symbol(initial_page_table); |
73 | saved_magic = 0x12345678; | 73 | saved_magic = 0x12345678; |
74 | #else /* CONFIG_64BIT */ | 74 | #else /* CONFIG_64BIT */ |
75 | #ifdef CONFIG_SMP | 75 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 9c2aa89a11cb..9a9110918ca7 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/apic.h> | 28 | #include <asm/apic.h> |
29 | #include <asm/ipi.h> | 29 | #include <asm/ipi.h> |
30 | #include <asm/apic_flat_64.h> | 30 | #include <asm/apic_flat_64.h> |
31 | #include <asm/pgtable.h> | ||
31 | 32 | ||
32 | static int numachip_system __read_mostly; | 33 | static int numachip_system __read_mostly; |
33 | 34 | ||
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index a24c462888f0..1905ce98bee0 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -167,7 +167,7 @@ int __cpuinit ppro_with_ram_bug(void) | |||
167 | #ifdef CONFIG_X86_F00F_BUG | 167 | #ifdef CONFIG_X86_F00F_BUG |
168 | static void __cpuinit trap_init_f00f_bug(void) | 168 | static void __cpuinit trap_init_f00f_bug(void) |
169 | { | 169 | { |
170 | __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO); | 170 | __set_fixmap(FIX_F00F_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO); |
171 | 171 | ||
172 | /* | 172 | /* |
173 | * Update the IDT descriptor and reload the IDT so that | 173 | * Update the IDT descriptor and reload the IDT so that |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 1d414029f1d8..42a392a9fd02 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -89,7 +89,7 @@ do_ftrace_mod_code(unsigned long ip, const void *new_code) | |||
89 | * kernel identity mapping to modify code. | 89 | * kernel identity mapping to modify code. |
90 | */ | 90 | */ |
91 | if (within(ip, (unsigned long)_text, (unsigned long)_etext)) | 91 | if (within(ip, (unsigned long)_text, (unsigned long)_etext)) |
92 | ip = (unsigned long)__va(__pa(ip)); | 92 | ip = (unsigned long)__va(__pa_symbol(ip)); |
93 | 93 | ||
94 | return probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE); | 94 | return probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE); |
95 | } | 95 | } |
@@ -279,7 +279,7 @@ static int ftrace_write(unsigned long ip, const char *val, int size) | |||
279 | * kernel identity mapping to modify code. | 279 | * kernel identity mapping to modify code. |
280 | */ | 280 | */ |
281 | if (within(ip, (unsigned long)_text, (unsigned long)_etext)) | 281 | if (within(ip, (unsigned long)_text, (unsigned long)_etext)) |
282 | ip = (unsigned long)__va(__pa(ip)); | 282 | ip = (unsigned long)__va(__pa_symbol(ip)); |
283 | 283 | ||
284 | return probe_kernel_write((void *)ip, val, size); | 284 | return probe_kernel_write((void *)ip, val, size); |
285 | } | 285 | } |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 9c2bd8bd4b4c..aa7e58b82b39 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -297,9 +297,9 @@ static void kvm_register_steal_time(void) | |||
297 | 297 | ||
298 | memset(st, 0, sizeof(*st)); | 298 | memset(st, 0, sizeof(*st)); |
299 | 299 | ||
300 | wrmsrl(MSR_KVM_STEAL_TIME, (__pa(st) | KVM_MSR_ENABLED)); | 300 | wrmsrl(MSR_KVM_STEAL_TIME, (slow_virt_to_phys(st) | KVM_MSR_ENABLED)); |
301 | printk(KERN_INFO "kvm-stealtime: cpu %d, msr %lx\n", | 301 | printk(KERN_INFO "kvm-stealtime: cpu %d, msr %lx\n", |
302 | cpu, __pa(st)); | 302 | cpu, slow_virt_to_phys(st)); |
303 | } | 303 | } |
304 | 304 | ||
305 | static DEFINE_PER_CPU(unsigned long, kvm_apic_eoi) = KVM_PV_EOI_DISABLED; | 305 | static DEFINE_PER_CPU(unsigned long, kvm_apic_eoi) = KVM_PV_EOI_DISABLED; |
@@ -324,7 +324,7 @@ void __cpuinit kvm_guest_cpu_init(void) | |||
324 | return; | 324 | return; |
325 | 325 | ||
326 | if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) { | 326 | if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF) && kvmapf) { |
327 | u64 pa = __pa(&__get_cpu_var(apf_reason)); | 327 | u64 pa = slow_virt_to_phys(&__get_cpu_var(apf_reason)); |
328 | 328 | ||
329 | #ifdef CONFIG_PREEMPT | 329 | #ifdef CONFIG_PREEMPT |
330 | pa |= KVM_ASYNC_PF_SEND_ALWAYS; | 330 | pa |= KVM_ASYNC_PF_SEND_ALWAYS; |
@@ -340,7 +340,8 @@ void __cpuinit kvm_guest_cpu_init(void) | |||
340 | /* Size alignment is implied but just to make it explicit. */ | 340 | /* Size alignment is implied but just to make it explicit. */ |
341 | BUILD_BUG_ON(__alignof__(kvm_apic_eoi) < 4); | 341 | BUILD_BUG_ON(__alignof__(kvm_apic_eoi) < 4); |
342 | __get_cpu_var(kvm_apic_eoi) = 0; | 342 | __get_cpu_var(kvm_apic_eoi) = 0; |
343 | pa = __pa(&__get_cpu_var(kvm_apic_eoi)) | KVM_MSR_ENABLED; | 343 | pa = slow_virt_to_phys(&__get_cpu_var(kvm_apic_eoi)) |
344 | | KVM_MSR_ENABLED; | ||
344 | wrmsrl(MSR_KVM_PV_EOI_EN, pa); | 345 | wrmsrl(MSR_KVM_PV_EOI_EN, pa); |
345 | } | 346 | } |
346 | 347 | ||
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 220a360010f8..9f966dc0b9e4 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
@@ -162,8 +162,8 @@ int kvm_register_clock(char *txt) | |||
162 | int low, high, ret; | 162 | int low, high, ret; |
163 | struct pvclock_vcpu_time_info *src = &hv_clock[cpu].pvti; | 163 | struct pvclock_vcpu_time_info *src = &hv_clock[cpu].pvti; |
164 | 164 | ||
165 | low = (int)__pa(src) | 1; | 165 | low = (int)slow_virt_to_phys(src) | 1; |
166 | high = ((u64)__pa(src) >> 32); | 166 | high = ((u64)slow_virt_to_phys(src) >> 32); |
167 | ret = native_write_msr_safe(msr_kvm_system_time, low, high); | 167 | ret = native_write_msr_safe(msr_kvm_system_time, low, high); |
168 | printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n", | 168 | printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n", |
169 | cpu, high, low, txt); | 169 | cpu, high, low, txt); |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a74701af74e3..be6e435cfc05 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -284,8 +284,8 @@ static void __init cleanup_highmap(void) | |||
284 | static void __init reserve_brk(void) | 284 | static void __init reserve_brk(void) |
285 | { | 285 | { |
286 | if (_brk_end > _brk_start) | 286 | if (_brk_end > _brk_start) |
287 | memblock_reserve(__pa(_brk_start), | 287 | memblock_reserve(__pa_symbol(_brk_start), |
288 | __pa(_brk_end) - __pa(_brk_start)); | 288 | _brk_end - _brk_start); |
289 | 289 | ||
290 | /* Mark brk area as locked down and no longer taking any | 290 | /* Mark brk area as locked down and no longer taking any |
291 | new allocations */ | 291 | new allocations */ |
@@ -903,12 +903,12 @@ void __init setup_arch(char **cmdline_p) | |||
903 | init_mm.end_data = (unsigned long) _edata; | 903 | init_mm.end_data = (unsigned long) _edata; |
904 | init_mm.brk = _brk_end; | 904 | init_mm.brk = _brk_end; |
905 | 905 | ||
906 | code_resource.start = virt_to_phys(_text); | 906 | code_resource.start = __pa_symbol(_text); |
907 | code_resource.end = virt_to_phys(_etext)-1; | 907 | code_resource.end = __pa_symbol(_etext)-1; |
908 | data_resource.start = virt_to_phys(_etext); | 908 | data_resource.start = __pa_symbol(_etext); |
909 | data_resource.end = virt_to_phys(_edata)-1; | 909 | data_resource.end = __pa_symbol(_edata)-1; |
910 | bss_resource.start = virt_to_phys(&__bss_start); | 910 | bss_resource.start = __pa_symbol(__bss_start); |
911 | bss_resource.end = virt_to_phys(&__bss_stop)-1; | 911 | bss_resource.end = __pa_symbol(__bss_stop)-1; |
912 | 912 | ||
913 | #ifdef CONFIG_CMDLINE_BOOL | 913 | #ifdef CONFIG_CMDLINE_BOOL |
914 | #ifdef CONFIG_CMDLINE_OVERRIDE | 914 | #ifdef CONFIG_CMDLINE_OVERRIDE |
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 1330dd102950..b014d9414d08 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -59,6 +59,9 @@ EXPORT_SYMBOL(memcpy); | |||
59 | EXPORT_SYMBOL(__memcpy); | 59 | EXPORT_SYMBOL(__memcpy); |
60 | EXPORT_SYMBOL(memmove); | 60 | EXPORT_SYMBOL(memmove); |
61 | 61 | ||
62 | #ifndef CONFIG_DEBUG_VIRTUAL | ||
63 | EXPORT_SYMBOL(phys_base); | ||
64 | #endif | ||
62 | EXPORT_SYMBOL(empty_zero_page); | 65 | EXPORT_SYMBOL(empty_zero_page); |
63 | #ifndef CONFIG_PARAVIRT | 66 | #ifndef CONFIG_PARAVIRT |
64 | EXPORT_SYMBOL(native_load_gs_index); | 67 | EXPORT_SYMBOL(native_load_gs_index); |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index df4176cdbb32..1cbd89ca5569 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -552,7 +552,8 @@ static void lguest_write_cr3(unsigned long cr3) | |||
552 | current_cr3 = cr3; | 552 | current_cr3 = cr3; |
553 | 553 | ||
554 | /* These two page tables are simple, linear, and used during boot */ | 554 | /* These two page tables are simple, linear, and used during boot */ |
555 | if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) | 555 | if (cr3 != __pa_symbol(swapper_pg_dir) && |
556 | cr3 != __pa_symbol(initial_page_table)) | ||
556 | cr3_changed = true; | 557 | cr3_changed = true; |
557 | } | 558 | } |
558 | 559 | ||
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index e2fcbc34c9df..edaa2daf4b37 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -804,12 +804,10 @@ void set_kernel_text_ro(void) | |||
804 | void mark_rodata_ro(void) | 804 | void mark_rodata_ro(void) |
805 | { | 805 | { |
806 | unsigned long start = PFN_ALIGN(_text); | 806 | unsigned long start = PFN_ALIGN(_text); |
807 | unsigned long rodata_start = | 807 | unsigned long rodata_start = PFN_ALIGN(__start_rodata); |
808 | ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; | ||
809 | unsigned long end = (unsigned long) &__end_rodata_hpage_align; | 808 | unsigned long end = (unsigned long) &__end_rodata_hpage_align; |
810 | unsigned long text_end = PAGE_ALIGN((unsigned long) &__stop___ex_table); | 809 | unsigned long text_end = PFN_ALIGN(&__stop___ex_table); |
811 | unsigned long rodata_end = PAGE_ALIGN((unsigned long) &__end_rodata); | 810 | unsigned long rodata_end = PFN_ALIGN(&__end_rodata); |
812 | unsigned long data_start = (unsigned long) &_sdata; | ||
813 | unsigned long all_end = PFN_ALIGN(&_end); | 811 | unsigned long all_end = PFN_ALIGN(&_end); |
814 | 812 | ||
815 | printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", | 813 | printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", |
@@ -835,12 +833,12 @@ void mark_rodata_ro(void) | |||
835 | #endif | 833 | #endif |
836 | 834 | ||
837 | free_init_pages("unused kernel memory", | 835 | free_init_pages("unused kernel memory", |
838 | (unsigned long) page_address(virt_to_page(text_end)), | 836 | (unsigned long) __va(__pa_symbol(text_end)), |
839 | (unsigned long) | 837 | (unsigned long) __va(__pa_symbol(rodata_start))); |
840 | page_address(virt_to_page(rodata_start))); | 838 | |
841 | free_init_pages("unused kernel memory", | 839 | free_init_pages("unused kernel memory", |
842 | (unsigned long) page_address(virt_to_page(rodata_end)), | 840 | (unsigned long) __va(__pa_symbol(rodata_end)), |
843 | (unsigned long) page_address(virt_to_page(data_start))); | 841 | (unsigned long) __va(__pa_symbol(_sdata))); |
844 | } | 842 | } |
845 | 843 | ||
846 | #endif | 844 | #endif |
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 2d125be1bae9..8504f3698753 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c | |||
@@ -193,7 +193,6 @@ int __init numa_add_memblk(int nid, u64 start, u64 end) | |||
193 | static void __init setup_node_data(int nid, u64 start, u64 end) | 193 | static void __init setup_node_data(int nid, u64 start, u64 end) |
194 | { | 194 | { |
195 | const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE); | 195 | const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE); |
196 | bool remapped = false; | ||
197 | u64 nd_pa; | 196 | u64 nd_pa; |
198 | void *nd; | 197 | void *nd; |
199 | int tnid; | 198 | int tnid; |
@@ -205,37 +204,28 @@ static void __init setup_node_data(int nid, u64 start, u64 end) | |||
205 | if (end && (end - start) < NODE_MIN_SIZE) | 204 | if (end && (end - start) < NODE_MIN_SIZE) |
206 | return; | 205 | return; |
207 | 206 | ||
208 | /* initialize remap allocator before aligning to ZONE_ALIGN */ | ||
209 | init_alloc_remap(nid, start, end); | ||
210 | |||
211 | start = roundup(start, ZONE_ALIGN); | 207 | start = roundup(start, ZONE_ALIGN); |
212 | 208 | ||
213 | printk(KERN_INFO "Initmem setup node %d [mem %#010Lx-%#010Lx]\n", | 209 | printk(KERN_INFO "Initmem setup node %d [mem %#010Lx-%#010Lx]\n", |
214 | nid, start, end - 1); | 210 | nid, start, end - 1); |
215 | 211 | ||
216 | /* | 212 | /* |
217 | * Allocate node data. Try remap allocator first, node-local | 213 | * Allocate node data. Try node-local memory and then any node. |
218 | * memory and then any node. Never allocate in DMA zone. | 214 | * Never allocate in DMA zone. |
219 | */ | 215 | */ |
220 | nd = alloc_remap(nid, nd_size); | 216 | nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid); |
221 | if (nd) { | 217 | if (!nd_pa) { |
222 | nd_pa = __pa(nd); | 218 | pr_err("Cannot find %zu bytes in node %d\n", |
223 | remapped = true; | 219 | nd_size, nid); |
224 | } else { | 220 | return; |
225 | nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid); | ||
226 | if (!nd_pa) { | ||
227 | pr_err("Cannot find %zu bytes in node %d\n", | ||
228 | nd_size, nid); | ||
229 | return; | ||
230 | } | ||
231 | nd = __va(nd_pa); | ||
232 | } | 221 | } |
222 | nd = __va(nd_pa); | ||
233 | 223 | ||
234 | /* report and initialize */ | 224 | /* report and initialize */ |
235 | printk(KERN_INFO " NODE_DATA [mem %#010Lx-%#010Lx]%s\n", | 225 | printk(KERN_INFO " NODE_DATA [mem %#010Lx-%#010Lx]\n", |
236 | nd_pa, nd_pa + nd_size - 1, remapped ? " (remapped)" : ""); | 226 | nd_pa, nd_pa + nd_size - 1); |
237 | tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); | 227 | tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); |
238 | if (!remapped && tnid != nid) | 228 | if (tnid != nid) |
239 | printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nid, tnid); | 229 | printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nid, tnid); |
240 | 230 | ||
241 | node_data[nid] = nd; | 231 | node_data[nid] = nd; |
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c index 534255a36b6b..73a6d7395bd3 100644 --- a/arch/x86/mm/numa_32.c +++ b/arch/x86/mm/numa_32.c | |||
@@ -73,167 +73,6 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn, | |||
73 | 73 | ||
74 | extern unsigned long highend_pfn, highstart_pfn; | 74 | extern unsigned long highend_pfn, highstart_pfn; |
75 | 75 | ||
76 | #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE) | ||
77 | |||
78 | static void *node_remap_start_vaddr[MAX_NUMNODES]; | ||
79 | void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); | ||
80 | |||
81 | /* | ||
82 | * Remap memory allocator | ||
83 | */ | ||
84 | static unsigned long node_remap_start_pfn[MAX_NUMNODES]; | ||
85 | static void *node_remap_end_vaddr[MAX_NUMNODES]; | ||
86 | static void *node_remap_alloc_vaddr[MAX_NUMNODES]; | ||
87 | |||
88 | /** | ||
89 | * alloc_remap - Allocate remapped memory | ||
90 | * @nid: NUMA node to allocate memory from | ||
91 | * @size: The size of allocation | ||
92 | * | ||
93 | * Allocate @size bytes from the remap area of NUMA node @nid. The | ||
94 | * size of the remap area is predetermined by init_alloc_remap() and | ||
95 | * only the callers considered there should call this function. For | ||
96 | * more info, please read the comment on top of init_alloc_remap(). | ||
97 | * | ||
98 | * The caller must be ready to handle allocation failure from this | ||
99 | * function and fall back to regular memory allocator in such cases. | ||
100 | * | ||
101 | * CONTEXT: | ||
102 | * Single CPU early boot context. | ||
103 | * | ||
104 | * RETURNS: | ||
105 | * Pointer to the allocated memory on success, %NULL on failure. | ||
106 | */ | ||
107 | void *alloc_remap(int nid, unsigned long size) | ||
108 | { | ||
109 | void *allocation = node_remap_alloc_vaddr[nid]; | ||
110 | |||
111 | size = ALIGN(size, L1_CACHE_BYTES); | ||
112 | |||
113 | if (!allocation || (allocation + size) > node_remap_end_vaddr[nid]) | ||
114 | return NULL; | ||
115 | |||
116 | node_remap_alloc_vaddr[nid] += size; | ||
117 | memset(allocation, 0, size); | ||
118 | |||
119 | return allocation; | ||
120 | } | ||
121 | |||
122 | #ifdef CONFIG_HIBERNATION | ||
123 | /** | ||
124 | * resume_map_numa_kva - add KVA mapping to the temporary page tables created | ||
125 | * during resume from hibernation | ||
126 | * @pgd_base - temporary resume page directory | ||
127 | */ | ||
128 | void resume_map_numa_kva(pgd_t *pgd_base) | ||
129 | { | ||
130 | int node; | ||
131 | |||
132 | for_each_online_node(node) { | ||
133 | unsigned long start_va, start_pfn, nr_pages, pfn; | ||
134 | |||
135 | start_va = (unsigned long)node_remap_start_vaddr[node]; | ||
136 | start_pfn = node_remap_start_pfn[node]; | ||
137 | nr_pages = (node_remap_end_vaddr[node] - | ||
138 | node_remap_start_vaddr[node]) >> PAGE_SHIFT; | ||
139 | |||
140 | printk(KERN_DEBUG "%s: node %d\n", __func__, node); | ||
141 | |||
142 | for (pfn = 0; pfn < nr_pages; pfn += PTRS_PER_PTE) { | ||
143 | unsigned long vaddr = start_va + (pfn << PAGE_SHIFT); | ||
144 | pgd_t *pgd = pgd_base + pgd_index(vaddr); | ||
145 | pud_t *pud = pud_offset(pgd, vaddr); | ||
146 | pmd_t *pmd = pmd_offset(pud, vaddr); | ||
147 | |||
148 | set_pmd(pmd, pfn_pmd(start_pfn + pfn, | ||
149 | PAGE_KERNEL_LARGE_EXEC)); | ||
150 | |||
151 | printk(KERN_DEBUG "%s: %08lx -> pfn %08lx\n", | ||
152 | __func__, vaddr, start_pfn + pfn); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | #endif | ||
157 | |||
158 | /** | ||
159 | * init_alloc_remap - Initialize remap allocator for a NUMA node | ||
160 | * @nid: NUMA node to initizlie remap allocator for | ||
161 | * | ||
162 | * NUMA nodes may end up without any lowmem. As allocating pgdat and | ||
163 | * memmap on a different node with lowmem is inefficient, a special | ||
164 | * remap allocator is implemented which can be used by alloc_remap(). | ||
165 | * | ||
166 | * For each node, the amount of memory which will be necessary for | ||
167 | * pgdat and memmap is calculated and two memory areas of the size are | ||
168 | * allocated - one in the node and the other in lowmem; then, the area | ||
169 | * in the node is remapped to the lowmem area. | ||
170 | * | ||
171 | * As pgdat and memmap must be allocated in lowmem anyway, this | ||
172 | * doesn't waste lowmem address space; however, the actual lowmem | ||
173 | * which gets remapped over is wasted. The amount shouldn't be | ||
174 | * problematic on machines this feature will be used. | ||
175 | * | ||
176 | * Initialization failure isn't fatal. alloc_remap() is used | ||
177 | * opportunistically and the callers will fall back to other memory | ||
178 | * allocation mechanisms on failure. | ||
179 | */ | ||
180 | void __init init_alloc_remap(int nid, u64 start, u64 end) | ||
181 | { | ||
182 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
183 | unsigned long end_pfn = end >> PAGE_SHIFT; | ||
184 | unsigned long size, pfn; | ||
185 | u64 node_pa, remap_pa; | ||
186 | void *remap_va; | ||
187 | |||
188 | /* | ||
189 | * The acpi/srat node info can show hot-add memroy zones where | ||
190 | * memory could be added but not currently present. | ||
191 | */ | ||
192 | printk(KERN_DEBUG "node %d pfn: [%lx - %lx]\n", | ||
193 | nid, start_pfn, end_pfn); | ||
194 | |||
195 | /* calculate the necessary space aligned to large page size */ | ||
196 | size = node_memmap_size_bytes(nid, start_pfn, end_pfn); | ||
197 | size += ALIGN(sizeof(pg_data_t), PAGE_SIZE); | ||
198 | size = ALIGN(size, LARGE_PAGE_BYTES); | ||
199 | |||
200 | /* allocate node memory and the lowmem remap area */ | ||
201 | node_pa = memblock_find_in_range(start, end, size, LARGE_PAGE_BYTES); | ||
202 | if (!node_pa) { | ||
203 | pr_warning("remap_alloc: failed to allocate %lu bytes for node %d\n", | ||
204 | size, nid); | ||
205 | return; | ||
206 | } | ||
207 | memblock_reserve(node_pa, size); | ||
208 | |||
209 | remap_pa = memblock_find_in_range(min_low_pfn << PAGE_SHIFT, | ||
210 | max_low_pfn << PAGE_SHIFT, | ||
211 | size, LARGE_PAGE_BYTES); | ||
212 | if (!remap_pa) { | ||
213 | pr_warning("remap_alloc: failed to allocate %lu bytes remap area for node %d\n", | ||
214 | size, nid); | ||
215 | memblock_free(node_pa, size); | ||
216 | return; | ||
217 | } | ||
218 | memblock_reserve(remap_pa, size); | ||
219 | remap_va = phys_to_virt(remap_pa); | ||
220 | |||
221 | /* perform actual remap */ | ||
222 | for (pfn = 0; pfn < size >> PAGE_SHIFT; pfn += PTRS_PER_PTE) | ||
223 | set_pmd_pfn((unsigned long)remap_va + (pfn << PAGE_SHIFT), | ||
224 | (node_pa >> PAGE_SHIFT) + pfn, | ||
225 | PAGE_KERNEL_LARGE); | ||
226 | |||
227 | /* initialize remap allocator parameters */ | ||
228 | node_remap_start_pfn[nid] = node_pa >> PAGE_SHIFT; | ||
229 | node_remap_start_vaddr[nid] = remap_va; | ||
230 | node_remap_end_vaddr[nid] = remap_va + size; | ||
231 | node_remap_alloc_vaddr[nid] = remap_va; | ||
232 | |||
233 | printk(KERN_DEBUG "remap_alloc: node %d [%08llx-%08llx) -> [%p-%p)\n", | ||
234 | nid, node_pa, node_pa + size, remap_va, remap_va + size); | ||
235 | } | ||
236 | |||
237 | void __init initmem_init(void) | 76 | void __init initmem_init(void) |
238 | { | 77 | { |
239 | x86_numa_init(); | 78 | x86_numa_init(); |
diff --git a/arch/x86/mm/numa_internal.h b/arch/x86/mm/numa_internal.h index 7178c3afe05e..ad86ec91e640 100644 --- a/arch/x86/mm/numa_internal.h +++ b/arch/x86/mm/numa_internal.h | |||
@@ -21,12 +21,6 @@ void __init numa_reset_distance(void); | |||
21 | 21 | ||
22 | void __init x86_numa_init(void); | 22 | void __init x86_numa_init(void); |
23 | 23 | ||
24 | #ifdef CONFIG_X86_64 | ||
25 | static inline void init_alloc_remap(int nid, u64 start, u64 end) { } | ||
26 | #else | ||
27 | void __init init_alloc_remap(int nid, u64 start, u64 end); | ||
28 | #endif | ||
29 | |||
30 | #ifdef CONFIG_NUMA_EMU | 24 | #ifdef CONFIG_NUMA_EMU |
31 | void __init numa_emulation(struct numa_meminfo *numa_meminfo, | 25 | void __init numa_emulation(struct numa_meminfo *numa_meminfo, |
32 | int numa_dist_cnt); | 26 | int numa_dist_cnt); |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 44acfcd6c16f..a1b1c88f9caf 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -94,12 +94,12 @@ static inline void split_page_count(int level) { } | |||
94 | 94 | ||
95 | static inline unsigned long highmap_start_pfn(void) | 95 | static inline unsigned long highmap_start_pfn(void) |
96 | { | 96 | { |
97 | return __pa(_text) >> PAGE_SHIFT; | 97 | return __pa_symbol(_text) >> PAGE_SHIFT; |
98 | } | 98 | } |
99 | 99 | ||
100 | static inline unsigned long highmap_end_pfn(void) | 100 | static inline unsigned long highmap_end_pfn(void) |
101 | { | 101 | { |
102 | return __pa(roundup(_brk_end, PMD_SIZE)) >> PAGE_SHIFT; | 102 | return __pa_symbol(roundup(_brk_end, PMD_SIZE)) >> PAGE_SHIFT; |
103 | } | 103 | } |
104 | 104 | ||
105 | #endif | 105 | #endif |
@@ -276,8 +276,8 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, | |||
276 | * The .rodata section needs to be read-only. Using the pfn | 276 | * The .rodata section needs to be read-only. Using the pfn |
277 | * catches all aliases. | 277 | * catches all aliases. |
278 | */ | 278 | */ |
279 | if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT, | 279 | if (within(pfn, __pa_symbol(__start_rodata) >> PAGE_SHIFT, |
280 | __pa((unsigned long)__end_rodata) >> PAGE_SHIFT)) | 280 | __pa_symbol(__end_rodata) >> PAGE_SHIFT)) |
281 | pgprot_val(forbidden) |= _PAGE_RW; | 281 | pgprot_val(forbidden) |= _PAGE_RW; |
282 | 282 | ||
283 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) | 283 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) |
@@ -364,6 +364,37 @@ pte_t *lookup_address(unsigned long address, unsigned int *level) | |||
364 | EXPORT_SYMBOL_GPL(lookup_address); | 364 | EXPORT_SYMBOL_GPL(lookup_address); |
365 | 365 | ||
366 | /* | 366 | /* |
367 | * This is necessary because __pa() does not work on some | ||
368 | * kinds of memory, like vmalloc() or the alloc_remap() | ||
369 | * areas on 32-bit NUMA systems. The percpu areas can | ||
370 | * end up in this kind of memory, for instance. | ||
371 | * | ||
372 | * This could be optimized, but it is only intended to be | ||
373 | * used at inititalization time, and keeping it | ||
374 | * unoptimized should increase the testing coverage for | ||
375 | * the more obscure platforms. | ||
376 | */ | ||
377 | phys_addr_t slow_virt_to_phys(void *__virt_addr) | ||
378 | { | ||
379 | unsigned long virt_addr = (unsigned long)__virt_addr; | ||
380 | phys_addr_t phys_addr; | ||
381 | unsigned long offset; | ||
382 | enum pg_level level; | ||
383 | unsigned long psize; | ||
384 | unsigned long pmask; | ||
385 | pte_t *pte; | ||
386 | |||
387 | pte = lookup_address(virt_addr, &level); | ||
388 | BUG_ON(!pte); | ||
389 | psize = page_level_size(level); | ||
390 | pmask = page_level_mask(level); | ||
391 | offset = virt_addr & ~pmask; | ||
392 | phys_addr = pte_pfn(*pte) << PAGE_SHIFT; | ||
393 | return (phys_addr | offset); | ||
394 | } | ||
395 | EXPORT_SYMBOL_GPL(slow_virt_to_phys); | ||
396 | |||
397 | /* | ||
367 | * Set the new pmd in all the pgds we know about: | 398 | * Set the new pmd in all the pgds we know about: |
368 | */ | 399 | */ |
369 | static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) | 400 | static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) |
@@ -396,7 +427,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
396 | pte_t new_pte, old_pte, *tmp; | 427 | pte_t new_pte, old_pte, *tmp; |
397 | pgprot_t old_prot, new_prot, req_prot; | 428 | pgprot_t old_prot, new_prot, req_prot; |
398 | int i, do_split = 1; | 429 | int i, do_split = 1; |
399 | unsigned int level; | 430 | enum pg_level level; |
400 | 431 | ||
401 | if (cpa->force_split) | 432 | if (cpa->force_split) |
402 | return 1; | 433 | return 1; |
@@ -412,15 +443,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
412 | 443 | ||
413 | switch (level) { | 444 | switch (level) { |
414 | case PG_LEVEL_2M: | 445 | case PG_LEVEL_2M: |
415 | psize = PMD_PAGE_SIZE; | ||
416 | pmask = PMD_PAGE_MASK; | ||
417 | break; | ||
418 | #ifdef CONFIG_X86_64 | 446 | #ifdef CONFIG_X86_64 |
419 | case PG_LEVEL_1G: | 447 | case PG_LEVEL_1G: |
420 | psize = PUD_PAGE_SIZE; | ||
421 | pmask = PUD_PAGE_MASK; | ||
422 | break; | ||
423 | #endif | 448 | #endif |
449 | psize = page_level_size(level); | ||
450 | pmask = page_level_mask(level); | ||
451 | break; | ||
424 | default: | 452 | default: |
425 | do_split = -EINVAL; | 453 | do_split = -EINVAL; |
426 | goto out_unlock; | 454 | goto out_unlock; |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 0eb572eda406..2610bd93c896 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -560,10 +560,10 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags) | |||
560 | { | 560 | { |
561 | unsigned long id_sz; | 561 | unsigned long id_sz; |
562 | 562 | ||
563 | if (base >= __pa(high_memory)) | 563 | if (base > __pa(high_memory-1)) |
564 | return 0; | 564 | return 0; |
565 | 565 | ||
566 | id_sz = (__pa(high_memory) < base + size) ? | 566 | id_sz = (__pa(high_memory-1) <= base + size) ? |
567 | __pa(high_memory) - base : | 567 | __pa(high_memory) - base : |
568 | size; | 568 | size; |
569 | 569 | ||
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index e27fbf887f3b..193350b51f90 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
@@ -334,7 +334,12 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, | |||
334 | if (changed && dirty) { | 334 | if (changed && dirty) { |
335 | *pmdp = entry; | 335 | *pmdp = entry; |
336 | pmd_update_defer(vma->vm_mm, address, pmdp); | 336 | pmd_update_defer(vma->vm_mm, address, pmdp); |
337 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | 337 | /* |
338 | * We had a write-protection fault here and changed the pmd | ||
339 | * to to more permissive. No need to flush the TLB for that, | ||
340 | * #PF is architecturally guaranteed to do that and in the | ||
341 | * worst-case we'll generate a spurious fault. | ||
342 | */ | ||
338 | } | 343 | } |
339 | 344 | ||
340 | return changed; | 345 | return changed; |
diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c index d2e2735327b4..e666cbbb9261 100644 --- a/arch/x86/mm/physaddr.c +++ b/arch/x86/mm/physaddr.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/bootmem.h> | ||
1 | #include <linux/mmdebug.h> | 2 | #include <linux/mmdebug.h> |
2 | #include <linux/module.h> | 3 | #include <linux/module.h> |
3 | #include <linux/mm.h> | 4 | #include <linux/mm.h> |
@@ -8,33 +9,54 @@ | |||
8 | 9 | ||
9 | #ifdef CONFIG_X86_64 | 10 | #ifdef CONFIG_X86_64 |
10 | 11 | ||
12 | #ifdef CONFIG_DEBUG_VIRTUAL | ||
11 | unsigned long __phys_addr(unsigned long x) | 13 | unsigned long __phys_addr(unsigned long x) |
12 | { | 14 | { |
13 | if (x >= __START_KERNEL_map) { | 15 | unsigned long y = x - __START_KERNEL_map; |
14 | x -= __START_KERNEL_map; | 16 | |
15 | VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE); | 17 | /* use the carry flag to determine if x was < __START_KERNEL_map */ |
16 | x += phys_base; | 18 | if (unlikely(x > y)) { |
19 | x = y + phys_base; | ||
20 | |||
21 | VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); | ||
17 | } else { | 22 | } else { |
18 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); | 23 | x = y + (__START_KERNEL_map - PAGE_OFFSET); |
19 | x -= PAGE_OFFSET; | 24 | |
20 | VIRTUAL_BUG_ON(!phys_addr_valid(x)); | 25 | /* carry flag will be set if starting x was >= PAGE_OFFSET */ |
26 | VIRTUAL_BUG_ON((x > y) || !phys_addr_valid(x)); | ||
21 | } | 27 | } |
28 | |||
22 | return x; | 29 | return x; |
23 | } | 30 | } |
24 | EXPORT_SYMBOL(__phys_addr); | 31 | EXPORT_SYMBOL(__phys_addr); |
25 | 32 | ||
33 | unsigned long __phys_addr_symbol(unsigned long x) | ||
34 | { | ||
35 | unsigned long y = x - __START_KERNEL_map; | ||
36 | |||
37 | /* only check upper bounds since lower bounds will trigger carry */ | ||
38 | VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); | ||
39 | |||
40 | return y + phys_base; | ||
41 | } | ||
42 | EXPORT_SYMBOL(__phys_addr_symbol); | ||
43 | #endif | ||
44 | |||
26 | bool __virt_addr_valid(unsigned long x) | 45 | bool __virt_addr_valid(unsigned long x) |
27 | { | 46 | { |
28 | if (x >= __START_KERNEL_map) { | 47 | unsigned long y = x - __START_KERNEL_map; |
29 | x -= __START_KERNEL_map; | 48 | |
30 | if (x >= KERNEL_IMAGE_SIZE) | 49 | /* use the carry flag to determine if x was < __START_KERNEL_map */ |
50 | if (unlikely(x > y)) { | ||
51 | x = y + phys_base; | ||
52 | |||
53 | if (y >= KERNEL_IMAGE_SIZE) | ||
31 | return false; | 54 | return false; |
32 | x += phys_base; | ||
33 | } else { | 55 | } else { |
34 | if (x < PAGE_OFFSET) | 56 | x = y + (__START_KERNEL_map - PAGE_OFFSET); |
35 | return false; | 57 | |
36 | x -= PAGE_OFFSET; | 58 | /* carry flag will be set if starting x was >= PAGE_OFFSET */ |
37 | if (!phys_addr_valid(x)) | 59 | if ((x > y) || !phys_addr_valid(x)) |
38 | return false; | 60 | return false; |
39 | } | 61 | } |
40 | 62 | ||
@@ -47,10 +69,16 @@ EXPORT_SYMBOL(__virt_addr_valid); | |||
47 | #ifdef CONFIG_DEBUG_VIRTUAL | 69 | #ifdef CONFIG_DEBUG_VIRTUAL |
48 | unsigned long __phys_addr(unsigned long x) | 70 | unsigned long __phys_addr(unsigned long x) |
49 | { | 71 | { |
72 | unsigned long phys_addr = x - PAGE_OFFSET; | ||
50 | /* VMALLOC_* aren't constants */ | 73 | /* VMALLOC_* aren't constants */ |
51 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); | 74 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); |
52 | VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); | 75 | VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); |
53 | return x - PAGE_OFFSET; | 76 | /* max_low_pfn is set early, but not _that_ early */ |
77 | if (max_low_pfn) { | ||
78 | VIRTUAL_BUG_ON((phys_addr >> PAGE_SHIFT) > max_low_pfn); | ||
79 | BUG_ON(slow_virt_to_phys((void *)x) != phys_addr); | ||
80 | } | ||
81 | return phys_addr; | ||
54 | } | 82 | } |
55 | EXPORT_SYMBOL(__phys_addr); | 83 | EXPORT_SYMBOL(__phys_addr); |
56 | #endif | 84 | #endif |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 36e53f0a9ce3..1743c1c92411 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -410,8 +410,8 @@ void __init efi_reserve_boot_services(void) | |||
410 | * - Not within any part of the kernel | 410 | * - Not within any part of the kernel |
411 | * - Not the bios reserved area | 411 | * - Not the bios reserved area |
412 | */ | 412 | */ |
413 | if ((start+size >= virt_to_phys(_text) | 413 | if ((start+size >= __pa_symbol(_text) |
414 | && start <= virt_to_phys(_end)) || | 414 | && start <= __pa_symbol(_end)) || |
415 | !e820_all_mapped(start, start+size, E820_RAM) || | 415 | !e820_all_mapped(start, start+size, E820_RAM) || |
416 | memblock_is_region_reserved(start, size)) { | 416 | memblock_is_region_reserved(start, size)) { |
417 | /* Could not reserve, skip it */ | 417 | /* Could not reserve, skip it */ |
diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c index 74202c1910cd..7d28c885d238 100644 --- a/arch/x86/power/hibernate_32.c +++ b/arch/x86/power/hibernate_32.c | |||
@@ -129,8 +129,6 @@ static int resume_physical_mapping_init(pgd_t *pgd_base) | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | resume_map_numa_kva(pgd_base); | ||
133 | |||
134 | return 0; | 132 | return 0; |
135 | } | 133 | } |
136 | 134 | ||
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c index 4b5bdc8c8710..a44f457e70a1 100644 --- a/arch/x86/realmode/init.c +++ b/arch/x86/realmode/init.c | |||
@@ -70,9 +70,9 @@ void __init setup_real_mode(void) | |||
70 | __va(real_mode_header->trampoline_header); | 70 | __va(real_mode_header->trampoline_header); |
71 | 71 | ||
72 | #ifdef CONFIG_X86_32 | 72 | #ifdef CONFIG_X86_32 |
73 | trampoline_header->start = __pa(startup_32_smp); | 73 | trampoline_header->start = __pa_symbol(startup_32_smp); |
74 | trampoline_header->gdt_limit = __BOOT_DS + 7; | 74 | trampoline_header->gdt_limit = __BOOT_DS + 7; |
75 | trampoline_header->gdt_base = __pa(boot_gdt); | 75 | trampoline_header->gdt_base = __pa_symbol(boot_gdt); |
76 | #else | 76 | #else |
77 | /* | 77 | /* |
78 | * Some AMD processors will #GP(0) if EFER.LMA is set in WRMSR | 78 | * Some AMD processors will #GP(0) if EFER.LMA is set in WRMSR |