summaryrefslogtreecommitdiff
path: root/drivers/tty/sysrq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/sysrq.c')
-rw-r--r--drivers/tty/sysrq.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 02217e3c916b..f85ce02e4725 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -450,6 +450,17 @@ static const struct sysrq_key_op sysrq_unrt_op = {
.enable_mask = SYSRQ_ENABLE_RTNICE,
};
+static void sysrq_handle_replay_logs(u8 key)
+{
+ console_try_replay_all();
+}
+static struct sysrq_key_op sysrq_replay_logs_op = {
+ .handler = sysrq_handle_replay_logs,
+ .help_msg = "replay-kernel-logs(R)",
+ .action_msg = "Replay kernel logs on consoles",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
+};
+
/* Key Operations table and lock */
static DEFINE_SPINLOCK(sysrq_key_table_lock);
@@ -519,7 +530,8 @@ static const struct sysrq_key_op *sysrq_key_table[62] = {
NULL, /* O */
NULL, /* P */
NULL, /* Q */
- NULL, /* R */
+ &sysrq_replay_logs_op, /* R */
+ /* S: May be registered by sched_ext for resetting */
NULL, /* S */
NULL, /* T */
NULL, /* U */
@@ -571,7 +583,6 @@ static void __sysrq_put_key_op(u8 key, const struct sysrq_key_op *op_p)
void __handle_sysrq(u8 key, bool check_mask)
{
const struct sysrq_key_op *op_p;
- int orig_log_level;
int orig_suppress_printk;
int i;
@@ -581,13 +592,12 @@ void __handle_sysrq(u8 key, bool check_mask)
rcu_sysrq_start();
rcu_read_lock();
/*
- * Raise the apparent loglevel to maximum so that the sysrq header
- * is shown to provide the user with positive feedback. We do not
- * simply emit this at KERN_EMERG as that would change message
- * routing in the consumers of /proc/kmsg.
+ * Enter in the force_console context so that sysrq header is shown to
+ * provide the user with positive feedback. We do not simply emit this
+ * at KERN_EMERG as that would change message routing in the consumers
+ * of /proc/kmsg.
*/
- orig_log_level = console_loglevel;
- console_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
+ printk_force_console_enter();
op_p = __sysrq_get_key_op(key);
if (op_p) {
@@ -597,11 +607,11 @@ void __handle_sysrq(u8 key, bool check_mask)
*/
if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
pr_info("%s\n", op_p->action_msg);
- console_loglevel = orig_log_level;
+ printk_force_console_exit();
op_p->handler(key);
} else {
pr_info("This sysrq operation is disabled.\n");
- console_loglevel = orig_log_level;
+ printk_force_console_exit();
}
} else {
pr_info("HELP : ");
@@ -619,7 +629,7 @@ void __handle_sysrq(u8 key, bool check_mask)
}
}
pr_cont("\n");
- console_loglevel = orig_log_level;
+ printk_force_console_exit();
}
rcu_read_unlock();
rcu_sysrq_end();
@@ -759,8 +769,6 @@ static void sysrq_of_get_keyreset_config(void)
{
u32 key;
struct device_node *np;
- struct property *prop;
- const __be32 *p;
np = of_find_node_by_path("/chosen/linux,sysrq-reset-seq");
if (!np) {
@@ -771,7 +779,7 @@ static void sysrq_of_get_keyreset_config(void)
/* Reset in case a __weak definition was present */
sysrq_reset_seq_len = 0;
- of_property_for_each_u32(np, "keyset", prop, p, key) {
+ of_property_for_each_u32(np, "keyset", key) {
if (key == KEY_RESERVED || key > KEY_MAX ||
sysrq_reset_seq_len == SYSRQ_KEY_RESET_MAX)
break;