aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/Kconfig.debug11
-rw-r--r--arch/parisc/include/asm/thread_info.h2
-rw-r--r--arch/parisc/kernel/irq.c31
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
4 files changed, 42 insertions, 4 deletions
diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug
index bc989e522a04..08a332f6ee87 100644
--- a/arch/parisc/Kconfig.debug
+++ b/arch/parisc/Kconfig.debug
@@ -13,3 +13,14 @@ config DEBUG_RODATA
13 If in doubt, say "N". 13 If in doubt, say "N".
14 14
15endmenu 15endmenu
16
17config DEBUG_STACKOVERFLOW
18 bool "Check for stack overflows"
19 default y
20 depends on DEBUG_KERNEL
21 ---help---
22 Say Y here if you want to check the overflows of kernel, IRQ
23 and exception stacks. This option will cause messages of the
24 stacks in detail when free stack space drops below a certain
25 limit.
26 If in doubt, say "N".
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 6182832e5b6c..540c88fa8f86 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -40,7 +40,7 @@ struct thread_info {
40 40
41/* thread information allocation */ 41/* thread information allocation */
42 42
43#define THREAD_SIZE_ORDER 2 43#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */
44/* Be sure to hunt all references to this down when you change the size of 44/* Be sure to hunt all references to this down when you change the size of
45 * the kernel stack */ 45 * the kernel stack */
46#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) 46#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 8094d3ed3b64..61e51ac85659 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -330,6 +330,34 @@ static inline int eirr_to_irq(unsigned long eirr)
330 return (BITS_PER_LONG - bit) + TIMER_IRQ; 330 return (BITS_PER_LONG - bit) + TIMER_IRQ;
331} 331}
332 332
333int sysctl_panic_on_stackoverflow = 1;
334
335static inline void stack_overflow_check(struct pt_regs *regs)
336{
337#ifdef CONFIG_DEBUG_STACKOVERFLOW
338 #define STACK_MARGIN (256*6)
339
340 /* Our stack starts directly behind the thread_info struct. */
341 unsigned long stack_start = (unsigned long) current_thread_info();
342 unsigned long sp = regs->gr[30];
343
344 /* if sr7 != 0, we interrupted a userspace process which we do not want
345 * to check for stack overflow. We will only check the kernel stack. */
346 if (regs->sr[7])
347 return;
348
349 if (likely((sp - stack_start) < (THREAD_SIZE - STACK_MARGIN)))
350 return;
351
352 pr_emerg("stackcheck: %s will most likely overflow kernel stack "
353 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
354 current->comm, sp, stack_start, stack_start + THREAD_SIZE);
355
356 if (sysctl_panic_on_stackoverflow)
357 panic("low stack detected by irq handler - check messages\n");
358#endif
359}
360
333/* ONLY called from entry.S:intr_extint() */ 361/* ONLY called from entry.S:intr_extint() */
334void do_cpu_irq_mask(struct pt_regs *regs) 362void do_cpu_irq_mask(struct pt_regs *regs)
335{ 363{
@@ -364,6 +392,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
364 goto set_out; 392 goto set_out;
365 } 393 }
366#endif 394#endif
395 stack_overflow_check(regs);
367 generic_handle_irq(irq); 396 generic_handle_irq(irq);
368 397
369 out: 398 out:
@@ -420,6 +449,4 @@ void __init init_IRQ(void)
420 cpu_eiem = EIEM_MASK(TIMER_IRQ); 449 cpu_eiem = EIEM_MASK(TIMER_IRQ);
421#endif 450#endif
422 set_eiem(cpu_eiem); /* EIEM : enable all external intr */ 451 set_eiem(cpu_eiem); /* EIEM : enable all external intr */
423
424} 452}
425
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 64a999882e4f..4bb095a2f6fc 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -95,7 +95,7 @@ SECTIONS
95 NOTES 95 NOTES
96 96
97 /* Data */ 97 /* Data */
98 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) 98 RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, PAGE_SIZE)
99 99
100 /* PA-RISC locks requires 16-byte alignment */ 100 /* PA-RISC locks requires 16-byte alignment */
101 . = ALIGN(16); 101 . = ALIGN(16);