* [PATCH 1/3] vt: order the fg_console switch against vt_console_print()
2026-09-22 1:27 [PATCH 0/3] vt: make the console_lock ordering explicit for three variables Jaidev Shastri via B4 Relay
@ 2026-09-22 1:27 ` Jaidev Shastri via B4 Relay
2026-09-23 12:50 ` Greg Kroah-Hartman
2026-09-22 1:27 ` [PATCH 2/3] vt: order console_blanked between blanking and unblanking Jaidev Shastri via B4 Relay
2026-09-22 1:27 ` [PATCH 3/3] vt: order the vc_cons[] clear against console_callback() Jaidev Shastri via B4 Relay
2 siblings, 1 reply; 5+ messages in thread
From: Jaidev Shastri via B4 Relay @ 2026-09-22 1:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby; +Cc: linux-kernel, linux-serial, Jaidev Shastri
From: Jaidev Shastri <jaidevshastri@vt.edu>
redraw_screen() switches fg_console with a plain store once the new
console's state is set up. vt_console_print(), the printk console
callback, indexes vc_cons[] with fg_console before it takes
printing_lock.
Store the new index with smp_store_release() and read it with
smp_load_acquire(), so that the printk path cannot reach the slot before
the console it denotes is complete.
Found with MBCheck, a static herd7-based memory consistency checker.
Signed-off-by: Jaidev Shastri <jaidevshastri@vt.edu>
---
drivers/tty/vt/vt.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 57edf3749..3abbd6cf9 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -973,7 +973,8 @@ void redraw_screen(struct vc_data *vc, int is_switch)
if (!con_is_visible(vc))
redraw = 1;
*vc->vc_display_fg = vc;
- fg_console = vc->vc_num;
+ /* Pairs with the smp_load_acquire() in vt_console_print(). */
+ smp_store_release(&fg_console, vc->vc_num);
hide_cursor(old_vc);
if (!con_is_visible(old_vc)) {
save_screen(old_vc);
@@ -3447,7 +3448,8 @@ int vt_kmsg_redirect(int new)
static void vt_console_print(struct console *co, const char *b, unsigned count)
{
- struct vc_data *vc = vc_cons[fg_console].d;
+ /* Pairs with the smp_store_release() in redraw_screen(). */
+ struct vc_data *vc = vc_cons[smp_load_acquire(&fg_console)].d;
unsigned char c;
static DEFINE_SPINLOCK(printing_lock);
const ushort *start;
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 1/3] vt: order the fg_console switch against vt_console_print()
2026-09-22 1:27 ` [PATCH 1/3] vt: order the fg_console switch against vt_console_print() Jaidev Shastri via B4 Relay
@ 2026-09-23 12:50 ` Greg Kroah-Hartman
0 siblings, 0 replies; 5+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-23 12:50 UTC (permalink / raw)
To: jaidevshastri; +Cc: Jiri Slaby, linux-kernel, linux-serial
On Mon, Sep 21, 2026 at 09:27:14PM -0400, Jaidev Shastri via B4 Relay wrote:
> From: Jaidev Shastri <jaidevshastri@vt.edu>
>
> redraw_screen() switches fg_console with a plain store once the new
> console's state is set up. vt_console_print(), the printk console
> callback, indexes vc_cons[] with fg_console before it takes
> printing_lock.
>
> Store the new index with smp_store_release() and read it with
> smp_load_acquire(), so that the printk path cannot reach the slot before
> the console it denotes is complete.
>
> Found with MBCheck, a static herd7-based memory consistency checker.
>
> Signed-off-by: Jaidev Shastri <jaidevshastri@vt.edu>
> ---
> drivers/tty/vt/vt.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
> index 57edf3749..3abbd6cf9 100644
> --- a/drivers/tty/vt/vt.c
> +++ b/drivers/tty/vt/vt.c
> @@ -973,7 +973,8 @@ void redraw_screen(struct vc_data *vc, int is_switch)
> if (!con_is_visible(vc))
> redraw = 1;
> *vc->vc_display_fg = vc;
> - fg_console = vc->vc_num;
> + /* Pairs with the smp_load_acquire() in vt_console_print(). */
> + smp_store_release(&fg_console, vc->vc_num);
Using these functions are almost always wrong. Fix things properly, do
not pepper these types of calls all over the kernel, that way lies
madness.
greg k-h
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/3] vt: order console_blanked between blanking and unblanking
2026-09-22 1:27 [PATCH 0/3] vt: make the console_lock ordering explicit for three variables Jaidev Shastri via B4 Relay
2026-09-22 1:27 ` [PATCH 1/3] vt: order the fg_console switch against vt_console_print() Jaidev Shastri via B4 Relay
@ 2026-09-22 1:27 ` Jaidev Shastri via B4 Relay
2026-09-22 1:27 ` [PATCH 3/3] vt: order the vc_cons[] clear against console_callback() Jaidev Shastri via B4 Relay
2 siblings, 0 replies; 5+ messages in thread
From: Jaidev Shastri via B4 Relay @ 2026-09-22 1:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby; +Cc: linux-kernel, linux-serial, Jaidev Shastri
From: Jaidev Shastri <jaidevshastri@vt.edu>
do_blank_screen() records the blanked console in console_blanked with a
plain store, after blank_state and the console state have been updated.
do_unblank_screen() tests console_blanked with a plain load before it
uses that state.
Store it 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@vt.edu>
---
drivers/tty/vt/vt.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3abbd6cf9..726402167 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4683,7 +4683,8 @@ void do_blank_screen(int entering_gfx)
hide_cursor(vc);
save_screen(vc);
vc->vc_sw->con_blank(vc, VESA_VSYNC_SUSPEND, 1);
- console_blanked = fg_console + 1;
+ /* Pairs with the smp_load_acquire() in do_unblank_screen(). */
+ smp_store_release(&console_blanked, fg_console + 1);
blank_state = blank_off;
set_origin(vc);
return;
@@ -4693,7 +4694,8 @@ void do_blank_screen(int entering_gfx)
/* don't blank graphics */
if (vc->vc_mode != KD_TEXT) {
- console_blanked = fg_console + 1;
+ /* Pairs with the smp_load_acquire() in do_unblank_screen(). */
+ smp_store_release(&console_blanked, fg_console + 1);
return;
}
@@ -4705,7 +4707,8 @@ void do_blank_screen(int entering_gfx)
/* In case we need to reset origin, blanking hook returns 1 */
i = vc->vc_sw->con_blank(vc, vesa_off_interval ? VESA_VSYNC_SUSPEND :
(vesa_blank_mode + 1), 0);
- console_blanked = fg_console + 1;
+ /* Pairs with the smp_load_acquire() in do_unblank_screen(). */
+ smp_store_release(&console_blanked, fg_console + 1);
if (i)
set_origin(vc);
@@ -4737,7 +4740,8 @@ void do_unblank_screen(int leaving_gfx)
WARN_CONSOLE_UNLOCKED();
ignore_poke = 0;
- if (!console_blanked)
+ /* Pairs with the smp_store_release() in do_blank_screen(). */
+ if (!smp_load_acquire(&console_blanked))
return;
if (!vc_cons_allocated(fg_console)) {
/* impossible */
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 3/3] vt: order the vc_cons[] clear against console_callback()
2026-09-22 1:27 [PATCH 0/3] vt: make the console_lock ordering explicit for three variables Jaidev Shastri via B4 Relay
2026-09-22 1:27 ` [PATCH 1/3] vt: order the fg_console switch against vt_console_print() Jaidev Shastri via B4 Relay
2026-09-22 1:27 ` [PATCH 2/3] vt: order console_blanked between blanking and unblanking Jaidev Shastri via B4 Relay
@ 2026-09-22 1:27 ` Jaidev Shastri via B4 Relay
2 siblings, 0 replies; 5+ messages in thread
From: Jaidev Shastri via B4 Relay @ 2026-09-22 1:27 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby; +Cc: linux-kernel, linux-serial, Jaidev Shastri
From: Jaidev Shastri <jaidevshastri@vt.edu>
vc_deallocate() frees the console's screen buffer and unimap and then
clears vc_cons[currcons].d with a plain store. console_callback() reads
vc_cons[fg_console].d with a plain load.
Clear the slot 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@vt.edu>
---
drivers/tty/vt/vt.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 726402167..66aa089bf 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1369,7 +1369,8 @@ struct vc_data *vc_deallocate(unsigned int currcons)
put_pid(vc->vt_pid);
vc_uniscr_set(vc, NULL);
kfree(vc->vc_screenbuf);
- vc_cons[currcons].d = NULL;
+ /* Pairs with the smp_load_acquire() in console_callback(). */
+ smp_store_release(&vc_cons[currcons].d, NULL);
if (vc->vc_saved_screen != NULL) {
kfree(vc->vc_saved_screen);
vc->vc_saved_screen = NULL;
@@ -3368,7 +3369,8 @@ static void console_callback(struct work_struct *ignored)
poke_blanked_console();
}
if (scrollback_delta) {
- struct vc_data *vc = vc_cons[fg_console].d;
+ /* Pairs with the smp_store_release() in vc_deallocate(). */
+ struct vc_data *vc = smp_load_acquire(&vc_cons[fg_console].d);
clear_selection();
if (vc->vc_mode == KD_TEXT && vc->vc_sw->con_scrolldelta)
vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread