| From 7d52be76b2415eda9aecd85404f6e3fcd42a5432 Mon Sep 17 00:00:00 2001 |
| From: Sameer Nanda <snanda@chromium.org> |
| Date: Mon, 6 Aug 2012 09:16:21 -0700 |
| Subject: [PATCH] CHROMIUM: sysrq: Added Chrome OS specific 'x' key |
| |
| On Chrome OS systems the magic sysrq x key will cause the following to |
| happen: |
| - show processes in blocked state |
| - emergency file sync |
| - crash the system |
| |
| This key combination can be used in the field by users to cause the |
| system to crash so that crash dumps can be collected to help debug UI |
| freeze issues. |
| |
| BUG=chromium-os:33249 |
| TEST=First "echo 0x1000 > /proc/sys/kernel/sysrq", then do the two tests |
| below: |
| 1. Alt-F10-x should cause the system to crash. Looks for kcrash logs |
| under /var/spool/crash when the system reboots. |
| 2. All other magic sysrq operation aside from alt-F10-x should be |
| ineffective. |
| |
| Change-Id: I62d0a7f0028c072928be0125da4e069bafa5d88c |
| Signed-off-by: Sameer Nanda <snanda@chromium.org> |
| Reviewed-on: https://gerrit.chromium.org/gerrit/29316 |
| |
| [rebase66(tzungbi): |
| Revised commit message. |
| Squashed: |
| CHROMIUM: sysrq: treat F10 as magic sysrq key |
| (https://gerrit.chromium.org/gerrit/29110) |
| CHROMIUM: sysrq: clear sysrq->active state on sysrq release |
| (https://chromium-review.googlesource.com/264198) |
| CHROMIUM: sysrq: Use KEY_VOLUMEUP for sysrq key |
| (https://crrev.com/c/2163131) |
| FIXUP: CHROMIUM: sysrq: Added Chrome OS specific x key |
| ] |
| Signed-off-by: Tzung-Bi Shih <tzungbi@chromium.org> |
| --- |
| drivers/tty/sysrq.c | 69 +++++++++++++++++++++++++++++++++++++++++-- |
| include/linux/sysrq.h | 1 + |
| 2 files changed, 68 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c |
| index e5974b8239c9904abbc15c1b658380bd800426b8..c28adc096726076cff702a4d8dfae1cb50c54d42 100644 |
| --- a/drivers/tty/sysrq.c |
| +++ b/drivers/tty/sysrq.c |
| @@ -51,6 +51,7 @@ |
| #include <linux/syscalls.h> |
| #include <linux/of.h> |
| #include <linux/rcupdate.h> |
| +#include <linux/delay.h> |
| |
| #include <asm/ptrace.h> |
| #include <asm/irq_regs.h> |
| @@ -461,6 +462,64 @@ static struct sysrq_key_op sysrq_replay_logs_op = { |
| .enable_mask = SYSRQ_ENABLE_DUMP, |
| }; |
| |
| +/* send a signal to a process named comm if it has a certain parent */ |
| +/* if parent is NULL, send to the first matching process */ |
| +static void sysrq_x_cros_signal_process(char *comm, char *parent, int sig) |
| +{ |
| + struct task_struct *p; |
| + |
| + read_lock(&tasklist_lock); |
| + for_each_process(p) { |
| + if (p->flags & (PF_KTHREAD | PF_EXITING)) |
| + continue; |
| + if (is_global_init(p)) |
| + continue; |
| + if (strncmp(p->comm, comm, TASK_COMM_LEN)) |
| + continue; |
| + if (parent && strncmp(p->parent->comm, parent, TASK_COMM_LEN)) |
| + continue; |
| + |
| + printk(KERN_INFO "%s: signal %d %s pid %u tgid %u\n", |
| + __func__, sig, comm, p->pid, p->tgid); |
| + do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); |
| + } |
| + read_unlock(&tasklist_lock); |
| +} |
| + |
| +/* how many seconds do we wait for subsequent keypresses after the first */ |
| +#define CROS_SYSRQ_WAIT 20 |
| + |
| +static void sysrq_handle_cros_xkey(u8 key) |
| +{ |
| + static unsigned long first_jiffies = INITIAL_JIFFIES - CROS_SYSRQ_WAIT * HZ; |
| + static unsigned int xkey_iteration; |
| + |
| + if (time_after(jiffies, first_jiffies + CROS_SYSRQ_WAIT * HZ)) { |
| + first_jiffies = jiffies; |
| + xkey_iteration = 0; |
| + } else { |
| + xkey_iteration++; |
| + } |
| + |
| + if (!xkey_iteration) { |
| + sysrq_x_cros_signal_process("chrome", "session_manager", |
| + SIGABRT); |
| + } else { |
| + sysrq_handle_showstate_blocked(key); |
| + sysrq_handle_sync(key); |
| + /* Delay for a bit to give time for sync to complete */ |
| + mdelay(1000); |
| + panic("ChromeOS X Key"); |
| + } |
| +} |
| + |
| +static struct sysrq_key_op sysrq_cros_xkey = { |
| + .handler = sysrq_handle_cros_xkey, |
| + .help_msg = "Cros-dump-and-crash", |
| + .action_msg = "Cros dump and crash", |
| + .enable_mask = SYSRQ_ENABLE_CROS_XKEY, |
| +}; |
| + |
| /* Key Operations table and lock */ |
| static DEFINE_SPINLOCK(sysrq_key_table_lock); |
| |
| @@ -509,7 +568,8 @@ static const struct sysrq_key_op *sysrq_key_table[62] = { |
| /* x: May be registered on mips for TLB dump */ |
| /* x: May be registered on ppc/powerpc for xmon */ |
| /* x: May be registered on sparc64 for global PMU dump */ |
| - NULL, /* x */ |
| + /* x: On Chrome OS, this is the dump and crash key */ |
| + &sysrq_cros_xkey, /* x */ |
| /* y: May be registered on sparc64 for global register dump */ |
| NULL, /* y */ |
| &sysrq_ftrace_dump_op, /* z */ |
| @@ -861,7 +921,12 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, |
| break; |
| |
| case KEY_SYSRQ: |
| - if (value == 1 && sysrq->alt != KEY_RESERVED) { |
| + case KEY_F10: |
| + case KEY_VOLUMEUP: |
| + if (!value) { |
| + /* sysrq is being released */ |
| + sysrq->active = false; |
| + } else if (value == 1 && sysrq->alt != KEY_RESERVED) { |
| sysrq->active = true; |
| sysrq->alt_use = sysrq->alt; |
| /* either RESERVED (for released) or actual code */ |
| diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h |
| index bdca467ebb77355c62dbd74b7f547a70627e0325..e78da8c37adb4d0dc810924bdba4a6afed5e2e39 100644 |
| --- a/include/linux/sysrq.h |
| +++ b/include/linux/sysrq.h |
| @@ -28,6 +28,7 @@ |
| #define SYSRQ_ENABLE_SIGNAL 0x0040 |
| #define SYSRQ_ENABLE_BOOT 0x0080 |
| #define SYSRQ_ENABLE_RTNICE 0x0100 |
| +#define SYSRQ_ENABLE_CROS_XKEY 0x1000 |
| |
| struct sysrq_key_op { |
| void (* const handler)(u8); |
| -- |
| 2.45.1.288.g0e0cd299f1-goog |
| |