diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-09-05 12:56:57 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-09-05 12:56:57 -0400 |
| commit | 616ad8c44281c0c6711a72b560e01ec335ff27e0 (patch) | |
| tree | 0a20453ffedb09db6fb41a0c2208ccc2c7751d3a /arch/sparc64/kernel | |
| parent | 99809963c99e1ed868d9ebeb4a5e7ee1cbe0309f (diff) | |
| parent | b380b0d4f7dffcc235c0facefa537d4655619101 (diff) | |
Merge branch 'linus' into x86/defconfig
Diffstat (limited to 'arch/sparc64/kernel')
| -rw-r--r-- | arch/sparc64/kernel/irq.c | 52 | ||||
| -rw-r--r-- | arch/sparc64/kernel/kstack.h | 60 | ||||
| -rw-r--r-- | arch/sparc64/kernel/of_device.c | 20 | ||||
| -rw-r--r-- | arch/sparc64/kernel/process.c | 27 | ||||
| -rw-r--r-- | arch/sparc64/kernel/smp.c | 4 | ||||
| -rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 13 | ||||
| -rw-r--r-- | arch/sparc64/kernel/traps.c | 7 |
7 files changed, 141 insertions, 42 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index ba43d85e8dde..9b6689d9d570 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
| @@ -682,10 +682,32 @@ void ack_bad_irq(unsigned int virt_irq) | |||
| 682 | ino, virt_irq); | 682 | ino, virt_irq); |
| 683 | } | 683 | } |
| 684 | 684 | ||
| 685 | void *hardirq_stack[NR_CPUS]; | ||
| 686 | void *softirq_stack[NR_CPUS]; | ||
| 687 | |||
| 688 | static __attribute__((always_inline)) void *set_hardirq_stack(void) | ||
| 689 | { | ||
| 690 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
| 691 | |||
| 692 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
| 693 | if (orig_sp < sp || | ||
| 694 | orig_sp > (sp + THREAD_SIZE)) { | ||
| 695 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
| 696 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
| 697 | } | ||
| 698 | |||
| 699 | return orig_sp; | ||
| 700 | } | ||
| 701 | static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
| 702 | { | ||
| 703 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
| 704 | } | ||
| 705 | |||
| 685 | void handler_irq(int irq, struct pt_regs *regs) | 706 | void handler_irq(int irq, struct pt_regs *regs) |
| 686 | { | 707 | { |
| 687 | unsigned long pstate, bucket_pa; | 708 | unsigned long pstate, bucket_pa; |
| 688 | struct pt_regs *old_regs; | 709 | struct pt_regs *old_regs; |
| 710 | void *orig_sp; | ||
| 689 | 711 | ||
| 690 | clear_softint(1 << irq); | 712 | clear_softint(1 << irq); |
| 691 | 713 | ||
| @@ -703,6 +725,8 @@ void handler_irq(int irq, struct pt_regs *regs) | |||
| 703 | "i" (PSTATE_IE) | 725 | "i" (PSTATE_IE) |
| 704 | : "memory"); | 726 | : "memory"); |
| 705 | 727 | ||
| 728 | orig_sp = set_hardirq_stack(); | ||
| 729 | |||
| 706 | while (bucket_pa) { | 730 | while (bucket_pa) { |
| 707 | struct irq_desc *desc; | 731 | struct irq_desc *desc; |
| 708 | unsigned long next_pa; | 732 | unsigned long next_pa; |
| @@ -719,10 +743,38 @@ void handler_irq(int irq, struct pt_regs *regs) | |||
| 719 | bucket_pa = next_pa; | 743 | bucket_pa = next_pa; |
| 720 | } | 744 | } |
| 721 | 745 | ||
| 746 | restore_hardirq_stack(orig_sp); | ||
| 747 | |||
| 722 | irq_exit(); | 748 | irq_exit(); |
| 723 | set_irq_regs(old_regs); | 749 | set_irq_regs(old_regs); |
| 724 | } | 750 | } |
| 725 | 751 | ||
| 752 | void do_softirq(void) | ||
| 753 | { | ||
| 754 | unsigned long flags; | ||
| 755 | |||
| 756 | if (in_interrupt()) | ||
| 757 | return; | ||
| 758 | |||
| 759 | local_irq_save(flags); | ||
| 760 | |||
| 761 | if (local_softirq_pending()) { | ||
| 762 | void *orig_sp, *sp = softirq_stack[smp_processor_id()]; | ||
| 763 | |||
| 764 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
| 765 | |||
| 766 | __asm__ __volatile__("mov %%sp, %0\n\t" | ||
| 767 | "mov %1, %%sp" | ||
| 768 | : "=&r" (orig_sp) | ||
| 769 | : "r" (sp)); | ||
| 770 | __do_softirq(); | ||
| 771 | __asm__ __volatile__("mov %0, %%sp" | ||
| 772 | : : "r" (orig_sp)); | ||
| 773 | } | ||
| 774 | |||
| 775 | local_irq_restore(flags); | ||
| 776 | } | ||
| 777 | |||
| 726 | #ifdef CONFIG_HOTPLUG_CPU | 778 | #ifdef CONFIG_HOTPLUG_CPU |
| 727 | void fixup_irqs(void) | 779 | void fixup_irqs(void) |
| 728 | { | 780 | { |
diff --git a/arch/sparc64/kernel/kstack.h b/arch/sparc64/kernel/kstack.h new file mode 100644 index 000000000000..4248d969272f --- /dev/null +++ b/arch/sparc64/kernel/kstack.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | #ifndef _KSTACK_H | ||
| 2 | #define _KSTACK_H | ||
| 3 | |||
| 4 | #include <linux/thread_info.h> | ||
| 5 | #include <linux/sched.h> | ||
| 6 | #include <asm/ptrace.h> | ||
| 7 | #include <asm/irq.h> | ||
| 8 | |||
| 9 | /* SP must be STACK_BIAS adjusted already. */ | ||
| 10 | static inline bool kstack_valid(struct thread_info *tp, unsigned long sp) | ||
| 11 | { | ||
| 12 | unsigned long base = (unsigned long) tp; | ||
| 13 | |||
| 14 | if (sp >= (base + sizeof(struct thread_info)) && | ||
| 15 | sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf))) | ||
| 16 | return true; | ||
| 17 | |||
| 18 | if (hardirq_stack[tp->cpu]) { | ||
| 19 | base = (unsigned long) hardirq_stack[tp->cpu]; | ||
| 20 | if (sp >= base && | ||
| 21 | sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf))) | ||
| 22 | return true; | ||
| 23 | base = (unsigned long) softirq_stack[tp->cpu]; | ||
| 24 | if (sp >= base && | ||
| 25 | sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf))) | ||
| 26 | return true; | ||
| 27 | } | ||
| 28 | return false; | ||
| 29 | } | ||
| 30 | |||
| 31 | /* Does "regs" point to a valid pt_regs trap frame? */ | ||
| 32 | static inline bool kstack_is_trap_frame(struct thread_info *tp, struct pt_regs *regs) | ||
| 33 | { | ||
| 34 | unsigned long base = (unsigned long) tp; | ||
| 35 | unsigned long addr = (unsigned long) regs; | ||
| 36 | |||
| 37 | if (addr >= base && | ||
| 38 | addr <= (base + THREAD_SIZE - sizeof(*regs))) | ||
| 39 | goto check_magic; | ||
| 40 | |||
| 41 | if (hardirq_stack[tp->cpu]) { | ||
| 42 | base = (unsigned long) hardirq_stack[tp->cpu]; | ||
| 43 | if (addr >= base && | ||
| 44 | addr <= (base + THREAD_SIZE - sizeof(*regs))) | ||
| 45 | goto check_magic; | ||
| 46 | base = (unsigned long) softirq_stack[tp->cpu]; | ||
| 47 | if (addr >= base && | ||
| 48 | addr <= (base + THREAD_SIZE - sizeof(*regs))) | ||
| 49 | goto check_magic; | ||
| 50 | } | ||
| 51 | return false; | ||
| 52 | |||
| 53 | check_magic: | ||
| 54 | if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) | ||
| 55 | return true; | ||
| 56 | return false; | ||
| 57 | |||
| 58 | } | ||
| 59 | |||
| 60 | #endif /* _KSTACK_H */ | ||
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index f8b50cbf4bf7..f845f150f565 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
| @@ -96,7 +96,7 @@ struct of_bus { | |||
| 96 | int *addrc, int *sizec); | 96 | int *addrc, int *sizec); |
| 97 | int (*map)(u32 *addr, const u32 *range, | 97 | int (*map)(u32 *addr, const u32 *range, |
| 98 | int na, int ns, int pna); | 98 | int na, int ns, int pna); |
| 99 | unsigned int (*get_flags)(const u32 *addr); | 99 | unsigned long (*get_flags)(const u32 *addr, unsigned long); |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | /* | 102 | /* |
| @@ -156,8 +156,10 @@ static int of_bus_default_map(u32 *addr, const u32 *range, | |||
| 156 | return 0; | 156 | return 0; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static unsigned int of_bus_default_get_flags(const u32 *addr) | 159 | static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long flags) |
| 160 | { | 160 | { |
| 161 | if (flags) | ||
| 162 | return flags; | ||
| 161 | return IORESOURCE_MEM; | 163 | return IORESOURCE_MEM; |
| 162 | } | 164 | } |
| 163 | 165 | ||
| @@ -249,17 +251,21 @@ static int of_bus_pci_map(u32 *addr, const u32 *range, | |||
| 249 | return 0; | 251 | return 0; |
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | static unsigned int of_bus_pci_get_flags(const u32 *addr) | 254 | static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags) |
| 253 | { | 255 | { |
| 254 | unsigned int flags = 0; | ||
| 255 | u32 w = addr[0]; | 256 | u32 w = addr[0]; |
| 256 | 257 | ||
| 258 | /* For PCI, we override whatever child busses may have used. */ | ||
| 259 | flags = 0; | ||
| 257 | switch((w >> 24) & 0x03) { | 260 | switch((w >> 24) & 0x03) { |
| 258 | case 0x01: | 261 | case 0x01: |
| 259 | flags |= IORESOURCE_IO; | 262 | flags |= IORESOURCE_IO; |
| 263 | break; | ||
| 264 | |||
| 260 | case 0x02: /* 32 bits */ | 265 | case 0x02: /* 32 bits */ |
| 261 | case 0x03: /* 64 bits */ | 266 | case 0x03: /* 64 bits */ |
| 262 | flags |= IORESOURCE_MEM; | 267 | flags |= IORESOURCE_MEM; |
| 268 | break; | ||
| 263 | } | 269 | } |
| 264 | if (w & 0x40000000) | 270 | if (w & 0x40000000) |
| 265 | flags |= IORESOURCE_PREFETCH; | 271 | flags |= IORESOURCE_PREFETCH; |
| @@ -478,10 +484,10 @@ static void __init build_device_resources(struct of_device *op, | |||
| 478 | int pna, pns; | 484 | int pna, pns; |
| 479 | 485 | ||
| 480 | size = of_read_addr(reg + na, ns); | 486 | size = of_read_addr(reg + na, ns); |
| 481 | flags = bus->get_flags(reg); | ||
| 482 | |||
| 483 | memcpy(addr, reg, na * 4); | 487 | memcpy(addr, reg, na * 4); |
| 484 | 488 | ||
| 489 | flags = bus->get_flags(addr, 0); | ||
| 490 | |||
| 485 | if (use_1to1_mapping(pp)) { | 491 | if (use_1to1_mapping(pp)) { |
| 486 | result = of_read_addr(addr, na); | 492 | result = of_read_addr(addr, na); |
| 487 | goto build_res; | 493 | goto build_res; |
| @@ -506,6 +512,8 @@ static void __init build_device_resources(struct of_device *op, | |||
| 506 | dna, dns, pna)) | 512 | dna, dns, pna)) |
| 507 | break; | 513 | break; |
| 508 | 514 | ||
| 515 | flags = pbus->get_flags(addr, flags); | ||
| 516 | |||
| 509 | dna = pna; | 517 | dna = pna; |
| 510 | dns = pns; | 518 | dns = pns; |
| 511 | dbus = pbus; | 519 | dbus = pbus; |
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]; |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 27b81775a4de..743ccad61c60 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
| @@ -858,9 +858,7 @@ void smp_tsb_sync(struct mm_struct *mm) | |||
| 858 | extern unsigned long xcall_flush_tlb_mm; | 858 | extern unsigned long xcall_flush_tlb_mm; |
| 859 | extern unsigned long xcall_flush_tlb_pending; | 859 | extern unsigned long xcall_flush_tlb_pending; |
| 860 | extern unsigned long xcall_flush_tlb_kernel_range; | 860 | extern unsigned long xcall_flush_tlb_kernel_range; |
| 861 | #ifdef CONFIG_MAGIC_SYSRQ | ||
| 862 | extern unsigned long xcall_fetch_glob_regs; | 861 | extern unsigned long xcall_fetch_glob_regs; |
| 863 | #endif | ||
| 864 | extern unsigned long xcall_receive_signal; | 862 | extern unsigned long xcall_receive_signal; |
| 865 | extern unsigned long xcall_new_mmu_context_version; | 863 | extern unsigned long xcall_new_mmu_context_version; |
| 866 | #ifdef CONFIG_KGDB | 864 | #ifdef CONFIG_KGDB |
| @@ -1005,12 +1003,10 @@ void kgdb_roundup_cpus(unsigned long flags) | |||
| 1005 | } | 1003 | } |
| 1006 | #endif | 1004 | #endif |
| 1007 | 1005 | ||
| 1008 | #ifdef CONFIG_MAGIC_SYSRQ | ||
| 1009 | void smp_fetch_global_regs(void) | 1006 | void smp_fetch_global_regs(void) |
| 1010 | { | 1007 | { |
| 1011 | smp_cross_call(&xcall_fetch_glob_regs, 0, 0, 0); | 1008 | smp_cross_call(&xcall_fetch_glob_regs, 0, 0, 0); |
| 1012 | } | 1009 | } |
| 1013 | #endif | ||
| 1014 | 1010 | ||
| 1015 | /* We know that the window frames of the user have been flushed | 1011 | /* We know that the window frames of the user have been flushed |
| 1016 | * to the stack before we get here because all callers of us | 1012 | * to the stack before we get here because all callers of us |
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index e9d7f0660f2e..4e21d4a57d3b 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c | |||
| @@ -5,10 +5,12 @@ | |||
| 5 | #include <asm/ptrace.h> | 5 | #include <asm/ptrace.h> |
| 6 | #include <asm/stacktrace.h> | 6 | #include <asm/stacktrace.h> |
| 7 | 7 | ||
| 8 | #include "kstack.h" | ||
| 9 | |||
| 8 | void save_stack_trace(struct stack_trace *trace) | 10 | void save_stack_trace(struct stack_trace *trace) |
| 9 | { | 11 | { |
| 10 | unsigned long ksp, fp, thread_base; | ||
| 11 | struct thread_info *tp = task_thread_info(current); | 12 | struct thread_info *tp = task_thread_info(current); |
| 13 | unsigned long ksp, fp; | ||
| 12 | 14 | ||
| 13 | stack_trace_flush(); | 15 | stack_trace_flush(); |
| 14 | 16 | ||
| @@ -18,23 +20,18 @@ void save_stack_trace(struct stack_trace *trace) | |||
| 18 | ); | 20 | ); |
| 19 | 21 | ||
| 20 | fp = ksp + STACK_BIAS; | 22 | fp = ksp + STACK_BIAS; |
| 21 | thread_base = (unsigned long) tp; | ||
| 22 | do { | 23 | do { |
| 23 | struct sparc_stackf *sf; | 24 | struct sparc_stackf *sf; |
| 24 | struct pt_regs *regs; | 25 | struct pt_regs *regs; |
| 25 | unsigned long pc; | 26 | unsigned long pc; |
| 26 | 27 | ||
| 27 | /* Bogus frame pointer? */ | 28 | if (!kstack_valid(tp, fp)) |
| 28 | if (fp < (thread_base + sizeof(struct thread_info)) || | ||
| 29 | fp > (thread_base + THREAD_SIZE - sizeof(struct sparc_stackf))) | ||
| 30 | break; | 29 | break; |
| 31 | 30 | ||
| 32 | sf = (struct sparc_stackf *) fp; | 31 | sf = (struct sparc_stackf *) fp; |
| 33 | regs = (struct pt_regs *) (sf + 1); | 32 | regs = (struct pt_regs *) (sf + 1); |
| 34 | 33 | ||
| 35 | if (((unsigned long)regs <= | 34 | if (kstack_is_trap_frame(tp, regs)) { |
| 36 | (thread_base + THREAD_SIZE - sizeof(*regs))) && | ||
| 37 | (regs->magic & ~0x1ff) == PT_REGS_MAGIC) { | ||
| 38 | if (!(regs->tstate & TSTATE_PRIV)) | 35 | if (!(regs->tstate & TSTATE_PRIV)) |
| 39 | break; | 36 | break; |
| 40 | pc = regs->tpc; | 37 | pc = regs->tpc; |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 404e8561e2d0..3d924121c796 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <asm/prom.h> | 39 | #include <asm/prom.h> |
| 40 | 40 | ||
| 41 | #include "entry.h" | 41 | #include "entry.h" |
| 42 | #include "kstack.h" | ||
| 42 | 43 | ||
| 43 | /* When an irrecoverable trap occurs at tl > 0, the trap entry | 44 | /* When an irrecoverable trap occurs at tl > 0, the trap entry |
| 44 | * code logs the trap state registers at every level in the trap | 45 | * code logs the trap state registers at every level in the trap |
| @@ -2115,14 +2116,12 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) | |||
| 2115 | struct pt_regs *regs; | 2116 | struct pt_regs *regs; |
| 2116 | unsigned long pc; | 2117 | unsigned long pc; |
| 2117 | 2118 | ||
| 2118 | /* Bogus frame pointer? */ | 2119 | if (!kstack_valid(tp, fp)) |
| 2119 | if (fp < (thread_base + sizeof(struct thread_info)) || | ||
| 2120 | fp >= (thread_base + THREAD_SIZE)) | ||
| 2121 | break; | 2120 | break; |
| 2122 | sf = (struct sparc_stackf *) fp; | 2121 | sf = (struct sparc_stackf *) fp; |
| 2123 | regs = (struct pt_regs *) (sf + 1); | 2122 | regs = (struct pt_regs *) (sf + 1); |
| 2124 | 2123 | ||
| 2125 | if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { | 2124 | if (kstack_is_trap_frame(tp, regs)) { |
| 2126 | if (!(regs->tstate & TSTATE_PRIV)) | 2125 | if (!(regs->tstate & TSTATE_PRIV)) |
| 2127 | break; | 2126 | break; |
| 2128 | pc = regs->tpc; | 2127 | pc = regs->tpc; |
