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