Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / char / sysrq.c
1 /* -*- linux-c -*-
2  *
3  *      $Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $
4  *
5  *      Linux Magic System Request Key Hacks
6  *
7  *      (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
8  *      based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
9  *
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
13  */
14
15 #include <linux/sched.h>
16 #include <linux/interrupt.h>
17 #include <linux/mm.h>
18 #include <linux/fs.h>
19 #include <linux/tty.h>
20 #include <linux/mount.h>
21 #include <linux/kdev_t.h>
22 #include <linux/major.h>
23 #include <linux/reboot.h>
24 #include <linux/sysrq.h>
25 #include <linux/kbd_kern.h>
26 #include <linux/quotaops.h>
27 #include <linux/smp_lock.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/suspend.h>
31 #include <linux/writeback.h>
32 #include <linux/buffer_head.h>          /* for fsync_bdev() */
33 #include <linux/swap.h>
34 #include <linux/spinlock.h>
35 #include <linux/vt_kern.h>
36 #include <linux/workqueue.h>
37 #include <linux/kexec.h>
38
39 #include <asm/ptrace.h>
40
41 /* Whether we react on sysrq keys or just ignore them */
42 int sysrq_enabled = 1;
43
44 static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs,
45                                   struct tty_struct *tty)
46 {
47         int i;
48         i = key - '0';
49         console_loglevel = 7;
50         printk("Loglevel set to %d\n", i);
51         console_loglevel = i;
52 }
53 static struct sysrq_key_op sysrq_loglevel_op = {
54         .handler        = sysrq_handle_loglevel,
55         .help_msg       = "loglevel0-8",
56         .action_msg     = "Changing Loglevel",
57         .enable_mask    = SYSRQ_ENABLE_LOG,
58 };
59
60 #ifdef CONFIG_VT
61 static void sysrq_handle_SAK(int key, struct pt_regs *pt_regs,
62                              struct tty_struct *tty)
63 {
64         if (tty)
65                 do_SAK(tty);
66         reset_vc(vc_cons[fg_console].d);
67 }
68 static struct sysrq_key_op sysrq_SAK_op = {
69         .handler        = sysrq_handle_SAK,
70         .help_msg       = "saK",
71         .action_msg     = "SAK",
72         .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
73 };
74 #else
75 #define sysrq_SAK_op (*(struct sysrq_key_op *)0)
76 #endif
77
78 #ifdef CONFIG_VT
79 static void sysrq_handle_unraw(int key, struct pt_regs *pt_regs,
80                                struct tty_struct *tty)
81 {
82         struct kbd_struct *kbd = &kbd_table[fg_console];
83
84         if (kbd)
85                 kbd->kbdmode = VC_XLATE;
86 }
87 static struct sysrq_key_op sysrq_unraw_op = {
88         .handler        = sysrq_handle_unraw,
89         .help_msg       = "unRaw",
90         .action_msg     = "Keyboard mode set to XLATE",
91         .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
92 };
93 #else
94 #define sysrq_unraw_op (*(struct sysrq_key_op *)0)
95 #endif /* CONFIG_VT */
96
97 static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
98                                 struct tty_struct *tty)
99 {
100 #ifdef CONFIG_KEXEC
101         crash_kexec(pt_regs);
102         /* can't get here if crash image is loaded */
103         printk("Kexec: Warning: crash image not loaded\n");
104 #endif
105         if(panic_on_oops)
106                 panic("SysRq-triggered panic!\n");
107 }
108 static struct sysrq_key_op sysrq_crashdump_op = {
109         .handler        = sysrq_handle_crashdump,
110         .help_msg       = "Crashdump",
111         .action_msg     = "Trigger a crashdump",
112         .enable_mask    = SYSRQ_ENABLE_DUMP,
113 };
114
115 static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
116                                 struct tty_struct *tty)
117 {
118         lockdep_off();
119         local_irq_enable();
120         emergency_restart();
121 }
122 static struct sysrq_key_op sysrq_reboot_op = {
123         .handler        = sysrq_handle_reboot,
124         .help_msg       = "reBoot",
125         .action_msg     = "Resetting",
126         .enable_mask    = SYSRQ_ENABLE_BOOT,
127 };
128
129 static void sysrq_handle_sync(int key, struct pt_regs *pt_regs,
130                               struct tty_struct *tty)
131 {
132         emergency_sync();
133 }
134 static struct sysrq_key_op sysrq_sync_op = {
135         .handler        = sysrq_handle_sync,
136         .help_msg       = "Sync",
137         .action_msg     = "Emergency Sync",
138         .enable_mask    = SYSRQ_ENABLE_SYNC,
139 };
140
141 static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs,
142                                  struct tty_struct *tty)
143 {
144         emergency_remount();
145 }
146 static struct sysrq_key_op sysrq_mountro_op = {
147         .handler        = sysrq_handle_mountro,
148         .help_msg       = "Unmount",
149         .action_msg     = "Emergency Remount R/O",
150         .enable_mask    = SYSRQ_ENABLE_REMOUNT,
151 };
152
153 #ifdef CONFIG_LOCKDEP
154 static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs,
155                                 struct tty_struct *tty)
156 {
157         debug_show_all_locks();
158 }
159
160 static struct sysrq_key_op sysrq_showlocks_op = {
161         .handler        = sysrq_handle_showlocks,
162         .help_msg       = "show-all-locks(D)",
163         .action_msg     = "Show Locks Held",
164 };
165 #else
166 #define sysrq_showlocks_op (*(struct sysrq_key_op *)0)
167 #endif
168
169 static void sysrq_handle_showregs(int key, struct pt_regs *pt_regs,
170                                   struct tty_struct *tty)
171 {
172         if (pt_regs)
173                 show_regs(pt_regs);
174 }
175 static struct sysrq_key_op sysrq_showregs_op = {
176         .handler        = sysrq_handle_showregs,
177         .help_msg       = "showPc",
178         .action_msg     = "Show Regs",
179         .enable_mask    = SYSRQ_ENABLE_DUMP,
180 };
181
182 static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs,
183                                    struct tty_struct *tty)
184 {
185         show_state();
186 }
187 static struct sysrq_key_op sysrq_showstate_op = {
188         .handler        = sysrq_handle_showstate,
189         .help_msg       = "showTasks",
190         .action_msg     = "Show State",
191         .enable_mask    = SYSRQ_ENABLE_DUMP,
192 };
193
194 static void sysrq_handle_showmem(int key, struct pt_regs *pt_regs,
195                                  struct tty_struct *tty)
196 {
197         show_mem();
198 }
199 static struct sysrq_key_op sysrq_showmem_op = {
200         .handler        = sysrq_handle_showmem,
201         .help_msg       = "showMem",
202         .action_msg     = "Show Memory",
203         .enable_mask    = SYSRQ_ENABLE_DUMP,
204 };
205
206 /*
207  * Signal sysrq helper function.  Sends a signal to all user processes.
208  */
209 static void send_sig_all(int sig)
210 {
211         struct task_struct *p;
212
213         for_each_process(p) {
214                 if (p->mm && p->pid != 1)
215                         /* Not swapper, init nor kernel thread */
216                         force_sig(sig, p);
217         }
218 }
219
220 static void sysrq_handle_term(int key, struct pt_regs *pt_regs,
221                               struct tty_struct *tty)
222 {
223         send_sig_all(SIGTERM);
224         console_loglevel = 8;
225 }
226 static struct sysrq_key_op sysrq_term_op = {
227         .handler        = sysrq_handle_term,
228         .help_msg       = "tErm",
229         .action_msg     = "Terminate All Tasks",
230         .enable_mask    = SYSRQ_ENABLE_SIGNAL,
231 };
232
233 static void moom_callback(void *ignored)
234 {
235         out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL],
236                         GFP_KERNEL, 0);
237 }
238
239 static DECLARE_WORK(moom_work, moom_callback, NULL);
240
241 static void sysrq_handle_moom(int key, struct pt_regs *pt_regs,
242                               struct tty_struct *tty)
243 {
244         schedule_work(&moom_work);
245 }
246 static struct sysrq_key_op sysrq_moom_op = {
247         .handler        = sysrq_handle_moom,
248         .help_msg       = "Full",
249         .action_msg     = "Manual OOM execution",
250 };
251
252 static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
253                               struct tty_struct *tty)
254 {
255         send_sig_all(SIGKILL);
256         console_loglevel = 8;
257 }
258 static struct sysrq_key_op sysrq_kill_op = {
259         .handler        = sysrq_handle_kill,
260         .help_msg       = "kIll",
261         .action_msg     = "Kill All Tasks",
262         .enable_mask    = SYSRQ_ENABLE_SIGNAL,
263 };
264
265 static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs,
266                                 struct tty_struct *tty)
267 {
268         normalize_rt_tasks();
269 }
270 static struct sysrq_key_op sysrq_unrt_op = {
271         .handler        = sysrq_handle_unrt,
272         .help_msg       = "Nice",
273         .action_msg     = "Nice All RT Tasks",
274         .enable_mask    = SYSRQ_ENABLE_RTNICE,
275 };
276
277 /* Key Operations table and lock */
278 static DEFINE_SPINLOCK(sysrq_key_table_lock);
279
280 static struct sysrq_key_op *sysrq_key_table[36] = {
281         &sysrq_loglevel_op,             /* 0 */
282         &sysrq_loglevel_op,             /* 1 */
283         &sysrq_loglevel_op,             /* 2 */
284         &sysrq_loglevel_op,             /* 3 */
285         &sysrq_loglevel_op,             /* 4 */
286         &sysrq_loglevel_op,             /* 5 */
287         &sysrq_loglevel_op,             /* 6 */
288         &sysrq_loglevel_op,             /* 7 */
289         &sysrq_loglevel_op,             /* 8 */
290         &sysrq_loglevel_op,             /* 9 */
291
292         /*
293          * Don't use for system provided sysrqs, it is handled specially on
294          * sparc and will never arrive
295          */
296         NULL,                           /* a */
297         &sysrq_reboot_op,               /* b */
298         &sysrq_crashdump_op,            /* c */
299         &sysrq_showlocks_op,            /* d */
300         &sysrq_term_op,                 /* e */
301         &sysrq_moom_op,                 /* f */
302         NULL,                           /* g */
303         NULL,                           /* h */
304         &sysrq_kill_op,                 /* i */
305         NULL,                           /* j */
306         &sysrq_SAK_op,                  /* k */
307         NULL,                           /* l */
308         &sysrq_showmem_op,              /* m */
309         &sysrq_unrt_op,                 /* n */
310         /* This will often be registered as 'Off' at init time */
311         NULL,                           /* o */
312         &sysrq_showregs_op,             /* p */
313         NULL,                           /* q */
314         &sysrq_unraw_op,                        /* r */
315         &sysrq_sync_op,                 /* s */
316         &sysrq_showstate_op,            /* t */
317         &sysrq_mountro_op,              /* u */
318         /* May be assigned at init time by SMP VOYAGER */
319         NULL,                           /* v */
320         NULL,                           /* w */
321         NULL,                           /* x */
322         NULL,                           /* y */
323         NULL                            /* z */
324 };
325
326 /* key2index calculation, -1 on invalid index */
327 static int sysrq_key_table_key2index(int key)
328 {
329         int retval;
330
331         if ((key >= '0') && (key <= '9'))
332                 retval = key - '0';
333         else if ((key >= 'a') && (key <= 'z'))
334                 retval = key + 10 - 'a';
335         else
336                 retval = -1;
337         return retval;
338 }
339
340 /*
341  * get and put functions for the table, exposed to modules.
342  */
343 struct sysrq_key_op *__sysrq_get_key_op(int key)
344 {
345         struct sysrq_key_op *op_p = NULL;
346         int i;
347
348         i = sysrq_key_table_key2index(key);
349         if (i != -1)
350                 op_p = sysrq_key_table[i];
351         return op_p;
352 }
353
354 static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
355 {
356         int i = sysrq_key_table_key2index(key);
357
358         if (i != -1)
359                 sysrq_key_table[i] = op_p;
360 }
361
362 /*
363  * This is the non-locking version of handle_sysrq.  It must/can only be called
364  * by sysrq key handlers, as they are inside of the lock
365  */
366 void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty,
367                         int check_mask)
368 {
369         struct sysrq_key_op *op_p;
370         int orig_log_level;
371         int i;
372         unsigned long flags;
373
374         spin_lock_irqsave(&sysrq_key_table_lock, flags);
375         orig_log_level = console_loglevel;
376         console_loglevel = 7;
377         printk(KERN_INFO "SysRq : ");
378
379         op_p = __sysrq_get_key_op(key);
380         if (op_p) {
381                 /*
382                  * Should we check for enabled operations (/proc/sysrq-trigger
383                  * should not) and is the invoked operation enabled?
384                  */
385                 if (!check_mask || sysrq_enabled == 1 ||
386                     (sysrq_enabled & op_p->enable_mask)) {
387                         printk("%s\n", op_p->action_msg);
388                         console_loglevel = orig_log_level;
389                         op_p->handler(key, pt_regs, tty);
390                 } else {
391                         printk("This sysrq operation is disabled.\n");
392                 }
393         } else {
394                 printk("HELP : ");
395                 /* Only print the help msg once per handler */
396                 for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
397                         if (sysrq_key_table[i]) {
398                                 int j;
399
400                                 for (j = 0; sysrq_key_table[i] !=
401                                                 sysrq_key_table[j]; j++)
402                                         ;
403                                 if (j != i)
404                                         continue;
405                                 printk("%s ", sysrq_key_table[i]->help_msg);
406                         }
407                 }
408                 printk("\n");
409                 console_loglevel = orig_log_level;
410         }
411         spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
412 }
413
414 /*
415  * This function is called by the keyboard handler when SysRq is pressed
416  * and any other keycode arrives.
417  */
418 void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
419 {
420         if (!sysrq_enabled)
421                 return;
422         __handle_sysrq(key, pt_regs, tty, 1);
423 }
424 EXPORT_SYMBOL(handle_sysrq);
425
426 static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
427                                 struct sysrq_key_op *remove_op_p)
428 {
429
430         int retval;
431         unsigned long flags;
432
433         spin_lock_irqsave(&sysrq_key_table_lock, flags);
434         if (__sysrq_get_key_op(key) == remove_op_p) {
435                 __sysrq_put_key_op(key, insert_op_p);
436                 retval = 0;
437         } else {
438                 retval = -1;
439         }
440         spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
441         return retval;
442 }
443
444 int register_sysrq_key(int key, struct sysrq_key_op *op_p)
445 {
446         return __sysrq_swap_key_ops(key, op_p, NULL);
447 }
448 EXPORT_SYMBOL(register_sysrq_key);
449
450 int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
451 {
452         return __sysrq_swap_key_ops(key, NULL, op_p);
453 }
454 EXPORT_SYMBOL(unregister_sysrq_key);