x86/debug changes for v3.3
Subsystems (3)
Linus,
Please pull the latest x86-debug-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-debug-for-linus
out-of-topic modifications in x86-debug-for-linus:
--------------------------------------------------include/linux/kernel.h # 55af779: x86: Panic on detection of stackkernel/sysctl.c # 55af779: x86: Panic on detection of stack
Thanks,
Ingo
------------------>
Dan Carpenter (1):
x86, NMI: Add to_cpumask() to silence compile warning
Don Zickus (5):
x86, reboot: Use NMI instead of REBOOT_VECTOR to stop cpus x86, NMI: Add NMI IPI selftest
x86, NMI: Add knob to disable using NMI IPIs to stop cpus x86, NMI: NMI-selftest should handle the UP case properly x86, NMI: NMI selftest depends on the local apic
Ingo Molnar (1):
x86: Fix the 32-bit stackoverflow-debug build
Mitsuo Hayasaka (4):
x86: Check stack overflow in detail
x86: Panic on detection of stack overflow
x86: Clean up the range of stack overflow checking
x86: Add stack top margin for stack overflow checking
Documentation/kernel-parameters.txt | 4 + Documentation/sysctl/kernel.txt | 14 +++ arch/x86/Kconfig.debug | 19 ++++- arch/x86/include/asm/smp.h | 6 + arch/x86/kernel/Makefile | 1 + arch/x86/kernel/irq_32.c | 5 + arch/x86/kernel/irq_64.c | 35 ++++++- arch/x86/kernel/nmi_selftest.c | 180 +++++++++++++++++++++++++++++++++++ arch/x86/kernel/smp.c | 72 ++++++++++++++- arch/x86/kernel/smpboot.c | 1 + include/linux/kernel.h | 1 + kernel/sysctl.c | 9 ++ 12 files changed, 337 insertions(+), 10 deletions(-) create mode 100644 arch/x86/kernel/nmi_selftest.c
Documentation/kernel-parameters.txt +4 -0
@@ -1796,6 +1796,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nomfgpt [X86-32] Disable Multi-Function General Purpose Timer usage (for AMD Geode machines). + nonmi_ipi [X86] Disable using NMI IPIs during panic/reboot to + shutdown the other cpus. Instead use the REBOOT_VECTOR + irq. + nopat [X86] Disable PAT (page attribute table extension of pagetables) support.
Documentation/sysctl/kernel.txt +14 -0
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel: - panic - panic_on_oops - panic_on_unrecovered_nmi +- panic_on_stackoverflow - pid_max - powersave-nap [ PPC only ] - printk
@@ -393,6 +394,19 @@ Controls the kernel's behaviour when an oops or BUG is encountered. ============================================================== +panic_on_stackoverflow: + +Controls the kernel's behavior when detecting the overflows of +kernel, IRQ and exception stacks except a user stack. +This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled. + +0: try to continue operation. + +1: panic immediately. + +============================================================== + + pid_max: PID allocation wrap value. When the kernel's next PID value
arch/x86/Kconfig.debug +17 -2
@@ -63,8 +63,11 @@ config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL ---help--- - This option will cause messages to be printed if free stack space - drops below a certain limit. + Say Y here if you want to check the overflows of kernel, IRQ + and exception stacks. This option will cause messages of the + stacks in detail when free stack space drops below a certain + limit. + If in doubt, say "N". config X86_PTDUMP bool "Export kernel pagetable layout to userspace via debugfs"
@@ -284,4 +287,16 @@ config DEBUG_STRICT_USER_COPY_CHECKS If unsure, or if you run an older (pre 4.4) gcc, say N. +config DEBUG_NMI_SELFTEST + bool "NMI Selftest" + depends on DEBUG_KERNEL && X86_LOCAL_APIC + ---help--- + Enabling this option turns on a quick NMI selftest to verify + that the NMI behaves correctly. + + This might help diagnose strange hangs that rely on NMI to + function properly. + + If unsure, say N. + endmenu
arch/x86/include/asm/smp.h +6 -0
@@ -225,5 +225,11 @@ extern int hard_smp_processor_id(void);#endif /* CONFIG_X86_LOCAL_APIC */ +#ifdef CONFIG_DEBUG_NMI_SELFTEST +extern void nmi_selftest (void ); +#else +#define nmi_selftest () do { } while (0) +#endif +#endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_SMP_H */
arch/x86/kernel/Makefile +1 -0
@@ -80,6 +80,7 @@ obj-$(CONFIG_APB_TIMER) += apb_timer.o obj-$(CONFIG_AMD_NB) += amd_nb.o obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o +obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o obj-$(CONFIG_KVM_GUEST) += kvm.o obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
arch/x86/kernel/irq_32.c +5 -0
@@ -28,6 +28,9 @@ DEFINE_PER_CPU(struct pt_regs *, irq_regs);EXPORT_PER_CPU_SYMBOL (irq_regs);#ifdef CONFIG_DEBUG_STACKOVERFLOW + +int sysctl_panic_on_stackoverflow__read_mostly ; +/* Debugging check for stack overflow: is there less than 1KB free? */ static int check_stack_overflow (void ) {
@@ -43,6 +46,8 @@ static void print_stack_overflow(void) {printk (KERN_WARNING "low stack detected by irq handler\n" );dump_stack (); +if (sysctl_panic_on_stackoverflow) +panic ("low stack detected by irq handler - check messages\n" ); }#else
arch/x86/kernel/irq_64.c +29 -6
@@ -26,6 +26,8 @@ EXPORT_PER_CPU_SYMBOL(irq_stat); DEFINE_PER_CPU(struct pt_regs *, irq_regs);EXPORT_PER_CPU_SYMBOL (irq_regs); +int sysctl_panic_on_stackoverflow; +/* * Probabilistic stack overflow check: *
@@ -36,18 +38,39 @@ EXPORT_PER_CPU_SYMBOL(irq_regs);static inline void stack_overflow_check (struct pt_regs *regs) {#ifdef CONFIG_DEBUG_STACKOVERFLOW +#define STACK_TOP_MARGIN 128 +struct orig_ist *oist; +u64 irq_stack_top, irq_stack_bottom; +u64 estack_top, estack_bottom;u64 curbase = (u64 )task_stack_page (current);if (user_mode_vm (regs))return ; -WARN_ONCE (regs->sp >= curbase && - regs->sp <= curbase +THREAD_SIZE && - regs->sp < curbase +sizeof (struct thread_info ) + -sizeof (struct pt_regs ) +128 , +if (regs->sp >= curbase +sizeof (struct thread_info ) + +sizeof (struct pt_regs ) +STACK_TOP_MARGIN && + regs->sp <= curbase +THREAD_SIZE ) +return ; + + irq_stack_top = (u64 )__get_cpu_var (irq_stack_union.irq_stack) + +STACK_TOP_MARGIN ; + irq_stack_bottom = (u64 )__get_cpu_var (irq_stack_ptr); +if (regs->sp >= irq_stack_top && regs->sp <= irq_stack_bottom) +return ; + + oist = &__get_cpu_var (orig_ist); + estack_top = (u64 )oist->ist[0 ] -EXCEPTION_STKSZ +STACK_TOP_MARGIN ; + estack_bottom = (u64 )oist->ist[N_EXCEPTION_STACKS -1 ]; +if (regs->sp >= estack_top && regs->sp <= estack_bottom) +return ; + +WARN_ONCE (1 ,"do_IRQ(): %s has overflown the kernel stack (cur:%Lx,sp:%lx,irq stk top-bottom:%Lx-%Lx,exception stk top-bottom:%Lx-%Lx)\n" , + current->comm, curbase, regs->sp, + irq_stack_top, irq_stack_bottom, + estack_top, estack_bottom); -"do_IRQ: %s near stack overflow (cur:%Lx,sp:%lx)\n" , - current->comm, curbase, regs->sp); +if (sysctl_panic_on_stackoverflow) +panic ("low stack detected by irq handler - check messages\n" );#endif }
arch/x86/kernel/nmi_selftest.c new file +180 -0
180 lines not on this page · raw message
arch/x86/kernel/smp.c +70 -2
107 lines not on this page · raw message
arch/x86/kernel/smpboot.c +1 -0
@@ -1142,6 +1142,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus) {pr_debug ("Boot done.\n" ); +nmi_selftest ();impress_friends ();#ifdef CONFIG_X86_IO_APIC setup_ioapic_dest ();
include/linux/kernel.h +1 -0
@@ -341,6 +341,7 @@ extern int panic_timeout;extern int panic_on_oops;extern int panic_on_unrecovered_nmi;extern int panic_on_io_nmi; +extern int sysctl_panic_on_stackoverflow;extern const char *print_tainted (void );extern void add_taint (unsigned flag);extern int test_taint (unsigned flag);
kernel/sysctl.c +9 -0
@@ -803,6 +803,15 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, +#ifdef CONFIG_DEBUG_STACKOVERFLOW + { + .procname = "panic_on_stackoverflow", + .data = &sysctl_panic_on_stackoverflow, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif { .procname = "bootloader_type", .data = &bootloader_type,
Quoted 4 lines · Ingo Molnar
Please pull the latest x86-debug-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.gitx86-debug-for-linus
Hell no!
Why do you send me this sh*t? The "Use NMI instead of REBOOT_VECTOR" commit has been reported to not work AT ALL.
It was totally broken - Don Zickus sent out the email to fix the completely bogus parenthesis in that commit just a day ago - yet you send me this KNOWN BROKEN CRAP.
And yes, I checked. The version you sent me is the f*cked one. I was hoping that you would have fixed it up. But no.
In short, you didn't merge the fix, and yet you sent me a patch series that was *known* to be broken for the last three+ weeks! And I know you were cc'd on the report, which was in the same thread as the automatic tip-bot message for the particular broken commit, so the particular broken commit that introduced it was well-known.
So that thing has been known broken since before Christmas, and was due to a major typo that made a "atomic_cmpxchg()" not work *at*all* - yet you blithely send me this crap.
Why? WHAT THE F*CK HAPPENED, INGO?
Yes, I'm angry as hell. Shit like this should NOT happen. I don't want people sending me known-buggy pull requests.
Linus
Quoted 6 lines · Linus Torvalds
Quoted 4 lines · Ingo Molnar
Please pull the latest x86-debug-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.gitx86-debug-for-linus
Quoted 8 lines
Hell no!
Why do you send me this sh*t? The "Use NMI instead of
REBOOT_VECTOR" commit has been reported to not work AT ALL.It was totally broken - Don Zickus sent out the email to fix the completely bogus parenthesis in that commit just a day ago
- yet you send me this KNOWN BROKEN CRAP.
My bad.
My primary mistake was that i could have noticed the original regression breaking kdump that Yinghai reported - i should have delayed the tree until a fix came in - like i delayed a couple of other trees that you didn't get sent.
Then, to compound it with another mistake, the fix for the kdump breakage was sent to me a couple of hours after i sent you the tree - and i havent processed all subsequent mails yet up until today - so you noticed it before i did. Double fail.
Anyway, i've queued up the fix and will send you the new tree after some testing.
Quoted 10 lines
And yes, I checked. The version you sent me is the f*cked one. I was hoping that you would have fixed it up. But no.
In short, you didn't merge the fix, and yet you sent me a patch series that was *known* to be broken for the last three+ weeks! And I know you were cc'd on the report, which was in the same thread as the automatic tip-bot message for the particular broken commit, so the particular broken commit that introduced it was well-known.
Quoted 8 lines
So that thing has been known broken since before Christmas, and was due to a major typo that made a "
atomic_cmpxchg()" not work *at*all* - yet you blithely send me this crap.Why? WHAT THE F*CK HAPPENED, INGO?
Yes, I'm angry as hell. Shit like this should NOT happen. I don't want people sending me known-buggy pull requests.
You are perfectly right, i messed up - sorry about that.
Thanks,
Ingo
Linus,
Please pull the latest x86-debug-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-debug-for-linus
out-of-topic modifications in x86-debug-for-linus:
--------------------------------------------------include/linux/kernel.h # 55af779: x86: Panic on detection of stackkernel/sysctl.c # 55af779: x86: Panic on detection of stack
Thanks,
Ingo
------------------>
Dan Carpenter (1):
x86, NMI: Add to_cpumask() to silence compile warning
Don Zickus (6):
x86, reboot: Use NMI instead of REBOOT_VECTOR to stop cpus x86, NMI: Add NMI IPI selftest
x86, NMI: Add knob to disable using NMI IPIs to stop cpus x86, NMI: NMI-selftest should handle the UP case properly x86, NMI: NMI selftest depends on the local apic x86, reboot: Fix typo in nmi reboot path
Ingo Molnar (1):
x86: Fix the 32-bit stackoverflow-debug build
Mitsuo Hayasaka (4):
x86: Check stack overflow in detail
x86: Panic on detection of stack overflow
x86: Clean up the range of stack overflow checking
x86: Add stack top margin for stack overflow checking
Documentation/kernel-parameters.txt | 4 + Documentation/sysctl/kernel.txt | 14 +++ arch/x86/Kconfig.debug | 19 ++++- arch/x86/include/asm/smp.h | 6 + arch/x86/kernel/Makefile | 1 + arch/x86/kernel/irq_32.c | 5 + arch/x86/kernel/irq_64.c | 35 ++++++- arch/x86/kernel/nmi_selftest.c | 180 +++++++++++++++++++++++++++++++++++ arch/x86/kernel/smp.c | 72 ++++++++++++++- arch/x86/kernel/smpboot.c | 1 + include/linux/kernel.h | 1 + kernel/sysctl.c | 9 ++ 12 files changed, 337 insertions(+), 10 deletions(-) create mode 100644 arch/x86/kernel/nmi_selftest.c
Documentation/kernel-parameters.txt +4 -0
@@ -1796,6 +1796,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nomfgpt [X86-32] Disable Multi-Function General Purpose Timer usage (for AMD Geode machines). + nonmi_ipi [X86] Disable using NMI IPIs during panic/reboot to + shutdown the other cpus. Instead use the REBOOT_VECTOR + irq. + nopat [X86] Disable PAT (page attribute table extension of pagetables) support.
Documentation/sysctl/kernel.txt +14 -0
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel: - panic - panic_on_oops - panic_on_unrecovered_nmi +- panic_on_stackoverflow - pid_max - powersave-nap [ PPC only ] - printk
@@ -393,6 +394,19 @@ Controls the kernel's behaviour when an oops or BUG is encountered. ============================================================== +panic_on_stackoverflow: + +Controls the kernel's behavior when detecting the overflows of +kernel, IRQ and exception stacks except a user stack. +This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled. + +0: try to continue operation. + +1: panic immediately. + +============================================================== + + pid_max: PID allocation wrap value. When the kernel's next PID value
arch/x86/Kconfig.debug +17 -2
@@ -63,8 +63,11 @@ config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL ---help--- - This option will cause messages to be printed if free stack space - drops below a certain limit. + Say Y here if you want to check the overflows of kernel, IRQ + and exception stacks. This option will cause messages of the + stacks in detail when free stack space drops below a certain + limit. + If in doubt, say "N". config X86_PTDUMP bool "Export kernel pagetable layout to userspace via debugfs"
@@ -284,4 +287,16 @@ config DEBUG_STRICT_USER_COPY_CHECKS If unsure, or if you run an older (pre 4.4) gcc, say N. +config DEBUG_NMI_SELFTEST + bool "NMI Selftest" + depends on DEBUG_KERNEL && X86_LOCAL_APIC + ---help--- + Enabling this option turns on a quick NMI selftest to verify + that the NMI behaves correctly. + + This might help diagnose strange hangs that rely on NMI to + function properly. + + If unsure, say N. + endmenu
arch/x86/include/asm/smp.h +6 -0
@@ -225,5 +225,11 @@ extern int hard_smp_processor_id(void);#endif /* CONFIG_X86_LOCAL_APIC */ +#ifdef CONFIG_DEBUG_NMI_SELFTEST +extern void nmi_selftest (void ); +#else +#define nmi_selftest () do { } while (0) +#endif +#endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_SMP_H */
arch/x86/kernel/Makefile +1 -0
@@ -80,6 +80,7 @@ obj-$(CONFIG_APB_TIMER) += apb_timer.o obj-$(CONFIG_AMD_NB) += amd_nb.o obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o +obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o obj-$(CONFIG_KVM_GUEST) += kvm.o obj-$(CONFIG_KVM_CLOCK) += kvmclock.o
arch/x86/kernel/irq_32.c +5 -0
@@ -28,6 +28,9 @@ DEFINE_PER_CPU(struct pt_regs *, irq_regs);EXPORT_PER_CPU_SYMBOL (irq_regs);#ifdef CONFIG_DEBUG_STACKOVERFLOW + +int sysctl_panic_on_stackoverflow__read_mostly ; +/* Debugging check for stack overflow: is there less than 1KB free? */ static int check_stack_overflow (void ) {
@@ -43,6 +46,8 @@ static void print_stack_overflow(void) {printk (KERN_WARNING "low stack detected by irq handler\n" );dump_stack (); +if (sysctl_panic_on_stackoverflow) +panic ("low stack detected by irq handler - check messages\n" ); }#else
arch/x86/kernel/irq_64.c +29 -6
@@ -26,6 +26,8 @@ EXPORT_PER_CPU_SYMBOL(irq_stat); DEFINE_PER_CPU(struct pt_regs *, irq_regs);EXPORT_PER_CPU_SYMBOL (irq_regs); +int sysctl_panic_on_stackoverflow; +/* * Probabilistic stack overflow check: *
@@ -36,18 +38,39 @@ EXPORT_PER_CPU_SYMBOL(irq_regs);static inline void stack_overflow_check (struct pt_regs *regs) {#ifdef CONFIG_DEBUG_STACKOVERFLOW +#define STACK_TOP_MARGIN 128 +struct orig_ist *oist; +u64 irq_stack_top, irq_stack_bottom; +u64 estack_top, estack_bottom;u64 curbase = (u64 )task_stack_page (current);if (user_mode_vm (regs))return ; -WARN_ONCE (regs->sp >= curbase && - regs->sp <= curbase +THREAD_SIZE && - regs->sp < curbase +sizeof (struct thread_info ) + -sizeof (struct pt_regs ) +128 , +if (regs->sp >= curbase +sizeof (struct thread_info ) + +sizeof (struct pt_regs ) +STACK_TOP_MARGIN && + regs->sp <= curbase +THREAD_SIZE ) +return ; + + irq_stack_top = (u64 )__get_cpu_var (irq_stack_union.irq_stack) + +STACK_TOP_MARGIN ; + irq_stack_bottom = (u64 )__get_cpu_var (irq_stack_ptr); +if (regs->sp >= irq_stack_top && regs->sp <= irq_stack_bottom) +return ; + + oist = &__get_cpu_var (orig_ist); + estack_top = (u64 )oist->ist[0 ] -EXCEPTION_STKSZ +STACK_TOP_MARGIN ; + estack_bottom = (u64 )oist->ist[N_EXCEPTION_STACKS -1 ]; +if (regs->sp >= estack_top && regs->sp <= estack_bottom) +return ; + +WARN_ONCE (1 ,"do_IRQ(): %s has overflown the kernel stack (cur:%Lx,sp:%lx,irq stk top-bottom:%Lx-%Lx,exception stk top-bottom:%Lx-%Lx)\n" , + current->comm, curbase, regs->sp, + irq_stack_top, irq_stack_bottom, + estack_top, estack_bottom); -"do_IRQ: %s near stack overflow (cur:%Lx,sp:%lx)\n" , - current->comm, curbase, regs->sp); +if (sysctl_panic_on_stackoverflow) +panic ("low stack detected by irq handler - check messages\n" );#endif }
arch/x86/kernel/nmi_selftest.c new file +180 -0
180 lines not on this page · raw message
arch/x86/kernel/smp.c +70 -2
107 lines not on this page · raw message
arch/x86/kernel/smpboot.c +1 -0
@@ -1142,6 +1142,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus) {pr_debug ("Boot done.\n" ); +nmi_selftest ();impress_friends ();#ifdef CONFIG_X86_IO_APIC setup_ioapic_dest ();
include/linux/kernel.h +1 -0
@@ -341,6 +341,7 @@ extern int panic_timeout;extern int panic_on_oops;extern int panic_on_unrecovered_nmi;extern int panic_on_io_nmi; +extern int sysctl_panic_on_stackoverflow;extern const char *print_tainted (void );extern void add_taint (unsigned flag);extern int test_taint (unsigned flag);
kernel/sysctl.c +9 -0
@@ -803,6 +803,15 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, +#ifdef CONFIG_DEBUG_STACKOVERFLOW + { + .procname = "panic_on_stackoverflow", + .data = &sysctl_panic_on_stackoverflow, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif { .procname = "bootloader_type", .data = &bootloader_type,