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 |
