diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/head-nommu.S | 4 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/arm/kernel/machine_kexec.c | 17 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/arm/kernel/relocate_kernel.S | 8 | ||||
-rw-r--r-- | arch/arm/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/arm/kernel/sigreturn_codes.S | 40 | ||||
-rw-r--r-- | arch/arm/kernel/stacktrace.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 3 |
9 files changed, 59 insertions, 27 deletions
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 14235ba64a90..716249cc2ee1 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
@@ -68,7 +68,7 @@ ENTRY(stext) | |||
68 | 68 | ||
69 | #ifdef CONFIG_ARM_MPU | 69 | #ifdef CONFIG_ARM_MPU |
70 | /* Calculate the size of a region covering just the kernel */ | 70 | /* Calculate the size of a region covering just the kernel */ |
71 | ldr r5, =PHYS_OFFSET @ Region start: PHYS_OFFSET | 71 | ldr r5, =PLAT_PHYS_OFFSET @ Region start: PHYS_OFFSET |
72 | ldr r6, =(_end) @ Cover whole kernel | 72 | ldr r6, =(_end) @ Cover whole kernel |
73 | sub r6, r6, r5 @ Minimum size of region to map | 73 | sub r6, r6, r5 @ Minimum size of region to map |
74 | clz r6, r6 @ Region size must be 2^N... | 74 | clz r6, r6 @ Region size must be 2^N... |
@@ -213,7 +213,7 @@ ENTRY(__setup_mpu) | |||
213 | set_region_nr r0, #MPU_RAM_REGION | 213 | set_region_nr r0, #MPU_RAM_REGION |
214 | isb | 214 | isb |
215 | /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */ | 215 | /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */ |
216 | ldr r0, =PHYS_OFFSET @ RAM starts at PHYS_OFFSET | 216 | ldr r0, =PLAT_PHYS_OFFSET @ RAM starts at PHYS_OFFSET |
217 | ldr r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL) | 217 | ldr r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL) |
218 | 218 | ||
219 | setup_region r0, r5, r6, MPU_DATA_SIDE @ PHYS_OFFSET, shared, enabled | 219 | setup_region r0, r5, r6, MPU_DATA_SIDE @ PHYS_OFFSET, shared, enabled |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 11d59b32fb8d..32f317e5828a 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -110,7 +110,7 @@ ENTRY(stext) | |||
110 | sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET) | 110 | sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET) |
111 | add r8, r8, r4 @ PHYS_OFFSET | 111 | add r8, r8, r4 @ PHYS_OFFSET |
112 | #else | 112 | #else |
113 | ldr r8, =PHYS_OFFSET @ always constant in this case | 113 | ldr r8, =PLAT_PHYS_OFFSET @ always constant in this case |
114 | #endif | 114 | #endif |
115 | 115 | ||
116 | /* | 116 | /* |
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 57221e349a7c..f0d180d8b29f 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
@@ -14,11 +14,12 @@ | |||
14 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
15 | #include <asm/mmu_context.h> | 15 | #include <asm/mmu_context.h> |
16 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
17 | #include <asm/fncpy.h> | ||
17 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
18 | #include <asm/smp_plat.h> | 19 | #include <asm/smp_plat.h> |
19 | #include <asm/system_misc.h> | 20 | #include <asm/system_misc.h> |
20 | 21 | ||
21 | extern const unsigned char relocate_new_kernel[]; | 22 | extern void relocate_new_kernel(void); |
22 | extern const unsigned int relocate_new_kernel_size; | 23 | extern const unsigned int relocate_new_kernel_size; |
23 | 24 | ||
24 | extern unsigned long kexec_start_address; | 25 | extern unsigned long kexec_start_address; |
@@ -142,6 +143,8 @@ void machine_kexec(struct kimage *image) | |||
142 | { | 143 | { |
143 | unsigned long page_list; | 144 | unsigned long page_list; |
144 | unsigned long reboot_code_buffer_phys; | 145 | unsigned long reboot_code_buffer_phys; |
146 | unsigned long reboot_entry = (unsigned long)relocate_new_kernel; | ||
147 | unsigned long reboot_entry_phys; | ||
145 | void *reboot_code_buffer; | 148 | void *reboot_code_buffer; |
146 | 149 | ||
147 | /* | 150 | /* |
@@ -168,16 +171,16 @@ void machine_kexec(struct kimage *image) | |||
168 | 171 | ||
169 | 172 | ||
170 | /* copy our kernel relocation code to the control code page */ | 173 | /* copy our kernel relocation code to the control code page */ |
171 | memcpy(reboot_code_buffer, | 174 | reboot_entry = fncpy(reboot_code_buffer, |
172 | relocate_new_kernel, relocate_new_kernel_size); | 175 | reboot_entry, |
176 | relocate_new_kernel_size); | ||
177 | reboot_entry_phys = (unsigned long)reboot_entry + | ||
178 | (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); | ||
173 | 179 | ||
174 | |||
175 | flush_icache_range((unsigned long) reboot_code_buffer, | ||
176 | (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); | ||
177 | printk(KERN_INFO "Bye!\n"); | 180 | printk(KERN_INFO "Bye!\n"); |
178 | 181 | ||
179 | if (kexec_reinit) | 182 | if (kexec_reinit) |
180 | kexec_reinit(); | 183 | kexec_reinit(); |
181 | 184 | ||
182 | soft_restart(reboot_code_buffer_phys); | 185 | soft_restart(reboot_entry_phys); |
183 | } | 186 | } |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 94f6b05f9e24..92f7b15dd221 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -404,6 +404,7 @@ EXPORT_SYMBOL(dump_fpu); | |||
404 | unsigned long get_wchan(struct task_struct *p) | 404 | unsigned long get_wchan(struct task_struct *p) |
405 | { | 405 | { |
406 | struct stackframe frame; | 406 | struct stackframe frame; |
407 | unsigned long stack_page; | ||
407 | int count = 0; | 408 | int count = 0; |
408 | if (!p || p == current || p->state == TASK_RUNNING) | 409 | if (!p || p == current || p->state == TASK_RUNNING) |
409 | return 0; | 410 | return 0; |
@@ -412,9 +413,11 @@ unsigned long get_wchan(struct task_struct *p) | |||
412 | frame.sp = thread_saved_sp(p); | 413 | frame.sp = thread_saved_sp(p); |
413 | frame.lr = 0; /* recovered from the stack */ | 414 | frame.lr = 0; /* recovered from the stack */ |
414 | frame.pc = thread_saved_pc(p); | 415 | frame.pc = thread_saved_pc(p); |
416 | stack_page = (unsigned long)task_stack_page(p); | ||
415 | do { | 417 | do { |
416 | int ret = unwind_frame(&frame); | 418 | if (frame.sp < stack_page || |
417 | if (ret < 0) | 419 | frame.sp >= stack_page + THREAD_SIZE || |
420 | unwind_frame(&frame) < 0) | ||
418 | return 0; | 421 | return 0; |
419 | if (!in_sched_functions(frame.pc)) | 422 | if (!in_sched_functions(frame.pc)) |
420 | return frame.pc; | 423 | return frame.pc; |
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index d0cdedf4864d..95858966d84e 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S | |||
@@ -2,10 +2,12 @@ | |||
2 | * relocate_kernel.S - put the kernel image in place to boot | 2 | * relocate_kernel.S - put the kernel image in place to boot |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/linkage.h> | ||
5 | #include <asm/kexec.h> | 6 | #include <asm/kexec.h> |
6 | 7 | ||
7 | .globl relocate_new_kernel | 8 | .align 3 /* not needed for this code, but keeps fncpy() happy */ |
8 | relocate_new_kernel: | 9 | |
10 | ENTRY(relocate_new_kernel) | ||
9 | 11 | ||
10 | ldr r0,kexec_indirection_page | 12 | ldr r0,kexec_indirection_page |
11 | ldr r1,kexec_start_address | 13 | ldr r1,kexec_start_address |
@@ -79,6 +81,8 @@ kexec_mach_type: | |||
79 | kexec_boot_atags: | 81 | kexec_boot_atags: |
80 | .long 0x0 | 82 | .long 0x0 |
81 | 83 | ||
84 | ENDPROC(relocate_new_kernel) | ||
85 | |||
82 | relocate_new_kernel_end: | 86 | relocate_new_kernel_end: |
83 | 87 | ||
84 | .globl relocate_new_kernel_size | 88 | .globl relocate_new_kernel_size |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 6a1b8a81b1ae..987a7f5bce5f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -873,8 +873,6 @@ void __init setup_arch(char **cmdline_p) | |||
873 | machine_desc = mdesc; | 873 | machine_desc = mdesc; |
874 | machine_name = mdesc->name; | 874 | machine_name = mdesc->name; |
875 | 875 | ||
876 | setup_dma_zone(mdesc); | ||
877 | |||
878 | if (mdesc->reboot_mode != REBOOT_HARD) | 876 | if (mdesc->reboot_mode != REBOOT_HARD) |
879 | reboot_mode = mdesc->reboot_mode; | 877 | reboot_mode = mdesc->reboot_mode; |
880 | 878 | ||
@@ -892,6 +890,7 @@ void __init setup_arch(char **cmdline_p) | |||
892 | sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); | 890 | sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); |
893 | 891 | ||
894 | early_paging_init(mdesc, lookup_processor_type(read_cpuid_id())); | 892 | early_paging_init(mdesc, lookup_processor_type(read_cpuid_id())); |
893 | setup_dma_zone(mdesc); | ||
895 | sanity_check_meminfo(); | 894 | sanity_check_meminfo(); |
896 | arm_memblock_init(&meminfo, mdesc); | 895 | arm_memblock_init(&meminfo, mdesc); |
897 | 896 | ||
diff --git a/arch/arm/kernel/sigreturn_codes.S b/arch/arm/kernel/sigreturn_codes.S index 3c5d0f2170fd..b84d0cb13682 100644 --- a/arch/arm/kernel/sigreturn_codes.S +++ b/arch/arm/kernel/sigreturn_codes.S | |||
@@ -30,6 +30,27 @@ | |||
30 | * snippets. | 30 | * snippets. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | /* | ||
34 | * In CPU_THUMBONLY case kernel arm opcodes are not allowed. | ||
35 | * Note in this case codes skips those instructions but it uses .org | ||
36 | * directive to keep correct layout of sigreturn_codes array. | ||
37 | */ | ||
38 | #ifndef CONFIG_CPU_THUMBONLY | ||
39 | #define ARM_OK(code...) code | ||
40 | #else | ||
41 | #define ARM_OK(code...) | ||
42 | #endif | ||
43 | |||
44 | .macro arm_slot n | ||
45 | .org sigreturn_codes + 12 * (\n) | ||
46 | ARM_OK( .arm ) | ||
47 | .endm | ||
48 | |||
49 | .macro thumb_slot n | ||
50 | .org sigreturn_codes + 12 * (\n) + 8 | ||
51 | .thumb | ||
52 | .endm | ||
53 | |||
33 | #if __LINUX_ARM_ARCH__ <= 4 | 54 | #if __LINUX_ARM_ARCH__ <= 4 |
34 | /* | 55 | /* |
35 | * Note we manually set minimally required arch that supports | 56 | * Note we manually set minimally required arch that supports |
@@ -45,26 +66,27 @@ | |||
45 | .global sigreturn_codes | 66 | .global sigreturn_codes |
46 | .type sigreturn_codes, #object | 67 | .type sigreturn_codes, #object |
47 | 68 | ||
48 | .arm | 69 | .align |
49 | 70 | ||
50 | sigreturn_codes: | 71 | sigreturn_codes: |
51 | 72 | ||
52 | /* ARM sigreturn syscall code snippet */ | 73 | /* ARM sigreturn syscall code snippet */ |
53 | mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) | 74 | arm_slot 0 |
54 | swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) | 75 | ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) ) |
76 | ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) | ||
55 | 77 | ||
56 | /* Thumb sigreturn syscall code snippet */ | 78 | /* Thumb sigreturn syscall code snippet */ |
57 | .thumb | 79 | thumb_slot 0 |
58 | movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) | 80 | movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) |
59 | swi #0 | 81 | swi #0 |
60 | 82 | ||
61 | /* ARM sigreturn_rt syscall code snippet */ | 83 | /* ARM sigreturn_rt syscall code snippet */ |
62 | .arm | 84 | arm_slot 1 |
63 | mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) | 85 | ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) ) |
64 | swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) | 86 | ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) |
65 | 87 | ||
66 | /* Thumb sigreturn_rt syscall code snippet */ | 88 | /* Thumb sigreturn_rt syscall code snippet */ |
67 | .thumb | 89 | thumb_slot 1 |
68 | movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) | 90 | movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) |
69 | swi #0 | 91 | swi #0 |
70 | 92 | ||
@@ -74,7 +96,7 @@ sigreturn_codes: | |||
74 | * it is thumb case or not, so we need additional | 96 | * it is thumb case or not, so we need additional |
75 | * word after real last entry. | 97 | * word after real last entry. |
76 | */ | 98 | */ |
77 | .arm | 99 | arm_slot 2 |
78 | .space 4 | 100 | .space 4 |
79 | 101 | ||
80 | .size sigreturn_codes, . - sigreturn_codes | 102 | .size sigreturn_codes, . - sigreturn_codes |
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 00f79e59985b..af4e8c8a5422 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c | |||
@@ -31,7 +31,7 @@ int notrace unwind_frame(struct stackframe *frame) | |||
31 | high = ALIGN(low, THREAD_SIZE); | 31 | high = ALIGN(low, THREAD_SIZE); |
32 | 32 | ||
33 | /* check current frame pointer is within bounds */ | 33 | /* check current frame pointer is within bounds */ |
34 | if (fp < (low + 12) || fp + 4 >= high) | 34 | if (fp < low + 12 || fp > high - 4) |
35 | return -EINVAL; | 35 | return -EINVAL; |
36 | 36 | ||
37 | /* restore the registers from the stack frame */ | 37 | /* restore the registers from the stack frame */ |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index dbf0923e8d76..7940241f0576 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -509,9 +509,10 @@ static inline int | |||
509 | __do_cache_op(unsigned long start, unsigned long end) | 509 | __do_cache_op(unsigned long start, unsigned long end) |
510 | { | 510 | { |
511 | int ret; | 511 | int ret; |
512 | unsigned long chunk = PAGE_SIZE; | ||
513 | 512 | ||
514 | do { | 513 | do { |
514 | unsigned long chunk = min(PAGE_SIZE, end - start); | ||
515 | |||
515 | if (signal_pending(current)) { | 516 | if (signal_pending(current)) { |
516 | struct thread_info *ti = current_thread_info(); | 517 | struct thread_info *ti = current_thread_info(); |
517 | 518 | ||