140123Sdes// SPDX-License-Identifier: GPL-2.0 266830Sobrien/* 366830Sobrien * Linux Magic System Request Key Hacks 466830Sobrien * 566830Sobrien * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> 666830Sobrien * based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz> 766830Sobrien * 866830Sobrien * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com> 966830Sobrien * overhauled to use key registration 1066830Sobrien * based upon discusions in irc://irc.openprojects.net/#kernelnewbies 1166830Sobrien * 1266830Sobrien * Copyright (c) 2010 Dmitry Torokhov 1366830Sobrien * Input handler conversion 1466830Sobrien */ 1566830Sobrien 1666830Sobrien#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 1766830Sobrien 1866830Sobrien#include <linux/sched/signal.h> 1966830Sobrien#include <linux/sched/rt.h> 2066830Sobrien#include <linux/sched/debug.h> 2166830Sobrien#include <linux/sched/task.h> 2266830Sobrien#include <linux/ctype.h> 2366830Sobrien#include <linux/interrupt.h> 2466830Sobrien#include <linux/mm.h> 2566830Sobrien#include <linux/fs.h> 2666830Sobrien#include <linux/mount.h> 2783871Sobrien#include <linux/kdev_t.h> 2850472Speter#include <linux/major.h> 2966830Sobrien#include <linux/reboot.h> 3037Srgrimes#include <linux/sysrq.h> 3137Srgrimes#include <linux/kbd_kern.h> 3237Srgrimes#include <linux/proc_fs.h> 3337Srgrimes#include <linux/nmi.h> 3437Srgrimes#include <linux/quotaops.h> 3537Srgrimes#include <linux/perf_event.h> 3651231Ssheldonh#include <linux/kernel.h> 3751231Ssheldonh#include <linux/module.h> 3851231Ssheldonh#include <linux/suspend.h> 3951231Ssheldonh#include <linux/writeback.h> 408460Sjkh#include <linux/swap.h> 4137Srgrimes#include <linux/spinlock.h> 4237Srgrimes#include <linux/vt_kern.h> 4337Srgrimes#include <linux/workqueue.h> 4437Srgrimes#include <linux/hrtimer.h> 4551231Ssheldonh#include <linux/oom.h> 4637Srgrimes#include <linux/slab.h> 4737Srgrimes#include <linux/input.h> 4837Srgrimes#include <linux/uaccess.h> 4968985Sdougb#include <linux/moduleparam.h> 5068985Sdougb#include <linux/jiffies.h> 5151231Ssheldonh#include <linux/syscalls.h> 5292441Scjc#include <linux/of.h> 5351231Ssheldonh#include <linux/rcupdate.h> 5437Srgrimes 5543179Sdillon#include <asm/ptrace.h> 5643803Sdillon#include <asm/irq_regs.h> 5743179Sdillon 5851231Ssheldonh/* Whether we react on sysrq keys or just ignore them */ 5943375Sdillonstatic int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE; 6043375Sdillonstatic bool __read_mostly sysrq_always_enabled; 6143803Sdillon 6243179Sdillonstatic bool sysrq_on(void) 6343179Sdillon{ 6443179Sdillon return sysrq_enabled || sysrq_always_enabled; 6543219Speter} 6643219Speter 6751231Ssheldonh/** 6843849Sjkh * sysrq_mask - Getter for sysrq_enabled mask. 6959674Ssheldonh * 7051231Ssheldonh * Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise. 7143219Speter */ 7243219Speterint sysrq_mask(void) 7343219Speter{ 7471014Sdougb if (sysrq_always_enabled) 7571014Sdougb return 1; 7678918Srwatson return sysrq_enabled; 7771014Sdougb} 7871014SdougbEXPORT_SYMBOL_GPL(sysrq_mask); 7971014Sdougb 8071014Sdougb/* 8169988Sbsd * A value of 1 means 'all', other nonzero values are an op mask: 8269988Sbsd */ 8369988Sbsdstatic bool sysrq_on_mask(int mask) 8469988Sbsd{ 8569988Sbsd return sysrq_always_enabled || 8669988Sbsd sysrq_enabled == 1 || 8769988Sbsd (sysrq_enabled & mask); 8869988Sbsd} 8969988Sbsd 9069988Sbsdstatic int __init sysrq_always_enabled_setup(char *str) 9169876Sobrien{ 9269988Sbsd sysrq_always_enabled = true; 9369949Sbsd pr_info("sysrq always enabled.\n"); 9469988Sbsd 9569949Sbsd return 1; 9669988Sbsd} 9769988Sbsd 9869988Sbsd__setup("sysrq_always_enabled", sysrq_always_enabled_setup); 9969988Sbsd 10069949Sbsd 10169876Sobrienstatic void sysrq_handle_loglevel(u8 key) 10269876Sobrien{ 10369988Sbsd u8 loglevel = key - '0'; 10467179Sjwd 10569988Sbsd console_loglevel = CONSOLE_LOGLEVEL_DEFAULT; 10689911Ssheldonh pr_info("Loglevel set to %u\n", loglevel); 10769988Sbsd console_loglevel = loglevel; 10870916Sbsd} 10970916Sbsdstatic const struct sysrq_key_op sysrq_loglevel_op = { 11069876Sobrien .handler = sysrq_handle_loglevel, 11192187Scjc .help_msg = "loglevel(0-9)", 11292187Scjc .action_msg = "Changing Loglevel", 11392187Scjc .enable_mask = SYSRQ_ENABLE_LOG, 11492187Scjc}; 11592187Scjc 11692187Scjc#ifdef CONFIG_VT 11792187Scjcstatic void sysrq_handle_SAK(u8 key) 11892187Scjc{ 11992187Scjc struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; 12092187Scjc 12192187Scjc schedule_work(SAK_work); 12273277Sdougb} 12373277Sdougbstatic const struct sysrq_key_op sysrq_SAK_op = { 12473277Sdougb .handler = sysrq_handle_SAK, 12573277Sdougb .help_msg = "sak(k)", 12673277Sdougb .action_msg = "SAK", 12773277Sdougb .enable_mask = SYSRQ_ENABLE_KEYBOARD, 12873277Sdougb}; 12973277Sdougb#else 13073277Sdougb#define sysrq_SAK_op (*(const struct sysrq_key_op *)NULL) 13173277Sdougb#endif 13287646Sru 13373277Sdougb#ifdef CONFIG_VT 13473277Sdougbstatic void sysrq_handle_unraw(u8 key) 13573277Sdougb{ 13673277Sdougb vt_reset_unicode(fg_console); 13773277Sdougb} 13873277Sdougb 13973277Sdougbstatic const struct sysrq_key_op sysrq_unraw_op = { 14073277Sdougb .handler = sysrq_handle_unraw, 14173277Sdougb .help_msg = "unraw(r)", 14274063Sdougb .action_msg = "Keyboard mode set to system default", 14387646Sru .enable_mask = SYSRQ_ENABLE_KEYBOARD, 14473277Sdougb}; 14573277Sdougb#else 14673277Sdougb#define sysrq_unraw_op (*(const struct sysrq_key_op *)NULL) 14773277Sdougb#endif /* CONFIG_VT */ 14873277Sdougb 14973277Sdougbstatic void sysrq_handle_crash(u8 key) 15073277Sdougb{ 15173277Sdougb /* release the RCU read lock before crashing */ 15273277Sdougb rcu_read_unlock(); 15374063Sdougb 15487646Sru panic("sysrq triggered crash\n"); 15573277Sdougb} 15673277Sdougbstatic const struct sysrq_key_op sysrq_crash_op = { 15773277Sdougb .handler = sysrq_handle_crash, 15873277Sdougb .help_msg = "crash(c)", 15973277Sdougb .action_msg = "Trigger a crash", 16073277Sdougb .enable_mask = SYSRQ_ENABLE_DUMP, 16173277Sdougb}; 16271014Sdougb 16367113Smarkmstatic void sysrq_handle_reboot(u8 key) 16467113Smarkm{ 16567113Smarkm lockdep_off(); 16667113Smarkm local_irq_enable(); 16767113Smarkm emergency_restart(); 16867113Smarkm} 16970922Sdougbstatic const struct sysrq_key_op sysrq_reboot_op = { 17070922Sdougb .handler = sysrq_handle_reboot, 17170922Sdougb .help_msg = "reboot(b)", 17270922Sdougb .action_msg = "Resetting", 17370922Sdougb .enable_mask = SYSRQ_ENABLE_BOOT, 17474063Sdougb}; 17574063Sdougb 17674063Sdougbconst struct sysrq_key_op *__sysrq_reboot_op = &sysrq_reboot_op; 17774063Sdougb 17874063Sdougbstatic void sysrq_handle_sync(u8 key) 17974063Sdougb{ 18074063Sdougb emergency_sync(); 18174063Sdougb} 18215568Sasamistatic const struct sysrq_key_op sysrq_sync_op = { 18351231Ssheldonh .handler = sysrq_handle_sync, 18451231Ssheldonh .help_msg = "sync(s)", 18515568Sasami .action_msg = "Emergency Sync", 18615568Sasami .enable_mask = SYSRQ_ENABLE_SYNC, 18715568Sasami}; 18851231Ssheldonh 18951231Ssheldonhstatic void sysrq_handle_show_timers(u8 key) 19045239Sgrog{ 19151231Ssheldonh sysrq_timer_list_show(); 19251231Ssheldonh} 19342741Sgrog 19443803Sdillonstatic const struct sysrq_key_op sysrq_show_timers_op = { 1953843Sdg .handler = sysrq_handle_show_timers, 19683957Sphk .help_msg = "show-all-timers(q)", 19783957Sphk .action_msg = "Show clockevent devices & pending hrtimers (no others)", 19883957Sphk}; 19983957Sphk 20083957Sphkstatic void sysrq_handle_mountro(u8 key) 20183957Sphk{ 20268985Sdougb emergency_remount(); 20351231Ssheldonh} 20470109Sdougbstatic const struct sysrq_key_op sysrq_mountro_op = { 20576946Sdd .handler = sysrq_handle_mountro, 20676946Sdd .help_msg = "unmount(u)", 20776946Sdd .action_msg = "Emergency Remount R/O", 20876946Sdd .enable_mask = SYSRQ_ENABLE_REMOUNT, 20976946Sdd}; 21076946Sdd 21176946Sdd#ifdef CONFIG_LOCKDEP 21276946Sddstatic void sysrq_handle_showlocks(u8 key) 21337Srgrimes{ 21437Srgrimes debug_show_all_locks(); 21537Srgrimes} 21637Srgrimes 21737Srgrimesstatic const struct sysrq_key_op sysrq_showlocks_op = { 21837Srgrimes .handler = sysrq_handle_showlocks, 21937Srgrimes .help_msg = "show-all-locks(d)", 22037Srgrimes .action_msg = "Show Locks Held", 22170109Sdougb}; 22237Srgrimes#else 22337Srgrimes#define sysrq_showlocks_op (*(const struct sysrq_key_op *)NULL) 22437Srgrimes#endif 22572031Sdougb 22672031Sdougb#ifdef CONFIG_SMP 22772031Sdougbstatic DEFINE_RAW_SPINLOCK(show_lock); 22872031Sdougb 22972031Sdougbstatic void showacpu(void *dummy) 23072031Sdougb{ 23172031Sdougb unsigned long flags; 23272031Sdougb 23372031Sdougb /* Idle CPUs have no interesting backtrace. */ 23472031Sdougb if (idle_cpu(smp_processor_id())) { 23572031Sdougb pr_info("CPU%d: backtrace skipped as idling\n", smp_processor_id()); 23672031Sdougb return; 23772031Sdougb } 23872031Sdougb 23972031Sdougb raw_spin_lock_irqsave(&show_lock, flags); 24072031Sdougb pr_info("CPU%d:\n", smp_processor_id()); 24172031Sdougb show_stack(NULL, NULL, KERN_INFO); 24272031Sdougb raw_spin_unlock_irqrestore(&show_lock, flags); 24337Srgrimes} 24437Srgrimes 24570109Sdougbstatic void sysrq_showregs_othercpus(struct work_struct *dummy) 24637Srgrimes{ 24737Srgrimes smp_call_function(showacpu, NULL, 0); 24837Srgrimes} 24937Srgrimes 25037Srgrimesstatic DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); 25137Srgrimes 25237Srgrimesstatic void sysrq_handle_showallcpus(u8 key) 25370109Sdougb{ 25437Srgrimes /* 25537Srgrimes * Fall back to the workqueue based printing if the 25637Srgrimes * backtrace printing did not succeed or the 25751231Ssheldonh * architecture has no support for it: 25851231Ssheldonh */ 25970109Sdougb if (!trigger_all_cpu_backtrace()) { 26051231Ssheldonh struct pt_regs *regs = NULL; 26151231Ssheldonh 26237Srgrimes if (in_hardirq()) 26345222Scracauer regs = get_irq_regs(); 26437Srgrimes 26537Srgrimes pr_info("CPU%d:\n", get_cpu()); 26643197Sdillon if (regs) 26743197Sdillon show_regs(regs); 26843197Sdillon else 26951231Ssheldonh show_stack(NULL, NULL, KERN_INFO); 27051231Ssheldonh 27151231Ssheldonh schedule_work(&sysrq_showallcpus); 27251231Ssheldonh put_cpu(); 27351231Ssheldonh } 27470109Sdougb} 27551231Ssheldonh 27651231Ssheldonhstatic const struct sysrq_key_op sysrq_showallcpus_op = { 27751231Ssheldonh .handler = sysrq_handle_showallcpus, 27851231Ssheldonh .help_msg = "show-backtrace-all-active-cpus(l)", 2791692Sphk .action_msg = "Show backtrace of all active CPUs", 28043803Sdillon .enable_mask = SYSRQ_ENABLE_DUMP, 28143197Sdillon}; 28288676Ssheldonh#else 28388676Ssheldonh#define sysrq_showallcpus_op (*(const struct sysrq_key_op *)NULL) 28488676Ssheldonh#endif 28588676Ssheldonh 28688676Ssheldonhstatic void sysrq_handle_showregs(u8 key) 28788676Ssheldonh{ 28888676Ssheldonh struct pt_regs *regs = NULL; 28988676Ssheldonh 29088676Ssheldonh if (in_hardirq()) 29188676Ssheldonh regs = get_irq_regs(); 29288676Ssheldonh if (regs) 29377974Ssheldonh show_regs(regs); 29488531Ssheldonh perf_event_print_debug(); 29588531Ssheldonh} 29688531Ssheldonhstatic const struct sysrq_key_op sysrq_showregs_op = { 29788531Ssheldonh .handler = sysrq_handle_showregs, 29888531Ssheldonh .help_msg = "show-registers(p)", 29988531Ssheldonh .action_msg = "Show Regs", 30088531Ssheldonh .enable_mask = SYSRQ_ENABLE_DUMP, 30151231Ssheldonh}; 30251231Ssheldonh 30351231Ssheldonhstatic void sysrq_handle_showstate(u8 key) 30451231Ssheldonh{ 30551231Ssheldonh show_state(); 30670109Sdougb show_all_workqueues(); 30743803Sdillon} 30851231Ssheldonhstatic const struct sysrq_key_op sysrq_showstate_op = { 30951231Ssheldonh .handler = sysrq_handle_showstate, 31037Srgrimes .help_msg = "show-task-states(t)", 31143197Sdillon .action_msg = "Show State", 31243197Sdillon .enable_mask = SYSRQ_ENABLE_DUMP, 31351231Ssheldonh}; 31450357Ssheldonh 31543197Sdillonstatic void sysrq_handle_showstate_blocked(u8 key) 31643197Sdillon{ 31771014Sdougb show_state_filter(TASK_UNINTERRUPTIBLE); 31871014Sdougb} 31971014Sdougbstatic const struct sysrq_key_op sysrq_showstate_blocked_op = { 32067179Sjwd .handler = sysrq_handle_showstate_blocked, 32167179Sjwd .help_msg = "show-blocked-tasks(w)", 32271014Sdougb .action_msg = "Show Blocked State", 32371014Sdougb .enable_mask = SYSRQ_ENABLE_DUMP, 32467179Sjwd}; 32571014Sdougb 32671014Sdougb#ifdef CONFIG_TRACING 32771014Sdougb#include <linux/ftrace.h> 32867179Sjwd 32971014Sdougbstatic void sysrq_ftrace_dump(u8 key) 33067179Sjwd{ 33167179Sjwd ftrace_dump(DUMP_ALL); 33267179Sjwd} 33371014Sdougbstatic const struct sysrq_key_op sysrq_ftrace_dump_op = { 33471014Sdougb .handler = sysrq_ftrace_dump, 33571014Sdougb .help_msg = "dump-ftrace-buffer(z)", 33671014Sdougb .action_msg = "Dump ftrace buffer", 33771014Sdougb .enable_mask = SYSRQ_ENABLE_DUMP, 33871014Sdougb}; 33971014Sdougb#else 34071014Sdougb#define sysrq_ftrace_dump_op (*(const struct sysrq_key_op *)NULL) 34171014Sdougb#endif 34267179Sjwd 3434091Sachestatic void sysrq_handle_showmem(u8 key) 344872Sache{ 34564400Sbrian show_mem(); 34664400Sbrian} 34764400Sbrianstatic const struct sysrq_key_op sysrq_showmem_op = { 34864400Sbrian .handler = sysrq_handle_showmem, 34964400Sbrian .help_msg = "show-memory-usage(m)", 35064400Sbrian .action_msg = "Show Memory", 35164400Sbrian .enable_mask = SYSRQ_ENABLE_DUMP, 35264400Sbrian}; 35364400Sbrian 35464449Sbrian/* 35564400Sbrian * Signal sysrq helper function. Sends a signal to all user processes. 35664449Sbrian */ 35776430Sbrianstatic void send_sig_all(int sig) 35876430Sbrian{ 35964449Sbrian struct task_struct *p; 36076430Sbrian 36176430Sbrian read_lock(&tasklist_lock); 36276430Sbrian for_each_process(p) { 36364400Sbrian if (p->flags & PF_KTHREAD) 36464400Sbrian continue; 36564400Sbrian if (is_global_init(p)) 36664400Sbrian continue; 36764400Sbrian 36864400Sbrian do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); 36938237Sbrian } 37088199Sbrian read_unlock(&tasklist_lock); 37188199Sbrian} 37239384Sbrian 37339384Sbrianstatic void sysrq_handle_term(u8 key) 37439384Sbrian{ 37551231Ssheldonh send_sig_all(SIGTERM); 37639384Sbrian console_loglevel = CONSOLE_LOGLEVEL_DEBUG; 37739384Sbrian} 37888199Sbrianstatic const struct sysrq_key_op sysrq_term_op = { 37988199Sbrian .handler = sysrq_handle_term, 38088199Sbrian .help_msg = "terminate-all-tasks(e)", 38188199Sbrian .action_msg = "Terminate All Tasks", 38288199Sbrian .enable_mask = SYSRQ_ENABLE_SIGNAL, 38338237Sbrian}; 38426450Sache 38588199Sbrianstatic void moom_callback(struct work_struct *ignored) 38688199Sbrian{ 38788199Sbrian const gfp_t gfp_mask = GFP_KERNEL; 38888199Sbrian struct oom_control oc = { 38988199Sbrian .zonelist = node_zonelist(first_memory_node, gfp_mask), 39021197Sphk .nodemask = NULL, 39117767Sjkh .memcg = NULL, 39251231Ssheldonh .gfp_mask = gfp_mask, 39351231Ssheldonh .order = -1, 39451231Ssheldonh }; 39551231Ssheldonh 39651231Ssheldonh mutex_lock(&oom_lock); 39775384Sru if (!out_of_memory(&oc)) 39870109Sdougb pr_info("OOM request ignored. No task eligible\n"); 39975384Sru mutex_unlock(&oom_lock); 40051231Ssheldonh} 40151231Ssheldonh 40251231Ssheldonhstatic DECLARE_WORK(moom_work, moom_callback); 40317767Sjkh 40451231Ssheldonhstatic void sysrq_handle_moom(u8 key) 40551231Ssheldonh{ 40651231Ssheldonh schedule_work(&moom_work); 40745096Simp} 40845096Simpstatic const struct sysrq_key_op sysrq_moom_op = { 40945096Simp .handler = sysrq_handle_moom, 41051231Ssheldonh .help_msg = "memory-full-oom-kill(f)", 41151231Ssheldonh .action_msg = "Manual OOM execution", 41251231Ssheldonh .enable_mask = SYSRQ_ENABLE_SIGNAL, 4137293Sjkh}; 4141675Sache 4151675Sache#ifdef CONFIG_BLOCK 41651231Ssheldonhstatic void sysrq_handle_thaw(u8 key) 41751231Ssheldonh{ 41851231Ssheldonh emergency_thaw_all(); 41914624Snate} 42014596Snatestatic const struct sysrq_key_op sysrq_thaw_op = { 42114596Snate .handler = sysrq_handle_thaw, 42251231Ssheldonh .help_msg = "thaw-filesystems(j)", 42351231Ssheldonh .action_msg = "Emergency Thaw of all frozen filesystems", 42451231Ssheldonh .enable_mask = SYSRQ_ENABLE_SIGNAL, 42525184Sjkh}; 42625184Sjkh#else 4277460Sjkh#define sysrq_thaw_op (*(const struct sysrq_key_op *)NULL) 4287460Sjkh#endif 42957398Sshin 43057398Sshinstatic void sysrq_handle_kill(u8 key) 43157398Sshin{ 43257398Sshin send_sig_all(SIGKILL); 43357398Sshin console_loglevel = CONSOLE_LOGLEVEL_DEBUG; 43457398Sshin} 43557398Sshinstatic const struct sysrq_key_op sysrq_kill_op = { 43657398Sshin .handler = sysrq_handle_kill, 43757398Sshin .help_msg = "kill-all-tasks(i)", 43877974Ssheldonh .action_msg = "Kill All Tasks", 43988531Ssheldonh .enable_mask = SYSRQ_ENABLE_SIGNAL, 44088531Ssheldonh}; 44188531Ssheldonh 44288531Ssheldonhstatic void sysrq_handle_unrt(u8 key) 44388531Ssheldonh{ 44477974Ssheldonh normalize_rt_tasks(); 44577974Ssheldonh} 44685136Sdougbstatic const struct sysrq_key_op sysrq_unrt_op = { 44785136Sdougb .handler = sysrq_handle_unrt, 44885136Sdougb .help_msg = "nice-all-RT-tasks(n)", 44985136Sdougb .action_msg = "Nice All RT Tasks", 45085136Sdougb .enable_mask = SYSRQ_ENABLE_RTNICE, 45185136Sdougb}; 45285136Sdougb 45385136Sdougb/* Key Operations table and lock */ 45485136Sdougbstatic DEFINE_SPINLOCK(sysrq_key_table_lock); 45585136Sdougb 45685136Sdougbstatic const struct sysrq_key_op *sysrq_key_table[62] = { 45785136Sdougb &sysrq_loglevel_op, /* 0 */ 45885136Sdougb &sysrq_loglevel_op, /* 1 */ 45985136Sdougb &sysrq_loglevel_op, /* 2 */ 46085136Sdougb &sysrq_loglevel_op, /* 3 */ 46185136Sdougb &sysrq_loglevel_op, /* 4 */ 46285136Sdougb &sysrq_loglevel_op, /* 5 */ 46385136Sdougb &sysrq_loglevel_op, /* 6 */ 46477974Ssheldonh &sysrq_loglevel_op, /* 7 */ 46577974Ssheldonh &sysrq_loglevel_op, /* 8 */ 4667487Srgrimes &sysrq_loglevel_op, /* 9 */ 46788531Ssheldonh 46888531Ssheldonh /* 46988531Ssheldonh * a: Don't use for system provided sysrqs, it is handled specially on 47088531Ssheldonh * sparc and will never arrive. 47188531Ssheldonh */ 47288531Ssheldonh NULL, /* a */ 47388531Ssheldonh &sysrq_reboot_op, /* b */ 47488531Ssheldonh &sysrq_crash_op, /* c */ 47588531Ssheldonh &sysrq_showlocks_op, /* d */ 47688531Ssheldonh &sysrq_term_op, /* e */ 47788531Ssheldonh &sysrq_moom_op, /* f */ 47888531Ssheldonh /* g: May be registered for the kernel debugger */ 47988531Ssheldonh NULL, /* g */ 48088531Ssheldonh NULL, /* h - reserved for help */ 48188531Ssheldonh &sysrq_kill_op, /* i */ 48288531Ssheldonh &sysrq_thaw_op, /* j */ 48388531Ssheldonh &sysrq_SAK_op, /* k */ 4847487Srgrimes &sysrq_showallcpus_op, /* l */ 48551231Ssheldonh &sysrq_showmem_op, /* m */ 48664893Ssheldonh &sysrq_unrt_op, /* n */ 48764893Ssheldonh /* o: This will often be registered as 'Off' at init time */ 48864893Ssheldonh NULL, /* o */ 48964893Ssheldonh &sysrq_showregs_op, /* p */ 49064893Ssheldonh &sysrq_show_timers_op, /* q */ 4917487Srgrimes &sysrq_unraw_op, /* r */ 49251231Ssheldonh &sysrq_sync_op, /* s */ 49351231Ssheldonh &sysrq_showstate_op, /* t */ 49438237Sbrian &sysrq_mountro_op, /* u */ 49588199Sbrian /* v: May be registered for frame buffer console restore */ 49638237Sbrian NULL, /* v */ 49731192Ssteve &sysrq_showstate_blocked_op, /* w */ 49831192Ssteve /* x: May be registered on mips for TLB dump */ 49931192Ssteve /* x: May be registered on ppc/powerpc for xmon */ 50031192Ssteve /* x: May be registered on sparc64 for global PMU dump */ 50131192Ssteve NULL, /* x */ 50231192Ssteve /* y: May be registered on sparc64 for global register dump */ 50331192Ssteve NULL, /* y */ 50451231Ssheldonh &sysrq_ftrace_dump_op, /* z */ 50551231Ssheldonh NULL, /* A */ 50670109Sdougb NULL, /* B */ 50731192Ssteve NULL, /* C */ 50831192Ssteve NULL, /* D */ 50931192Ssteve NULL, /* E */ 51051231Ssheldonh NULL, /* F */ 51151231Ssheldonh NULL, /* G */ 51270109Sdougb NULL, /* H */ 51351231Ssheldonh NULL, /* I */ 51451231Ssheldonh NULL, /* J */ 51531192Ssteve NULL, /* K */ 51651231Ssheldonh NULL, /* L */ 51738915Scracauer NULL, /* M */ 51851231Ssheldonh NULL, /* N */ 51938915Scracauer NULL, /* O */ 52038915Scracauer NULL, /* P */ 52151231Ssheldonh NULL, /* Q */ 52251231Ssheldonh NULL, /* R */ 5237487Srgrimes NULL, /* S */ 52492192Srwatson NULL, /* T */ 52592192Srwatson NULL, /* U */ 52692192Srwatson NULL, /* V */ 52792192Srwatson NULL, /* W */ 52892192Srwatson NULL, /* X */ 52992192Srwatson NULL, /* Y */ 53092192Srwatson NULL, /* Z */ 53170109Sdougb}; 53251231Ssheldonh 53351231Ssheldonh/* key2index calculation, -1 on invalid index */ 53451231Ssheldonhstatic int sysrq_key_table_key2index(u8 key) 5357259Sjkh{ 53651231Ssheldonh switch (key) { 53751231Ssheldonh case '0' ... '9': 53824463Spst return key - '0'; 53951231Ssheldonh case 'a' ... 'z': 54075525Sphk return key - 'a' + 10; 54124463Spst case 'A' ... 'Z': 54224463Spst return key - 'A' + 10 + 26; 54324463Spst default: 54424463Spst return -1; 54524463Spst } 54678905Sdd} 54778905Sdd 54851231Ssheldonh/* 54951231Ssheldonh * get and put functions for the table, exposed to modules. 55051231Ssheldonh */ 55125339Sjkhstatic const struct sysrq_key_op *__sysrq_get_key_op(u8 key) 55225339Sjkh{ 55367445Sphk const struct sysrq_key_op *op_p = NULL; 55467040Sache int i; 55567445Sphk 55670109Sdougb i = sysrq_key_table_key2index(key); 55767445Sphk if (i != -1) 55867445Sphk op_p = sysrq_key_table[i]; 55967445Sphk 56067040Sache return op_p; 56192187Scjc} 56232340Sjoerg 56351231Ssheldonhstatic void __sysrq_put_key_op(u8 key, const struct sysrq_key_op *op_p) 56492187Scjc{ 56584744Sdougb int i = sysrq_key_table_key2index(key); 56684744Sdougb 56784744Sdougb if (i != -1) 56884744Sdougb sysrq_key_table[i] = op_p; 56992080Scjc} 57092080Scjc 57192080Scjcvoid __handle_sysrq(u8 key, bool check_mask) 57284744Sdougb{ 57384744Sdougb const struct sysrq_key_op *op_p; 57492187Scjc int orig_log_level; 57592187Scjc int orig_suppress_printk; 57692187Scjc int i; 57751231Ssheldonh 57892187Scjc orig_suppress_printk = suppress_printk; 57932340Sjoerg suppress_printk = 0; 58050357Ssheldonh 58139384Sbrian rcu_sysrq_start(); 582857Sdg rcu_read_lock(); 58337Srgrimes /* 58444818Sbillf * Raise the apparent loglevel to maximum so that the sysrq header 58551231Ssheldonh * is shown to provide the user with positive feedback. We do not 58651231Ssheldonh * simply emit this at KERN_EMERG as that would change message 58751231Ssheldonh * routing in the consumers of /proc/kmsg. 58851231Ssheldonh */ 58951231Ssheldonh orig_log_level = console_loglevel; 59070109Sdougb console_loglevel = CONSOLE_LOGLEVEL_DEFAULT; 59151231Ssheldonh 59251231Ssheldonh op_p = __sysrq_get_key_op(key); 59351231Ssheldonh if (op_p) { 59451231Ssheldonh /* 59544818Sbillf * Should we check for enabled operations (/proc/sysrq-trigger 59670109Sdougb * should not) and is the invoked operation enabled? 59751231Ssheldonh */ 59851231Ssheldonh if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { 59951231Ssheldonh pr_info("%s\n", op_p->action_msg); 60051231Ssheldonh console_loglevel = orig_log_level; 60144818Sbillf op_p->handler(key); 60250357Ssheldonh } else { 60339384Sbrian pr_info("This sysrq operation is disabled.\n"); 6047477Sache console_loglevel = orig_log_level; 6057477Sache } 60651231Ssheldonh } else { 60751231Ssheldonh pr_info("HELP : "); 60851231Ssheldonh /* Only print the help msg once per handler */ 6097487Srgrimes for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) { 6107487Srgrimes if (sysrq_key_table[i]) { 6117238Sache int j; 6127238Sache 61351231Ssheldonh for (j = 0; sysrq_key_table[i] != 61451231Ssheldonh sysrq_key_table[j]; j++) 61551231Ssheldonh ; 61670109Sdougb if (j != i) 61751231Ssheldonh continue; 61851231Ssheldonh pr_cont("%s ", sysrq_key_table[i]->help_msg); 61951231Ssheldonh } 62051231Ssheldonh } 62111992Sache pr_cont("\n"); 62251231Ssheldonh console_loglevel = orig_log_level; 62351231Ssheldonh } 6247238Sache rcu_read_unlock(); 62527365Sjkh rcu_sysrq_end(); 62627365Sjkh 62751231Ssheldonh suppress_printk = orig_suppress_printk; 62864520Sjdp} 62964520Sjdp 63064520Sjdpvoid handle_sysrq(u8 key) 63164520Sjdp{ 63264520Sjdp if (sysrq_on()) 63364520Sjdp __handle_sysrq(key, true); 63438512Sgpalmer} 63551231SsheldonhEXPORT_SYMBOL(handle_sysrq); 63651231Ssheldonh 63739329Sjdp#ifdef CONFIG_INPUT 63850357Ssheldonhstatic int sysrq_reset_downtime_ms; 63951231Ssheldonh 64050357Ssheldonh/* Simple translation table for the SysRq keys */ 64139329Sjdpstatic const unsigned char sysrq_xlate[KEY_CNT] = 64239329Sjdp "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ 64370109Sdougb "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ 64464520Sjdp "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ 64551231Ssheldonh "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ 64651231Ssheldonh "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ 64739329Sjdp "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ 64841648Sjb "\r\000/"; /* 0x60 - 0x6f */ 64990178Snyan 65051231Ssheldonhstruct sysrq_state { 65143951Sjkh struct input_handle handle; 65241648Sjb struct work_struct reinject_work; 65341648Sjb unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; 65450357Ssheldonh unsigned int alt; 65551231Ssheldonh unsigned int alt_use; 65650357Ssheldonh unsigned int shift; 65741648Sjb unsigned int shift_use; 65841648Sjb bool active; 65970109Sdougb bool need_reinject; 66064520Sjdp bool reinjecting; 66151231Ssheldonh 66251231Ssheldonh /* reset sequence handling */ 66338512Sgpalmer bool reset_canceled; 6647296Sjkh bool reset_requested; 66517210Spst unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)]; 66617210Spst int reset_seq_len; 66770109Sdougb int reset_seq_cnt; 66851231Ssheldonh int reset_seq_version; 66951231Ssheldonh struct timer_list keyreset_timer; 67051231Ssheldonh}; 67151231Ssheldonh 67278905Sdd#define SYSRQ_KEY_RESET_MAX 20 /* Should be plenty */ 67351231Ssheldonhstatic unsigned short sysrq_reset_seq[SYSRQ_KEY_RESET_MAX]; 67451231Ssheldonhstatic unsigned int sysrq_reset_seq_len; 67517210Spststatic unsigned int sysrq_reset_seq_version = 1; 67651231Ssheldonh 67751231Ssheldonhstatic void sysrq_parse_reset_sequence(struct sysrq_state *state) 67851231Ssheldonh{ 67951231Ssheldonh int i; 68071340Sdougb unsigned short key; 68151231Ssheldonh 68251231Ssheldonh state->reset_seq_cnt = 0; 68326727Spst 68451231Ssheldonh for (i = 0; i < sysrq_reset_seq_len; i++) { 68551231Ssheldonh key = sysrq_reset_seq[i]; 68651231Ssheldonh 68751231Ssheldonh if (key == KEY_RESERVED || key > KEY_MAX) 68851231Ssheldonh break; 68917210Spst 69057572Smarkm __set_bit(key, state->reset_keybit); 69157572Smarkm state->reset_seq_len++; 69257572Smarkm 69357572Smarkm if (test_bit(key, state->key_down)) 69457572Smarkm state->reset_seq_cnt++; 69557572Smarkm } 69657572Smarkm 69757572Smarkm /* Disable reset until old keys are not released */ 69857572Smarkm state->reset_canceled = state->reset_seq_cnt != 0; 69951231Ssheldonh 70051231Ssheldonh state->reset_seq_version = sysrq_reset_seq_version; 70142498Sn_hibma} 70251231Ssheldonh 70351231Ssheldonhstatic void sysrq_do_reset(struct timer_list *t) 70442498Sn_hibma{ 70590750Scjc struct sysrq_state *state = from_timer(state, t, keyreset_timer); 70690750Scjc 70790750Scjc state->reset_requested = true; 70890750Scjc 70990750Scjc orderly_reboot(); 71090750Scjc} 71190750Scjc 71274198Speterstatic void sysrq_handle_reset_request(struct sysrq_state *state) 71390808Sgshapiro{ 71490750Scjc if (state->reset_requested) 71574198Speter __handle_sysrq(sysrq_xlate[KEY_B], false); 71674198Speter 71790808Sgshapiro if (sysrq_reset_downtime_ms) 71890808Sgshapiro mod_timer(&state->keyreset_timer, 71990808Sgshapiro jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms)); 72090808Sgshapiro else 72190808Sgshapiro sysrq_do_reset(&state->keyreset_timer); 72290808Sgshapiro} 72390750Scjc 72490750Scjcstatic void sysrq_detect_reset_sequence(struct sysrq_state *state, 72574198Speter unsigned int code, int value) 72690808Sgshapiro{ 72790808Sgshapiro if (!test_bit(code, state->reset_keybit)) { 72890808Sgshapiro /* 72990808Sgshapiro * Pressing any key _not_ in reset sequence cancels 73090808Sgshapiro * the reset sequence. Also cancelling the timer in 73190808Sgshapiro * case additional keys were pressed after a reset 73290808Sgshapiro * has been requested. 73390808Sgshapiro */ 73490808Sgshapiro if (value && state->reset_seq_cnt) { 73517161Spst state->reset_canceled = true; 73617161Spst del_timer(&state->keyreset_timer); 73716671Spst } 73850612Simp } else if (value == 0) { 73919314Speter /* 74050357Ssheldonh * Key release - all keys in the reset sequence need 74170109Sdougb * to be pressed and held for the reset timeout 74255511Speter * to hold. 74319314Speter */ 74451231Ssheldonh del_timer(&state->keyreset_timer); 74519314Speter 74619314Speter if (--state->reset_seq_cnt == 0) 74719314Speter state->reset_canceled = false; 74819314Speter } else if (value == 1) { 74919314Speter /* key press, not autorepeat */ 75051231Ssheldonh if (++state->reset_seq_cnt == state->reset_seq_len && 75155451Speter !state->reset_canceled) { 75219314Speter sysrq_handle_reset_request(state); 75316671Spst } 75419314Speter } 75519314Speter} 75619314Speter 75719314Speter#ifdef CONFIG_OF 75850357Ssheldonhstatic void sysrq_of_get_keyreset_config(void) 75955511Speter{ 76019314Speter u32 key; 76151231Ssheldonh struct device_node *np; 76219314Speter struct property *prop; 76319314Speter const __be32 *p; 76419314Speter 76519314Speter np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq"); 76619314Speter if (!np) { 76719314Speter pr_debug("No sysrq node found"); 76855453Speter return; 76951231Ssheldonh } 77055451Speter 77119314Speter /* Reset in case a __weak definition was present */ 77255451Speter sysrq_reset_seq_len = 0; 77319314Speter 77419314Speter of_property_for_each_u32(np, "keyset", prop, p, key) { 77519314Speter if (key == KEY_RESERVED || key > KEY_MAX || 77670109Sdougb sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX) 77716671Spst break; 77816671Spst 77951231Ssheldonh sysrq_reset_seq[sysrq_reset_seq_len++] = (unsigned short)key; 78051231Ssheldonh } 78170109Sdougb 78237899Snectar /* Get reset timeout if any. */ 78337899Snectar of_property_read_u32(np, "timeout-ms", &sysrq_reset_downtime_ms); 78437899Snectar 78551231Ssheldonh of_node_put(np); 78651231Ssheldonh} 78751231Ssheldonh#else 78851231Ssheldonhstatic void sysrq_of_get_keyreset_config(void) 78951231Ssheldonh{ 79050357Ssheldonh} 79150357Ssheldonh#endif 79250357Ssheldonh 79350357Ssheldonhstatic void sysrq_reinject_alt_sysrq(struct work_struct *work) 79449451Speter{ 79549451Speter struct sysrq_state *sysrq = 79650357Ssheldonh container_of(work, struct sysrq_state, reinject_work); 79749451Speter struct input_handle *handle = &sysrq->handle; 79851231Ssheldonh unsigned int alt_code = sysrq->alt_use; 79951231Ssheldonh 80051231Ssheldonh if (sysrq->need_reinject) { 80183956Sobrien /* we do not want the assignment to be reordered */ 80283956Sobrien sysrq->reinjecting = true; 80383956Sobrien mb(); 80483956Sobrien 80583956Sobrien /* Simulate press and release of Alt + SysRq */ 80683956Sobrien input_inject_event(handle, EV_KEY, alt_code, 1); 80751617Snsayer input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); 80851617Snsayer input_inject_event(handle, EV_SYN, SYN_REPORT, 1); 80990178Snyan 81051617Snsayer input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); 81151617Snsayer input_inject_event(handle, EV_KEY, alt_code, 0); 81251617Snsayer input_inject_event(handle, EV_SYN, SYN_REPORT, 1); 81351617Snsayer 81470856Sjhb mb(); 81570856Sjhb sysrq->reinjecting = false; 81670856Sjhb } 81770856Sjhb} 81870856Sjhb 81970856Sjhbstatic bool sysrq_handle_keypress(struct sysrq_state *sysrq, 82070109Sdougb unsigned int code, int value) 82164684Sobrien{ 82271121Sdes bool was_active = sysrq->active; 82371121Sdes bool suppress; 82471121Sdes 82571121Sdes switch (code) { 82671121Sdes 82771121Sdes case KEY_LEFTALT: 82871121Sdes case KEY_RIGHTALT: 82971121Sdes if (!value) { 83071121Sdes /* One of ALTs is being released */ 83171121Sdes if (sysrq->active && code == sysrq->alt_use) 83264684Sobrien sysrq->active = false; 83364684Sobrien 83464684Sobrien sysrq->alt = KEY_RESERVED; 83564684Sobrien 83664809Ssheldonh } else if (value != 2) { 83764809Ssheldonh sysrq->alt = code; 83864809Ssheldonh sysrq->need_reinject = false; 83964809Ssheldonh } 84064809Ssheldonh break; 84164809Ssheldonh 84264809Ssheldonh case KEY_LEFTSHIFT: 84364684Sobrien case KEY_RIGHTSHIFT: 84464684Sobrien if (!value) 84564684Sobrien sysrq->shift = KEY_RESERVED; 84664684Sobrien else if (value != 2) 84764684Sobrien sysrq->shift = code; 84864684Sobrien if (sysrq->active) 84964684Sobrien sysrq->shift_use = sysrq->shift; 85076553Speter break; 85164684Sobrien 85264684Sobrien case KEY_SYSRQ: 85364684Sobrien if (value == 1 && sysrq->alt != KEY_RESERVED) { 85470109Sdougb sysrq->active = true; 85564810Ssheldonh sysrq->alt_use = sysrq->alt; 85641704Sdillon /* either RESERVED (for released) or actual code */ 85743951Sjkh sysrq->shift_use = sysrq->shift; 85843951Sjkh /* 85943951Sjkh * If nothing else will be pressed we'll need 86041704Sdillon * to re-inject Alt-SysRq keysroke. 86141704Sdillon */ 86251231Ssheldonh sysrq->need_reinject = true; 86351231Ssheldonh } 86451231Ssheldonh 86559674Ssheldonh /* 86659674Ssheldonh * Pretend that sysrq was never pressed at all. This 86759674Ssheldonh * is needed to properly handle KGDB which will try 86851231Ssheldonh * to release all keys after exiting debugger. If we 86951231Ssheldonh * do not clear key bit it KGDB will end up sending 87051231Ssheldonh * release events for Alt and SysRq, potentially 87151231Ssheldonh * triggering print screen function. 87251231Ssheldonh */ 87351231Ssheldonh if (sysrq->active) 87470109Sdougb clear_bit(KEY_SYSRQ, sysrq->handle.dev->key); 87551231Ssheldonh 87643197Sdillon break; 87741704Sdillon 87841704Sdillon default: 87951617Snsayer if (sysrq->active && value && value != 2) { 88051617Snsayer unsigned char c = sysrq_xlate[code]; 88151617Snsayer 88251617Snsayer sysrq->need_reinject = false; 88351617Snsayer if (sysrq->shift_use != KEY_RESERVED) 88451617Snsayer c = toupper(c); 88551617Snsayer __handle_sysrq(c, true); 88679825Sroam } 88787728Sroam break; 88887728Sroam } 88987728Sroam 89051617Snsayer suppress = sysrq->active; 89151617Snsayer 89251617Snsayer if (!sysrq->active) { 89379825Sroam 89451617Snsayer /* 89551617Snsayer * See if reset sequence has changed since the last time. 89651617Snsayer */ 89779825Sroam if (sysrq->reset_seq_version != sysrq_reset_seq_version) 89879825Sroam sysrq_parse_reset_sequence(sysrq); 89979825Sroam 90079825Sroam /* 90179825Sroam * If we are not suppressing key presses keep track of 90279825Sroam * keyboard state so we can release keys that have been 90383897Sobrien * pressed before entering SysRq mode. 90484370Sru */ 90584332Sobrien if (value) 90679825Sroam set_bit(code, sysrq->key_down); 90779825Sroam else 90879825Sroam clear_bit(code, sysrq->key_down); 90970109Sdougb 91051617Snsayer if (was_active) 91151617Snsayer schedule_work(&sysrq->reinject_work); 91251617Snsayer 91353314Sache /* Check for reset sequence */ 91453314Sache sysrq_detect_reset_sequence(sysrq, code, value); 91553314Sache 91653314Sache } else if (value == 0 && test_and_clear_bit(code, sysrq->key_down)) { 91737106Sjkoshy /* 91837106Sjkoshy * Pass on release events for keys that was pressed before 91951231Ssheldonh * entering SysRq mode. 92051231Ssheldonh */ 92151231Ssheldonh suppress = false; 92251231Ssheldonh } 92370109Sdougb 92487646Sru return suppress; 92551231Ssheldonh} 92651231Ssheldonh 92751231Ssheldonhstatic bool sysrq_filter(struct input_handle *handle, 92837106Sjkoshy unsigned int type, unsigned int code, int value) 92976946Sdd{ 93076946Sdd struct sysrq_state *sysrq = handle->private; 93176946Sdd bool suppress; 93276946Sdd 93376946Sdd /* 93476946Sdd * Do not filter anything if we are in the process of re-injecting 93576946Sdd * Alt+SysRq combination. 93676460Smckusick */ 93770109Sdougb if (sysrq->reinjecting) 93870109Sdougb return false; 93937Srgrimes 94070109Sdougb switch (type) { 94137Srgrimes 94270109Sdougb case EV_SYN: 943 suppress = false; 944 break; 945 946 case EV_KEY: 947 suppress = sysrq_handle_keypress(sysrq, code, value); 948 break; 949 950 default: 951 suppress = sysrq->active; 952 break; 953 } 954 955 return suppress; 956} 957 958static int sysrq_connect(struct input_handler *handler, 959 struct input_dev *dev, 960 const struct input_device_id *id) 961{ 962 struct sysrq_state *sysrq; 963 int error; 964 965 sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL); 966 if (!sysrq) 967 return -ENOMEM; 968 969 INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq); 970 971 sysrq->handle.dev = dev; 972 sysrq->handle.handler = handler; 973 sysrq->handle.name = "sysrq"; 974 sysrq->handle.private = sysrq; 975 timer_setup(&sysrq->keyreset_timer, sysrq_do_reset, 0); 976 977 error = input_register_handle(&sysrq->handle); 978 if (error) { 979 pr_err("Failed to register input sysrq handler, error %d\n", 980 error); 981 goto err_free; 982 } 983 984 error = input_open_device(&sysrq->handle); 985 if (error) { 986 pr_err("Failed to open input device, error %d\n", error); 987 goto err_unregister; 988 } 989 990 return 0; 991 992 err_unregister: 993 input_unregister_handle(&sysrq->handle); 994 err_free: 995 kfree(sysrq); 996 return error; 997} 998 999static void sysrq_disconnect(struct input_handle *handle) 1000{ 1001 struct sysrq_state *sysrq = handle->private; 1002 1003 input_close_device(handle); 1004 cancel_work_sync(&sysrq->reinject_work); 1005 timer_shutdown_sync(&sysrq->keyreset_timer); 1006 input_unregister_handle(handle); 1007 kfree(sysrq); 1008} 1009 1010/* 1011 * We are matching on KEY_LEFTALT instead of KEY_SYSRQ because not all 1012 * keyboards have SysRq key predefined and so user may add it to keymap 1013 * later, but we expect all such keyboards to have left alt. 1014 */ 1015static const struct input_device_id sysrq_ids[] = { 1016 { 1017 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | 1018 INPUT_DEVICE_ID_MATCH_KEYBIT, 1019 .evbit = { [BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY) }, 1020 .keybit = { [BIT_WORD(KEY_LEFTALT)] = BIT_MASK(KEY_LEFTALT) }, 1021 }, 1022 { }, 1023}; 1024 1025static struct input_handler sysrq_handler = { 1026 .filter = sysrq_filter, 1027 .connect = sysrq_connect, 1028 .disconnect = sysrq_disconnect, 1029 .name = "sysrq", 1030 .id_table = sysrq_ids, 1031}; 1032 1033static inline void sysrq_register_handler(void) 1034{ 1035 int error; 1036 1037 sysrq_of_get_keyreset_config(); 1038 1039 error = input_register_handler(&sysrq_handler); 1040 if (error) 1041 pr_err("Failed to register input handler, error %d", error); 1042} 1043 1044static inline void sysrq_unregister_handler(void) 1045{ 1046 input_unregister_handler(&sysrq_handler); 1047} 1048 1049static int sysrq_reset_seq_param_set(const char *buffer, 1050 const struct kernel_param *kp) 1051{ 1052 unsigned long val; 1053 int error; 1054 1055 error = kstrtoul(buffer, 0, &val); 1056 if (error < 0) 1057 return error; 1058 1059 if (val > KEY_MAX) 1060 return -EINVAL; 1061 1062 *((unsigned short *)kp->arg) = val; 1063 sysrq_reset_seq_version++; 1064 1065 return 0; 1066} 1067 1068static const struct kernel_param_ops param_ops_sysrq_reset_seq = { 1069 .get = param_get_ushort, 1070 .set = sysrq_reset_seq_param_set, 1071}; 1072 1073#define param_check_sysrq_reset_seq(name, p) \ 1074 __param_check(name, p, unsigned short) 1075 1076/* 1077 * not really modular, but the easiest way to keep compat with existing 1078 * bootargs behaviour is to continue using module_param here. 1079 */ 1080module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq, 1081 &sysrq_reset_seq_len, 0644); 1082 1083module_param_named(sysrq_downtime_ms, sysrq_reset_downtime_ms, int, 0644); 1084 1085#else 1086 1087static inline void sysrq_register_handler(void) 1088{ 1089} 1090 1091static inline void sysrq_unregister_handler(void) 1092{ 1093} 1094 1095#endif /* CONFIG_INPUT */ 1096 1097int sysrq_toggle_support(int enable_mask) 1098{ 1099 bool was_enabled = sysrq_on(); 1100 1101 sysrq_enabled = enable_mask; 1102 1103 if (was_enabled != sysrq_on()) { 1104 if (sysrq_on()) 1105 sysrq_register_handler(); 1106 else 1107 sysrq_unregister_handler(); 1108 } 1109 1110 return 0; 1111} 1112EXPORT_SYMBOL_GPL(sysrq_toggle_support); 1113 1114static int __sysrq_swap_key_ops(u8 key, const struct sysrq_key_op *insert_op_p, 1115 const struct sysrq_key_op *remove_op_p) 1116{ 1117 int retval; 1118 1119 spin_lock(&sysrq_key_table_lock); 1120 if (__sysrq_get_key_op(key) == remove_op_p) { 1121 __sysrq_put_key_op(key, insert_op_p); 1122 retval = 0; 1123 } else { 1124 retval = -1; 1125 } 1126 spin_unlock(&sysrq_key_table_lock); 1127 1128 /* 1129 * A concurrent __handle_sysrq either got the old op or the new op. 1130 * Wait for it to go away before returning, so the code for an old 1131 * op is not freed (eg. on module unload) while it is in use. 1132 */ 1133 synchronize_rcu(); 1134 1135 return retval; 1136} 1137 1138int register_sysrq_key(u8 key, const struct sysrq_key_op *op_p) 1139{ 1140 return __sysrq_swap_key_ops(key, op_p, NULL); 1141} 1142EXPORT_SYMBOL(register_sysrq_key); 1143 1144int unregister_sysrq_key(u8 key, const struct sysrq_key_op *op_p) 1145{ 1146 return __sysrq_swap_key_ops(key, NULL, op_p); 1147} 1148EXPORT_SYMBOL(unregister_sysrq_key); 1149 1150#ifdef CONFIG_PROC_FS 1151/* 1152 * writing 'C' to /proc/sysrq-trigger is like sysrq-C 1153 * Normally, only the first character written is processed. 1154 * However, if the first character is an underscore, 1155 * all characters are processed. 1156 */ 1157static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, 1158 size_t count, loff_t *ppos) 1159{ 1160 bool bulk = false; 1161 size_t i; 1162 1163 for (i = 0; i < count; i++) { 1164 char c; 1165 1166 if (get_user(c, buf + i)) 1167 return -EFAULT; 1168 1169 if (c == '_') 1170 bulk = true; 1171 else 1172 __handle_sysrq(c, false); 1173 1174 if (!bulk) 1175 break; 1176 } 1177 1178 return count; 1179} 1180 1181static const struct proc_ops sysrq_trigger_proc_ops = { 1182 .proc_write = write_sysrq_trigger, 1183 .proc_lseek = noop_llseek, 1184}; 1185 1186static void sysrq_init_procfs(void) 1187{ 1188 if (!proc_create("sysrq-trigger", S_IWUSR, NULL, 1189 &sysrq_trigger_proc_ops)) 1190 pr_err("Failed to register proc interface\n"); 1191} 1192 1193#else 1194 1195static inline void sysrq_init_procfs(void) 1196{ 1197} 1198 1199#endif /* CONFIG_PROC_FS */ 1200 1201static int __init sysrq_init(void) 1202{ 1203 sysrq_init_procfs(); 1204 1205 if (sysrq_on()) 1206 sysrq_register_handler(); 1207 1208 return 0; 1209} 1210device_initcall(sysrq_init); 1211