diff options
Diffstat (limited to 'arch/powerpc/kernel/process.c')
-rw-r--r-- | arch/powerpc/kernel/process.c | 54 |
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 = ¤t->thread; | 311 | old_thread = ¤t->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 | ||
824 | static 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 | |||
826 | int validate_sp(unsigned long sp, struct task_struct *p, | 852 | int 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 |