Because of the locking changes in the inteldrm(4) update, the code that swicthes to the console framebuffer is pretty much broken. The diff below fixes the issue inteldrm(4) by introducing a new enter_ddb() "accessop" for wsdisplay(4). The implementation of this function should bypass as much of the locking as is feasable. The KMS drivers can implement this by calling drm_fb_helper_debug_enter(). If the function isn't implemented it falls back on using show_screen() which should be sufficient for simple framebuffer drivers like efifb(4).
I'd like to commit this diff ASAP to make sure we get better bug reports for panics that happen wile running X. I'll fix radeondrm(4) in a followup diff. Note that you'll end up in a slightly funny state if you enter the ddb with this diff. The console framebuffer will be visible but we didn't do a complete VT switch. So if you type "continue" X will still e active, but on a framebuffer you don't see. You can easily get out of that sitaution by doing a VT switch to the console and back to X. But I can also look at adding a leave_ddb() "accessop" that switches things back as they were upon leaving ddb. ok? Index: dev/wscons/wsdisplay.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsdisplay.c,v retrieving revision 1.126 diff -u -p -r1.126 wsdisplay.c --- dev/wscons/wsdisplay.c 11 Jan 2017 08:21:33 -0000 1.126 +++ dev/wscons/wsdisplay.c 18 Jul 2017 18:34:15 -0000 @@ -2133,6 +2133,30 @@ wsdisplay_switchtoconsole(void) } /* + * Switch rhe console display to its ddb screen, avoiding locking + * where we can. + */ +void +wsdisplay_enter_ddb(void) +{ + struct wsdisplay_softc *sc; + struct wsscreen *scr; + + if (wsdisplay_console_device != NULL && cn_tab == &wsdisplay_cons) { + sc = wsdisplay_console_device; + if ((scr = sc->sc_scr[0]) == NULL) + return; + if (sc->sc_accessops) { + (*sc->sc_accessops->enter_ddb)(sc->sc_accesscookie, + scr->scr_dconf->emulcookie); + } else { + (*sc->sc_accessops->show_screen)(sc->sc_accesscookie, + scr->scr_dconf->emulcookie, 0, NULL, NULL); + } + } +} + +/* * Deal with the xserver doing driver in userland and thus screwing up suspend * and resume by switching away from it at suspend/resume time. * Index: dev/wscons/wsdisplayvar.h =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsdisplayvar.h,v retrieving revision 1.30 diff -u -p -r1.30 wsdisplayvar.h --- dev/wscons/wsdisplayvar.h 4 Sep 2016 18:20:34 -0000 1.30 +++ dev/wscons/wsdisplayvar.h 18 Jul 2017 18:34:15 -0000 @@ -145,6 +145,7 @@ struct wsdisplay_accessops { int (*getchar)(void *, int, int, struct wsdisplay_charcell *); void (*burn_screen)(void *, u_int, u_int); void (*pollc)(void *, int); + void (*enter_ddb)(void *, void *); }; /* passed to wscons by the video driver to tell about its capabilities */ @@ -229,6 +230,7 @@ int wsdisplay_cfg_ioctl(struct wsdisplay */ #define WSDISPLAY_NULLSCREEN -1 void wsdisplay_switchtoconsole(void); +void wsdisplay_enter_ddb(void); void wsdisplay_suspend(void); void wsdisplay_resume(void); const struct wsscreen_descr * Index: dev/pci/drm/i915/i915_drv.c =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v retrieving revision 1.105 diff -u -p -r1.105 i915_drv.c --- dev/pci/drm/i915/i915_drv.c 12 Jul 2017 20:12:19 -0000 1.105 +++ dev/pci/drm/i915/i915_drv.c 18 Jul 2017 18:34:15 -0000 @@ -1879,6 +1879,7 @@ void inteldrm_free_screen(void *, void * int inteldrm_show_screen(void *, void *, int, void (*)(void *, int, int), void *); void inteldrm_doswitch(void *); +void inteldrm_enter_ddb(void *, void *); int inteldrm_load_font(void *, void *, struct wsdisplay_font *); int inteldrm_list_font(void *, struct wsdisplay_font *); int inteldrm_getchar(void *, int, int, struct wsdisplay_charcell *); @@ -1908,6 +1909,7 @@ struct wsdisplay_accessops inteldrm_acce .alloc_screen = inteldrm_alloc_screen, .free_screen = inteldrm_free_screen, .show_screen = inteldrm_show_screen, + .enter_ddb = inteldrm_enter_ddb, .getchar = inteldrm_getchar, .load_font = inteldrm_load_font, .list_font = inteldrm_list_font, @@ -2031,6 +2033,20 @@ inteldrm_doswitch(void *v) if (dev_priv->switchcb) (*dev_priv->switchcb)(dev_priv->switchcbarg, 0, 0); +} + +void +inteldrm_enter_ddb(void *v, void *cookie) +{ + struct inteldrm_softc *dev_priv = v; + struct rasops_info *ri = &dev_priv->ro; + struct drm_fb_helper *helper = &dev_priv->fbdev->helper; + + if (cookie == ri->ri_active) + return; + + rasops_show_screen(ri, cookie, 0, NULL, NULL); + drm_fb_helper_debug_enter(helper->fbdev); } int Index: arch/amd64/amd64/db_interface.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/db_interface.c,v retrieving revision 1.28 diff -u -p -r1.28 db_interface.c --- arch/amd64/amd64/db_interface.c 30 Apr 2017 16:45:45 -0000 1.28 +++ arch/amd64/amd64/db_interface.c 18 Jul 2017 18:34:16 -0000 @@ -112,7 +112,7 @@ db_ktrap(int type, int code, db_regs_t * int s; #if NWSDISPLAY > 0 - wsdisplay_switchtoconsole(); + wsdisplay_enter_ddb(); #endif switch (type) { Index: arch/i386/i386/db_interface.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/db_interface.c,v retrieving revision 1.35 diff -u -p -r1.35 db_interface.c --- arch/i386/i386/db_interface.c 30 Apr 2017 16:45:45 -0000 1.35 +++ arch/i386/i386/db_interface.c 18 Jul 2017 18:34:16 -0000 @@ -106,7 +106,7 @@ db_ktrap(int type, int code, db_regs_t * int s; #if NWSDISPLAY > 0 - wsdisplay_switchtoconsole(); + wsdisplay_enter_ddb(); #endif switch (type) {