linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] input / sysrq fixes for use with kdb
@ 2010-10-07 20:35 Jason Wessel
  2010-10-07 20:35 ` [PATCH 1/3] keyboard,kgdboc: Allow key release on kernel resume Jason Wessel
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
  To: dmitry.torokhov; +Cc: kgdb-bugreport, linux-input, linux-kernel

The goal of this patch set is to help eliminate the problems of
resuming from the kernel debugger and having "stuck keys".

I am completely open to moving the code chunks around if it makes more
sense to put the function in the input.c.

I had posted the first patch in the series before and never received
an ack or acceptance into the linux-input merge queue.

Thanks,
Jason.

---

The following changes since commit cb655d0f3d57c23db51b981648e452988c0223f9:
  Linus Torvalds (1):
        Linux 2.6.36-rc7

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb.git for_input

Jason Wessel (2):
      keyboard,kgdboc: Allow key release on kernel resume
      sysrq,keyboard: properly deal with alt-sysrq in sysrq input filter

Maxim Levitsky (1):
      keyboard,kdb: inject SYN events in kbd_clear_keys_helper

 drivers/char/keyboard.c  |   38 +++++++++++++++++++++++++++
 drivers/char/sysrq.c     |   64 +++++++++++++++++++++++++++++++++++++++++++--
 drivers/serial/kgdboc.c  |   13 +++++++++
 include/linux/kbd_kern.h |    1 +
 4 files changed, 113 insertions(+), 3 deletions(-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] keyboard,kgdboc: Allow key release on kernel resume
  2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
@ 2010-10-07 20:35 ` Jason Wessel
  2010-10-07 20:35 ` [PATCH 2/3] keyboard,kdb: inject SYN events in kbd_clear_keys_helper Jason Wessel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: kgdb-bugreport, linux-input, linux-kernel, Jason Wessel,
	Greg Kroah-Hartman

When using a keyboard with kdb, a hook point to free all the
keystrokes is required for resuming kernel operations.

This is mainly because there is no way to force the end user to hold
down the original keys that were pressed prior to entering kdb when
resuming the kernel.

The kgdboc driver will call kbd_dbg_clear_keys() just prior to
resuming the kernel execution which will schedule a callback to clear
any keys which were depressed prior to the entering the kernel
debugger.

CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: linux-input@vger.kernel.org
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
 drivers/char/keyboard.c  |   37 +++++++++++++++++++++++++++++++++++++
 drivers/serial/kgdboc.c  |   13 +++++++++++++
 include/linux/kbd_kern.h |    1 +
 3 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index a7ca752..0c6c641 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -363,6 +363,43 @@ static void to_utf8(struct vc_data *vc, uint c)
 	}
 }
 
+#ifdef CONFIG_KDB_KEYBOARD
+static int kbd_clear_keys_helper(struct input_handle *handle, void *data)
+{
+	unsigned int *keycode = data;
+	input_inject_event(handle, EV_KEY, *keycode, 0);
+	return 0;
+}
+
+static void kbd_clear_keys_callback(struct work_struct *dummy)
+{
+	unsigned int i, j, k;
+
+	for (i = 0; i < ARRAY_SIZE(key_down); i++) {
+		if (!key_down[i])
+			continue;
+
+		k = i * BITS_PER_LONG;
+
+		for (j = 0; j < BITS_PER_LONG; j++, k++) {
+			if (!test_bit(k, key_down))
+				continue;
+			input_handler_for_each_handle(&kbd_handler, &k,
+				      kbd_clear_keys_helper);
+		}
+	}
+}
+
+static DECLARE_WORK(kbd_clear_keys_work, kbd_clear_keys_callback);
+
+/* Called to clear any key presses after resuming the kernel. */
+void kbd_dbg_clear_keys(void)
+{
+	schedule_work(&kbd_clear_keys_work);
+}
+EXPORT_SYMBOL_GPL(kbd_dbg_clear_keys);
+#endif /* CONFIG_KDB_KEYBOARD */
+
 /*
  * Called after returning from RAW mode or when changing consoles - recompute
  * shift_down[] and shift_state from key_down[] maybe called when keymap is
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c
index 39f9a1a..62b6edc 100644
--- a/drivers/serial/kgdboc.c
+++ b/drivers/serial/kgdboc.c
@@ -18,6 +18,7 @@
 #include <linux/tty.h>
 #include <linux/console.h>
 #include <linux/vt_kern.h>
+#include <linux/kbd_kern.h>
 
 #define MAX_CONFIG_LEN		40
 
@@ -37,12 +38,16 @@ static struct tty_driver	*kgdb_tty_driver;
 static int			kgdb_tty_line;
 
 #ifdef CONFIG_KDB_KEYBOARD
+static bool			kgdboc_use_kbd;
+
 static int kgdboc_register_kbd(char **cptr)
 {
+	kgdboc_use_kbd = false;
 	if (strncmp(*cptr, "kbd", 3) == 0) {
 		if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
 			kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
 			kdb_poll_idx++;
+			kgdboc_use_kbd = true;
 			if (cptr[0][3] == ',')
 				*cptr += 4;
 			else
@@ -65,9 +70,16 @@ static void kgdboc_unregister_kbd(void)
 		}
 	}
 }
+
+static inline void kgdboc_clear_kbd(void)
+{
+	if (kgdboc_use_kbd)
+		kbd_dbg_clear_keys(); /* Release all pressed keys */
+}
 #else /* ! CONFIG_KDB_KEYBOARD */
 #define kgdboc_register_kbd(x) 0
 #define kgdboc_unregister_kbd()
+#define kgdboc_clear_kbd()
 #endif /* ! CONFIG_KDB_KEYBOARD */
 
 static int kgdboc_option_setup(char *opt)
@@ -231,6 +243,7 @@ static void kgdboc_post_exp_handler(void)
 		dbg_restore_graphics = 0;
 		con_debug_leave();
 	}
+	kgdboc_clear_kbd();
 }
 
 static struct kgdb_io kgdboc_io_ops = {
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index 506ad20..ae87c0a 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -144,6 +144,7 @@ struct console;
 int getkeycode(unsigned int scancode);
 int setkeycode(unsigned int scancode, unsigned int keycode);
 void compute_shiftstate(void);
+void kbd_dbg_clear_keys(void);
 
 /* defkeymap.c */
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] keyboard,kdb: inject SYN events in kbd_clear_keys_helper
  2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
  2010-10-07 20:35 ` [PATCH 1/3] keyboard,kgdboc: Allow key release on kernel resume Jason Wessel
@ 2010-10-07 20:35 ` Jason Wessel
  2010-10-07 20:35 ` [PATCH 3/3] sysrq,keyboard: properly deal with alt-sysrq in sysrq input filter Jason Wessel
  2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
  3 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: kgdb-bugreport, linux-input, linux-kernel, Maxim Levitsky, Jason Wessel

From: Maxim Levitsky <maximlevitsky@gmail.com>

The kbd_clear_keys_helper injects the keyup events alright, but it
doesn't inject SYN events, and therefore X evdev driver doesn't pick
these injected events untill next SYN event.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
 drivers/char/keyboard.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 0c6c641..7df6af5 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -368,6 +368,7 @@ static int kbd_clear_keys_helper(struct input_handle *handle, void *data)
 {
 	unsigned int *keycode = data;
 	input_inject_event(handle, EV_KEY, *keycode, 0);
+	input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
 	return 0;
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] sysrq,keyboard: properly deal with alt-sysrq in sysrq input filter
  2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
  2010-10-07 20:35 ` [PATCH 1/3] keyboard,kgdboc: Allow key release on kernel resume Jason Wessel
  2010-10-07 20:35 ` [PATCH 2/3] keyboard,kdb: inject SYN events in kbd_clear_keys_helper Jason Wessel
@ 2010-10-07 20:35 ` Jason Wessel
  2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
  3 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-07 20:35 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: kgdb-bugreport, linux-input, linux-kernel, Jason Wessel,
	Greg Kroah-Hartman

This patch addresses 2 problems:

1) You should still be able to use alt-PrintScreen to capture a grab
   of a single window when the sysrq filter is active.

2) The sysrq filter should reset the low level key mask so that future
   key presses will not show up as a repeated key.  The problem was
   that when you executed alt-sysrq g and then resumed the kernel, you
   would have to press 'g' twice to get it working again.

CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: linux-input@vger.kernel.org
Reported-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
 drivers/char/sysrq.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index ef31bb8..b1fad74 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -566,6 +566,57 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] =
 static bool sysrq_down;
 static int sysrq_alt_use;
 static int sysrq_alt;
+static bool sysrq_kbd_triggered;
+
+/*
+ * This function was a copy of input_pass_event but modified to allow
+ * by-passing a specific filter, to allow for injected events without
+ * filter recursion.
+ */
+static void input_pass_event_ignore(struct input_dev *dev,
+			     unsigned int type, unsigned int code, int value,
+			     struct input_handle *ignore_handle)
+{
+	struct input_handler *handler;
+	struct input_handle *handle;
+
+	rcu_read_lock();
+
+	handle = rcu_dereference(dev->grab);
+	if (handle)
+		handle->handler->event(handle, type, code, value);
+	else {
+		bool filtered = false;
+
+		list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
+			if (!handle->open || handle == ignore_handle)
+				continue;
+			handler = handle->handler;
+			if (!handler->filter) {
+				if (filtered)
+					break;
+
+				handler->event(handle, type, code, value);
+
+			} else if (handler->filter(handle, type, code, value))
+				filtered = true;
+		}
+	}
+
+	rcu_read_unlock();
+}
+
+/*
+ * Pass along alt-print_screen, if there was no sysrq processing by
+ * sending a key press down and then passing the key up event.
+ */
+static void simulate_alt_sysrq(struct input_handle *handle)
+{
+	input_pass_event_ignore(handle->dev, EV_KEY, KEY_SYSRQ, 1, handle);
+	input_pass_event_ignore(handle->dev, EV_SYN, SYN_REPORT, 0, handle);
+	input_pass_event_ignore(handle->dev, EV_KEY, KEY_SYSRQ, 0, handle);
+	input_pass_event_ignore(handle->dev, EV_SYN, SYN_REPORT, 0, handle);
+}
 
 static bool sysrq_filter(struct input_handle *handle, unsigned int type,
 		         unsigned int code, int value)
@@ -580,9 +631,11 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type,
 		if (value)
 			sysrq_alt = code;
 		else {
-			if (sysrq_down && code == sysrq_alt_use)
+			if (sysrq_down && code == sysrq_alt_use) {
 				sysrq_down = false;
-
+				if (!sysrq_kbd_triggered)
+					simulate_alt_sysrq(handle);
+			}
 			sysrq_alt = 0;
 		}
 		break;
@@ -590,13 +643,18 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type,
 	case KEY_SYSRQ:
 		if (value == 1 && sysrq_alt) {
 			sysrq_down = true;
+			sysrq_kbd_triggered = false;
 			sysrq_alt_use = sysrq_alt;
 		}
 		break;
 
 	default:
-		if (sysrq_down && value && value != 2)
+		if (sysrq_down && value && value != 2 && !sysrq_kbd_triggered) {
+			sysrq_kbd_triggered = true;
 			__handle_sysrq(sysrq_xlate[code], true);
+			/* Clear handled keys from being flagged as a repeated stroke */
+			__clear_bit(code, handle->dev->key);
+		}
 		break;
 	}
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] input / sysrq fixes for use with kdb
  2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
                   ` (2 preceding siblings ...)
  2010-10-07 20:35 ` [PATCH 3/3] sysrq,keyboard: properly deal with alt-sysrq in sysrq input filter Jason Wessel
@ 2010-10-10 21:19 ` Dmitry Torokhov
  2010-10-27 12:53   ` Jason Wessel
  3 siblings, 1 reply; 6+ messages in thread
From: Dmitry Torokhov @ 2010-10-10 21:19 UTC (permalink / raw)
  To: Jason Wessel; +Cc: kgdb-bugreport, linux-input, linux-kernel

On Thu, Oct 07, 2010 at 03:35:45PM -0500, Jason Wessel wrote:
> The goal of this patch set is to help eliminate the problems of
> resuming from the kernel debugger and having "stuck keys".
> 
> I am completely open to moving the code chunks around if it makes more
> sense to put the function in the input.c.
> 
> I had posted the first patch in the series before and never received
> an ack or acceptance into the linux-input merge queue.
> 

Jason,

I am aware of the problem however I am not quite happy with the proposed
solution yet. Let me mull it over for a bit and I will get back to you.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] input / sysrq fixes for use with kdb
  2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
@ 2010-10-27 12:53   ` Jason Wessel
  0 siblings, 0 replies; 6+ messages in thread
From: Jason Wessel @ 2010-10-27 12:53 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: kgdb-bugreport, linux-input, linux-kernel

On 10/10/2010 04:19 PM, Dmitry Torokhov wrote:
> On Thu, Oct 07, 2010 at 03:35:45PM -0500, Jason Wessel wrote:
>   
>> The goal of this patch set is to help eliminate the problems of
>> resuming from the kernel debugger and having "stuck keys".
>>
>> I am completely open to moving the code chunks around if it makes more
>> sense to put the function in the input.c.
>>
>> I had posted the first patch in the series before and never received
>> an ack or acceptance into the linux-input merge queue.
>>
>>     
>
> Jason,
>
> I am aware of the problem however I am not quite happy with the proposed
> solution yet. Let me mull it over for a bit and I will get back to you.
>   
Ping :-)

The merge window for 2.6.37 is almost over, and I would really like to
fix this or make it better than it is today, given that remainder of the
atomic KMS API is now merged in 2.6.37.


Thanks,
Jason.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-10-27 12:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-07 20:35 [PATCH 0/3] input / sysrq fixes for use with kdb Jason Wessel
2010-10-07 20:35 ` [PATCH 1/3] keyboard,kgdboc: Allow key release on kernel resume Jason Wessel
2010-10-07 20:35 ` [PATCH 2/3] keyboard,kdb: inject SYN events in kbd_clear_keys_helper Jason Wessel
2010-10-07 20:35 ` [PATCH 3/3] sysrq,keyboard: properly deal with alt-sysrq in sysrq input filter Jason Wessel
2010-10-10 21:19 ` [PATCH 0/3] input / sysrq fixes for use with kdb Dmitry Torokhov
2010-10-27 12:53   ` Jason Wessel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).