diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-07-19 14:34:11 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-07-19 14:34:11 +0000 |
commit | 5bfa92540d5e3d2a68895b4f754be2625844d96c (patch) | |
tree | 69b5ccea2823af33ded2581c5d74aef91202d3b7 /sys | |
parent | a3b66c601bf82fd0a8ad2bf8322510aff0e9e972 (diff) |
Add a enter_ddb() "accessop" to wsdisplay(4) to allow KMS drivers to bypass
the modeset lock when entering ddb. This avoids triggering various asserts
when the kernel panics while running X.
ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/db_interface.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/i386/db_interface.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 16 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplay.c | 26 | ||||
-rw-r--r-- | sys/dev/wscons/wsdisplayvar.h | 4 |
5 files changed, 48 insertions, 6 deletions
diff --git a/sys/arch/amd64/amd64/db_interface.c b/sys/arch/amd64/amd64/db_interface.c index c68c74026d9..a8931294d51 100644 --- a/sys/arch/amd64/amd64/db_interface.c +++ b/sys/arch/amd64/amd64/db_interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_interface.c,v 1.28 2017/04/30 16:45:45 mpi Exp $ */ +/* $OpenBSD: db_interface.c,v 1.29 2017/07/19 14:34:10 kettenis Exp $ */ /* $NetBSD: db_interface.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */ /* @@ -112,7 +112,7 @@ db_ktrap(int type, int code, db_regs_t *regs) int s; #if NWSDISPLAY > 0 - wsdisplay_switchtoconsole(); + wsdisplay_enter_ddb(); #endif switch (type) { diff --git a/sys/arch/i386/i386/db_interface.c b/sys/arch/i386/i386/db_interface.c index 07d123ba1c2..db211b13175 100644 --- a/sys/arch/i386/i386/db_interface.c +++ b/sys/arch/i386/i386/db_interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_interface.c,v 1.35 2017/04/30 16:45:45 mpi Exp $ */ +/* $OpenBSD: db_interface.c,v 1.36 2017/07/19 14:34:10 kettenis Exp $ */ /* $NetBSD: db_interface.c,v 1.22 1996/05/03 19:42:00 christos Exp $ */ /* @@ -106,7 +106,7 @@ db_ktrap(int type, int code, db_regs_t *regs) int s; #if NWSDISPLAY > 0 - wsdisplay_switchtoconsole(); + wsdisplay_enter_ddb(); #endif switch (type) { diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index 327b17e7737..cb6a43c6b6e 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -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_accessops = { .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, @@ -2033,6 +2035,20 @@ inteldrm_doswitch(void *v) (*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 inteldrm_getchar(void *v, int row, int col, struct wsdisplay_charcell *cell) { diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c index 90c8f4680e1..74102fa0962 100644 --- a/sys/dev/wscons/wsdisplay.c +++ b/sys/dev/wscons/wsdisplay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsdisplay.c,v 1.127 2017/07/18 21:27:50 kettenis Exp $ */ +/* $OpenBSD: wsdisplay.c,v 1.128 2017/07/19 14:34:10 kettenis Exp $ */ /* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */ /* @@ -2137,6 +2137,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. * diff --git a/sys/dev/wscons/wsdisplayvar.h b/sys/dev/wscons/wsdisplayvar.h index 9e20834d751..995d09200ea 100644 --- a/sys/dev/wscons/wsdisplayvar.h +++ b/sys/dev/wscons/wsdisplayvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsdisplayvar.h,v 1.30 2016/09/04 18:20:34 tedu Exp $ */ +/* $OpenBSD: wsdisplayvar.h,v 1.31 2017/07/19 14:34:10 kettenis Exp $ */ /* $NetBSD: wsdisplayvar.h,v 1.30 2005/02/04 02:10:49 perry Exp $ */ /* @@ -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_softc *sc, */ #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 * |