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 <dumbb...@freebsd.org>
AuthorDate: 2023-11-24 17:30:33 +0000
Commit:     Jean-Sébastien Pédron <dumbb...@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);
 }
 

Reply via email to