aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/irq.c31
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
2 files changed, 30 insertions, 3 deletions
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);