git: f958aa7e754d - main - vt: Fix timer race between vtterm_splash() and vt_flush()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 02 Oct 2026 02:20:58 UTC
The branch main has been updated by vexeduxr:
URL: https://cgit.FreeBSD.org/src/commit/?id=f958aa7e754d88f3955f3c30a13f0e492822e3c3
commit f958aa7e754d88f3955f3c30a13f0e492822e3c3
Author: Quentin Thébault <quentin.thebault@defenso.fr>
AuthorDate: 2026-09-30 01:42:33 +0000
Commit: Ahmad Khalifa <vexeduxr@FreeBSD.org>
CommitDate: 2026-10-02 02:13:15 +0000
vt: Fix timer race between vtterm_splash() and vt_flush()
Current code leads to console text being drawn over the splash image.
vt_flush() draws while holding the vtbuf lock. Have it check VDF_SPLASH
under it too, and make vtterm_splash() take the vtbuf lock when setting
it, before drawing the splash.
Sponsored by: Defenso
Signed-off-by: Quentin Thébault <quentin.thebault@defenso.fr>
Reviewed by: vexeduxr
Differential Revision: https://reviews.freebsd.org/D59928
---
sys/dev/vt/vt_core.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 0030a3868219..0ea2ec58f4cc 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -1501,7 +1501,7 @@ vt_flush(struct vt_device *vd)
if (vw == NULL)
return (0);
- if (vd->vd_flags & VDF_SPLASH || vw->vw_flags & VWF_BUSY)
+ if (vw->vw_flags & VWF_BUSY)
return (0);
vf = vw->vw_font;
@@ -1511,6 +1511,13 @@ vt_flush(struct vt_device *vd)
VT_FLUSH_LOCK(vd);
vtbuf_lock(&vw->vw_buf);
+
+ if (vd->vd_flags & VDF_SPLASH) {
+ vtbuf_unlock(&vw->vw_buf);
+ VT_FLUSH_UNLOCK(vd);
+ return (0);
+ }
+
inside_vt_flush = true;
#ifndef SC_NO_CUTPASTE
@@ -1697,17 +1704,21 @@ vtterm_splash(struct vt_device *vd)
si = MD_FETCH(preload_kmdp, rebooting == 1 ? MODINFOMD_SHTDWNSPLASH :
MODINFOMD_SPLASH, struct splash_info *);
+ /* Quit before taking the lock if the backend lacks something. */
if (si == NULL) {
if (vd->vd_driver->vd_bitblt_bmp == NULL)
return;
- } else if (vd->vd_driver->vd_bitblt_argb == NULL)
+ } else if (vd->vd_driver->vd_bitblt_argb == NULL || si->si_depth != 4)
+ return;
+ if (rebooting == 1 && vd->vd_driver->vd_blank == NULL)
return;
- if (rebooting == 1) {
- if (vd->vd_driver->vd_blank == NULL)
- return;
+ vtbuf_lock(&vd->vd_curwindow->vw_buf);
+ vd->vd_flags |= VDF_SPLASH;
+ vtbuf_unlock(&vd->vd_curwindow->vw_buf);
+
+ if (rebooting == 1)
vd->vd_driver->vd_blank(vd, TC_BLACK);
- }
if (si == NULL) {
top = (vd->vd_height - vt_logo_height) / 2;
@@ -1716,8 +1727,6 @@ vtterm_splash(struct vt_device *vd)
vd->vd_curwindow, vt_logo_image, NULL, vt_logo_width,
vt_logo_height, left, top, TC_WHITE, TC_BLACK);
} else {
- if (si->si_depth != 4)
- return;
image = (uintptr_t)si + sizeof(struct splash_info);
image = roundup2(image, 8);
top = (vd->vd_height - si->si_height) / 2;
@@ -1726,7 +1735,6 @@ vtterm_splash(struct vt_device *vd)
(unsigned char *)image, si->si_width, si->si_height,
left, top);
}
- vd->vd_flags |= VDF_SPLASH;
}
#endif