aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>2011-11-29 01:08:36 -0500
committerIngo Molnar <mingo@elte.hu>2011-12-05 05:37:47 -0500
commit55af77969fbd7a841838220ea2287432e0da8ae5 (patch)
treef5f819e160799fb0477ec33c06aa8d022466687d
parent37fe6a42b3433b79a159ceb06a94cd1ef00e279d (diff)
x86: Panic on detection of stack overflow
Currently, messages are just output on the detection of stack overflow, which is not sufficient for systems that need a high reliability. This is because in general the overflow may corrupt data, and the additional corruption may occur due to reading them unless systems stop. This patch adds the sysctl parameter kernel.panic_on_stackoverflow and causes a panic when detecting the overflows of kernel, IRQ and exception stacks except user stack according to the parameter. It is disabled by default. Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com> Cc: yrl.pp-manager.tt@hitachi.com Cc: Randy Dunlap <rdunlap@xenotime.net> Cc: "H. Peter Anvin" <hpa@zytor.com> Link: http://lkml.kernel.org/r/20111129060836.11076.12323.stgit@ltc219.sdl.hitachi.co.jp Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--Documentation/sysctl/kernel.txt14
-rw-r--r--arch/x86/kernel/irq_32.c2
-rw-r--r--arch/x86/kernel/irq_64.c5
-rw-r--r--include/linux/kernel.h1
-rw-r--r--kernel/sysctl.c9
5 files changed, 31 insertions, 0 deletions
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 1f2463671a1a..6d8cd8b2c30d 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
49- panic 49- panic
50- panic_on_oops 50- panic_on_oops
51- panic_on_unrecovered_nmi 51- panic_on_unrecovered_nmi
52- panic_on_stackoverflow
52- pid_max 53- pid_max
53- powersave-nap [ PPC only ] 54- powersave-nap [ PPC only ]
54- printk 55- printk
@@ -393,6 +394,19 @@ Controls the kernel's behaviour when an oops or BUG is encountered.
393 394
394============================================================== 395==============================================================
395 396
397panic_on_stackoverflow:
398
399Controls the kernel's behavior when detecting the overflows of
400kernel, IRQ and exception stacks except a user stack.
401This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled.
402
4030: try to continue operation.
404
4051: panic immediately.
406
407==============================================================
408
409
396pid_max: 410pid_max:
397 411
398PID allocation wrap value. When the kernel's next PID value 412PID allocation wrap value. When the kernel's next PID value
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 72090705a656..e16e99ebd7ad 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -43,6 +43,8 @@ static void print_stack_overflow(void)
43{ 43{
44 printk(KERN_WARNING "low stack detected by irq handler\n"); 44 printk(KERN_WARNING "low stack detected by irq handler\n");
45 dump_stack(); 45 dump_stack();
46 if (sysctl_panic_on_stackoverflow)
47 panic("low stack detected by irq handler - check messages\n");
46} 48}
47 49
48#else 50#else
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 928a7e909619..42552b0dce6a 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -26,6 +26,8 @@ EXPORT_PER_CPU_SYMBOL(irq_stat);
26DEFINE_PER_CPU(struct pt_regs *, irq_regs); 26DEFINE_PER_CPU(struct pt_regs *, irq_regs);
27EXPORT_PER_CPU_SYMBOL(irq_regs); 27EXPORT_PER_CPU_SYMBOL(irq_regs);
28 28
29int sysctl_panic_on_stackoverflow;
30
29/* 31/*
30 * Probabilistic stack overflow check: 32 * Probabilistic stack overflow check:
31 * 33 *
@@ -65,6 +67,9 @@ static inline void stack_overflow_check(struct pt_regs *regs)
65 current->comm, curbase, regs->sp, 67 current->comm, curbase, regs->sp,
66 irq_stack_top, irq_stack_bottom, 68 irq_stack_top, irq_stack_bottom,
67 estack_top, estack_bottom); 69 estack_top, estack_bottom);
70
71 if (sysctl_panic_on_stackoverflow)
72 panic("low stack detected by irq handler - check messages\n");
68#endif 73#endif
69} 74}
70 75
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index e8b1597b5cf2..ff83683c0b9d 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -341,6 +341,7 @@ extern int panic_timeout;
341extern int panic_on_oops; 341extern int panic_on_oops;
342extern int panic_on_unrecovered_nmi; 342extern int panic_on_unrecovered_nmi;
343extern int panic_on_io_nmi; 343extern int panic_on_io_nmi;
344extern int sysctl_panic_on_stackoverflow;
344extern const char *print_tainted(void); 345extern const char *print_tainted(void);
345extern void add_taint(unsigned flag); 346extern void add_taint(unsigned flag);
346extern int test_taint(unsigned flag); 347extern int test_taint(unsigned flag);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ae2719643854..f487f257e05e 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -803,6 +803,15 @@ static struct ctl_table kern_table[] = {
803 .mode = 0644, 803 .mode = 0644,
804 .proc_handler = proc_dointvec, 804 .proc_handler = proc_dointvec,
805 }, 805 },
806#ifdef CONFIG_DEBUG_STACKOVERFLOW
807 {
808 .procname = "panic_on_stackoverflow",
809 .data = &sysctl_panic_on_stackoverflow,
810 .maxlen = sizeof(int),
811 .mode = 0644,
812 .proc_handler = proc_dointvec,
813 },
814#endif
806 { 815 {
807 .procname = "bootloader_type", 816 .procname = "bootloader_type",
808 .data = &bootloader_type, 817 .data = &bootloader_type,