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() */
35 #include <linux/spinlock.h>
37 #include <asm/ptrace.h>
39 extern void reset_vc(unsigned int);
40 extern struct list_head super_blocks
;
42 /* Whether we react on sysrq keys or just ignore them */
43 int sysrq_enabled
= 1;
45 /* Machine specific power off function */
46 void (*sysrq_power_off
)(void);
48 /* Loglevel sysrq handler */
49 static void sysrq_handle_loglevel(int key
, struct pt_regs
*pt_regs
,
50 struct tty_struct
*tty
)
55 printk("Loglevel set to %d\n", i
);
58 static struct sysrq_key_op sysrq_loglevel_op
= {
59 .handler
= sysrq_handle_loglevel
,
60 .help_msg
= "loglevel0-8",
61 .action_msg
= "Changing Loglevel",
65 /* SAK sysrq handler */
67 static void sysrq_handle_SAK(int key
, struct pt_regs
*pt_regs
,
68 struct tty_struct
*tty
)
74 static struct sysrq_key_op sysrq_SAK_op
= {
75 .handler
= sysrq_handle_SAK
,
82 /* unraw sysrq handler */
83 static void sysrq_handle_unraw(int key
, struct pt_regs
*pt_regs
,
84 struct tty_struct
*tty
)
86 struct kbd_struct
*kbd
= &kbd_table
[fg_console
];
89 kbd
->kbdmode
= VC_XLATE
;
91 static struct sysrq_key_op sysrq_unraw_op
= {
92 .handler
= sysrq_handle_unraw
,
94 .action_msg
= "Keyboard mode set to XLATE",
96 #endif /* CONFIG_VT */
98 /* reboot sysrq handler */
99 static void sysrq_handle_reboot(int key
, struct pt_regs
*pt_regs
,
100 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",
111 static void sysrq_handle_sync(int key
, struct pt_regs
*pt_regs
,
112 struct tty_struct
*tty
)
117 static struct sysrq_key_op sysrq_sync_op
= {
118 .handler
= sysrq_handle_sync
,
120 .action_msg
= "Emergency Sync",
123 static void sysrq_handle_mountro(int key
, struct pt_regs
*pt_regs
,
124 struct tty_struct
*tty
)
129 static struct sysrq_key_op sysrq_mountro_op
= {
130 .handler
= sysrq_handle_mountro
,
131 .help_msg
= "Unmount",
132 .action_msg
= "Emergency Remount R/O",
135 /* END SYNC SYSRQ HANDLERS BLOCK */
138 /* SHOW SYSRQ HANDLERS BLOCK */
140 static void sysrq_handle_showregs(int key
, struct pt_regs
*pt_regs
,
141 struct tty_struct
*tty
)
146 static struct sysrq_key_op sysrq_showregs_op
= {
147 .handler
= sysrq_handle_showregs
,
148 .help_msg
= "showPc",
149 .action_msg
= "Show Regs",
153 static void sysrq_handle_showstate(int key
, struct pt_regs
*pt_regs
,
154 struct tty_struct
*tty
)
158 static struct sysrq_key_op sysrq_showstate_op
= {
159 .handler
= sysrq_handle_showstate
,
160 .help_msg
= "showTasks",
161 .action_msg
= "Show State",
165 static void sysrq_handle_showmem(int key
, struct pt_regs
*pt_regs
,
166 struct tty_struct
*tty
)
170 static struct sysrq_key_op sysrq_showmem_op
= {
171 .handler
= sysrq_handle_showmem
,
172 .help_msg
= "showMem",
173 .action_msg
= "Show Memory",
176 /* SHOW SYSRQ HANDLERS BLOCK */
179 /* SIGNAL SYSRQ HANDLERS BLOCK */
181 /* signal sysrq helper function
182 * Sends a signal to all user processes */
183 static void send_sig_all(int sig
)
185 struct task_struct
*p
;
187 for_each_process(p
) {
188 if (p
->mm
&& p
->pid
!= 1)
189 /* Not swapper, init nor kernel thread */
194 static void sysrq_handle_term(int key
, struct pt_regs
*pt_regs
,
195 struct tty_struct
*tty
)
197 send_sig_all(SIGTERM
);
198 console_loglevel
= 8;
200 static struct sysrq_key_op sysrq_term_op
= {
201 .handler
= sysrq_handle_term
,
203 .action_msg
= "Terminate All Tasks",
206 static void sysrq_handle_kill(int key
, struct pt_regs
*pt_regs
,
207 struct tty_struct
*tty
)
209 send_sig_all(SIGKILL
);
210 console_loglevel
= 8;
212 static struct sysrq_key_op sysrq_kill_op
= {
213 .handler
= sysrq_handle_kill
,
215 .action_msg
= "Kill All Tasks",
218 /* END SIGNAL SYSRQ HANDLERS BLOCK */
221 /* Key Operations table and lock */
222 static spinlock_t sysrq_key_table_lock
= SPIN_LOCK_UNLOCKED
;
223 #define SYSRQ_KEY_TABLE_LENGTH 36
224 static struct sysrq_key_op
*sysrq_key_table
[SYSRQ_KEY_TABLE_LENGTH
] = {
225 /* 0 */ &sysrq_loglevel_op
,
226 /* 1 */ &sysrq_loglevel_op
,
227 /* 2 */ &sysrq_loglevel_op
,
228 /* 3 */ &sysrq_loglevel_op
,
229 /* 4 */ &sysrq_loglevel_op
,
230 /* 5 */ &sysrq_loglevel_op
,
231 /* 6 */ &sysrq_loglevel_op
,
232 /* 7 */ &sysrq_loglevel_op
,
233 /* 8 */ &sysrq_loglevel_op
,
234 /* 9 */ &sysrq_loglevel_op
,
235 /* a */ NULL
, /* Don't use for system provided sysrqs,
236 it is handled specially on the sparc
237 and will never arrive */
238 /* b */ &sysrq_reboot_op
,
241 /* e */ &sysrq_term_op
,
245 /* i */ &sysrq_kill_op
,
248 /* k */ &sysrq_SAK_op
,
253 /* m */ &sysrq_showmem_op
,
255 /* o */ NULL
, /* This will often be registered
256 as 'Off' at init time */
257 /* p */ &sysrq_showregs_op
,
260 /* r */ &sysrq_unraw_op
,
264 /* s */ &sysrq_sync_op
,
265 /* t */ &sysrq_showstate_op
,
266 /* u */ &sysrq_mountro_op
,
267 /* v */ NULL
, /* May be assigned at init time by SMP VOYAGER */
274 /* key2index calculation, -1 on invalid index */
275 static __inline__
int sysrq_key_table_key2index(int key
) {
277 if ((key
>= '0') & (key
<= '9')) {
279 } else if ((key
>= 'a') & (key
<= 'z')) {
280 retval
= key
+ 10 - 'a';
288 * table lock and unlocking functions, exposed to modules
291 void __sysrq_lock_table (void) { spin_lock(&sysrq_key_table_lock
); }
293 void __sysrq_unlock_table (void) { spin_unlock(&sysrq_key_table_lock
); }
296 * get and put functions for the table, exposed to modules.
299 struct sysrq_key_op
*__sysrq_get_key_op (int key
) {
300 struct sysrq_key_op
*op_p
;
303 i
= sysrq_key_table_key2index(key
);
304 op_p
= (i
== -1) ? NULL
: sysrq_key_table
[i
];
308 void __sysrq_put_key_op (int key
, struct sysrq_key_op
*op_p
) {
311 i
= sysrq_key_table_key2index(key
);
313 sysrq_key_table
[i
] = op_p
;
317 * This function is called by the keyboard handler when SysRq is pressed
318 * and any other keycode arrives.
321 void handle_sysrq(int key
, struct pt_regs
*pt_regs
, struct tty_struct
*tty
)
326 __sysrq_lock_table();
327 __handle_sysrq_nolock(key
, pt_regs
, tty
);
328 __sysrq_unlock_table();
332 * This is the non-locking version of handle_sysrq
333 * It must/can only be called by sysrq key handlers,
334 * as they are inside of the lock
337 void __handle_sysrq_nolock(int key
, struct pt_regs
*pt_regs
,
338 struct tty_struct
*tty
)
340 struct sysrq_key_op
*op_p
;
347 orig_log_level
= console_loglevel
;
348 console_loglevel
= 7;
349 printk(KERN_INFO
"SysRq : ");
351 op_p
= __sysrq_get_key_op(key
);
353 printk ("%s\n", op_p
->action_msg
);
354 console_loglevel
= orig_log_level
;
355 op_p
->handler(key
, pt_regs
, tty
);
358 /* Only print the help msg once per handler */
359 for (i
=0; i
<SYSRQ_KEY_TABLE_LENGTH
; i
++)
360 if (sysrq_key_table
[i
]) {
361 for (j
=0; sysrq_key_table
[i
] != sysrq_key_table
[j
]; j
++);
363 printk ("%s ", sysrq_key_table
[i
]->help_msg
);
366 console_loglevel
= orig_log_level
;
370 EXPORT_SYMBOL(handle_sysrq
);
371 EXPORT_SYMBOL(__handle_sysrq_nolock
);
372 EXPORT_SYMBOL(__sysrq_lock_table
);
373 EXPORT_SYMBOL(__sysrq_unlock_table
);
374 EXPORT_SYMBOL(__sysrq_get_key_op
);
375 EXPORT_SYMBOL(__sysrq_put_key_op
);