aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r--arch/powerpc/kernel/process.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e53b2988d1bf..e509aae2feb3 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -305,9 +305,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
305 set_dabr(new->thread.dabr); 305 set_dabr(new->thread.dabr);
306 __get_cpu_var(current_dabr) = new->thread.dabr; 306 __get_cpu_var(current_dabr) = new->thread.dabr;
307 } 307 }
308 308#endif /* CONFIG_PPC64 */
309 flush_tlb_pending();
310#endif
311 309
312 new_thread = &new->thread; 310 new_thread = &new->thread;
313 old_thread = &current->thread; 311 old_thread = &current->thread;
@@ -402,11 +400,11 @@ static void printbits(unsigned long val, struct regbit *bits)
402} 400}
403 401
404#ifdef CONFIG_PPC64 402#ifdef CONFIG_PPC64
405#define REG "%016lX" 403#define REG "%016lx"
406#define REGS_PER_LINE 4 404#define REGS_PER_LINE 4
407#define LAST_VOLATILE 13 405#define LAST_VOLATILE 13
408#else 406#else
409#define REG "%08lX" 407#define REG "%08lx"
410#define REGS_PER_LINE 8 408#define REGS_PER_LINE 8
411#define LAST_VOLATILE 12 409#define LAST_VOLATILE 12
412#endif 410#endif
@@ -421,7 +419,7 @@ void show_regs(struct pt_regs * regs)
421 regs, regs->trap, print_tainted(), init_utsname()->release); 419 regs, regs->trap, print_tainted(), init_utsname()->release);
422 printk("MSR: "REG" ", regs->msr); 420 printk("MSR: "REG" ", regs->msr);
423 printbits(regs->msr, msr_bits); 421 printbits(regs->msr, msr_bits);
424 printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer); 422 printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
425 trap = TRAP(regs); 423 trap = TRAP(regs);
426 if (trap == 0x300 || trap == 0x600) 424 if (trap == 0x300 || trap == 0x600)
427 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); 425 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
@@ -572,7 +570,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
572 kregs->nip = *((unsigned long *)ret_from_fork); 570 kregs->nip = *((unsigned long *)ret_from_fork);
573#else 571#else
574 kregs->nip = (unsigned long)ret_from_fork; 572 kregs->nip = (unsigned long)ret_from_fork;
575 p->thread.last_syscall = -1;
576#endif 573#endif
577 574
578 return 0; 575 return 0;
@@ -823,6 +820,35 @@ out:
823 return error; 820 return error;
824} 821}
825 822
823#ifdef CONFIG_IRQSTACKS
824static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
825 unsigned long nbytes)
826{
827 unsigned long stack_page;
828 unsigned long cpu = task_cpu(p);
829
830 /*
831 * Avoid crashing if the stack has overflowed and corrupted
832 * task_cpu(p), which is in the thread_info struct.
833 */
834 if (cpu < NR_CPUS && cpu_possible(cpu)) {
835 stack_page = (unsigned long) hardirq_ctx[cpu];
836 if (sp >= stack_page + sizeof(struct thread_struct)
837 && sp <= stack_page + THREAD_SIZE - nbytes)
838 return 1;
839
840 stack_page = (unsigned long) softirq_ctx[cpu];
841 if (sp >= stack_page + sizeof(struct thread_struct)
842 && sp <= stack_page + THREAD_SIZE - nbytes)
843 return 1;
844 }
845 return 0;
846}
847
848#else
849#define valid_irq_stack(sp, p, nb) 0
850#endif /* CONFIG_IRQSTACKS */
851
826int validate_sp(unsigned long sp, struct task_struct *p, 852int validate_sp(unsigned long sp, struct task_struct *p,
827 unsigned long nbytes) 853 unsigned long nbytes)
828{ 854{
@@ -832,19 +858,7 @@ int validate_sp(unsigned long sp, struct task_struct *p,
832 && sp <= stack_page + THREAD_SIZE - nbytes) 858 && sp <= stack_page + THREAD_SIZE - nbytes)
833 return 1; 859 return 1;
834 860
835#ifdef CONFIG_IRQSTACKS 861 return valid_irq_stack(sp, p, nbytes);
836 stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
837 if (sp >= stack_page + sizeof(struct thread_struct)
838 && sp <= stack_page + THREAD_SIZE - nbytes)
839 return 1;
840
841 stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
842 if (sp >= stack_page + sizeof(struct thread_struct)
843 && sp <= stack_page + THREAD_SIZE - nbytes)
844 return 1;
845#endif
846
847 return 0;
848} 862}
849 863
850#ifdef CONFIG_PPC64 864#ifdef CONFIG_PPC64