diff options
| -rw-r--r-- | drivers/char/sysrq.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 8e0dd254eb11..81f13958e751 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
| @@ -571,6 +571,7 @@ struct sysrq_state { | |||
| 571 | unsigned int alt_use; | 571 | unsigned int alt_use; |
| 572 | bool active; | 572 | bool active; |
| 573 | bool need_reinject; | 573 | bool need_reinject; |
| 574 | bool reinjecting; | ||
| 574 | }; | 575 | }; |
| 575 | 576 | ||
| 576 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) | 577 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) |
| @@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) | |||
| 581 | unsigned int alt_code = sysrq->alt_use; | 582 | unsigned int alt_code = sysrq->alt_use; |
| 582 | 583 | ||
| 583 | if (sysrq->need_reinject) { | 584 | if (sysrq->need_reinject) { |
| 585 | /* we do not want the assignment to be reordered */ | ||
| 586 | sysrq->reinjecting = true; | ||
| 587 | mb(); | ||
| 588 | |||
| 584 | /* Simulate press and release of Alt + SysRq */ | 589 | /* Simulate press and release of Alt + SysRq */ |
| 585 | input_inject_event(handle, EV_KEY, alt_code, 1); | 590 | input_inject_event(handle, EV_KEY, alt_code, 1); |
| 586 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); | 591 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); |
| @@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) | |||
| 589 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); | 594 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); |
| 590 | input_inject_event(handle, EV_KEY, alt_code, 0); | 595 | input_inject_event(handle, EV_KEY, alt_code, 0); |
| 591 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); | 596 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); |
| 597 | |||
| 598 | mb(); | ||
| 599 | sysrq->reinjecting = false; | ||
| 592 | } | 600 | } |
| 593 | } | 601 | } |
| 594 | 602 | ||
| @@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_handle *handle, | |||
| 599 | bool was_active = sysrq->active; | 607 | bool was_active = sysrq->active; |
| 600 | bool suppress; | 608 | bool suppress; |
| 601 | 609 | ||
| 610 | /* | ||
| 611 | * Do not filter anything if we are in the process of re-injecting | ||
| 612 | * Alt+SysRq combination. | ||
| 613 | */ | ||
| 614 | if (sysrq->reinjecting) | ||
| 615 | return false; | ||
| 616 | |||
| 602 | switch (type) { | 617 | switch (type) { |
| 603 | 618 | ||
| 604 | case EV_SYN: | 619 | case EV_SYN: |
| @@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle, | |||
| 629 | sysrq->alt_use = sysrq->alt; | 644 | sysrq->alt_use = sysrq->alt; |
| 630 | /* | 645 | /* |
| 631 | * If nothing else will be pressed we'll need | 646 | * If nothing else will be pressed we'll need |
| 632 | * to * re-inject Alt-SysRq keysroke. | 647 | * to re-inject Alt-SysRq keysroke. |
| 633 | */ | 648 | */ |
| 634 | sysrq->need_reinject = true; | 649 | sysrq->need_reinject = true; |
| 635 | } | 650 | } |
