diff options
Diffstat (limited to 'arch/sparc64/kernel/process.c')
-rw-r--r-- | arch/sparc64/kernel/process.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 7f5debdc5fed..15f4178592e7 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <asm/irq_regs.h> | 52 | #include <asm/irq_regs.h> |
53 | #include <asm/smp.h> | 53 | #include <asm/smp.h> |
54 | 54 | ||
55 | #include "kstack.h" | ||
56 | |||
55 | static void sparc64_yield(int cpu) | 57 | static void sparc64_yield(int cpu) |
56 | { | 58 | { |
57 | if (tlb_type != hypervisor) | 59 | if (tlb_type != hypervisor) |
@@ -235,19 +237,6 @@ void show_regs(struct pt_regs *regs) | |||
235 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; | 237 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; |
236 | static DEFINE_SPINLOCK(global_reg_snapshot_lock); | 238 | static DEFINE_SPINLOCK(global_reg_snapshot_lock); |
237 | 239 | ||
238 | static bool kstack_valid(struct thread_info *tp, struct reg_window *rw) | ||
239 | { | ||
240 | unsigned long thread_base, fp; | ||
241 | |||
242 | thread_base = (unsigned long) tp; | ||
243 | fp = (unsigned long) rw; | ||
244 | |||
245 | if (fp < (thread_base + sizeof(struct thread_info)) || | ||
246 | fp >= (thread_base + THREAD_SIZE)) | ||
247 | return false; | ||
248 | return true; | ||
249 | } | ||
250 | |||
251 | static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, | 240 | static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, |
252 | int this_cpu) | 241 | int this_cpu) |
253 | { | 242 | { |
@@ -264,11 +253,11 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, | |||
264 | 253 | ||
265 | rw = (struct reg_window *) | 254 | rw = (struct reg_window *) |
266 | (regs->u_regs[UREG_FP] + STACK_BIAS); | 255 | (regs->u_regs[UREG_FP] + STACK_BIAS); |
267 | if (kstack_valid(tp, rw)) { | 256 | if (kstack_valid(tp, (unsigned long) rw)) { |
268 | global_reg_snapshot[this_cpu].i7 = rw->ins[7]; | 257 | global_reg_snapshot[this_cpu].i7 = rw->ins[7]; |
269 | rw = (struct reg_window *) | 258 | rw = (struct reg_window *) |
270 | (rw->ins[6] + STACK_BIAS); | 259 | (rw->ins[6] + STACK_BIAS); |
271 | if (kstack_valid(tp, rw)) | 260 | if (kstack_valid(tp, (unsigned long) rw)) |
272 | global_reg_snapshot[this_cpu].rpc = rw->ins[7]; | 261 | global_reg_snapshot[this_cpu].rpc = rw->ins[7]; |
273 | } | 262 | } |
274 | } else { | 263 | } else { |
@@ -828,7 +817,7 @@ out: | |||
828 | unsigned long get_wchan(struct task_struct *task) | 817 | unsigned long get_wchan(struct task_struct *task) |
829 | { | 818 | { |
830 | unsigned long pc, fp, bias = 0; | 819 | unsigned long pc, fp, bias = 0; |
831 | unsigned long thread_info_base; | 820 | struct thread_info *tp; |
832 | struct reg_window *rw; | 821 | struct reg_window *rw; |
833 | unsigned long ret = 0; | 822 | unsigned long ret = 0; |
834 | int count = 0; | 823 | int count = 0; |
@@ -837,14 +826,12 @@ unsigned long get_wchan(struct task_struct *task) | |||
837 | task->state == TASK_RUNNING) | 826 | task->state == TASK_RUNNING) |
838 | goto out; | 827 | goto out; |
839 | 828 | ||
840 | thread_info_base = (unsigned long) task_stack_page(task); | 829 | tp = task_thread_info(task); |
841 | bias = STACK_BIAS; | 830 | bias = STACK_BIAS; |
842 | fp = task_thread_info(task)->ksp + bias; | 831 | fp = task_thread_info(task)->ksp + bias; |
843 | 832 | ||
844 | do { | 833 | do { |
845 | /* Bogus frame pointer? */ | 834 | if (!kstack_valid(tp, fp)) |
846 | if (fp < (thread_info_base + sizeof(struct thread_info)) || | ||
847 | fp >= (thread_info_base + THREAD_SIZE)) | ||
848 | break; | 835 | break; |
849 | rw = (struct reg_window *) fp; | 836 | rw = (struct reg_window *) fp; |
850 | pc = rw->ins[7]; | 837 | pc = rw->ins[7]; |