Re: [PATCH 0/4] Introduce the aural error reporting framework
On Mon, Apr 01, 2019 at 12:24:51PM +0200, Matteo Croce wrote: > The buzzer driver is simple, requires just a few register writes to work, > the hardware is extremely cheap and is already present on most machines. What, no morse-code register dumps?
[PATCH 5/4] procfs: utility handler to trigger different errors
Add a /proc/crashtest handler which triggers different kernel errors. Just write a single character (if many are written, only the first one is read), to trigger different errors: - p: raise a kernel panic - w: generate a warning - o: raise an oops The handler permissions are set to 0220 to avoid non root users to crash the system. Signed-off-by: Matteo Croce --- fs/proc/Makefile| 1 + fs/proc/crashtest.c | 43 +++ 2 files changed, 44 insertions(+) create mode 100644 fs/proc/crashtest.c diff --git a/fs/proc/Makefile b/fs/proc/Makefile index ead487e80510..df99d3245ad9 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -15,6 +15,7 @@ proc-$(CONFIG_TTY) += proc_tty.o proc-y += cmdline.o proc-y += consoles.o proc-y += cpuinfo.o +proc-y += crashtest.o proc-y += devices.o proc-y += interrupts.o proc-y += loadavg.o diff --git a/fs/proc/crashtest.c b/fs/proc/crashtest.c new file mode 100644 index ..ad7d21cc9d98 --- /dev/null +++ b/fs/proc/crashtest.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +static ssize_t crashtest_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + char cmd; + + if (!count) + return 0; + + if (get_user(cmd, buf)) + return -EFAULT; + + switch (cmd) { + case 'p': + panic("crashtest"); + break; + case 'w': + WARN(1, "crashtest"); + break; + case 'o': + *(int*)0 = 0; + break; + default: + return -EINVAL; + } + + return count; +} + +static const struct file_operations proc_crashtest_ops = { + .write = crashtest_write, +}; + +static int __init proc_crashtest_init(void) +{ + return !proc_create("crashtest", 0220, NULL, _crashtest_ops); +} +fs_initcall(proc_crashtest_init); -- 2.20.1
[PATCH 3/4] bug: use the aural error reporting framework to report warnings
Use the new aural error reporting framework to signal kernel bugs. Emit the sound at the end of the __warn(), so the WARN_* are all covered. If panic_on_warn is set, panic() will play its sound and never return, so there is no risk to emit two sounds or the wrong one. Signed-off-by: Matteo Croce --- kernel/panic.c| 18 ++ lib/Kconfig.debug | 10 ++ 2 files changed, 28 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index 360578e092e7..b87c4403924d 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -81,6 +81,22 @@ static struct note panic_sound[] = { }; #endif +#ifdef CONFIG_AUDIBLE_WARN +static struct note warn_sound[] = { + { 440, 400 }, + { 440, 300 }, + { 440, 100 }, + { 440, 400 }, + { 523, 300 }, + { 494, 100 }, + { 494, 300 }, + { 440, 100 }, + { 440, 300 }, + { 440, 100 }, + { 440, 800 }, +}; +#endif + static long no_blink(int state) { return 0; @@ -609,6 +625,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, /* Just a warning, don't kill lockdep. */ add_taint(taint, LOCKDEP_STILL_OK); + + play(warn_sound, ARRAY_SIZE(warn_sound)); } #ifdef WANT_WARN_ON_SLOWPATH diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index e5d187dfc74a..909c271d283b 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1007,6 +1007,16 @@ config AUDIBLE_PANIC the system buzzer and not via any soundcard. Not available on all platforms. +config AUDIBLE_WARN + bool "Aural warning" + select PLAY_LIB + default n + help + If you say Y here, warnings will play a sound just + after the stacktrace and registers dump. The sound is played via + the system buzzer and not via any soundcard. + Not available on all platforms. + config SCHED_DEBUG bool "Collect scheduler debugging info" depends on DEBUG_KERNEL && PROC_FS -- 2.20.1
[PATCH 1/4] aural error reporting framework
The Linux kernel has had verbal error reporting since the beginning. Different error conditions trigger different error messages, with different severity: from a simple warning to the most feared kernel panic. While this detailed error reporting is much helpful to developers or end users, there are some cases in which it's impossible to notice that an error happened. The most common case is headless devices, such as home servers without an attached display, or routers without an exposed serial port. Needless to say, logging into the machine via SSH is not an option after such a severe error. In other cases the monitor might be attached, but the system is unable to display the error, probably because there is an X server running and the KMS switch fails. Or simply the user is visually impaired. These are all cases when the aural errors framework comes to help. This framework adds to the kernel a generic library to play sounds, which can be used to report errors or generic events. As the sound card driver could, and most probably will, become unusable during a kernel crash, the sounds are played via the system buzzer which has been around since the dawn of time. The buzzer driver is simple, requires just a few register writes to work, the hardware is extremely cheap and is already present on most machines. Signed-off-by: Matteo Croce --- arch/x86/lib/Makefile | 1 + arch/x86/lib/play.c | 75 +++ include/linux/play.h | 34 lib/Kconfig.debug | 5 +++ 4 files changed, 115 insertions(+) create mode 100644 arch/x86/lib/play.c create mode 100644 include/linux/play.h diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 140e61843a07..fcd1ee6adfad 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -28,6 +28,7 @@ lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o lib-$(CONFIG_RETPOLINE) += retpoline.o +lib-$(CONFIG_PLAY_LIB) += play.o obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o obj-y += iomem.o diff --git a/arch/x86/lib/play.c b/arch/x86/lib/play.c new file mode 100644 index ..e798eeb144f8 --- /dev/null +++ b/arch/x86/lib/play.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Aural kernel panic - x86 implementation + * + * Copyright (C) 2019 Matteo Croce + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#define CONTROL_WORD_REG 0x43 +#define COUNTER2 0x42 +#define SPEAKER_PORT 0x61 + +void arch_play_one(unsigned int ms, unsigned int hz) +{ + unsigned long flags; + u8 p61; + + /* filter out non audible by humans freqs */ + if (hz >= 16 && hz <= 22000) { + unsigned int count = PIT_TICK_RATE / hz; + + raw_spin_lock_irqsave(_lock, flags); + + /* set buzzer +* 0xB6 +* 1 0 Counter 2 +* 1 1 2xRD/2xWR bits 0..7, 8..15 of counter value +* 0 1 1Mode 3: Square Wave +* 0Counter is a 16 bit binary counter +*/ + outb_p(0xB6, CONTROL_WORD_REG); + + /* select desired HZ with two writes in counter 2, port 42h */ + outb_p(count, COUNTER2); + outb_p(count >> 8, COUNTER2); + + /* start beep +* set bit 0-1 (0: SPEAKER DATA; 1: OUT2) of GATE2 (port 61h) +*/ + p61 = inb_p(SPEAKER_PORT); + if ((p61 & 3) != 3) + outb_p(p61 | 3, SPEAKER_PORT); + + raw_spin_unlock_irqrestore(_lock, flags); + } + + msleep(ms * 9 / 10); + + raw_spin_lock_irqsave(_lock, flags); + + /* stop beep +* clear bit 0-1 of port 61h +*/ + p61 = inb_p(SPEAKER_PORT); + if (p61 & 3) + outb(p61 & 0xFC, SPEAKER_PORT); + + raw_spin_unlock_irqrestore(_lock, flags); + + msleep(ms / 10); +} diff --git a/include/linux/play.h b/include/linux/play.h new file mode 100644 index ..ae30cb8a0c1d --- /dev/null +++ b/include/linux/play.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * play.h - Definitions and headers for the aural error reporting framework. + * + * Copyright (C) 2019 Matteo Croce + * + * This file is released under the GPLv2. + */ + +#ifndef _LINUX_PLAY_H +#define
[PATCH 4/4] oops: use the aural error reporting framework to report oopses
Use the new aural error reporting framework when reporting an oops. The sound is emitted at the end of oops_exit(), to avoid interfering with other oops actions, like stack dump. Signed-off-by: Matteo Croce --- kernel/panic.c| 18 ++ lib/Kconfig.debug | 10 ++ 2 files changed, 28 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index b87c4403924d..ea34f93ce410 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -97,6 +97,23 @@ static struct note warn_sound[] = { }; #endif +#ifdef CONFIG_AUDIBLE_OOPS +static struct note oops_sound[] = { + { 494, 100 }, + { 698, 100 }, + { 0, 100 }, + { 698, 100 }, + { 698, 133 }, + { 659, 133 }, + { 587, 133 }, + { 523, 100 }, + { 330, 100 }, + { 262, 100 }, + { 330, 100 }, + { 262, 100 }, +}; +#endif + static long no_blink(int state) { return 0; @@ -575,6 +592,7 @@ void oops_exit(void) do_oops_enter_exit(); print_oops_end_marker(); kmsg_dump(KMSG_DUMP_OOPS); + play(oops_sound, ARRAY_SIZE(oops_sound)); } struct warn_args { diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 909c271d283b..74745ef386ce 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -1017,6 +1017,16 @@ config AUDIBLE_WARN the system buzzer and not via any soundcard. Not available on all platforms. +config AUDIBLE_OOPS + bool "Aural oops" + select PLAY_LIB + default n + help + If you say Y here, oops will play a sound just + after the stacktrace and registers dump. The sound is played via + the system buzzer and not via any soundcard. + Not available on all platforms. + config SCHED_DEBUG bool "Collect scheduler debugging info" depends on DEBUG_KERNEL && PROC_FS -- 2.20.1
[PATCH 0/4] Introduce the aural error reporting framework
The Linux kernel has had verbal error reporting since the beginning. Different error conditions trigger different error messages, with different severity: from a simple warning to the most feared kernel panic. While this detailed error reporting is much helpful to developers or end users, there are some cases in which it's impossible to notice that an error happened. The most common case is headless devices, such as home servers without an attached display, or routers without an exposed serial port. Needless to say, logging into the machine via SSH is not an option after such a severe error. In other cases the monitor might be attached, but the system is unable to display the error, probably because there is an X server running and the KMS switch fails. Or simply the user is visually impaired. These are all cases when the aural errors framework comes to help. This framework adds to the kernel a generic library to play sounds, which can be used to report errors or generic events. As the sound card driver could, and most probably will, become unusable during a kernel crash, the sounds are played via the system buzzer which has been around since the dawn of time. The buzzer driver is simple, requires just a few register writes to work, the hardware is extremely cheap and is already present on most machines. The first patch introduces the framework functions, the other three make use of it in, respectively, kernel panic, warning and oops. The last patch, not to be merged, creates a procfs handler useful to test the error reporting. Matteo Croce (4): aural error reporting framework panic: use the aural error reporting framework to report panics bug: use the aural error reporting framework to report warnings oops: use the aural error reporting framework to report oopses arch/x86/lib/Makefile | 1 + arch/x86/lib/play.c | 75 +++ include/linux/play.h | 34 kernel/panic.c| 61 +++ lib/Kconfig.debug | 35 5 files changed, 206 insertions(+) create mode 100644 arch/x86/lib/play.c create mode 100644 include/linux/play.h -- 2.20.1
[PATCH 2/4] panic: use the aural error reporting framework to report panics
Use the new aural error reporting framework to signal kernel panic. The error sound is emitted between the stack dump and the kexec jump. Signed-off-by: Matteo Croce --- kernel/panic.c| 25 + lib/Kconfig.debug | 10 ++ 2 files changed, 35 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index 0ae0d7332f12..360578e092e7 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define PANIC_TIMER_STEP 100 @@ -57,6 +58,29 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list); EXPORT_SYMBOL(panic_notifier_list); +#ifdef CONFIG_AUDIBLE_PANIC +static struct note panic_sound[] = { + { 784, 400 }, + { 784, 400 }, + { 784, 400 }, + { 622, 300 }, + { 932, 100 }, + { 784, 400 }, + { 622, 300 }, + { 932, 100 }, + { 784, 800 }, + { 1174, 400 }, + { 1174, 400 }, + { 1174, 400 }, + { 1244, 300 }, + { 932, 100 }, + { 740, 400 }, + { 622, 300 }, + { 932, 100 }, + { 784, 800 }, +}; +#endif + static long no_blink(int state) { return 0; @@ -213,6 +237,7 @@ void panic(const char *fmt, ...) if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) dump_stack(); #endif + play(panic_sound, ARRAY_SIZE(panic_sound)); /* * If we have crashed and we have a crash kernel loaded let it handle diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 10d04b266aef..e5d187dfc74a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -997,6 +997,16 @@ config PLAY_LIB depends on HAVE_PCSPKR_PLATFORM default n +config AUDIBLE_PANIC + bool "Aural panic" + select PLAY_LIB + default n + help + If you say Y here, kernel panics will play a sound just + after the stacktrace and registers dump. The sound is played via + the system buzzer and not via any soundcard. + Not available on all platforms. + config SCHED_DEBUG bool "Collect scheduler debugging info" depends on DEBUG_KERNEL && PROC_FS -- 2.20.1
kernel panic
Hi , I have Linux panic when started play music with one of my USB audio device. first please see this logs: [ 71.684730] usbcore: registered new interface driver snd-usb-audio [ 73.835355] BUG: unable to handle kernel NULL pointer dereference at 0008 [ 73.835412] IP: [] snd_usb_endpoint_start+0x23c/0x2f0 [snd_usb_audio] [ 73.835414] PGD 0 [ 73.835415] [ 73.835418] Oops: [#1] PREEMPT SMP [ 73.835482] Modules linked in: snd_usb_audio snd_usbmidi_lib snd_hwdep snd_pcm_oss snd_mixer_oss snd_ pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device snd_timer snd soundcore coretemp iwl3945 iwlegacy i915 ehci_pci iTCO_wdt ehci_hcd pcmcia iTCO_vendor_support kvm usbcore mac80211 e1000e yenta_socket sr_mod pcmcia_rsrc cfg80211 pcmcia_core lpc_ich mfd_core drm_kms_helper cdrom rfkill ata_ge neric irqbypass ptp pps_core joydev sg pcspkr i2c_i801 drm battery i2c_algo_bit ata_piix i2c_smbus usb_c ommon shpchp rng_core ac acpi_cpufreq video button nls_utf8 cifs sha256_ssse3 cmac md4 des_generic arc4 dns_resolver fscache sunrpc loop ip_tables x_tables autofs4 ext4 crc16 jbd2 crc32c_generic fscrypto ecb glue_helper lrw gf128mul ablk_helper cryptd aes_x86_64 mbcache sd_mod ahci libahci [ 73.835486] evdev libata psmouse serio_raw scsi_mod thermal [ 73.835491] CPU: 1 PID: 1099 Comm: output:oops Not tainted 4.9.144-rt93 #1 [ 73.835492] Hardware name: LENOVO 636962M/636962M, BIOS 7IET38WW (1.19 ) 03/22/2011 [ 73.835494] task: 8beb97502c40 task.stack: ac1901068000 [ 73.835505] RIP: 0010:[] [] snd_usb_endpoint_start+0x23c/0x2f0 [ snd_usb_audio] [ 73.835507] RSP: :ac190106bcc0 EFLAGS: 00010246 [ 73.835508] RAX: ffea RBX: 8beb96c0 RCX: ffea [ 73.835509] RDX: RSI: c0b5bf98 RDI: 8beb99a18000 [ 73.835511] RBP: 0002 R08: c0b5a8d3 R09: [ 73.835512] R10: fe00 R11: 0200 R12: 8beb96c80070 [ 73.835513] R13: 8beb99a18000 R14: 0002 R15: [ 73.835516] FS: 7fdfedc66700() GS:8bebbf30() knlGS: [ 73.835518] CS: 0010 DS: ES: CR0: 80050033 [ 73.835519] CR2: 0008 CR3: b4ab6000 CR4: 0670 [ 73.835520] Stack: [ 73.835525] 8bebbc18 8beb96c0 8002 [ 73.835528] 7fdfe40197d0 c0b4e7cd 8bebbc18 8beb974b2400 [ 73.835531] c0b5088a 8bebac44 8bebb206d300 [ 73.835531] Call Trace: [ 73.835545] [] ? start_endpoints+0x3d/0x150 [snd_usb_audio] [ 73.83] [] ? snd_usb_pcm_prepare+0x2ea/0x520 [snd_usb_audio] [ 73.835577] [] ? snd_pcm_sw_params_user+0x56/0x90 [snd_pcm] [ 73.835584] [] ? snd_pcm_do_prepare+0x19/0x30 [snd_pcm] [ 73.835591] [] ? snd_pcm_action_single+0x36/0x80 [snd_pcm] [ 73.835598] [] ? snd_pcm_action_nonatomic+0x61/0x70 [snd_pcm] [ 73.835606] [] ? snd_pcm_common_ioctl1+0x3a9/0xc60 [snd_pcm] [ 73.835674] [] ? ext4_file_write_iter+0x22e/0x370 [ext4] [ 73.835682] [] ? snd_pcm_playback_ioctl1+0x1da/0x240 [snd_pcm] [ 73.835690] [] ? __seccomp_filter+0x78/0x2a0 [ 73.835698] [] ? snd_pcm_playback_ioctl+0x23/0x30 [snd_pcm] [ 73.835702] [] ? do_vfs_ioctl+0xa4/0x620 [ 73.835706] [] ? syscall_trace_enter+0x144/0x300 [ 73.835709] [] ? SyS_ioctl+0x74/0x80 [ 73.835711] [] ? do_syscall_64+0x76/0x100 [ 73.835717] [] ? entry_SYSCALL_64_after_swapgs+0x58/0xc6 [ 73.835747] Code: c0 d3 a8 b5 c0 83 f8 a6 74 15 83 f8 e0 49 c7 c0 8c a8 b5 c0 48 c7 c2 74 a8 b5 c0 4c 0f 45 c2 48 8b 13 89 c1 48 c7 c6 98 bf b5 c0 <48> 8b 7a 08 89 ea 48 81 c7 98 00 00 00 e8 e2 7b f4 f8 f0 80 63 [ 73.835757] RIP [] snd_usb_endpoint_start+0x23c/0x2f0 [snd_usb_audio] [ 73.835758] RSP [ 73.835759] CR2: 0008 I give you more detail, I have Debian Linux 4.9.144-rt93. I tested under Debian 4.19 and Ubuntu same panic present. Please help me to fix this problem, this device working fine under Windows. I believe this problem in Linux audio driver. I ready to provide any additional details if needs. -- Regards, Viktor L