git: 24d6f256f825 - main - vt(4): Skip vt_window_switch() for nested panics
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Nov 2023 17:31:56 UTC
The branch main has been updated by dumbbell:
URL: https://cgit.FreeBSD.org/src/commit/?id=24d6f256f825e5d7f8ca6b5d16499f13614f9cdd
commit 24d6f256f825e5d7f8ca6b5d16499f13614f9cdd
Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2023-11-24 17:30:33 +0000
Commit: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
CommitDate: 2023-11-24 17:31:33 +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
---
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);
}