3 * $Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $
5 * Linux Magic System Request Key Hacks
7 * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8 * based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
10 * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
11 * overhauled to use key registration
12 * based upon discusions in irc://irc.openprojects.net/#kernelnewbies
15 #include <linux/config.h>
16 #include <linux/sched.h>
17 #include <linux/interrupt.h>
20 #include <linux/tty.h>
21 #include <linux/mount.h>
22 #include <linux/kdev_t.h>
23 #include <linux/major.h>
24 #include <linux/reboot.h>
25 #include <linux/sysrq.h>
26 #include <linux/kbd_kern.h>
27 #include <linux/quotaops.h>
28 #include <linux/smp_lock.h>
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/suspend.h>
32 #include <linux/writeback.h>
33 #include <linux/buffer_head.h> /* for fsync_bdev() */
34 #include <linux/swap.h>
35 #include <linux/spinlock.h>
36 #include <linux/vt_kern.h>
37 #include <linux/workqueue.h>
39 #include <asm/ptrace.h>
41 /* Whether we react on sysrq keys or just ignore them */
42 int sysrq_enabled
= 1;
44 /* Loglevel sysrq handler */
45 static void sysrq_handle_loglevel(int key
, struct pt_regs
*pt_regs
,
46 struct tty_struct
*tty
)
51 printk("Loglevel set to %d\n", i
);
54 static struct sysrq_key_op sysrq_loglevel_op
= {
55 .handler
= sysrq_handle_loglevel
,
56 .help_msg
= "loglevel0-8",
57 .action_msg
= "Changing Loglevel",
58 .enable_mask
= SYSRQ_ENABLE_LOG
,
62 /* SAK sysrq handler */
64 static void sysrq_handle_SAK(int key
, struct pt_regs
*pt_regs
,
65 struct tty_struct
*tty
)
69 reset_vc(vc_cons
[fg_console
].d
);
71 static struct sysrq_key_op sysrq_SAK_op
= {
72 .handler
= sysrq_handle_SAK
,
75 .enable_mask
= SYSRQ_ENABLE_KEYBOARD
,
80 /* unraw sysrq handler */
81 static void sysrq_handle_unraw(int key
, struct pt_regs
*pt_regs
,
82 struct tty_struct
*tty
)
84 struct kbd_struct
*kbd
= &kbd_table
[fg_console
];
87 kbd
->kbdmode
= VC_XLATE
;
89 static struct sysrq_key_op sysrq_unraw_op
= {
90 .handler
= sysrq_handle_unraw
,
92 .action_msg
= "Keyboard mode set to XLATE",
93 .enable_mask
= SYSRQ_ENABLE_KEYBOARD
,
95 #endif /* CONFIG_VT */
97 /* reboot sysrq handler */
98 static void sysrq_handle_reboot(int key
, struct pt_regs
*pt_regs
,
99 struct tty_struct
*tty
)
102 machine_restart(NULL
);
105 static struct sysrq_key_op sysrq_reboot_op
= {
106 .handler
= sysrq_handle_reboot
,
107 .help_msg
= "reBoot",
108 .action_msg
= "Resetting",
109 .enable_mask
= SYSRQ_ENABLE_BOOT
,
112 static void sysrq_handle_sync(int key
, struct pt_regs
*pt_regs
,
113 struct tty_struct
*tty
)
118 static struct sysrq_key_op sysrq_sync_op
= {
119 .handler
= sysrq_handle_sync
,
121 .action_msg
= "Emergency Sync",
122 .enable_mask
= SYSRQ_ENABLE_SYNC
,
125 static void sysrq_handle_mountro(int key
, struct pt_regs
*pt_regs
,
126 struct tty_struct
*tty
)
131 static struct sysrq_key_op sysrq_mountro_op
= {
132 .handler
= sysrq_handle_mountro
,
133 .help_msg
= "Unmount",
134 .action_msg
= "Emergency Remount R/O",
135 .enable_mask
= SYSRQ_ENABLE_REMOUNT
,
138 /* END SYNC SYSRQ HANDLERS BLOCK */
141 /* SHOW SYSRQ HANDLERS BLOCK */
143 static void sysrq_handle_showregs(int key
, struct pt_regs
*pt_regs
,
144 struct tty_struct
*tty
)
149 static struct sysrq_key_op sysrq_showregs_op
= {
150 .handler
= sysrq_handle_showregs
,
151 .help_msg
= "showPc",
152 .action_msg
= "Show Regs",
153 .enable_mask
= SYSRQ_ENABLE_DUMP
,
157 static void sysrq_handle_showstate(int key
, struct pt_regs
*pt_regs
,
158 struct tty_struct
*tty
)
162 static struct sysrq_key_op sysrq_showstate_op
= {
163 .handler
= sysrq_handle_showstate
,
164 .help_msg
= "showTasks",
165 .action_msg
= "Show State",
166 .enable_mask
= SYSRQ_ENABLE_DUMP
,
170 static void sysrq_handle_showmem(int key
, struct pt_regs
*pt_regs
,
171 struct tty_struct
*tty
)
175 static struct sysrq_key_op sysrq_showmem_op
= {
176 .handler
= sysrq_handle_showmem
,
177 .help_msg
= "showMem",
178 .action_msg
= "Show Memory",
179 .enable_mask
= SYSRQ_ENABLE_DUMP
,
182 /* SHOW SYSRQ HANDLERS BLOCK */
185 /* SIGNAL SYSRQ HANDLERS BLOCK */
187 /* signal sysrq helper function
188 * Sends a signal to all user processes */
189 static void send_sig_all(int sig
)
191 struct task_struct
*p
;
193 for_each_process(p
) {
194 if (p
->mm
&& p
->pid
!= 1)
195 /* Not swapper, init nor kernel thread */
200 static void sysrq_handle_term(int key
, struct pt_regs
*pt_regs
,
201 struct tty_struct
*tty
)
203 send_sig_all(SIGTERM
);
204 console_loglevel
= 8;
206 static struct sysrq_key_op sysrq_term_op
= {
207 .handler
= sysrq_handle_term
,
209 .action_msg
= "Terminate All Tasks",
210 .enable_mask
= SYSRQ_ENABLE_SIGNAL
,
213 static void moom_callback(void *ignored
)
215 out_of_memory(GFP_KERNEL
);
218 static DECLARE_WORK(moom_work
, moom_callback
, NULL
);
220 static void sysrq_handle_moom(int key
, struct pt_regs
*pt_regs
,
221 struct tty_struct
*tty
)
223 schedule_work(&moom_work
);
225 static struct sysrq_key_op sysrq_moom_op
= {
226 .handler
= sysrq_handle_moom
,
228 .action_msg
= "Manual OOM execution",
231 static void sysrq_handle_kill(int key
, struct pt_regs
*pt_regs
,
232 struct tty_struct
*tty
)
234 send_sig_all(SIGKILL
);
235 console_loglevel
= 8;
237 static struct sysrq_key_op sysrq_kill_op
= {
238 .handler
= sysrq_handle_kill
,
240 .action_msg
= "Kill All Tasks",
241 .enable_mask
= SYSRQ_ENABLE_SIGNAL
,
244 /* END SIGNAL SYSRQ HANDLERS BLOCK */
246 static void sysrq_handle_unrt(int key
, struct pt_regs
*pt_regs
,
247 struct tty_struct
*tty
)
249 normalize_rt_tasks();
251 static struct sysrq_key_op sysrq_unrt_op
= {
252 .handler
= sysrq_handle_unrt
,
254 .action_msg
= "Nice All RT Tasks",
255 .enable_mask
= SYSRQ_ENABLE_RTNICE
,
258 /* Key Operations table and lock */
259 static DEFINE_SPINLOCK(sysrq_key_table_lock
);
260 #define SYSRQ_KEY_TABLE_LENGTH 36
261 static struct sysrq_key_op
*sysrq_key_table
[SYSRQ_KEY_TABLE_LENGTH
] = {
262 /* 0 */ &sysrq_loglevel_op
,
263 /* 1 */ &sysrq_loglevel_op
,
264 /* 2 */ &sysrq_loglevel_op
,
265 /* 3 */ &sysrq_loglevel_op
,
266 /* 4 */ &sysrq_loglevel_op
,
267 /* 5 */ &sysrq_loglevel_op
,
268 /* 6 */ &sysrq_loglevel_op
,
269 /* 7 */ &sysrq_loglevel_op
,
270 /* 8 */ &sysrq_loglevel_op
,
271 /* 9 */ &sysrq_loglevel_op
,
272 /* a */ NULL
, /* Don't use for system provided sysrqs,
273 it is handled specially on the sparc
274 and will never arrive */
275 /* b */ &sysrq_reboot_op
,
278 /* e */ &sysrq_term_op
,
279 /* f */ &sysrq_moom_op
,
282 /* i */ &sysrq_kill_op
,
285 /* k */ &sysrq_SAK_op
,
290 /* m */ &sysrq_showmem_op
,
291 /* n */ &sysrq_unrt_op
,
292 /* o */ NULL
, /* This will often be registered
293 as 'Off' at init time */
294 /* p */ &sysrq_showregs_op
,
297 /* r */ &sysrq_unraw_op
,
301 /* s */ &sysrq_sync_op
,
302 /* t */ &sysrq_showstate_op
,
303 /* u */ &sysrq_mountro_op
,
304 /* v */ NULL
, /* May be assigned at init time by SMP VOYAGER */
311 /* key2index calculation, -1 on invalid index */
312 static int sysrq_key_table_key2index(int key
) {
314 if ((key
>= '0') && (key
<= '9')) {
316 } else if ((key
>= 'a') && (key
<= 'z')) {
317 retval
= key
+ 10 - 'a';
325 * get and put functions for the table, exposed to modules.
328 struct sysrq_key_op
*__sysrq_get_key_op (int key
) {
329 struct sysrq_key_op
*op_p
;
332 i
= sysrq_key_table_key2index(key
);
333 op_p
= (i
== -1) ? NULL
: sysrq_key_table
[i
];
337 void __sysrq_put_key_op (int key
, struct sysrq_key_op
*op_p
) {
340 i
= sysrq_key_table_key2index(key
);
342 sysrq_key_table
[i
] = op_p
;
346 * This is the non-locking version of handle_sysrq
347 * It must/can only be called by sysrq key handlers,
348 * as they are inside of the lock
351 void __handle_sysrq(int key
, struct pt_regs
*pt_regs
, struct tty_struct
*tty
, int check_mask
)
353 struct sysrq_key_op
*op_p
;
358 spin_lock_irqsave(&sysrq_key_table_lock
, flags
);
359 orig_log_level
= console_loglevel
;
360 console_loglevel
= 7;
361 printk(KERN_INFO
"SysRq : ");
363 op_p
= __sysrq_get_key_op(key
);
365 /* Should we check for enabled operations (/proc/sysrq-trigger should not)
366 * and is the invoked operation enabled? */
367 if (!check_mask
|| sysrq_enabled
== 1 ||
368 (sysrq_enabled
& op_p
->enable_mask
)) {
369 printk ("%s\n", op_p
->action_msg
);
370 console_loglevel
= orig_log_level
;
371 op_p
->handler(key
, pt_regs
, tty
);
374 printk("This sysrq operation is disabled.\n");
377 /* Only print the help msg once per handler */
378 for (i
=0; i
<SYSRQ_KEY_TABLE_LENGTH
; i
++)
379 if (sysrq_key_table
[i
]) {
380 for (j
=0; sysrq_key_table
[i
] != sysrq_key_table
[j
]; j
++);
382 printk ("%s ", sysrq_key_table
[i
]->help_msg
);
385 console_loglevel
= orig_log_level
;
387 spin_unlock_irqrestore(&sysrq_key_table_lock
, flags
);
391 * This function is called by the keyboard handler when SysRq is pressed
392 * and any other keycode arrives.
395 void handle_sysrq(int key
, struct pt_regs
*pt_regs
, struct tty_struct
*tty
)
399 __handle_sysrq(key
, pt_regs
, tty
, 1);
402 int __sysrq_swap_key_ops(int key
, struct sysrq_key_op
*insert_op_p
,
403 struct sysrq_key_op
*remove_op_p
) {
408 spin_lock_irqsave(&sysrq_key_table_lock
, flags
);
409 if (__sysrq_get_key_op(key
) == remove_op_p
) {
410 __sysrq_put_key_op(key
, insert_op_p
);
415 spin_unlock_irqrestore(&sysrq_key_table_lock
, flags
);
420 int register_sysrq_key(int key
, struct sysrq_key_op
*op_p
)
422 return __sysrq_swap_key_ops(key
, op_p
, NULL
);
425 int unregister_sysrq_key(int key
, struct sysrq_key_op
*op_p
)
427 return __sysrq_swap_key_ops(key
, NULL
, op_p
);
430 EXPORT_SYMBOL(handle_sysrq
);
431 EXPORT_SYMBOL(register_sysrq_key
);
432 EXPORT_SYMBOL(unregister_sysrq_key
);