tty/sysrq: Extend the sysrq_key_table to cover capital letters
authorAndrzej Pietrasiewicz <andrzej.p@collabora.com>
Tue, 18 Aug 2020 11:28:24 +0000 (13:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 Oct 2020 12:56:06 +0000 (14:56 +0200)
All slots in sysrq_key_table[] are either used, reserved or at least
commented with their intended use. This patch adds capital letter versions
available, which means adding 26 more entries.

For already existing SysRq operations the user presses Alt-SysRq-<key>, and
for the newly added ones Alt-Shift-SysRq-<key>.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://lore.kernel.org/r/20200818112825.6445-2-andrzej.p@collabora.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/admin-guide/sysrq.rst
drivers/gpu/drm/drm_fb_helper.c
drivers/tty/sysrq.c

index e6424d8c58468408536b25bffe23414d0f08d336..67dfa4c290935bb3f15df294770704cf91c3b1a9 100644 (file)
@@ -79,6 +79,8 @@ On all
 
                echo t > /proc/sysrq-trigger
 
+The :kbd:`<command key>` is case sensitive.
+
 What are the 'command' keys?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index 8697554ccd41383359bf117bb3ee83752d817e80..1543d9d109705cc27085f09ecbec20ce0d830c1e 100644 (file)
@@ -325,7 +325,7 @@ static void drm_fb_helper_sysrq(int dummy1)
 
 static const struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
        .handler = drm_fb_helper_sysrq,
-       .help_msg = "force-fb(V)",
+       .help_msg = "force-fb(v)",
        .action_msg = "Restore framebuffer console",
 };
 #else
index a8e39b2cdd5526f65c584df6d1f5bf24f6051dd2..959f9e121cc61a3f9b23749ec7b130564e26d689 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sched/rt.h>
 #include <linux/sched/debug.h>
 #include <linux/sched/task.h>
+#include <linux/ctype.h>
 #include <linux/interrupt.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
@@ -440,7 +441,7 @@ static const struct sysrq_key_op sysrq_unrt_op = {
 /* Key Operations table and lock */
 static DEFINE_SPINLOCK(sysrq_key_table_lock);
 
-static const struct sysrq_key_op *sysrq_key_table[36] = {
+static const struct sysrq_key_op *sysrq_key_table[62] = {
        &sysrq_loglevel_op,             /* 0 */
        &sysrq_loglevel_op,             /* 1 */
        &sysrq_loglevel_op,             /* 2 */
@@ -497,6 +498,32 @@ static const struct sysrq_key_op *sysrq_key_table[36] = {
        /* y: May be registered on sparc64 for global register dump */
        NULL,                           /* y */
        &sysrq_ftrace_dump_op,          /* z */
+       NULL,                           /* A */
+       NULL,                           /* B */
+       NULL,                           /* C */
+       NULL,                           /* D */
+       NULL,                           /* E */
+       NULL,                           /* F */
+       NULL,                           /* G */
+       NULL,                           /* H */
+       NULL,                           /* I */
+       NULL,                           /* J */
+       NULL,                           /* K */
+       NULL,                           /* L */
+       NULL,                           /* M */
+       NULL,                           /* N */
+       NULL,                           /* O */
+       NULL,                           /* P */
+       NULL,                           /* Q */
+       NULL,                           /* R */
+       NULL,                           /* S */
+       NULL,                           /* T */
+       NULL,                           /* U */
+       NULL,                           /* V */
+       NULL,                           /* W */
+       NULL,                           /* X */
+       NULL,                           /* Y */
+       NULL,                           /* Z */
 };
 
 /* key2index calculation, -1 on invalid index */
@@ -508,6 +535,8 @@ static int sysrq_key_table_key2index(int key)
                retval = key - '0';
        else if ((key >= 'a') && (key <= 'z'))
                retval = key + 10 - 'a';
+       else if ((key >= 'A') && (key <= 'Z'))
+               retval = key + 36 - 'A';
        else
                retval = -1;
        return retval;
@@ -621,6 +650,8 @@ struct sysrq_state {
        unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
        unsigned int alt;
        unsigned int alt_use;
+       unsigned int shift;
+       unsigned int shift_use;
        bool active;
        bool need_reinject;
        bool reinjecting;
@@ -805,10 +836,20 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
                }
                break;
 
+       case KEY_LEFTSHIFT:
+       case KEY_RIGHTSHIFT:
+               if (!value)
+                       sysrq->shift = KEY_RESERVED;
+               else if (value != 2)
+                       sysrq->shift = code;
+               break;
+
        case KEY_SYSRQ:
                if (value == 1 && sysrq->alt != KEY_RESERVED) {
                        sysrq->active = true;
                        sysrq->alt_use = sysrq->alt;
+                       /* either RESERVED (for released) or actual code */
+                       sysrq->shift_use = sysrq->shift;
                        /*
                         * If nothing else will be pressed we'll need
                         * to re-inject Alt-SysRq keysroke.
@@ -831,8 +872,12 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
 
        default:
                if (sysrq->active && value && value != 2) {
+                       unsigned char c = sysrq_xlate[code];
+
                        sysrq->need_reinject = false;
-                       __handle_sysrq(sysrq_xlate[code], true);
+                       if (sysrq->shift_use != KEY_RESERVED)
+                               c = toupper(c);
+                       __handle_sysrq(c, true);
                }
                break;
        }