aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/sysrq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/sysrq.c')
-rw-r--r--drivers/tty/sysrq.c276
1 files changed, 202 insertions, 74 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 40e5b3919e27..814655ee2d61 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -42,6 +42,7 @@
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/input.h> 43#include <linux/input.h>
44#include <linux/uaccess.h> 44#include <linux/uaccess.h>
45#include <linux/moduleparam.h>
45 46
46#include <asm/ptrace.h> 47#include <asm/ptrace.h>
47#include <asm/irq_regs.h> 48#include <asm/irq_regs.h>
@@ -578,8 +579,71 @@ struct sysrq_state {
578 bool active; 579 bool active;
579 bool need_reinject; 580 bool need_reinject;
580 bool reinjecting; 581 bool reinjecting;
582
583 /* reset sequence handling */
584 bool reset_canceled;
585 unsigned long reset_keybit[BITS_TO_LONGS(KEY_CNT)];
586 int reset_seq_len;
587 int reset_seq_cnt;
588 int reset_seq_version;
581}; 589};
582 590
591#define SYSRQ_KEY_RESET_MAX 20 /* Should be plenty */
592static unsigned short sysrq_reset_seq[SYSRQ_KEY_RESET_MAX];
593static unsigned int sysrq_reset_seq_len;
594static unsigned int sysrq_reset_seq_version = 1;
595
596static void sysrq_parse_reset_sequence(struct sysrq_state *state)
597{
598 int i;
599 unsigned short key;
600
601 state->reset_seq_cnt = 0;
602
603 for (i = 0; i < sysrq_reset_seq_len; i++) {
604 key = sysrq_reset_seq[i];
605
606 if (key == KEY_RESERVED || key > KEY_MAX)
607 break;
608
609 __set_bit(key, state->reset_keybit);
610 state->reset_seq_len++;
611
612 if (test_bit(key, state->key_down))
613 state->reset_seq_cnt++;
614 }
615
616 /* Disable reset until old keys are not released */
617 state->reset_canceled = state->reset_seq_cnt != 0;
618
619 state->reset_seq_version = sysrq_reset_seq_version;
620}
621
622static bool sysrq_detect_reset_sequence(struct sysrq_state *state,
623 unsigned int code, int value)
624{
625 if (!test_bit(code, state->reset_keybit)) {
626 /*
627 * Pressing any key _not_ in reset sequence cancels
628 * the reset sequence.
629 */
630 if (value && state->reset_seq_cnt)
631 state->reset_canceled = true;
632 } else if (value == 0) {
633 /* key release */
634 if (--state->reset_seq_cnt == 0)
635 state->reset_canceled = false;
636 } else if (value == 1) {
637 /* key press, not autorepeat */
638 if (++state->reset_seq_cnt == state->reset_seq_len &&
639 !state->reset_canceled) {
640 return true;
641 }
642 }
643
644 return false;
645}
646
583static void sysrq_reinject_alt_sysrq(struct work_struct *work) 647static void sysrq_reinject_alt_sysrq(struct work_struct *work)
584{ 648{
585 struct sysrq_state *sysrq = 649 struct sysrq_state *sysrq =
@@ -606,100 +670,121 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
606 } 670 }
607} 671}
608 672
609static bool sysrq_filter(struct input_handle *handle, 673static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
610 unsigned int type, unsigned int code, int value) 674 unsigned int code, int value)
611{ 675{
612 struct sysrq_state *sysrq = handle->private;
613 bool was_active = sysrq->active; 676 bool was_active = sysrq->active;
614 bool suppress; 677 bool suppress;
615 678
616 /* 679 switch (code) {
617 * Do not filter anything if we are in the process of re-injecting
618 * Alt+SysRq combination.
619 */
620 if (sysrq->reinjecting)
621 return false;
622 680
623 switch (type) { 681 case KEY_LEFTALT:
682 case KEY_RIGHTALT:
683 if (!value) {
684 /* One of ALTs is being released */
685 if (sysrq->active && code == sysrq->alt_use)
686 sysrq->active = false;
624 687
625 case EV_SYN: 688 sysrq->alt = KEY_RESERVED;
626 suppress = false; 689
690 } else if (value != 2) {
691 sysrq->alt = code;
692 sysrq->need_reinject = false;
693 }
627 break; 694 break;
628 695
629 case EV_KEY: 696 case KEY_SYSRQ:
630 switch (code) { 697 if (value == 1 && sysrq->alt != KEY_RESERVED) {
698 sysrq->active = true;
699 sysrq->alt_use = sysrq->alt;
700 /*
701 * If nothing else will be pressed we'll need
702 * to re-inject Alt-SysRq keysroke.
703 */
704 sysrq->need_reinject = true;
705 }
631 706
632 case KEY_LEFTALT: 707 /*
633 case KEY_RIGHTALT: 708 * Pretend that sysrq was never pressed at all. This
634 if (!value) { 709 * is needed to properly handle KGDB which will try
635 /* One of ALTs is being released */ 710 * to release all keys after exiting debugger. If we
636 if (sysrq->active && code == sysrq->alt_use) 711 * do not clear key bit it KGDB will end up sending
637 sysrq->active = false; 712 * release events for Alt and SysRq, potentially
713 * triggering print screen function.
714 */
715 if (sysrq->active)
716 clear_bit(KEY_SYSRQ, sysrq->handle.dev->key);
638 717
639 sysrq->alt = KEY_RESERVED; 718 break;
640 719
641 } else if (value != 2) { 720 default:
642 sysrq->alt = code; 721 if (sysrq->active && value && value != 2) {
643 sysrq->need_reinject = false; 722 sysrq->need_reinject = false;
644 } 723 __handle_sysrq(sysrq_xlate[code], true);
645 break; 724 }
725 break;
726 }
646 727
647 case KEY_SYSRQ: 728 suppress = sysrq->active;
648 if (value == 1 && sysrq->alt != KEY_RESERVED) {
649 sysrq->active = true;
650 sysrq->alt_use = sysrq->alt;
651 /*
652 * If nothing else will be pressed we'll need
653 * to re-inject Alt-SysRq keysroke.
654 */
655 sysrq->need_reinject = true;
656 }
657 729
658 /* 730 if (!sysrq->active) {
659 * Pretend that sysrq was never pressed at all. This
660 * is needed to properly handle KGDB which will try
661 * to release all keys after exiting debugger. If we
662 * do not clear key bit it KGDB will end up sending
663 * release events for Alt and SysRq, potentially
664 * triggering print screen function.
665 */
666 if (sysrq->active)
667 clear_bit(KEY_SYSRQ, handle->dev->key);
668 731
669 break; 732 /*
733 * See if reset sequence has changed since the last time.
734 */
735 if (sysrq->reset_seq_version != sysrq_reset_seq_version)
736 sysrq_parse_reset_sequence(sysrq);
670 737
671 default: 738 /*
672 if (sysrq->active && value && value != 2) { 739 * If we are not suppressing key presses keep track of
673 sysrq->need_reinject = false; 740 * keyboard state so we can release keys that have been
674 __handle_sysrq(sysrq_xlate[code], true); 741 * pressed before entering SysRq mode.
675 } 742 */
676 break; 743 if (value)
744 set_bit(code, sysrq->key_down);
745 else
746 clear_bit(code, sysrq->key_down);
747
748 if (was_active)
749 schedule_work(&sysrq->reinject_work);
750
751 if (sysrq_detect_reset_sequence(sysrq, code, value)) {
752 /* Force emergency reboot */
753 __handle_sysrq(sysrq_xlate[KEY_B], false);
677 } 754 }
678 755
679 suppress = sysrq->active; 756 } else if (value == 0 && test_and_clear_bit(code, sysrq->key_down)) {
757 /*
758 * Pass on release events for keys that was pressed before
759 * entering SysRq mode.
760 */
761 suppress = false;
762 }
680 763
681 if (!sysrq->active) { 764 return suppress;
682 /* 765}
683 * If we are not suppressing key presses keep track of
684 * keyboard state so we can release keys that have been
685 * pressed before entering SysRq mode.
686 */
687 if (value)
688 set_bit(code, sysrq->key_down);
689 else
690 clear_bit(code, sysrq->key_down);
691 766
692 if (was_active) 767static bool sysrq_filter(struct input_handle *handle,
693 schedule_work(&sysrq->reinject_work); 768 unsigned int type, unsigned int code, int value)
769{
770 struct sysrq_state *sysrq = handle->private;
771 bool suppress;
694 772
695 } else if (value == 0 && 773 /*
696 test_and_clear_bit(code, sysrq->key_down)) { 774 * Do not filter anything if we are in the process of re-injecting
697 /* 775 * Alt+SysRq combination.
698 * Pass on release events for keys that was pressed before 776 */
699 * entering SysRq mode. 777 if (sysrq->reinjecting)
700 */ 778 return false;
701 suppress = false; 779
702 } 780 switch (type) {
781
782 case EV_SYN:
783 suppress = false;
784 break;
785
786 case EV_KEY:
787 suppress = sysrq_handle_keypress(sysrq, code, value);
703 break; 788 break;
704 789
705 default: 790 default:
@@ -787,7 +872,20 @@ static bool sysrq_handler_registered;
787 872
788static inline void sysrq_register_handler(void) 873static inline void sysrq_register_handler(void)
789{ 874{
875 extern unsigned short platform_sysrq_reset_seq[] __weak;
876 unsigned short key;
790 int error; 877 int error;
878 int i;
879
880 if (platform_sysrq_reset_seq) {
881 for (i = 0; i < ARRAY_SIZE(sysrq_reset_seq); i++) {
882 key = platform_sysrq_reset_seq[i];
883 if (key == KEY_RESERVED || key > KEY_MAX)
884 break;
885
886 sysrq_reset_seq[sysrq_reset_seq_len++] = key;
887 }
888 }
791 889
792 error = input_register_handler(&sysrq_handler); 890 error = input_register_handler(&sysrq_handler);
793 if (error) 891 if (error)
@@ -804,6 +902,36 @@ static inline void sysrq_unregister_handler(void)
804 } 902 }
805} 903}
806 904
905static int sysrq_reset_seq_param_set(const char *buffer,
906 const struct kernel_param *kp)
907{
908 unsigned long val;
909 int error;
910
911 error = strict_strtoul(buffer, 0, &val);
912 if (error < 0)
913 return error;
914
915 if (val > KEY_MAX)
916 return -EINVAL;
917
918 *((unsigned short *)kp->arg) = val;
919 sysrq_reset_seq_version++;
920
921 return 0;
922}
923
924static struct kernel_param_ops param_ops_sysrq_reset_seq = {
925 .get = param_get_ushort,
926 .set = sysrq_reset_seq_param_set,
927};
928
929#define param_check_sysrq_reset_seq(name, p) \
930 __param_check(name, p, unsigned short)
931
932module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq,
933 &sysrq_reset_seq_len, 0644);
934
807#else 935#else
808 936
809static inline void sysrq_register_handler(void) 937static inline void sysrq_register_handler(void)