diff options
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 14 | ||||
-rw-r--r-- | arch/arm/kernel/head.S | 3 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 25 | ||||
-rw-r--r-- | arch/arm/kernel/sys_arm.c | 2 | ||||
-rw-r--r-- | arch/arm/kernel/traps.c | 14 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 3 |
6 files changed, 31 insertions, 30 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 080df907f242..4eb36155dc93 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -17,8 +17,8 @@ | |||
17 | 17 | ||
18 | #include <asm/glue.h> | 18 | #include <asm/glue.h> |
19 | #include <asm/vfpmacros.h> | 19 | #include <asm/vfpmacros.h> |
20 | #include <asm/hardware.h> @ should be moved into entry-macro.S | 20 | #include <asm/hardware.h> /* should be moved into entry-macro.S */ |
21 | #include <asm/arch/irqs.h> @ should be moved into entry-macro.S | 21 | #include <asm/arch/irqs.h> /* should be moved into entry-macro.S */ |
22 | #include <asm/arch/entry-macro.S> | 22 | #include <asm/arch/entry-macro.S> |
23 | 23 | ||
24 | #include "entry-header.S" | 24 | #include "entry-header.S" |
@@ -505,9 +505,9 @@ ENTRY(__switch_to) | |||
505 | mra r4, r5, acc0 | 505 | mra r4, r5, acc0 |
506 | stmia ip, {r4, r5} | 506 | stmia ip, {r4, r5} |
507 | #endif | 507 | #endif |
508 | #ifdef CONFIG_HAS_TLS_REG | 508 | #if defined(CONFIG_HAS_TLS_REG) |
509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register | 509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register |
510 | #else | 510 | #elif !defined(CONFIG_TLS_REG_EMUL) |
511 | mov r4, #0xffff0fff | 511 | mov r4, #0xffff0fff |
512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 | 512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 |
513 | #endif | 513 | #endif |
@@ -690,11 +690,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
690 | 690 | ||
691 | __kuser_get_tls: @ 0xffff0fe0 | 691 | __kuser_get_tls: @ 0xffff0fe0 |
692 | 692 | ||
693 | #ifndef CONFIG_HAS_TLS_REG | 693 | #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) |
694 | |||
695 | #ifdef CONFIG_SMP /* sanity check */ | ||
696 | #error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong" | ||
697 | #endif | ||
698 | 694 | ||
699 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 | 695 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 |
700 | mov pc, lr | 696 | mov pc, lr |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 171b3e811c71..4733877296d4 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/procinfo.h> | 19 | #include <asm/procinfo.h> |
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | #include <asm/constants.h> | 21 | #include <asm/constants.h> |
22 | #include <asm/thread_info.h> | ||
22 | #include <asm/system.h> | 23 | #include <asm/system.h> |
23 | 24 | ||
24 | #define PROCINFO_MMUFLAGS 8 | 25 | #define PROCINFO_MMUFLAGS 8 |
@@ -131,7 +132,7 @@ __switch_data: | |||
131 | .long processor_id @ r4 | 132 | .long processor_id @ r4 |
132 | .long __machine_arch_type @ r5 | 133 | .long __machine_arch_type @ r5 |
133 | .long cr_alignment @ r6 | 134 | .long cr_alignment @ r6 |
134 | .long init_thread_union+8192 @ sp | 135 | .long init_thread_union + THREAD_START_SP @ sp |
135 | 136 | ||
136 | /* | 137 | /* |
137 | * The following fragment of code is executed with the MMU on, and uses | 138 | * The following fragment of code is executed with the MMU on, and uses |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 26eacd3e5def..8f146a4b4752 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -256,8 +256,6 @@ static unsigned long *thread_info_head; | |||
256 | static unsigned int nr_thread_info; | 256 | static unsigned int nr_thread_info; |
257 | 257 | ||
258 | #define EXTRA_TASK_STRUCT 4 | 258 | #define EXTRA_TASK_STRUCT 4 |
259 | #define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) | ||
260 | #define ll_free_task_struct(p) free_pages((unsigned long)(p),1) | ||
261 | 259 | ||
262 | struct thread_info *alloc_thread_info(struct task_struct *task) | 260 | struct thread_info *alloc_thread_info(struct task_struct *task) |
263 | { | 261 | { |
@@ -274,17 +272,16 @@ struct thread_info *alloc_thread_info(struct task_struct *task) | |||
274 | } | 272 | } |
275 | 273 | ||
276 | if (!thread) | 274 | if (!thread) |
277 | thread = ll_alloc_task_struct(); | 275 | thread = (struct thread_info *) |
276 | __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); | ||
278 | 277 | ||
279 | #ifdef CONFIG_MAGIC_SYSRQ | 278 | #ifdef CONFIG_DEBUG_STACK_USAGE |
280 | /* | 279 | /* |
281 | * The stack must be cleared if you want SYSRQ-T to | 280 | * The stack must be cleared if you want SYSRQ-T to |
282 | * give sensible stack usage information | 281 | * give sensible stack usage information |
283 | */ | 282 | */ |
284 | if (thread) { | 283 | if (thread) |
285 | char *p = (char *)thread; | 284 | memzero(thread, THREAD_SIZE); |
286 | memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); | ||
287 | } | ||
288 | #endif | 285 | #endif |
289 | return thread; | 286 | return thread; |
290 | } | 287 | } |
@@ -297,7 +294,7 @@ void free_thread_info(struct thread_info *thread) | |||
297 | thread_info_head = p; | 294 | thread_info_head = p; |
298 | nr_thread_info += 1; | 295 | nr_thread_info += 1; |
299 | } else | 296 | } else |
300 | ll_free_task_struct(thread); | 297 | free_pages((unsigned long)thread, THREAD_SIZE_ORDER); |
301 | } | 298 | } |
302 | 299 | ||
303 | /* | 300 | /* |
@@ -350,7 +347,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, | |||
350 | struct thread_info *thread = p->thread_info; | 347 | struct thread_info *thread = p->thread_info; |
351 | struct pt_regs *childregs; | 348 | struct pt_regs *childregs; |
352 | 349 | ||
353 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; | 350 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; |
354 | *childregs = *regs; | 351 | *childregs = *regs; |
355 | childregs->ARM_r0 = 0; | 352 | childregs->ARM_r0 = 0; |
356 | childregs->ARM_sp = stack_start; | 353 | childregs->ARM_sp = stack_start; |
@@ -447,15 +444,17 @@ EXPORT_SYMBOL(kernel_thread); | |||
447 | unsigned long get_wchan(struct task_struct *p) | 444 | unsigned long get_wchan(struct task_struct *p) |
448 | { | 445 | { |
449 | unsigned long fp, lr; | 446 | unsigned long fp, lr; |
450 | unsigned long stack_page; | 447 | unsigned long stack_start, stack_end; |
451 | int count = 0; | 448 | int count = 0; |
452 | if (!p || p == current || p->state == TASK_RUNNING) | 449 | if (!p || p == current || p->state == TASK_RUNNING) |
453 | return 0; | 450 | return 0; |
454 | 451 | ||
455 | stack_page = 4096 + (unsigned long)p->thread_info; | 452 | stack_start = (unsigned long)(p->thread_info + 1); |
453 | stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE; | ||
454 | |||
456 | fp = thread_saved_fp(p); | 455 | fp = thread_saved_fp(p); |
457 | do { | 456 | do { |
458 | if (fp < stack_page || fp > 4092+stack_page) | 457 | if (fp < stack_start || fp > stack_end) |
459 | return 0; | 458 | return 0; |
460 | lr = pc_pointer (((unsigned long *)fp)[-1]); | 459 | lr = pc_pointer (((unsigned long *)fp)[-1]); |
461 | if (!in_sched_functions(lr)) | 460 | if (!in_sched_functions(lr)) |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index ef32577da304..f897ce2ccf0d 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
@@ -302,7 +302,7 @@ long execve(const char *filename, char **argv, char **envp) | |||
302 | "b ret_to_user" | 302 | "b ret_to_user" |
303 | : | 303 | : |
304 | : "r" (current_thread_info()), | 304 | : "r" (current_thread_info()), |
305 | "Ir" (THREAD_SIZE - 8 - sizeof(regs)), | 305 | "Ir" (THREAD_START_SP - sizeof(regs)), |
306 | "r" (®s), | 306 | "r" (®s), |
307 | "Ir" (sizeof(regs)) | 307 | "Ir" (sizeof(regs)) |
308 | : "r0", "r1", "r2", "r3", "ip", "memory"); | 308 | : "r0", "r1", "r2", "r3", "ip", "memory"); |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 3a001fe5540b..14df16b983f4 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -218,7 +218,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) | |||
218 | tsk->comm, tsk->pid, tsk->thread_info + 1); | 218 | tsk->comm, tsk->pid, tsk->thread_info + 1); |
219 | 219 | ||
220 | if (!user_mode(regs) || in_interrupt()) { | 220 | if (!user_mode(regs) || in_interrupt()) { |
221 | dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); | 221 | dump_mem("Stack: ", regs->ARM_sp, |
222 | THREAD_SIZE + (unsigned long)tsk->thread_info); | ||
222 | dump_backtrace(regs, tsk); | 223 | dump_backtrace(regs, tsk); |
223 | dump_instr(regs); | 224 | dump_instr(regs); |
224 | } | 225 | } |
@@ -450,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
450 | 451 | ||
451 | case NR(set_tls): | 452 | case NR(set_tls): |
452 | thread->tp_value = regs->ARM_r0; | 453 | thread->tp_value = regs->ARM_r0; |
453 | #ifdef CONFIG_HAS_TLS_REG | 454 | #if defined(CONFIG_HAS_TLS_REG) |
454 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); | 455 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); |
455 | #else | 456 | #elif !defined(CONFIG_TLS_REG_EMUL) |
456 | /* | 457 | /* |
457 | * User space must never try to access this directly. | 458 | * User space must never try to access this directly. |
458 | * Expect your app to break eventually if you do so. | 459 | * Expect your app to break eventually if you do so. |
@@ -497,11 +498,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
497 | return 0; | 498 | return 0; |
498 | } | 499 | } |
499 | 500 | ||
500 | #if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG) | 501 | #ifdef CONFIG_TLS_REG_EMUL |
501 | 502 | ||
502 | /* | 503 | /* |
503 | * We might be running on an ARMv6+ processor which should have the TLS | 504 | * We might be running on an ARMv6+ processor which should have the TLS |
504 | * register, but for some reason we can't use it and have to emulate it. | 505 | * register but for some reason we can't use it, or maybe an SMP system |
506 | * using a pre-ARMv6 processor (there are apparently a few prototypes like | ||
507 | * that in existence) and therefore access to that register must be | ||
508 | * emulated. | ||
505 | */ | 509 | */ |
506 | 510 | ||
507 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) | 511 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index a39c6a42d68a..ad2d66c93a5c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <asm-generic/vmlinux.lds.h> | 6 | #include <asm-generic/vmlinux.lds.h> |
7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
8 | #include <asm/thread_info.h> | ||
8 | 9 | ||
9 | OUTPUT_ARCH(arm) | 10 | OUTPUT_ARCH(arm) |
10 | ENTRY(stext) | 11 | ENTRY(stext) |
@@ -103,7 +104,7 @@ SECTIONS | |||
103 | __data_loc = ALIGN(4); /* location in binary */ | 104 | __data_loc = ALIGN(4); /* location in binary */ |
104 | . = DATAADDR; | 105 | . = DATAADDR; |
105 | #else | 106 | #else |
106 | . = ALIGN(8192); | 107 | . = ALIGN(THREAD_SIZE); |
107 | __data_loc = .; | 108 | __data_loc = .; |
108 | #endif | 109 | #endif |
109 | 110 | ||