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]; |
