summaryrefslogtreecommitdiffstats
path: root/drivers/char/sysrq.c
diff options
context:
space:
mode:
authorDmitry Torokhov2011-02-03 07:59:54 +0100
committerDmitry Torokhov2011-02-03 08:02:23 +0100
commit7ab7b5adfb923978a2cab7bd3fac9ccf7d21cc3f (patch)
tree252719cab248978672597586560353fb1c95b6d0 /drivers/char/sysrq.c
parentInput: serio - clear pending rescans after sysfs driver rebind (diff)
downloadkernel-qcow2-linux-7ab7b5adfb923978a2cab7bd3fac9ccf7d21cc3f.tar.gz
kernel-qcow2-linux-7ab7b5adfb923978a2cab7bd3fac9ccf7d21cc3f.tar.xz
kernel-qcow2-linux-7ab7b5adfb923978a2cab7bd3fac9ccf7d21cc3f.zip
Input: sysrq - rework re-inject logic
Internally 'disable' the filter when re-injecting Alt-SysRq instead of relying on input core to suppress delivery of injected events to the originating handler. This allows to revert commit 5fdbe44d033d059cc56c2803e6b4dbd8cb4e5e39 which causes problems with existing userspace programs trying to loopback the events via evdev. Reported-by: Kristen Carlson Accardi <kristen@linux.intel.com> Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/char/sysrq.c')
-rw-r--r--drivers/char/sysrq.c17
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 {
unsigned int alt_use;
bool active;
bool need_reinject;
+ bool reinjecting;
};
static void sysrq_reinject_alt_sysrq(struct work_struct *work)
@@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
unsigned int alt_code = sysrq->alt_use;
if (sysrq->need_reinject) {
+ /* we do not want the assignment to be reordered */
+ sysrq->reinjecting = true;
+ mb();
+
/* Simulate press and release of Alt + SysRq */
input_inject_event(handle, EV_KEY, alt_code, 1);
input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
@@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
input_inject_event(handle, EV_KEY, alt_code, 0);
input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+ mb();
+ sysrq->reinjecting = false;
}
}
@@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_handle *handle,
bool was_active = sysrq->active;
bool suppress;
+ /*
+ * Do not filter anything if we are in the process of re-injecting
+ * Alt+SysRq combination.
+ */
+ if (sysrq->reinjecting)
+ return false;
+
switch (type) {
case EV_SYN:
@@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle,
sysrq->alt_use = sysrq->alt;
/*
* If nothing else will be pressed we'll need
- * to * re-inject Alt-SysRq keysroke.
+ * to re-inject Alt-SysRq keysroke.
*/
sysrq->need_reinject = true;
}