diff options
author | Matthew Wilcox <matthew@wil.cx> | 2006-12-16 00:47:47 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@athena.road.mcmartin.ca> | 2007-02-17 00:51:25 -0500 |
commit | 9f15c82686251cd2b97ac6859de62959d3c4afe1 (patch) | |
tree | 6bacc1d1422fd9770d9b5f90417a804a8cad7ef1 /arch/parisc | |
parent | e6fc0449be45a0e7520da6a17a64520743b9aa20 (diff) |
[PARISC] Fix show_stack() when we can't kmalloc
show_stack() was calling kzalloc() to allocate a struct pt_regs.
This meant that *really* early stack dumps would cause a null pointer
dereference. x86_64 allocates its pt_regs on the stack, so do the same.
Kyle actually committed this exact patch to CVS on
Wed Jul 26 14:32:39 2006 UTC, and never moved it across to git.
Bad Kyle.
Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc')
-rw-r--r-- | arch/parisc/kernel/traps.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index fa0811295acc..949722540864 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
@@ -187,18 +187,19 @@ void show_stack(struct task_struct *task, unsigned long *s) | |||
187 | 187 | ||
188 | if (!task) { | 188 | if (!task) { |
189 | unsigned long sp; | 189 | unsigned long sp; |
190 | struct pt_regs *r; | ||
191 | 190 | ||
192 | HERE: | 191 | HERE: |
193 | asm volatile ("copy %%r30, %0" : "=r"(sp)); | 192 | asm volatile ("copy %%r30, %0" : "=r"(sp)); |
194 | r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL); | 193 | { |
195 | if (!r) | 194 | struct pt_regs r; |
196 | return; | 195 | |
197 | r->iaoq[0] = (unsigned long)&&HERE; | 196 | memset(&r, 0, sizeof(struct pt_regs)); |
198 | r->gr[2] = (unsigned long)__builtin_return_address(0); | 197 | r.iaoq[0] = (unsigned long)&&HERE; |
199 | r->gr[30] = sp; | 198 | r.gr[2] = (unsigned long)__builtin_return_address(0); |
200 | unwind_frame_init(&info, current, r); | 199 | r.gr[30] = sp; |
201 | kfree(r); | 200 | |
201 | unwind_frame_init(&info, current, &r); | ||
202 | } | ||
202 | } else { | 203 | } else { |
203 | unwind_frame_init_from_blocked_task(&info, task); | 204 | unwind_frame_init_from_blocked_task(&info, task); |
204 | } | 205 | } |