diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-12-06 15:27:54 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-12-06 15:27:54 -0500 |
commit | 3ee0fc5ca129cbae81c073756febcb1c552af446 (patch) | |
tree | 08f061c1ec9e948df760a0746441bec9f290d774 /arch/arm/kernel | |
parent | deee6d5359969a0ce4e2760cfd7b9f379bd5698a (diff) | |
parent | 4e8ee7de227e3ab9a72040b448ad728c5428a042 (diff) |
Merge branch 'kexec/idmap' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/head.S | 18 | ||||
-rw-r--r-- | arch/arm/kernel/sleep.S | 2 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 32 | ||||
-rw-r--r-- | arch/arm/kernel/suspend.c | 18 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 7 |
5 files changed, 24 insertions, 53 deletions
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 08c82fd844a8..fb2945be5a51 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -170,11 +170,11 @@ __create_page_tables: | |||
170 | * Create identity mapping to cater for __enable_mmu. | 170 | * Create identity mapping to cater for __enable_mmu. |
171 | * This identity mapping will be removed by paging_init(). | 171 | * This identity mapping will be removed by paging_init(). |
172 | */ | 172 | */ |
173 | adr r0, __enable_mmu_loc | 173 | adr r0, __turn_mmu_on_loc |
174 | ldmia r0, {r3, r5, r6} | 174 | ldmia r0, {r3, r5, r6} |
175 | sub r0, r0, r3 @ virt->phys offset | 175 | sub r0, r0, r3 @ virt->phys offset |
176 | add r5, r5, r0 @ phys __enable_mmu | 176 | add r5, r5, r0 @ phys __turn_mmu_on |
177 | add r6, r6, r0 @ phys __enable_mmu_end | 177 | add r6, r6, r0 @ phys __turn_mmu_on_end |
178 | mov r5, r5, lsr #SECTION_SHIFT | 178 | mov r5, r5, lsr #SECTION_SHIFT |
179 | mov r6, r6, lsr #SECTION_SHIFT | 179 | mov r6, r6, lsr #SECTION_SHIFT |
180 | 180 | ||
@@ -287,10 +287,10 @@ __create_page_tables: | |||
287 | ENDPROC(__create_page_tables) | 287 | ENDPROC(__create_page_tables) |
288 | .ltorg | 288 | .ltorg |
289 | .align | 289 | .align |
290 | __enable_mmu_loc: | 290 | __turn_mmu_on_loc: |
291 | .long . | 291 | .long . |
292 | .long __enable_mmu | 292 | .long __turn_mmu_on |
293 | .long __enable_mmu_end | 293 | .long __turn_mmu_on_end |
294 | 294 | ||
295 | #if defined(CONFIG_SMP) | 295 | #if defined(CONFIG_SMP) |
296 | __CPUINIT | 296 | __CPUINIT |
@@ -398,15 +398,17 @@ ENDPROC(__enable_mmu) | |||
398 | * other registers depend on the function called upon completion | 398 | * other registers depend on the function called upon completion |
399 | */ | 399 | */ |
400 | .align 5 | 400 | .align 5 |
401 | __turn_mmu_on: | 401 | .pushsection .idmap.text, "ax" |
402 | ENTRY(__turn_mmu_on) | ||
402 | mov r0, r0 | 403 | mov r0, r0 |
403 | mcr p15, 0, r0, c1, c0, 0 @ write control reg | 404 | mcr p15, 0, r0, c1, c0, 0 @ write control reg |
404 | mrc p15, 0, r3, c0, c0, 0 @ read id reg | 405 | mrc p15, 0, r3, c0, c0, 0 @ read id reg |
405 | mov r3, r3 | 406 | mov r3, r3 |
406 | mov r3, r13 | 407 | mov r3, r13 |
407 | mov pc, r3 | 408 | mov pc, r3 |
408 | __enable_mmu_end: | 409 | __turn_mmu_on_end: |
409 | ENDPROC(__turn_mmu_on) | 410 | ENDPROC(__turn_mmu_on) |
411 | .popsection | ||
410 | 412 | ||
411 | 413 | ||
412 | #ifdef CONFIG_SMP_ON_UP | 414 | #ifdef CONFIG_SMP_ON_UP |
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 020e99c845e7..9e64231c8cfe 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S | |||
@@ -54,6 +54,7 @@ ENDPROC(cpu_suspend_abort) | |||
54 | * r0 = control register value | 54 | * r0 = control register value |
55 | */ | 55 | */ |
56 | .align 5 | 56 | .align 5 |
57 | .pushsection .idmap.text,"ax" | ||
57 | ENTRY(cpu_resume_mmu) | 58 | ENTRY(cpu_resume_mmu) |
58 | ldr r3, =cpu_resume_after_mmu | 59 | ldr r3, =cpu_resume_after_mmu |
59 | mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc | 60 | mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc |
@@ -62,6 +63,7 @@ ENTRY(cpu_resume_mmu) | |||
62 | mov r0, r0 | 63 | mov r0, r0 |
63 | mov pc, r3 @ jump to virtual address | 64 | mov pc, r3 @ jump to virtual address |
64 | ENDPROC(cpu_resume_mmu) | 65 | ENDPROC(cpu_resume_mmu) |
66 | .popsection | ||
65 | cpu_resume_after_mmu: | 67 | cpu_resume_after_mmu: |
66 | bl cpu_init @ restore the und/abt/irq banked regs | 68 | bl cpu_init @ restore the und/abt/irq banked regs |
67 | mov r0, #0 @ return zero on success | 69 | mov r0, #0 @ return zero on success |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index ef5640b9e218..76ff28d87bf3 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/cpu.h> | 31 | #include <asm/cpu.h> |
32 | #include <asm/cputype.h> | 32 | #include <asm/cputype.h> |
33 | #include <asm/exception.h> | 33 | #include <asm/exception.h> |
34 | #include <asm/idmap.h> | ||
34 | #include <asm/topology.h> | 35 | #include <asm/topology.h> |
35 | #include <asm/mmu_context.h> | 36 | #include <asm/mmu_context.h> |
36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
@@ -61,7 +62,6 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
61 | { | 62 | { |
62 | struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); | 63 | struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); |
63 | struct task_struct *idle = ci->idle; | 64 | struct task_struct *idle = ci->idle; |
64 | pgd_t *pgd; | ||
65 | int ret; | 65 | int ret; |
66 | 66 | ||
67 | /* | 67 | /* |
@@ -84,29 +84,11 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
84 | } | 84 | } |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * Allocate initial page tables to allow the new CPU to | ||
88 | * enable the MMU safely. This essentially means a set | ||
89 | * of our "standard" page tables, with the addition of | ||
90 | * a 1:1 mapping for the physical address of the kernel. | ||
91 | */ | ||
92 | pgd = pgd_alloc(&init_mm); | ||
93 | if (!pgd) | ||
94 | return -ENOMEM; | ||
95 | |||
96 | if (PHYS_OFFSET != PAGE_OFFSET) { | ||
97 | #ifndef CONFIG_HOTPLUG_CPU | ||
98 | identity_mapping_add(pgd, __pa(__init_begin), __pa(__init_end)); | ||
99 | #endif | ||
100 | identity_mapping_add(pgd, __pa(_stext), __pa(_etext)); | ||
101 | identity_mapping_add(pgd, __pa(_sdata), __pa(_edata)); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * We need to tell the secondary core where to find | 87 | * We need to tell the secondary core where to find |
106 | * its stack and the page tables. | 88 | * its stack and the page tables. |
107 | */ | 89 | */ |
108 | secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; | 90 | secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; |
109 | secondary_data.pgdir = virt_to_phys(pgd); | 91 | secondary_data.pgdir = virt_to_phys(idmap_pgd); |
110 | secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); | 92 | secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); |
111 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); | 93 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); |
112 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); | 94 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); |
@@ -142,16 +124,6 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
142 | secondary_data.stack = NULL; | 124 | secondary_data.stack = NULL; |
143 | secondary_data.pgdir = 0; | 125 | secondary_data.pgdir = 0; |
144 | 126 | ||
145 | if (PHYS_OFFSET != PAGE_OFFSET) { | ||
146 | #ifndef CONFIG_HOTPLUG_CPU | ||
147 | identity_mapping_del(pgd, __pa(__init_begin), __pa(__init_end)); | ||
148 | #endif | ||
149 | identity_mapping_del(pgd, __pa(_stext), __pa(_etext)); | ||
150 | identity_mapping_del(pgd, __pa(_sdata), __pa(_edata)); | ||
151 | } | ||
152 | |||
153 | pgd_free(&init_mm, pgd); | ||
154 | |||
155 | return ret; | 127 | return ret; |
156 | } | 128 | } |
157 | 129 | ||
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c index 93a22d282c16..1794cc3b0f18 100644 --- a/arch/arm/kernel/suspend.c +++ b/arch/arm/kernel/suspend.c | |||
@@ -1,13 +1,12 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | 2 | ||
3 | #include <asm/idmap.h> | ||
3 | #include <asm/pgalloc.h> | 4 | #include <asm/pgalloc.h> |
4 | #include <asm/pgtable.h> | 5 | #include <asm/pgtable.h> |
5 | #include <asm/memory.h> | 6 | #include <asm/memory.h> |
6 | #include <asm/suspend.h> | 7 | #include <asm/suspend.h> |
7 | #include <asm/tlbflush.h> | 8 | #include <asm/tlbflush.h> |
8 | 9 | ||
9 | static pgd_t *suspend_pgd; | ||
10 | |||
11 | extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); | 10 | extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); |
12 | extern void cpu_resume_mmu(void); | 11 | extern void cpu_resume_mmu(void); |
13 | 12 | ||
@@ -21,7 +20,7 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr) | |||
21 | *save_ptr = virt_to_phys(ptr); | 20 | *save_ptr = virt_to_phys(ptr); |
22 | 21 | ||
23 | /* This must correspond to the LDM in cpu_resume() assembly */ | 22 | /* This must correspond to the LDM in cpu_resume() assembly */ |
24 | *ptr++ = virt_to_phys(suspend_pgd); | 23 | *ptr++ = virt_to_phys(idmap_pgd); |
25 | *ptr++ = sp; | 24 | *ptr++ = sp; |
26 | *ptr++ = virt_to_phys(cpu_do_resume); | 25 | *ptr++ = virt_to_phys(cpu_do_resume); |
27 | 26 | ||
@@ -42,7 +41,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) | |||
42 | struct mm_struct *mm = current->active_mm; | 41 | struct mm_struct *mm = current->active_mm; |
43 | int ret; | 42 | int ret; |
44 | 43 | ||
45 | if (!suspend_pgd) | 44 | if (!idmap_pgd) |
46 | return -EINVAL; | 45 | return -EINVAL; |
47 | 46 | ||
48 | /* | 47 | /* |
@@ -59,14 +58,3 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) | |||
59 | 58 | ||
60 | return ret; | 59 | return ret; |
61 | } | 60 | } |
62 | |||
63 | static int __init cpu_suspend_init(void) | ||
64 | { | ||
65 | suspend_pgd = pgd_alloc(&init_mm); | ||
66 | if (suspend_pgd) { | ||
67 | unsigned long addr = virt_to_phys(cpu_resume_mmu); | ||
68 | identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE); | ||
69 | } | ||
70 | return suspend_pgd ? 0 : -ENOMEM; | ||
71 | } | ||
72 | core_initcall(cpu_suspend_init); | ||
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 20b3041e0860..f76e75548670 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -13,6 +13,12 @@ | |||
13 | *(.proc.info.init) \ | 13 | *(.proc.info.init) \ |
14 | VMLINUX_SYMBOL(__proc_info_end) = .; | 14 | VMLINUX_SYMBOL(__proc_info_end) = .; |
15 | 15 | ||
16 | #define IDMAP_TEXT \ | ||
17 | ALIGN_FUNCTION(); \ | ||
18 | VMLINUX_SYMBOL(__idmap_text_start) = .; \ | ||
19 | *(.idmap.text) \ | ||
20 | VMLINUX_SYMBOL(__idmap_text_end) = .; | ||
21 | |||
16 | #ifdef CONFIG_HOTPLUG_CPU | 22 | #ifdef CONFIG_HOTPLUG_CPU |
17 | #define ARM_CPU_DISCARD(x) | 23 | #define ARM_CPU_DISCARD(x) |
18 | #define ARM_CPU_KEEP(x) x | 24 | #define ARM_CPU_KEEP(x) x |
@@ -92,6 +98,7 @@ SECTIONS | |||
92 | SCHED_TEXT | 98 | SCHED_TEXT |
93 | LOCK_TEXT | 99 | LOCK_TEXT |
94 | KPROBES_TEXT | 100 | KPROBES_TEXT |
101 | IDMAP_TEXT | ||
95 | #ifdef CONFIG_MMU | 102 | #ifdef CONFIG_MMU |
96 | *(.fixup) | 103 | *(.fixup) |
97 | #endif | 104 | #endif |