git: 95007bfd64c6 - stable/14 - vt(4): Skip vt_window_switch() for nested panics
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 17 Feb 2024 21:32:29 UTC
The branch stable/14 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=95007bfd64c63f217c97210cd4cdf2d729f2f696 commit 95007bfd64c63f217c97210cd4cdf2d729f2f696 Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org> AuthorDate: 2023-11-24 17:30:33 +0000 Commit: Vladimir Kondratyev <wulf@FreeBSD.org> CommitDate: 2024-02-17 20:58:34 +0000 vt(4): Skip vt_window_switch() for nested panics [Why] The same protection was added to vt_flush() in the previous commit. We want the same one in vt_window_switch(): if e.g. the DRM driver panics while handling a call to vt_window_switch(), we don't want to recursively call vt_window_switch() again and trigger another panic. Reviewed by: imp, manu Approved by: imp, manu Differential Revision: https://reviews.freebsd.org/D42750 (cherry picked from commit 24d6f256f825e5d7f8ca6b5d16499f13614f9cdd) --- sys/dev/vt/vt_core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index 406472a8fbf6..6d44c81181a3 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -275,6 +275,7 @@ SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, vt_upgrade, &vt_consdev); static bool inside_vt_flush = false; +static bool inside_vt_window_switch = false; /* Initialize locks/mem depended members. */ static void @@ -564,6 +565,11 @@ vt_window_switch(struct vt_window *vw) struct vt_window *curvw = vd->vd_curwindow; keyboard_t *kbd; + if (inside_vt_window_switch && KERNEL_PANICKED()) + return (0); + + inside_vt_window_switch = true; + if (kdb_active) { /* * When grabbing the console for the debugger, avoid @@ -575,13 +581,16 @@ vt_window_switch(struct vt_window *vw) */ if (curvw == vw) return (0); - if (!(vw->vw_flags & (VWF_OPENED|VWF_CONSOLE))) + if (!(vw->vw_flags & (VWF_OPENED|VWF_CONSOLE))) { + inside_vt_window_switch = false; return (EINVAL); + } vd->vd_curwindow = vw; vd->vd_flags |= VDF_INVALID; if (vd->vd_driver->vd_postswitch) vd->vd_driver->vd_postswitch(vd); + inside_vt_window_switch = false; return (0); } @@ -595,10 +604,12 @@ vt_window_switch(struct vt_window *vw) if ((kdb_active || KERNEL_PANICKED()) && vd->vd_driver->vd_postswitch) vd->vd_driver->vd_postswitch(vd); + inside_vt_window_switch = false; VT_UNLOCK(vd); return (0); } if (!(vw->vw_flags & (VWF_OPENED|VWF_CONSOLE))) { + inside_vt_window_switch = false; VT_UNLOCK(vd); return (EINVAL); } @@ -627,6 +638,7 @@ vt_window_switch(struct vt_window *vw) mtx_unlock(&Giant); DPRINTF(10, "%s(ttyv%d) done\n", __func__, vw->vw_number); + inside_vt_window_switch = false; return (0); }