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.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index f3d4dd580dd6..972b2acbe713 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -818,6 +818,35 @@ out:
818 return error; 818 return error;
819} 819}
820 820
821#ifdef CONFIG_IRQSTACKS
822static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
823 unsigned long nbytes)
824{
825 unsigned long stack_page;
826 unsigned long cpu = task_cpu(p);
827
828 /*
829 * Avoid crashing if the stack has overflowed and corrupted
830 * task_cpu(p), which is in the thread_info struct.
831 */
832 if (cpu < NR_CPUS && cpu_possible(cpu)) {
833 stack_page = (unsigned long) hardirq_ctx[cpu];
834 if (sp >= stack_page + sizeof(struct thread_struct)
835 && sp <= stack_page + THREAD_SIZE - nbytes)
836 return 1;
837
838 stack_page = (unsigned long) softirq_ctx[cpu];
839 if (sp >= stack_page + sizeof(struct thread_struct)
840 && sp <= stack_page + THREAD_SIZE - nbytes)
841 return 1;
842 }
843 return 0;
844}
845
846#else
847#define valid_irq_stack(sp, p, nb) 0
848#endif /* CONFIG_IRQSTACKS */
849
821int validate_sp(unsigned long sp, struct task_struct *p, 850int validate_sp(unsigned long sp, struct task_struct *p,
822 unsigned long nbytes) 851 unsigned long nbytes)
823{ 852{
@@ -827,19 +856,7 @@ int validate_sp(unsigned long sp, struct task_struct *p,
827 && sp <= stack_page + THREAD_SIZE - nbytes) 856 && sp <= stack_page + THREAD_SIZE - nbytes)
828 return 1; 857 return 1;
829 858
830#ifdef CONFIG_IRQSTACKS 859 return valid_irq_stack(sp, p, nbytes);
831 stack_page = (unsigned long) hardirq_ctx[task_cpu(p)];
832 if (sp >= stack_page + sizeof(struct thread_struct)
833 && sp <= stack_page + THREAD_SIZE - nbytes)
834 return 1;
835
836 stack_page = (unsigned long) softirq_ctx[task_cpu(p)];
837 if (sp >= stack_page + sizeof(struct thread_struct)
838 && sp <= stack_page + THREAD_SIZE - nbytes)
839 return 1;
840#endif
841
842 return 0;
843} 860}
844 861
845#ifdef CONFIG_PPC64 862#ifdef CONFIG_PPC64