linux/drivers/char/sysrq.c
<<
>>
Prefs
   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/proc_fs.h>
  27#include <linux/nmi.h>
  28#include <linux/quotaops.h>
  29#include <linux/perf_event.h>
  30#include <linux/kernel.h>
  31#include <linux/module.h>
  32#include <linux/suspend.h>
  33#include <linux/writeback.h>
  34#include <linux/buffer_head.h>          /* for fsync_bdev() */
  35#include <linux/swap.h>
  36#include <linux/spinlock.h>
  37#include <linux/vt_kern.h>
  38#include <linux/workqueue.h>
  39#include <linux/hrtimer.h>
  40#include <linux/oom.h>
  41
  42#include <asm/ptrace.h>
  43#include <asm/irq_regs.h>
  44
  45/* Whether we react on sysrq keys or just ignore them */
  46int __read_mostly __sysrq_enabled = 1;
  47
  48static int __read_mostly sysrq_always_enabled;
  49
  50int sysrq_on(void)
  51{
  52        return __sysrq_enabled || sysrq_always_enabled;
  53}
  54
  55/*
  56 * A value of 1 means 'all', other nonzero values are an op mask:
  57 */
  58static inline int sysrq_on_mask(int mask)
  59{
  60        return sysrq_always_enabled || __sysrq_enabled == 1 ||
  61                                                (__sysrq_enabled & mask);
  62}
  63
  64static int __init sysrq_always_enabled_setup(char *str)
  65{
  66        sysrq_always_enabled = 1;
  67        printk(KERN_INFO "debug: sysrq always enabled.\n");
  68
  69        return 1;
  70}
  71
  72__setup("sysrq_always_enabled", sysrq_always_enabled_setup);
  73
  74
  75static void sysrq_handle_loglevel(int key, struct tty_struct *tty)
  76{
  77        int i;
  78        i = key - '0';
  79        console_loglevel = 7;
  80        printk("Loglevel set to %d\n", i);
  81        console_loglevel = i;
  82}
  83static struct sysrq_key_op sysrq_loglevel_op = {
  84        .handler        = sysrq_handle_loglevel,
  85        .help_msg       = "loglevel(0-9)",
  86        .action_msg     = "Changing Loglevel",
  87        .enable_mask    = SYSRQ_ENABLE_LOG,
  88};
  89
  90#ifdef CONFIG_VT
  91static void sysrq_handle_SAK(int key, struct tty_struct *tty)
  92{
  93        struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
  94        schedule_work(SAK_work);
  95}
  96static struct sysrq_key_op sysrq_SAK_op = {
  97        .handler        = sysrq_handle_SAK,
  98        .help_msg       = "saK",
  99        .action_msg     = "SAK",
 100        .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
 101};
 102#else
 103#define sysrq_SAK_op (*(struct sysrq_key_op *)0)
 104#endif
 105
 106#ifdef CONFIG_VT
 107static void sysrq_handle_unraw(int key, struct tty_struct *tty)
 108{
 109        struct kbd_struct *kbd = &kbd_table[fg_console];
 110
 111        if (kbd)
 112                kbd->kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
 113}
 114static struct sysrq_key_op sysrq_unraw_op = {
 115        .handler        = sysrq_handle_unraw,
 116        .help_msg       = "unRaw",
 117        .action_msg     = "Keyboard mode set to system default",
 118        .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
 119};
 120#else
 121#define sysrq_unraw_op (*(struct sysrq_key_op *)0)
 122#endif /* CONFIG_VT */
 123
 124static void sysrq_handle_crash(int key, struct tty_struct *tty)
 125{
 126        char *killer = NULL;
 127
 128        panic_on_oops = 1;      /* force panic */
 129        wmb();
 130        *killer = 1;
 131}
 132static struct sysrq_key_op sysrq_crash_op = {
 133        .handler        = sysrq_handle_crash,
 134        .help_msg       = "Crash",
 135        .action_msg     = "Trigger a crash",
 136        .enable_mask    = SYSRQ_ENABLE_DUMP,
 137};
 138
 139static void sysrq_handle_reboot(int key, struct tty_struct *tty)
 140{
 141        lockdep_off();
 142        local_irq_enable();
 143        emergency_restart();
 144}
 145static struct sysrq_key_op sysrq_reboot_op = {
 146        .handler        = sysrq_handle_reboot,
 147        .help_msg       = "reBoot",
 148        .action_msg     = "Resetting",
 149        .enable_mask    = SYSRQ_ENABLE_BOOT,
 150};
 151
 152static void sysrq_handle_sync(int key, struct tty_struct *tty)
 153{
 154        emergency_sync();
 155}
 156static struct sysrq_key_op sysrq_sync_op = {
 157        .handler        = sysrq_handle_sync,
 158        .help_msg       = "Sync",
 159        .action_msg     = "Emergency Sync",
 160        .enable_mask    = SYSRQ_ENABLE_SYNC,
 161};
 162
 163static void sysrq_handle_show_timers(int key, struct tty_struct *tty)
 164{
 165        sysrq_timer_list_show();
 166}
 167
 168static struct sysrq_key_op sysrq_show_timers_op = {
 169        .handler        = sysrq_handle_show_timers,
 170        .help_msg       = "show-all-timers(Q)",
 171        .action_msg     = "Show clockevent devices & pending hrtimers (no others)",
 172};
 173
 174static void sysrq_handle_mountro(int key, struct tty_struct *tty)
 175{
 176        emergency_remount();
 177}
 178static struct sysrq_key_op sysrq_mountro_op = {
 179        .handler        = sysrq_handle_mountro,
 180        .help_msg       = "Unmount",
 181        .action_msg     = "Emergency Remount R/O",
 182        .enable_mask    = SYSRQ_ENABLE_REMOUNT,
 183};
 184
 185#ifdef CONFIG_LOCKDEP
 186static void sysrq_handle_showlocks(int key, struct tty_struct *tty)
 187{
 188        debug_show_all_locks();
 189}
 190
 191static struct sysrq_key_op sysrq_showlocks_op = {
 192        .handler        = sysrq_handle_showlocks,
 193        .help_msg       = "show-all-locks(D)",
 194        .action_msg     = "Show Locks Held",
 195};
 196#else
 197#define sysrq_showlocks_op (*(struct sysrq_key_op *)0)
 198#endif
 199
 200#ifdef CONFIG_SMP
 201static DEFINE_SPINLOCK(show_lock);
 202
 203static void showacpu(void *dummy)
 204{
 205        unsigned long flags;
 206
 207        /* Idle CPUs have no interesting backtrace. */
 208        if (idle_cpu(smp_processor_id()))
 209                return;
 210
 211        spin_lock_irqsave(&show_lock, flags);
 212        printk(KERN_INFO "CPU%d:\n", smp_processor_id());
 213        show_stack(NULL, NULL);
 214        spin_unlock_irqrestore(&show_lock, flags);
 215}
 216
 217static void sysrq_showregs_othercpus(struct work_struct *dummy)
 218{
 219        smp_call_function(showacpu, NULL, 0);
 220}
 221
 222static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);
 223
 224static void sysrq_handle_showallcpus(int key, struct tty_struct *tty)
 225{
 226        /*
 227         * Fall back to the workqueue based printing if the
 228         * backtrace printing did not succeed or the
 229         * architecture has no support for it:
 230         */
 231        if (!trigger_all_cpu_backtrace()) {
 232                struct pt_regs *regs = get_irq_regs();
 233
 234                if (regs) {
 235                        printk(KERN_INFO "CPU%d:\n", smp_processor_id());
 236                        show_regs(regs);
 237                }
 238                schedule_work(&sysrq_showallcpus);
 239        }
 240}
 241
 242static struct sysrq_key_op sysrq_showallcpus_op = {
 243        .handler        = sysrq_handle_showallcpus,
 244        .help_msg       = "show-backtrace-all-active-cpus(L)",
 245        .action_msg     = "Show backtrace of all active CPUs",
 246        .enable_mask    = SYSRQ_ENABLE_DUMP,
 247};
 248#endif
 249
 250static void sysrq_handle_showregs(int key, struct tty_struct *tty)
 251{
 252        struct pt_regs *regs = get_irq_regs();
 253        if (regs)
 254                show_regs(regs);
 255        perf_event_print_debug();
 256}
 257static struct sysrq_key_op sysrq_showregs_op = {
 258        .handler        = sysrq_handle_showregs,
 259        .help_msg       = "show-registers(P)",
 260        .action_msg     = "Show Regs",
 261        .enable_mask    = SYSRQ_ENABLE_DUMP,
 262};
 263
 264static void sysrq_handle_showstate(int key, struct tty_struct *tty)
 265{
 266        show_state();
 267}
 268static struct sysrq_key_op sysrq_showstate_op = {
 269        .handler        = sysrq_handle_showstate,
 270        .help_msg       = "show-task-states(T)",
 271        .action_msg     = "Show State",
 272        .enable_mask    = SYSRQ_ENABLE_DUMP,
 273};
 274
 275static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty)
 276{
 277        show_state_filter(TASK_UNINTERRUPTIBLE);
 278}
 279static struct sysrq_key_op sysrq_showstate_blocked_op = {
 280        .handler        = sysrq_handle_showstate_blocked,
 281        .help_msg       = "show-blocked-tasks(W)",
 282        .action_msg     = "Show Blocked State",
 283        .enable_mask    = SYSRQ_ENABLE_DUMP,
 284};
 285
 286#ifdef CONFIG_TRACING
 287#include <linux/ftrace.h>
 288
 289static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
 290{
 291        ftrace_dump();
 292}
 293static struct sysrq_key_op sysrq_ftrace_dump_op = {
 294        .handler        = sysrq_ftrace_dump,
 295        .help_msg       = "dump-ftrace-buffer(Z)",
 296        .action_msg     = "Dump ftrace buffer",
 297        .enable_mask    = SYSRQ_ENABLE_DUMP,
 298};
 299#else
 300#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)0)
 301#endif
 302
 303static void sysrq_handle_showmem(int key, struct tty_struct *tty)
 304{
 305        show_mem();
 306}
 307static struct sysrq_key_op sysrq_showmem_op = {
 308        .handler        = sysrq_handle_showmem,
 309        .help_msg       = "show-memory-usage(M)",
 310        .action_msg     = "Show Memory",
 311        .enable_mask    = SYSRQ_ENABLE_DUMP,
 312};
 313
 314/*
 315 * Signal sysrq helper function.  Sends a signal to all user processes.
 316 */
 317static void send_sig_all(int sig)
 318{
 319        struct task_struct *p;
 320
 321        for_each_process(p) {
 322                if (p->mm && !is_global_init(p))
 323                        /* Not swapper, init nor kernel thread */
 324                        force_sig(sig, p);
 325        }
 326}
 327
 328static void sysrq_handle_term(int key, struct tty_struct *tty)
 329{
 330        send_sig_all(SIGTERM);
 331        console_loglevel = 8;
 332}
 333static struct sysrq_key_op sysrq_term_op = {
 334        .handler        = sysrq_handle_term,
 335        .help_msg       = "terminate-all-tasks(E)",
 336        .action_msg     = "Terminate All Tasks",
 337        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
 338};
 339
 340static void moom_callback(struct work_struct *ignored)
 341{
 342        out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0);
 343}
 344
 345static DECLARE_WORK(moom_work, moom_callback);
 346
 347static void sysrq_handle_moom(int key, struct tty_struct *tty)
 348{
 349        schedule_work(&moom_work);
 350}
 351static struct sysrq_key_op sysrq_moom_op = {
 352        .handler        = sysrq_handle_moom,
 353        .help_msg       = "memory-full-oom-kill(F)",
 354        .action_msg     = "Manual OOM execution",
 355        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
 356};
 357
 358#ifdef CONFIG_BLOCK
 359static void sysrq_handle_thaw(int key, struct tty_struct *tty)
 360{
 361        emergency_thaw_all();
 362}
 363static struct sysrq_key_op sysrq_thaw_op = {
 364        .handler        = sysrq_handle_thaw,
 365        .help_msg       = "thaw-filesystems(J)",
 366        .action_msg     = "Emergency Thaw of all frozen filesystems",
 367        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
 368};
 369#endif
 370
 371static void sysrq_handle_kill(int key, struct tty_struct *tty)
 372{
 373        send_sig_all(SIGKILL);
 374        console_loglevel = 8;
 375}
 376static struct sysrq_key_op sysrq_kill_op = {
 377        .handler        = sysrq_handle_kill,
 378        .help_msg       = "kill-all-tasks(I)",
 379        .action_msg     = "Kill All Tasks",
 380        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
 381};
 382
 383static void sysrq_handle_unrt(int key, struct tty_struct *tty)
 384{
 385        normalize_rt_tasks();
 386}
 387static struct sysrq_key_op sysrq_unrt_op = {
 388        .handler        = sysrq_handle_unrt,
 389        .help_msg       = "nice-all-RT-tasks(N)",
 390        .action_msg     = "Nice All RT Tasks",
 391        .enable_mask    = SYSRQ_ENABLE_RTNICE,
 392};
 393
 394/* Key Operations table and lock */
 395static DEFINE_SPINLOCK(sysrq_key_table_lock);
 396
 397static struct sysrq_key_op *sysrq_key_table[36] = {
 398        &sysrq_loglevel_op,             /* 0 */
 399        &sysrq_loglevel_op,             /* 1 */
 400        &sysrq_loglevel_op,             /* 2 */
 401        &sysrq_loglevel_op,             /* 3 */
 402        &sysrq_loglevel_op,             /* 4 */
 403        &sysrq_loglevel_op,             /* 5 */
 404        &sysrq_loglevel_op,             /* 6 */
 405        &sysrq_loglevel_op,             /* 7 */
 406        &sysrq_loglevel_op,             /* 8 */
 407        &sysrq_loglevel_op,             /* 9 */
 408
 409        /*
 410         * a: Don't use for system provided sysrqs, it is handled specially on
 411         * sparc and will never arrive.
 412         */
 413        NULL,                           /* a */
 414        &sysrq_reboot_op,               /* b */
 415        &sysrq_crash_op,                /* c & ibm_emac driver debug */
 416        &sysrq_showlocks_op,            /* d */
 417        &sysrq_term_op,                 /* e */
 418        &sysrq_moom_op,                 /* f */
 419        /* g: May be registered for the kernel debugger */
 420        NULL,                           /* g */
 421        NULL,                           /* h - reserved for help */
 422        &sysrq_kill_op,                 /* i */
 423#ifdef CONFIG_BLOCK
 424        &sysrq_thaw_op,                 /* j */
 425#else
 426        NULL,                           /* j */
 427#endif
 428        &sysrq_SAK_op,                  /* k */
 429#ifdef CONFIG_SMP
 430        &sysrq_showallcpus_op,          /* l */
 431#else
 432        NULL,                           /* l */
 433#endif
 434        &sysrq_showmem_op,              /* m */
 435        &sysrq_unrt_op,                 /* n */
 436        /* o: This will often be registered as 'Off' at init time */
 437        NULL,                           /* o */
 438        &sysrq_showregs_op,             /* p */
 439        &sysrq_show_timers_op,          /* q */
 440        &sysrq_unraw_op,                /* r */
 441        &sysrq_sync_op,                 /* s */
 442        &sysrq_showstate_op,            /* t */
 443        &sysrq_mountro_op,              /* u */
 444        /* v: May be registered for frame buffer console restore */
 445        NULL,                           /* v */
 446        &sysrq_showstate_blocked_op,    /* w */
 447        /* x: May be registered on ppc/powerpc for xmon */
 448        NULL,                           /* x */
 449        /* y: May be registered on sparc64 for global register dump */
 450        NULL,                           /* y */
 451        &sysrq_ftrace_dump_op,          /* z */
 452};
 453
 454/* key2index calculation, -1 on invalid index */
 455static int sysrq_key_table_key2index(int key)
 456{
 457        int retval;
 458
 459        if ((key >= '0') && (key <= '9'))
 460                retval = key - '0';
 461        else if ((key >= 'a') && (key <= 'z'))
 462                retval = key + 10 - 'a';
 463        else
 464                retval = -1;
 465        return retval;
 466}
 467
 468/*
 469 * get and put functions for the table, exposed to modules.
 470 */
 471struct sysrq_key_op *__sysrq_get_key_op(int key)
 472{
 473        struct sysrq_key_op *op_p = NULL;
 474        int i;
 475
 476        i = sysrq_key_table_key2index(key);
 477        if (i != -1)
 478                op_p = sysrq_key_table[i];
 479        return op_p;
 480}
 481
 482static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
 483{
 484        int i = sysrq_key_table_key2index(key);
 485
 486        if (i != -1)
 487                sysrq_key_table[i] = op_p;
 488}
 489
 490/*
 491 * This is the non-locking version of handle_sysrq.  It must/can only be called
 492 * by sysrq key handlers, as they are inside of the lock
 493 */
 494void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
 495{
 496        struct sysrq_key_op *op_p;
 497        int orig_log_level;
 498        int i;
 499        unsigned long flags;
 500
 501        spin_lock_irqsave(&sysrq_key_table_lock, flags);
 502        /*
 503         * Raise the apparent loglevel to maximum so that the sysrq header
 504         * is shown to provide the user with positive feedback.  We do not
 505         * simply emit this at KERN_EMERG as that would change message
 506         * routing in the consumers of /proc/kmsg.
 507         */
 508        orig_log_level = console_loglevel;
 509        console_loglevel = 7;
 510        printk(KERN_INFO "SysRq : ");
 511
 512        op_p = __sysrq_get_key_op(key);
 513        if (op_p) {
 514                /*
 515                 * Should we check for enabled operations (/proc/sysrq-trigger
 516                 * should not) and is the invoked operation enabled?
 517                 */
 518                if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
 519                        printk("%s\n", op_p->action_msg);
 520                        console_loglevel = orig_log_level;
 521                        op_p->handler(key, tty);
 522                } else {
 523                        printk("This sysrq operation is disabled.\n");
 524                }
 525        } else {
 526                printk("HELP : ");
 527                /* Only print the help msg once per handler */
 528                for (i = 0; i < ARRAY_SIZE(sysrq_key_table); i++) {
 529                        if (sysrq_key_table[i]) {
 530                                int j;
 531
 532                                for (j = 0; sysrq_key_table[i] !=
 533                                                sysrq_key_table[j]; j++)
 534                                        ;
 535                                if (j != i)
 536                                        continue;
 537                                printk("%s ", sysrq_key_table[i]->help_msg);
 538                        }
 539                }
 540                printk("\n");
 541                console_loglevel = orig_log_level;
 542        }
 543        spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
 544}
 545
 546/*
 547 * This function is called by the keyboard handler when SysRq is pressed
 548 * and any other keycode arrives.
 549 */
 550void handle_sysrq(int key, struct tty_struct *tty)
 551{
 552        if (sysrq_on())
 553                __handle_sysrq(key, tty, 1);
 554}
 555EXPORT_SYMBOL(handle_sysrq);
 556
 557static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
 558                                struct sysrq_key_op *remove_op_p)
 559{
 560
 561        int retval;
 562        unsigned long flags;
 563
 564        spin_lock_irqsave(&sysrq_key_table_lock, flags);
 565        if (__sysrq_get_key_op(key) == remove_op_p) {
 566                __sysrq_put_key_op(key, insert_op_p);
 567                retval = 0;
 568        } else {
 569                retval = -1;
 570        }
 571        spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
 572        return retval;
 573}
 574
 575int register_sysrq_key(int key, struct sysrq_key_op *op_p)
 576{
 577        return __sysrq_swap_key_ops(key, op_p, NULL);
 578}
 579EXPORT_SYMBOL(register_sysrq_key);
 580
 581int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
 582{
 583        return __sysrq_swap_key_ops(key, NULL, op_p);
 584}
 585EXPORT_SYMBOL(unregister_sysrq_key);
 586
 587#ifdef CONFIG_PROC_FS
 588/*
 589 * writing 'C' to /proc/sysrq-trigger is like sysrq-C
 590 */
 591static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
 592                                   size_t count, loff_t *ppos)
 593{
 594        if (count) {
 595                char c;
 596
 597                if (get_user(c, buf))
 598                        return -EFAULT;
 599                __handle_sysrq(c, NULL, 0);
 600        }
 601        return count;
 602}
 603
 604static const struct file_operations proc_sysrq_trigger_operations = {
 605        .write          = write_sysrq_trigger,
 606};
 607
 608static int __init sysrq_init(void)
 609{
 610        proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
 611        return 0;
 612}
 613module_init(sysrq_init);
 614#endif
 615