[PATCH 6/6] vt: keyboard: publish the shift_down[] counters with release semantics

From: Jaidev Shastri via B4 Relay

Date: Mon Sep 21 2026 - 21:33:33 EST


From: Jaidev Shastri <jaidevshastri@xxxxxx>

k_shift() maintains the per-modifier depress counters in shift_down[]
and k_pad() tests shift_down[KG_SHIFT] to choose between application and
numeric keypad codes.

Update the counter with smp_store_release() and read it with
smp_load_acquire().

Found with MBCheck, a static herd7-based memory consistency checker.

Signed-off-by: Jaidev Shastri <jaidevshastri@xxxxxx>
---
drivers/tty/vt/keyboard.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 87970415a..e6112e0db 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -823,7 +823,8 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
return; /* no action, if this is a key release */

/* kludge... shift forces cursor/number keys */
- if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
+ /* Pairs with the smp_store_release() in k_shift(). */
+ if (vc_kbd_mode(kbd, VC_APPLIC) && !smp_load_acquire(&shift_down[KG_SHIFT])) {
applkey(vc, app_map[value], 1);
return;
}
@@ -877,6 +878,7 @@ static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
{
int old_state = shift_state;
int state;
+ unsigned char cnt;

if (rep)
return;
@@ -890,15 +892,18 @@ static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
}

+ cnt = shift_down[value];
if (up_flag) {
/*
* handle the case that two shift or control
* keys are depressed simultaneously
*/
- if (shift_down[value])
- shift_down[value]--;
+ if (cnt)
+ cnt--;
} else
- shift_down[value]++;
+ cnt++;
+ /* Pairs with the smp_load_acquire() in k_pad(). */
+ smp_store_release(&shift_down[value], cnt);

if (shift_down[value])
state = shift_state | BIT(value);

--
2.43.0