In the Linux kernel, the following vulnerability has been resolved:
net: dsa: mv88e6xxx: don't use devres for mdiobus
As explained in commits: 74b6d7d13307 ("net: dsa: realtek: register the MDIO bus under devres") 5135e96a3dd2 ("net: dsa: don't allocate the slavemiibus using devres")
mdiobusfree() will panic when called from devmmdiobusfree() <- devresreleaseall() <- _devicereleasedriver(), and that mdiobus was not previously unregistered.
The mv88e6xxx is an MDIO device, so the initial set of constraints that I thought would cause this (I2C or SPI buses which call ->remove on ->shutdown) do not apply. But there is one more which applies here.
If the DSA master itself is on a bus that calls ->remove from ->shutdown (like dpaa2-eth, which is on the fsl-mc bus), there is a device link between the switch and the DSA master, and devicelinksunbind_consumers() will unbind the Marvell switch driver on shutdown.
systemd-shutdown[1]: Powering off. mv88e6085 0x0000000008b96000:00 swgl0: Link is Down fsl-mc dpbp.9: Removing from iommu group 7 fsl-mc dpbp.8: Removing from iommu group 7 ------------[ cut here ]------------ kernel BUG at drivers/net/phy/mdiobus.c:677! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 5.16.5-00040-gdc05f73788e5 #15 pc : mdiobusfree+0x44/0x50 lr : devmmdiobusfree+0x10/0x20 Call trace: mdiobusfree+0x44/0x50 devmmdiobusfree+0x10/0x20 devresreleaseall+0xa0/0x100 _devicereleasedriver+0x190/0x220 devicereleasedriverinternal+0xac/0xb0 devicelinksunbindconsumers+0xd4/0x100 _devicereleasedriver+0x4c/0x220 devicereleasedriverinternal+0xac/0xb0 devicelinksunbindconsumers+0xd4/0x100 _devicereleasedriver+0x94/0x220 devicereleasedriver+0x28/0x40 busremovedevice+0x118/0x124 devicedel+0x174/0x420 fslmcdeviceremove+0x24/0x40 _fslmcdeviceremove+0xc/0x20 deviceforeachchild+0x58/0xa0 dprcremove+0x90/0xb0 fslmcdriverremove+0x20/0x5c _devicereleasedriver+0x21c/0x220 devicereleasedriver+0x28/0x40 busremovedevice+0x118/0x124 devicedel+0x174/0x420 fslmcbusremove+0x80/0x100 fslmcbusshutdown+0xc/0x1c platformshutdown+0x20/0x30 deviceshutdown+0x154/0x330 kernelpoweroff+0x34/0x6c _dosysreboot+0x15c/0x250 _arm64sysreboot+0x20/0x30 invokesyscall.constprop.0+0x4c/0xe0 doel0svc+0x4c/0x150 el0svc+0x24/0xb0 el0t64synchandler+0xa8/0xb0 el0t64_sync+0x178/0x17c
So the same treatment must be applied to all DSA switch drivers, which is: either use devres for both the mdiobus allocation and registration, or don't use devres at all.
The Marvell driver already has a good structure for mdiobus removal, so just plug in mdiobus_free and get rid of devres.