DF-5103 / fix.diff
--- a/sys/dev/apple/fw/apple_fw.h +++ b/sys/dev/apple/fw/apple_fw.h @@ -64,6 +64,7 @@ struct apple_fw_softc { device_t sc_dev; struct lock sc_lock; + struct sysctl_ctx_list sc_sctx; /* OSDW state: 1 = macOS detected, 0 = other OS */ int sc_osdw; @@ -82,6 +83,6 @@ struct apple_fw_softc { /* apple_fw_dsm.c */ void apple_fw_discover_dsm_devices(device_t dev); /* apple_fw_sysctl.c */ -void apple_fw_sysctl_init(device_t dev); +void apple_fw_sysctl_init(device_t dev, struct sysctl_ctx_list *ctx); --- a/sys/dev/apple/fw/apple_fw.c +++ b/sys/dev/apple/fw/apple_fw.c @@ -122,9 +122,11 @@ apple_fw_attach(device_t dev) sc->sc_dev = dev; lockinit(&sc->sc_lock, "apple_fw", 0, LK_CANRECURSE); + sysctl_ctx_init(&sc->sc_sctx); /* Enumerate Apple-specific SSDTs */ apple_fw_enumerate_ssdts(dev); @@ -141,12 +143,17 @@ apple_fw_attach(device_t dev) apple_fw_discover_dsm_devices(dev); /* Register sysctl tree */ - apple_fw_sysctl_init(dev); + apple_fw_sysctl_init(dev, &sc->sc_sctx); return (0); } static int apple_fw_detach(device_t dev) { struct apple_fw_softc *sc = device_get_softc(dev); + /* + * Tear down the softc-backed sysctls BEFORE returning: newbus frees + * the softc in device_set_driver() before it runs device_sysctl_fini(), + * leaving a window where live oids point at freed memory. + */ + sysctl_ctx_free(&sc->sc_sctx); lockuninit(&sc->sc_lock); return (0); } --- a/sys/dev/apple/fw/apple_fw_sysctl.c +++ b/sys/dev/apple/fw/apple_fw_sysctl.c @@ -14,6 +14,7 @@ void -apple_fw_sysctl_init(device_t dev) +apple_fw_sysctl_init(device_t dev, struct sysctl_ctx_list *ctx) { struct apple_fw_softc *sc = device_get_softc(dev); @@ -25,8 +26,6 @@ apple_fw_sysctl_init(device_t dev) char numbuf[8]; int i, j; - ctx = device_get_sysctl_ctx(dev); tree = device_get_sysctl_tree(dev); *** NOTE: with the driver-owned ctx, the oids should hang off the device *** tree node obtained via device_get_sysctl_tree(dev) as before; only the *** ctx that owns their lifetime changes. |