aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-05-05 08:11:00 -0400
committerRussell King <rmk@dyn-67.arm.linux.org.uk>2005-05-05 08:11:00 -0400
commit4f7a18124c1a44858fb74a1c4234015009952959 (patch)
tree978f55875b776c83ebcfed24737784ac098d1a4e /arch/arm
parent897f5ab2cd733a77a2279268262919caa8154b9d (diff)
[PATCH] ARM: Fix kernel stack offset calculations
Various places in the ARM kernel implicitly assumed that kernel stacks are always 8K due to hard coded constants. Replace these constants with definitions. Correct the allowable range of kernel stack pointer values within the allocation. Arrange for the entire kernel stack to be zeroed, not just the upper 4K if CONFIG_DEBUG_STACK_USAGE is set. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/head.S3
-rw-r--r--arch/arm/kernel/process.c25
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/traps.c3
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
5 files changed, 19 insertions, 17 deletions
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;
256static unsigned int nr_thread_info; 256static 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
262struct thread_info *alloc_thread_info(struct task_struct *task) 260struct 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);
447unsigned long get_wchan(struct task_struct *p) 444unsigned 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" (&regs), 306 "r" (&regs),
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..8988c02119fd 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 }
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
9OUTPUT_ARCH(arm) 10OUTPUT_ARCH(arm)
10ENTRY(stext) 11ENTRY(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