aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-12-06 15:27:54 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-12-06 15:27:54 -0500
commit3ee0fc5ca129cbae81c073756febcb1c552af446 (patch)
tree08f061c1ec9e948df760a0746441bec9f290d774 /arch/arm/kernel
parentdeee6d5359969a0ce4e2760cfd7b9f379bd5698a (diff)
parent4e8ee7de227e3ab9a72040b448ad728c5428a042 (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.S18
-rw-r--r--arch/arm/kernel/sleep.S2
-rw-r--r--arch/arm/kernel/smp.c32
-rw-r--r--arch/arm/kernel/suspend.c18
-rw-r--r--arch/arm/kernel/vmlinux.lds.S7
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:
287ENDPROC(__create_page_tables) 287ENDPROC(__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"
402ENTRY(__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:
409ENDPROC(__turn_mmu_on) 410ENDPROC(__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"
57ENTRY(cpu_resume_mmu) 58ENTRY(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
64ENDPROC(cpu_resume_mmu) 65ENDPROC(cpu_resume_mmu)
66 .popsection
65cpu_resume_after_mmu: 67cpu_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
9static pgd_t *suspend_pgd;
10
11extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); 10extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
12extern void cpu_resume_mmu(void); 11extern 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
63static 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}
72core_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