diff options
Diffstat (limited to 'drivers/tty/sysrq.c')
-rw-r--r-- | drivers/tty/sysrq.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 5f68f2cfdfd..d5cc3acecfd 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -44,6 +44,7 @@ #include <linux/uaccess.h> #include <linux/moduleparam.h> #include <linux/jiffies.h> +#include <linux/syscalls.h> #include <asm/ptrace.h> #include <asm/irq_regs.h> @@ -586,6 +587,7 @@ struct sysrq_state { /* reset sequence handling */ bool reset_canceled; + bool reset_requested; unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)]; int reset_seq_len; int reset_seq_cnt; @@ -624,18 +626,26 @@ static void sysrq_parse_reset_sequence(struct sysrq_state *state) state->reset_seq_version = sysrq_reset_seq_version; } -static void sysrq_do_reset(unsigned long dummy) +static void sysrq_do_reset(unsigned long _state) { - __handle_sysrq(sysrq_xlate[KEY_B], false); + struct sysrq_state *state = (struct sysrq_state *) _state; + + state->reset_requested = true; + + sys_sync(); + kernel_restart(NULL); } static void sysrq_handle_reset_request(struct sysrq_state *state) { + if (state->reset_requested) + __handle_sysrq(sysrq_xlate[KEY_B], false); + if (sysrq_reset_downtime_ms) mod_timer(&state->keyreset_timer, jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms)); else - sysrq_do_reset(0); + sysrq_do_reset((unsigned long)state); } static void sysrq_detect_reset_sequence(struct sysrq_state *state, @@ -837,7 +847,8 @@ static int sysrq_connect(struct input_handler *handler, sysrq->handle.handler = handler; sysrq->handle.name = "sysrq"; sysrq->handle.private = sysrq; - setup_timer(&sysrq->keyreset_timer, sysrq_do_reset, 0); + setup_timer(&sysrq->keyreset_timer, + sysrq_do_reset, (unsigned long)sysrq); error = input_register_handle(&sysrq->handle); if (error) { |