linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration
@ 2020-10-29 11:32 Jiri Slaby
  2020-10-29 11:32 ` [PATCH 02/17] vt: keyboard, include linux/spinlock.h Jiri Slaby
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

ctrl_alt_del is already declared in linux/reboot.h which we include. So
remove this second (superfluous) declaration.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 78acc270e39a..69bbb6c1b3de 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -49,8 +49,6 @@
 
 #include <asm/irq_regs.h>
 
-extern void ctrl_alt_del(void);
-
 /*
  * Exported functions/variables
  */
-- 
2.29.1


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

* [PATCH 02/17] vt: keyboard, include linux/spinlock.h
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 03/17] vt: keyboard, sort includes Jiri Slaby
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

We use spin locks, but don't include linux/spinlock.h in keyboards.c. So
fix this up.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 69bbb6c1b3de..275093a15564 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -33,6 +33,7 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/nospec.h>
+#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-- 
2.29.1


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

* [PATCH 03/17] vt: keyboard, sort includes
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
  2020-10-29 11:32 ` [PATCH 02/17] vt: keyboard, include linux/spinlock.h Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 04/17] vt: keyboard, sort key types by their number Jiri Slaby
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

There are many includes and it is hard to check if something is there or
not. So sort them alphabetically.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 275093a15564..9e45feb15a3e 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -26,27 +26,26 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/consolemap.h>
-#include <linux/module.h>
-#include <linux/sched/signal.h>
-#include <linux/sched/debug.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/jiffies.h>
+#include <linux/kbd_diacr.h>
+#include <linux/kbd_kern.h>
+#include <linux/leds.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/nospec.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/sched/debug.h>
+#include <linux/sched/signal.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/leds.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/kbd_diacr.h>
-#include <linux/vt_kern.h>
-#include <linux/input.h>
-#include <linux/reboot.h>
-#include <linux/notifier.h>
-#include <linux/jiffies.h>
+#include <linux/tty_flip.h>
+#include <linux/tty.h>
 #include <linux/uaccess.h>
+#include <linux/vt_kern.h>
 
 #include <asm/irq_regs.h>
 
-- 
2.29.1


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

* [PATCH 04/17] vt: keyboard, sort key types by their number
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
  2020-10-29 11:32 ` [PATCH 02/17] vt: keyboard, include linux/spinlock.h Jiri Slaby
  2020-10-29 11:32 ` [PATCH 03/17] vt: keyboard, sort includes Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 05/17] vt: keyboard, clean up max_vals Jiri Slaby
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

KT_LETTER was numerically missorted. So sort all KT_* entries.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/uapi/linux/keyboard.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/uapi/linux/keyboard.h b/include/uapi/linux/keyboard.h
index 4846716e7c5c..36d230cedf12 100644
--- a/include/uapi/linux/keyboard.h
+++ b/include/uapi/linux/keyboard.h
@@ -27,7 +27,6 @@
 #define MAX_NR_FUNC	256	/* max nr of strings assigned to keys */
 
 #define KT_LATIN	0	/* we depend on this being zero */
-#define KT_LETTER	11	/* symbol that can be acted upon by CapsLock */
 #define KT_FN		1
 #define KT_SPEC		2
 #define KT_PAD		3
@@ -38,6 +37,7 @@
 #define KT_META		8
 #define KT_ASCII	9
 #define KT_LOCK		10
+#define KT_LETTER	11	/* symbol that can be acted upon by CapsLock */
 #define KT_SLOCK	12
 #define KT_DEAD2	13
 #define KT_BRL		14
-- 
2.29.1


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

* [PATCH 05/17] vt: keyboard, clean up max_vals
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (2 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 04/17] vt: keyboard, sort key types by their number Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 06/17] vt: keyboard, extract vt_kdgkbent and vt_kdskbent Jiri Slaby
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Define one limit per line and index them by their index, so that it is
clear what is what.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 9e45feb15a3e..4545afd3ef2f 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -111,10 +111,22 @@ static struct kbd_struct kbd_table[MAX_NR_CONSOLES];
 static struct kbd_struct *kbd = kbd_table;
 
 /* maximum values each key_handler can handle */
-static const int max_vals[] = {
-	255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
-	NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
-	255, NR_LOCK - 1, 255, NR_BRL - 1
+static const unsigned char max_vals[] = {
+	[ KT_LATIN	] = 255,
+	[ KT_FN		] = ARRAY_SIZE(func_table) - 1,
+	[ KT_SPEC	] = ARRAY_SIZE(fn_handler) - 1,
+	[ KT_PAD	] = NR_PAD - 1,
+	[ KT_DEAD	] = NR_DEAD - 1,
+	[ KT_CONS	] = 255,
+	[ KT_CUR	] = 3,
+	[ KT_SHIFT	] = NR_SHIFT - 1,
+	[ KT_META	] = 255,
+	[ KT_ASCII	] = NR_ASCII - 1,
+	[ KT_LOCK	] = NR_LOCK - 1,
+	[ KT_LETTER	] = 255,
+	[ KT_SLOCK	] = NR_LOCK - 1,
+	[ KT_DEAD2	] = 255,
+	[ KT_BRL	] = NR_BRL - 1,
 };
 
 static const int NR_TYPES = ARRAY_SIZE(max_vals);
-- 
2.29.1


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

* [PATCH 06/17] vt: keyboard, extract vt_kdgkbent and vt_kdskbent
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (3 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 05/17] vt: keyboard, clean up max_vals Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 07/17] vt: keyboard, union perm checks in vt_do_kdsk_ioctl Jiri Slaby
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Split vt_do_kdsk_ioctl into three functions:
* getter (KDGKBENT/vt_kdgkbent)
* setter (KDSKBENT/vt_kdskbent)
* switch-case helper (vt_do_kdsk_ioctl)

This eliminates the need of ugly one-letter macros as we use parameters
now:
* i aka tmp.kb_index -> idx
* s aka tmp.kb_table -> map
* v aka tmp.kb_value -> val

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 189 ++++++++++++++++++++------------------
 1 file changed, 102 insertions(+), 87 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 4545afd3ef2f..c1709b8dbb52 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1897,114 +1897,129 @@ int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
 	return kc;
 }
 
-#define i (tmp.kb_index)
-#define s (tmp.kb_table)
-#define v (tmp.kb_value)
-
-int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
-						int console)
+static unsigned short vt_kdgkbent(unsigned char kbdmode, unsigned char idx,
+		unsigned char map)
 {
-	struct kbd_struct *kb = kbd_table + console;
-	struct kbentry tmp;
-	ushort *key_map, *new_map, val, ov;
+	unsigned short *key_map, val;
 	unsigned long flags;
 
-	if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
-		return -EFAULT;
+	/* Ensure another thread doesn't free it under us */
+	spin_lock_irqsave(&kbd_event_lock, flags);
+	key_map = key_maps[map];
+	if (key_map) {
+		val = U(key_map[idx]);
+		if (kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
+			val = K_HOLE;
+	} else
+		val = idx ? K_HOLE : K_NOSUCHMAP;
+	spin_unlock_irqrestore(&kbd_event_lock, flags);
 
-	if (!capable(CAP_SYS_TTY_CONFIG))
-		perm = 0;
+	return val;
+}
 
-	switch (cmd) {
-	case KDGKBENT:
-		/* Ensure another thread doesn't free it under us */
+static int vt_kdskbent(unsigned char kbdmode, unsigned char idx,
+		unsigned char map, unsigned short val)
+{
+	unsigned long flags;
+	unsigned short *key_map, *new_map, oldval;
+
+	if (!idx && val == K_NOSUCHMAP) {
 		spin_lock_irqsave(&kbd_event_lock, flags);
-		key_map = key_maps[s];
-		if (key_map) {
-		    val = U(key_map[i]);
-		    if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
-			val = K_HOLE;
-		} else
-		    val = (i ? K_HOLE : K_NOSUCHMAP);
-		spin_unlock_irqrestore(&kbd_event_lock, flags);
-		return put_user(val, &user_kbe->kb_value);
-	case KDSKBENT:
-		if (!perm)
-			return -EPERM;
-		if (!i && v == K_NOSUCHMAP) {
-			spin_lock_irqsave(&kbd_event_lock, flags);
-			/* deallocate map */
-			key_map = key_maps[s];
-			if (s && key_map) {
-			    key_maps[s] = NULL;
-			    if (key_map[0] == U(K_ALLOCATED)) {
-					kfree(key_map);
-					keymap_count--;
-			    }
+		/* deallocate map */
+		key_map = key_maps[map];
+		if (map && key_map) {
+			key_maps[map] = NULL;
+			if (key_map[0] == U(K_ALLOCATED)) {
+				kfree(key_map);
+				keymap_count--;
 			}
-			spin_unlock_irqrestore(&kbd_event_lock, flags);
-			break;
 		}
+		spin_unlock_irqrestore(&kbd_event_lock, flags);
 
-		if (KTYP(v) < NR_TYPES) {
-		    if (KVAL(v) > max_vals[KTYP(v)])
-				return -EINVAL;
-		} else
-		    if (kb->kbdmode != VC_UNICODE)
-				return -EINVAL;
+		return 0;
+	}
 
-		/* ++Geert: non-PC keyboards may generate keycode zero */
+	if (KTYP(val) < NR_TYPES) {
+		if (KVAL(val) > max_vals[KTYP(val)])
+			return -EINVAL;
+	} else if (kbdmode != VC_UNICODE)
+		return -EINVAL;
+
+	/* ++Geert: non-PC keyboards may generate keycode zero */
 #if !defined(__mc68000__) && !defined(__powerpc__)
-		/* assignment to entry 0 only tests validity of args */
-		if (!i)
-			break;
+	/* assignment to entry 0 only tests validity of args */
+	if (!idx)
+		return 0;
 #endif
 
-		new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
-		if (!new_map)
-			return -ENOMEM;
-		spin_lock_irqsave(&kbd_event_lock, flags);
-		key_map = key_maps[s];
-		if (key_map == NULL) {
-			int j;
-
-			if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
-			    !capable(CAP_SYS_RESOURCE)) {
-				spin_unlock_irqrestore(&kbd_event_lock, flags);
-				kfree(new_map);
-				return -EPERM;
-			}
-			key_maps[s] = new_map;
-			key_map = new_map;
-			key_map[0] = U(K_ALLOCATED);
-			for (j = 1; j < NR_KEYS; j++)
-				key_map[j] = U(K_HOLE);
-			keymap_count++;
-		} else
-			kfree(new_map);
+	new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
 
-		ov = U(key_map[i]);
-		if (v == ov)
-			goto out;
-		/*
-		 * Attention Key.
-		 */
-		if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
+	spin_lock_irqsave(&kbd_event_lock, flags);
+	key_map = key_maps[map];
+	if (key_map == NULL) {
+		int j;
+
+		if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
+		    !capable(CAP_SYS_RESOURCE)) {
 			spin_unlock_irqrestore(&kbd_event_lock, flags);
+			kfree(new_map);
 			return -EPERM;
 		}
-		key_map[i] = U(v);
-		if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
-			do_compute_shiftstate();
-out:
+		key_maps[map] = new_map;
+		key_map = new_map;
+		key_map[0] = U(K_ALLOCATED);
+		for (j = 1; j < NR_KEYS; j++)
+			key_map[j] = U(K_HOLE);
+		keymap_count++;
+	} else
+		kfree(new_map);
+
+	oldval = U(key_map[idx]);
+	if (val == oldval)
+		goto out;
+
+	/* Attention Key */
+	if ((oldval == K_SAK || val == K_SAK) && !capable(CAP_SYS_ADMIN)) {
 		spin_unlock_irqrestore(&kbd_event_lock, flags);
-		break;
+		return -EPERM;
+	}
+
+	key_map[idx] = U(val);
+	if (!map && (KTYP(oldval) == KT_SHIFT || KTYP(val) == KT_SHIFT))
+		do_compute_shiftstate();
+out:
+	spin_unlock_irqrestore(&kbd_event_lock, flags);
+
+	return 0;
+}
+
+int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
+						int console)
+{
+	struct kbd_struct *kb = kbd_table + console;
+	struct kbentry kbe;
+
+	if (copy_from_user(&kbe, user_kbe, sizeof(struct kbentry)))
+		return -EFAULT;
+
+	if (!capable(CAP_SYS_TTY_CONFIG))
+		perm = 0;
+
+	switch (cmd) {
+	case KDGKBENT:
+		return put_user(vt_kdgkbent(kb->kbdmode, kbe.kb_index,
+					kbe.kb_table),
+				&user_kbe->kb_value);
+	case KDSKBENT:
+		if (!perm)
+			return -EPERM;
+		return vt_kdskbent(kb->kbdmode, kbe.kb_index, kbe.kb_table,
+				kbe.kb_value);
 	}
 	return 0;
 }
-#undef i
-#undef s
-#undef v
 
 /* FIXME: This one needs untangling */
 int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
-- 
2.29.1


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

* [PATCH 07/17] vt: keyboard, union perm checks in vt_do_kdsk_ioctl
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (4 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 06/17] vt: keyboard, extract vt_kdgkbent and vt_kdskbent Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 08/17] vt: keyboard, use DECLARE_BITMAP for key_down Jiri Slaby
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Do the permission check on a single place. That is where perm is really
checked.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index c1709b8dbb52..823df9bb52b1 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -2004,16 +2004,13 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
 	if (copy_from_user(&kbe, user_kbe, sizeof(struct kbentry)))
 		return -EFAULT;
 
-	if (!capable(CAP_SYS_TTY_CONFIG))
-		perm = 0;
-
 	switch (cmd) {
 	case KDGKBENT:
 		return put_user(vt_kdgkbent(kb->kbdmode, kbe.kb_index,
 					kbe.kb_table),
 				&user_kbe->kb_value);
 	case KDSKBENT:
-		if (!perm)
+		if (!perm || !capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
 		return vt_kdskbent(kb->kbdmode, kbe.kb_index, kbe.kb_table,
 				kbe.kb_value);
-- 
2.29.1


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

* [PATCH 08/17] vt: keyboard, use DECLARE_BITMAP for key_down
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (5 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 07/17] vt: keyboard, union perm checks in vt_do_kdsk_ioctl Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 09/17] vt: keyboard, use bool for rep Jiri Slaby
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

key_down is sued as a bitmap using test_bit, set_bit and similar.
So declare it using DECLARE_BITMAP to make it obvious even from the
declaration.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 823df9bb52b1..c4791f33c145 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -135,7 +135,7 @@ static struct input_handler kbd_handler;
 static DEFINE_SPINLOCK(kbd_event_lock);
 static DEFINE_SPINLOCK(led_lock);
 static DEFINE_SPINLOCK(func_buf_lock); /* guard 'func_buf'  and friends */
-static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];	/* keyboard key bitmap */
+static DECLARE_BITMAP(key_down, KEY_CNT);	/* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];		/* shift state counters.. */
 static bool dead_key_next;
 
-- 
2.29.1


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

* [PATCH 09/17] vt: keyboard, use bool for rep
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (6 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 08/17] vt: keyboard, use DECLARE_BITMAP for key_down Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 10/17] vt: keyboard, rename i to kb_func in vt_do_kdgkb_ioctl Jiri Slaby
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

rep is used as a bool in the code, so declare it as such.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index c4791f33c145..e47a1c6bfa44 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -144,7 +144,7 @@ static bool npadch_active;
 static unsigned int npadch_value;
 
 static unsigned int diacr;
-static char rep;					/* flag telling character repeat */
+static bool rep;			/* flag telling character repeat */
 
 static int shift_state = 0;
 
-- 
2.29.1


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

* [PATCH 10/17] vt: keyboard, rename i to kb_func in vt_do_kdgkb_ioctl
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (7 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 09/17] vt: keyboard, use bool for rep Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 11/17] vt: keyboard, reorder user buffer handling " Jiri Slaby
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

There are too many one-letter variables in vt_do_kdgkb_ioctl which is
rather confusing.  Rename 'i' to 'kb_func' and change its type to be the
same as its originating value (struct kbsentry.kb_func) -- unsigned
char.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index e47a1c6bfa44..55014f57a3de 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -2026,9 +2026,10 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 	int sz, fnw_sz;
 	int delta;
 	char *first_free, *fj, *fnw;
-	int i, j, k;
+	int j, k;
 	int ret;
 	unsigned long flags;
+	unsigned char kb_func;
 
 	if (!capable(CAP_SYS_TTY_CONFIG))
 		perm = 0;
@@ -2045,7 +2046,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		goto reterr;
 	}
 	kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
-	i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
+	kb_func = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
 
 	switch (cmd) {
 	case KDGKBSENT: {
@@ -2053,7 +2054,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		ssize_t len = sizeof(user_kdgkb->kb_string);
 
 		spin_lock_irqsave(&func_buf_lock, flags);
-		len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
+		len = strlcpy(kbs->kb_string, func_table[kb_func] ? : "", len);
 		spin_unlock_irqrestore(&func_buf_lock, flags);
 
 		ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
@@ -2072,11 +2073,11 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		/* race aginst other writers */
 		again:
 		spin_lock_irqsave(&func_buf_lock, flags);
-		q = func_table[i];
+		q = func_table[kb_func];
 
 		/* fj pointer to next entry after 'q' */
 		first_free = funcbufptr + (funcbufsize - funcbufleft);
-		for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
+		for (j = kb_func + 1; j < MAX_NR_FUNC && !func_table[j]; j++)
 			;
 		if (j < MAX_NR_FUNC)
 			fj = func_table[j];
@@ -2094,7 +2095,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 				func_table[k] += delta;
 		    }
 		    if (!q)
-		      func_table[i] = fj;
+		      func_table[kb_func] = fj;
 		    funcbufleft -= delta;
 		} else {			/* allocate a larger buffer */
 		    sz = 256;
@@ -2113,7 +2114,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		    }
 
 		    if (!q)
-		      func_table[i] = fj;
+		      func_table[kb_func] = fj;
 		    /* copy data before insertion point to new location */
 		    if (fj > funcbufptr)
 			memmove(fnw, funcbufptr, fj - funcbufptr);
@@ -2135,7 +2136,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		    funcbufsize = sz;
 		}
 		/* finally insert item itself */
-		strcpy(func_table[i], kbs->kb_string);
+		strcpy(func_table[kb_func], kbs->kb_string);
 		spin_unlock_irqrestore(&func_buf_lock, flags);
 		break;
 	}
-- 
2.29.1


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

* [PATCH 11/17] vt: keyboard, reorder user buffer handling in vt_do_kdgkb_ioctl
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (8 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 10/17] vt: keyboard, rename i to kb_func in vt_do_kdgkb_ioctl Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 12/17] vt: keyboard, extract and simplify vt_kdskbsent Jiri Slaby
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

KDGKBSENT (the getter) needs only 'user_kdgkb->kb_func' from the
userspace, i.e. the index. Then it needs a buffer for a local copy of
'kb_string'.

KDSKBSENT (the setter) needs a copy up to the length of
'user_kdgkb->kb_string'.

That means, we obtain the index before the switch-case and use it in
both paths and:
1) allocate full space in the getter case, and
2) copy the string only in the setter case. We do it by strndup_user
   helper now which was not available when this function was written.

Given we copy the two members of 'struct kbsentry' separately, we no
longer need a local definition. Hence we need to change all the sizeofs
here too.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 42 +++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 55014f57a3de..81afe0438b34 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -2021,7 +2021,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
 /* FIXME: This one needs untangling */
 int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 {
-	struct kbsentry *kbs;
+	char *kbs;
 	u_char *q;
 	int sz, fnw_sz;
 	int delta;
@@ -2034,39 +2034,37 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 	if (!capable(CAP_SYS_TTY_CONFIG))
 		perm = 0;
 
-	kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
-	if (!kbs) {
-		ret = -ENOMEM;
-		goto reterr;
-	}
+	if (get_user(kb_func, &user_kdgkb->kb_func))
+		return -EFAULT;
 
-	/* we mostly copy too much here (512bytes), but who cares ;) */
-	if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
-		ret = -EFAULT;
-		goto reterr;
-	}
-	kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
-	kb_func = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
+	kb_func = array_index_nospec(kb_func, MAX_NR_FUNC);
 
 	switch (cmd) {
 	case KDGKBSENT: {
 		/* size should have been a struct member */
 		ssize_t len = sizeof(user_kdgkb->kb_string);
 
+		kbs = kmalloc(len, GFP_KERNEL);
+		if (!kbs)
+			return -ENOMEM;
+
 		spin_lock_irqsave(&func_buf_lock, flags);
-		len = strlcpy(kbs->kb_string, func_table[kb_func] ? : "", len);
+		len = strlcpy(kbs, func_table[kb_func] ? : "", len);
 		spin_unlock_irqrestore(&func_buf_lock, flags);
 
-		ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
-				len + 1) ? -EFAULT : 0;
+		ret = copy_to_user(user_kdgkb->kb_string, kbs, len + 1) ?
+			-EFAULT : 0;
 
 		goto reterr;
 	}
 	case KDSKBSENT:
-		if (!perm) {
-			ret = -EPERM;
-			goto reterr;
-		}
+		if (!perm)
+			return -EPERM;
+
+		kbs = strndup_user(user_kdgkb->kb_string,
+				sizeof(user_kdgkb->kb_string));
+		if (IS_ERR(kbs))
+			return PTR_ERR(kbs);
 
 		fnw = NULL;
 		fnw_sz = 0;
@@ -2084,7 +2082,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		else
 			fj = first_free;
 		/* buffer usage increase by new entry */
-		delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
+		delta = (q ? -strlen(q) : 1) + strlen(kbs);
 
 		if (delta <= funcbufleft) { 	/* it fits in current buf */
 		    if (j < MAX_NR_FUNC) {
@@ -2136,7 +2134,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		    funcbufsize = sz;
 		}
 		/* finally insert item itself */
-		strcpy(func_table[kb_func], kbs->kb_string);
+		strcpy(func_table[kb_func], kbs);
 		spin_unlock_irqrestore(&func_buf_lock, flags);
 		break;
 	}
-- 
2.29.1


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

* [PATCH 12/17] vt: keyboard, extract and simplify vt_kdskbsent
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (9 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 11/17] vt: keyboard, reorder user buffer handling " Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 13/17] vt: keyboard, remove unneeded func_* declarations Jiri Slaby
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Setting of function key strings is now very complex. It uses a global
buffer 'func_buf' which is prefilled in defkeymap.c_shipped. Then there
is also an index table called 'func_table'. So initially, we have
something like this:
char func_buf[] =	"\e[[A\0" // for F1
			"\e[[B\0" // for F2
			...;
char *func_table[] = {
	func_buf + 0, // for F1
	func_buf + 5, // for F2
	... }

When a user changes some specific func string by KDSKBSENT, it is
changed in 'func_buf'. If it is shorter or equal to the current one, it
is handled by a very quick 'strcpy'.

When the user's string is longer, the whole 'func_buf' is reallocated to
allow expansion somewhere in the middle. The buffer before the user's
string is copied, the user's string appended and the rest appended too.
Now, the index table (func_table) needs to be recomputed, of course.
One more complication is the held spinlock -- we have to unlock,
reallocate, lock again and do the whole thing again to be sure noone
raced with us.

In this patch, we chose completely orthogonal approach: when the user's
string is longer than the current one, we simply assign the 'kstrdup'ed
copy to the index table (func_table) and modify func_buf in no way. We
only need to make sure we free the old entries. So we need a bitmap
is_kmalloc and free the old entries (but not the original func_buf
rodata string).

Also note that we do not waste so much space as previous approach. We
only allocate space for single entries which are longer, while before,
the whole buffer was duplicated plus space for the longer string.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 102 +++++++++-----------------------------
 1 file changed, 23 insertions(+), 79 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 81afe0438b34..648bdfb05e25 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -2018,18 +2018,27 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
 	return 0;
 }
 
-/* FIXME: This one needs untangling */
+static char *vt_kdskbsent(char *kbs, unsigned char cur)
+{
+	static DECLARE_BITMAP(is_kmalloc, MAX_NR_FUNC);
+	char *cur_f = func_table[cur];
+
+	if (cur_f && strlen(cur_f) >= strlen(kbs)) {
+		strcpy(cur_f, kbs);
+		return kbs;
+	}
+
+	func_table[cur] = kbs;
+
+	return __test_and_set_bit(cur, is_kmalloc) ? cur_f : NULL;
+}
+
 int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 {
+	unsigned char kb_func;
+	unsigned long flags;
 	char *kbs;
-	u_char *q;
-	int sz, fnw_sz;
-	int delta;
-	char *first_free, *fj, *fnw;
-	int j, k;
 	int ret;
-	unsigned long flags;
-	unsigned char kb_func;
 
 	if (!capable(CAP_SYS_TTY_CONFIG))
 		perm = 0;
@@ -2055,7 +2064,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		ret = copy_to_user(user_kdgkb->kb_string, kbs, len + 1) ?
 			-EFAULT : 0;
 
-		goto reterr;
+		break;
 	}
 	case KDSKBSENT:
 		if (!perm)
@@ -2066,81 +2075,16 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		if (IS_ERR(kbs))
 			return PTR_ERR(kbs);
 
-		fnw = NULL;
-		fnw_sz = 0;
-		/* race aginst other writers */
-		again:
 		spin_lock_irqsave(&func_buf_lock, flags);
-		q = func_table[kb_func];
-
-		/* fj pointer to next entry after 'q' */
-		first_free = funcbufptr + (funcbufsize - funcbufleft);
-		for (j = kb_func + 1; j < MAX_NR_FUNC && !func_table[j]; j++)
-			;
-		if (j < MAX_NR_FUNC)
-			fj = func_table[j];
-		else
-			fj = first_free;
-		/* buffer usage increase by new entry */
-		delta = (q ? -strlen(q) : 1) + strlen(kbs);
-
-		if (delta <= funcbufleft) { 	/* it fits in current buf */
-		    if (j < MAX_NR_FUNC) {
-			/* make enough space for new entry at 'fj' */
-			memmove(fj + delta, fj, first_free - fj);
-			for (k = j; k < MAX_NR_FUNC; k++)
-			    if (func_table[k])
-				func_table[k] += delta;
-		    }
-		    if (!q)
-		      func_table[kb_func] = fj;
-		    funcbufleft -= delta;
-		} else {			/* allocate a larger buffer */
-		    sz = 256;
-		    while (sz < funcbufsize - funcbufleft + delta)
-		      sz <<= 1;
-		    if (fnw_sz != sz) {
-		      spin_unlock_irqrestore(&func_buf_lock, flags);
-		      kfree(fnw);
-		      fnw = kmalloc(sz, GFP_KERNEL);
-		      fnw_sz = sz;
-		      if (!fnw) {
-			ret = -ENOMEM;
-			goto reterr;
-		      }
-		      goto again;
-		    }
-
-		    if (!q)
-		      func_table[kb_func] = fj;
-		    /* copy data before insertion point to new location */
-		    if (fj > funcbufptr)
-			memmove(fnw, funcbufptr, fj - funcbufptr);
-		    for (k = 0; k < j; k++)
-		      if (func_table[k])
-			func_table[k] = fnw + (func_table[k] - funcbufptr);
-
-		    /* copy data after insertion point to new location */
-		    if (first_free > fj) {
-			memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
-			for (k = j; k < MAX_NR_FUNC; k++)
-			  if (func_table[k])
-			    func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
-		    }
-		    if (funcbufptr != func_buf)
-		      kfree(funcbufptr);
-		    funcbufptr = fnw;
-		    funcbufleft = funcbufleft - delta + sz - funcbufsize;
-		    funcbufsize = sz;
-		}
-		/* finally insert item itself */
-		strcpy(func_table[kb_func], kbs);
+		kbs = vt_kdskbsent(kbs, kb_func);
 		spin_unlock_irqrestore(&func_buf_lock, flags);
+
+		ret = 0;
 		break;
 	}
-	ret = 0;
-reterr:
+
 	kfree(kbs);
+
 	return ret;
 }
 
-- 
2.29.1


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

* [PATCH 13/17] vt: keyboard, remove unneeded func_* declarations
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (10 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 12/17] vt: keyboard, extract and simplify vt_kdskbsent Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 14/17] vt: keyboard, union perm checks in vt_do_kdgkb_ioctl Jiri Slaby
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Now that we removed the ugly handling of func_buf, remove unneeded
declarations of func_* variables. The definitions are in the generated
defkeymap.c_shipped, so we cannot really remove them (but we would love
to).

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/kbd_kern.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index bb2246c8ec13..82f29aa35062 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -9,9 +9,6 @@
 extern struct tasklet_struct keyboard_tasklet;
 
 extern char *func_table[MAX_NR_FUNC];
-extern char func_buf[];
-extern char *funcbufptr;
-extern int funcbufsize, funcbufleft;
 
 /*
  * kbd->xxx contains the VC-local things (flag settings etc..)
-- 
2.29.1


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

* [PATCH 14/17] vt: keyboard, union perm checks in vt_do_kdgkb_ioctl
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (11 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 13/17] vt: keyboard, remove unneeded func_* declarations Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 15/17] vt: keyboard, make HW_RAW a function Jiri Slaby
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Do the permission check on a single place. That is where perm is
really checked.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 648bdfb05e25..1de0d5217aed 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -2040,9 +2040,6 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 	char *kbs;
 	int ret;
 
-	if (!capable(CAP_SYS_TTY_CONFIG))
-		perm = 0;
-
 	if (get_user(kb_func, &user_kdgkb->kb_func))
 		return -EFAULT;
 
@@ -2067,7 +2064,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 		break;
 	}
 	case KDSKBSENT:
-		if (!perm)
+		if (!perm || !capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
 
 		kbs = strndup_user(user_kdgkb->kb_string,
-- 
2.29.1


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

* [PATCH 15/17] vt: keyboard, make HW_RAW a function
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (12 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 14/17] vt: keyboard, union perm checks in vt_do_kdgkb_ioctl Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 16/17] vt: keyboard, use find_next_bit in kbd_match Jiri Slaby
  2020-10-29 11:32 ` [PATCH 17/17] vt: keyboard, use tty_insert_flip_string in puts_queue Jiri Slaby
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Instead of a multiline macro, convert HW_RAW to an inline function. It
allows for type checking of the parameter. And given we split the code
into two tests, it is now more readable too.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 1de0d5217aed..dea2f25a5d9f 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1259,8 +1259,14 @@ DECLARE_TASKLET_DISABLED_OLD(keyboard_tasklet, kbd_bh);
     defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
     (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
 
-#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
-			((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
+static inline bool kbd_is_hw_raw(const struct input_dev *dev)
+{
+	if (!test_bit(EV_MSC, dev->evbit) || !test_bit(MSC_RAW, dev->mscbit))
+		return false;
+
+	return dev->id.bustype == BUS_I8042 &&
+		dev->id.vendor == 0x0001 && dev->id.product == 0x0001;
+}
 
 static const unsigned short x86_keycodes[256] =
 	{ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
@@ -1345,7 +1351,10 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
 
 #else
 
-#define HW_RAW(dev)	0
+static inline bool kbd_is_hw_raw(const struct input_dev *dev)
+{
+	return false;
+}
 
 static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
 {
@@ -1366,7 +1375,7 @@ static void kbd_rawcode(unsigned char data)
 		put_queue(vc, data);
 }
 
-static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
+static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
 	unsigned short keysym, *key_map;
@@ -1511,10 +1520,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
 	/* We are called with interrupts disabled, just take the lock */
 	spin_lock(&kbd_event_lock);
 
-	if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
+	if (event_type == EV_MSC && event_code == MSC_RAW &&
+			kbd_is_hw_raw(handle->dev))
 		kbd_rawcode(value);
 	if (event_type == EV_KEY && event_code <= KEY_MAX)
-		kbd_keycode(event_code, value, HW_RAW(handle->dev));
+		kbd_keycode(event_code, value, kbd_is_hw_raw(handle->dev));
 
 	spin_unlock(&kbd_event_lock);
 
-- 
2.29.1


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

* [PATCH 16/17] vt: keyboard, use find_next_bit in kbd_match
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (13 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 15/17] vt: keyboard, make HW_RAW a function Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  2020-10-29 11:32 ` [PATCH 17/17] vt: keyboard, use tty_insert_flip_string in puts_queue Jiri Slaby
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Instead of a 'for' loop with 'test_bit's to find a bit in a range, use
find_next_bit to achieve the same in a simpler and faster manner.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index dea2f25a5d9f..149f1791d7ec 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1535,18 +1535,16 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
 
 static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
 {
-	int i;
-
 	if (test_bit(EV_SND, dev->evbit))
 		return true;
 
 	if (test_bit(EV_KEY, dev->evbit)) {
-		for (i = KEY_RESERVED; i < BTN_MISC; i++)
-			if (test_bit(i, dev->keybit))
-				return true;
-		for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
-			if (test_bit(i, dev->keybit))
-				return true;
+		if (find_next_bit(dev->keybit, BTN_MISC, KEY_RESERVED) <
+				BTN_MISC)
+			return true;
+		if (find_next_bit(dev->keybit, KEY_BRL_DOT10 + 1,
+					KEY_BRL_DOT1) <= KEY_BRL_DOT10)
+			return true;
 	}
 
 	return false;
-- 
2.29.1


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

* [PATCH 17/17] vt: keyboard, use tty_insert_flip_string in puts_queue
  2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
                   ` (14 preceding siblings ...)
  2020-10-29 11:32 ` [PATCH 16/17] vt: keyboard, use find_next_bit in kbd_match Jiri Slaby
@ 2020-10-29 11:32 ` Jiri Slaby
  15 siblings, 0 replies; 17+ messages in thread
From: Jiri Slaby @ 2020-10-29 11:32 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

'puts_queue' currently loops over characters and employs the full tty
buffer machinery for every character. Do the buffer allocation only once
and copy all the character at once. This is achieved using
tty_insert_flip_string instead of loop+tty_insert_flip_char.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/keyboard.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 149f1791d7ec..56b5e8f8fe88 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -324,12 +324,9 @@ static void put_queue(struct vc_data *vc, int ch)
 	tty_schedule_flip(&vc->port);
 }
 
-static void puts_queue(struct vc_data *vc, char *cp)
+static void puts_queue(struct vc_data *vc, const char *cp)
 {
-	while (*cp) {
-		tty_insert_flip_char(&vc->port, *cp, 0);
-		cp++;
-	}
+	tty_insert_flip_string(&vc->port, cp, strlen(cp));
 	tty_schedule_flip(&vc->port);
 }
 
-- 
2.29.1


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

end of thread, other threads:[~2020-10-29 11:33 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-29 11:32 [PATCH 01/17] vt: keyboard, remove ctrl_alt_del declaration Jiri Slaby
2020-10-29 11:32 ` [PATCH 02/17] vt: keyboard, include linux/spinlock.h Jiri Slaby
2020-10-29 11:32 ` [PATCH 03/17] vt: keyboard, sort includes Jiri Slaby
2020-10-29 11:32 ` [PATCH 04/17] vt: keyboard, sort key types by their number Jiri Slaby
2020-10-29 11:32 ` [PATCH 05/17] vt: keyboard, clean up max_vals Jiri Slaby
2020-10-29 11:32 ` [PATCH 06/17] vt: keyboard, extract vt_kdgkbent and vt_kdskbent Jiri Slaby
2020-10-29 11:32 ` [PATCH 07/17] vt: keyboard, union perm checks in vt_do_kdsk_ioctl Jiri Slaby
2020-10-29 11:32 ` [PATCH 08/17] vt: keyboard, use DECLARE_BITMAP for key_down Jiri Slaby
2020-10-29 11:32 ` [PATCH 09/17] vt: keyboard, use bool for rep Jiri Slaby
2020-10-29 11:32 ` [PATCH 10/17] vt: keyboard, rename i to kb_func in vt_do_kdgkb_ioctl Jiri Slaby
2020-10-29 11:32 ` [PATCH 11/17] vt: keyboard, reorder user buffer handling " Jiri Slaby
2020-10-29 11:32 ` [PATCH 12/17] vt: keyboard, extract and simplify vt_kdskbsent Jiri Slaby
2020-10-29 11:32 ` [PATCH 13/17] vt: keyboard, remove unneeded func_* declarations Jiri Slaby
2020-10-29 11:32 ` [PATCH 14/17] vt: keyboard, union perm checks in vt_do_kdgkb_ioctl Jiri Slaby
2020-10-29 11:32 ` [PATCH 15/17] vt: keyboard, make HW_RAW a function Jiri Slaby
2020-10-29 11:32 ` [PATCH 16/17] vt: keyboard, use find_next_bit in kbd_match Jiri Slaby
2020-10-29 11:32 ` [PATCH 17/17] vt: keyboard, use tty_insert_flip_string in puts_queue Jiri Slaby

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).