linux-stable/drivers/net
Vladimir Oltean a7d82367da net: dsa: mv88e6xxx: avoid reg_lock deadlock in mv88e6xxx_setup_port()
In the blamed commit, it was not noticed that one implementation of
chip->info->ops->phylink_get_caps(), called by mv88e6xxx_get_caps(),
may access hardware registers, and in doing so, it takes the
mv88e6xxx_reg_lock(). Namely, this is mv88e6352_phylink_get_caps().

This is a problem because mv88e6xxx_get_caps(), apart from being
a top-level function (method invoked by dsa_switch_ops), is now also
directly called from mv88e6xxx_setup_port(), which runs under the
mv88e6xxx_reg_lock() taken by mv88e6xxx_setup(). Therefore, when running
on mv88e6352, the reg_lock would be acquired a second time and the
system would deadlock on driver probe.

The things that mv88e6xxx_setup() can compete with in terms of register
access with are the IRQ handlers and MDIO bus operations registered by
mv88e6xxx_probe(). So there is a real need to acquire the register lock.

The register lock can, in principle, be dropped and re-acquired pretty
much at will within the driver, as long as no operations that involve
waiting for indirect access to complete (essentially, callers of
mv88e6xxx_smi_direct_wait() and mv88e6xxx_wait_mask()) are interrupted
with the lock released. However, I would guess that in mv88e6xxx_setup(),
the critical section is kept open for such a long time just in order to
optimize away multiple lock/unlock operations on the registers.

We could, in principle, drop the reg_lock right before the
mv88e6xxx_setup_port() -> mv88e6xxx_get_caps() call, and
re-acquire it immediately afterwards. But this would look ugly, because
mv88e6xxx_setup_port() would release a lock which it didn't acquire, but
the caller did.

A cleaner solution to this issue comes from the observation that struct
mv88e6xxxx_ops methods generally assume they are called with the
reg_lock already acquired. Whereas mv88e6352_phylink_get_caps() is more
the exception rather than the norm, in that it acquires the lock itself.

Let's enforce the same locking pattern/convention for
chip->info->ops->phylink_get_caps() as well, and make
mv88e6xxx_get_caps(), the top-level function, acquire the register lock
explicitly, for this one implementation that will access registers for
port 4 to work properly.

This means that mv88e6xxx_setup_port() will no longer call the top-level
function, but the low-level mv88e6xxx_ops method which expects the
correct calling context (register lock held).

Compared to chip->info->ops->phylink_get_caps(), mv88e6xxx_get_caps()
also fixes up the supported_interfaces bitmap for internal ports, since
that can be done generically and does not require per-switch knowledge.
That's code which will no longer execute, however mv88e6xxx_setup_port()
doesn't need that. It just needs to look at the mac_capabilities bitmap.

Fixes: cc1049ccee ("net: dsa: mv88e6xxx: fix speed setting for CPU/DSA ports")
Reported-by: Maksim Kiselev <bigunclemax@gmail.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
Link: https://lore.kernel.org/r/20221214110120.3368472-1-vladimir.oltean@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2022-12-15 15:42:23 +01:00
..
appletalk
arcnet
bonding bonding: do failover when high prio link up 2022-12-13 19:19:32 -08:00
caif
can can: tcan4x5x: Specify separate read/write ranges 2022-12-12 12:01:01 +01:00
dsa net: dsa: mv88e6xxx: avoid reg_lock deadlock in mv88e6xxx_setup_port() 2022-12-15 15:42:23 +01:00
ethernet ravb: Fix "failed to switch device to config mode" message during unbind 2022-12-15 15:36:05 +01:00
fddi net: defxx: Fix missing err handling in dfx_init() 2022-12-09 10:44:27 +00:00
fjes
hamradio Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-13 09:49:29 +01:00
hippi
hyperv
ieee802154 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-08 18:19:59 -08:00
ipa net: ipa: add IPA v4.7 support 2022-12-12 15:55:06 -08:00
ipvlan Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-11-29 13:04:52 -08:00
mctp
mdio net: mdio: fix unbalanced fwnode reference count in mdio_device_release() 2022-12-06 12:50:00 +01:00
netdevsim xfrm: allow state packet offload mode 2022-12-05 10:32:44 +01:00
pcs net: pcs: altera-tse: remove unnecessary register definitions 2022-11-29 20:29:55 -08:00
phy Networking changes for 6.2. 2022-12-13 15:47:48 -08:00
plip net: plip: don't call kfree_skb/dev_kfree_skb() under spin_lock_irq() 2022-12-07 20:10:47 -08:00
ppp Networking changes for 6.2. 2022-12-13 15:47:48 -08:00
pse-pd
slip
team Networking changes for 6.2. 2022-12-13 15:47:48 -08:00
usb net: asix: add support for the Linux Automation GmbH USB 10Base-T1L 2022-12-07 17:12:09 -08:00
vmxnet3 vmxnet3: use correct intrConf reference when using extended queues 2022-12-02 10:30:07 +00:00
vxlan
wan net: farsync: Fix kmemleak when rmmods farsync 2022-12-12 09:42:45 +00:00
wireguard wireguard: timers: cast enum limits members to int in prints 2022-12-13 19:30:45 -08:00
wireless Networking changes for 6.2. 2022-12-13 15:47:48 -08:00
wwan Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-08 18:19:59 -08:00
xen-netback xen/netback: fix build warning 2022-12-07 16:03:21 +01:00
Kconfig
LICENSE.SRC
Makefile
Space.c
amt.c
bareudp.c
dummy.c
eql.c
geneve.c
gtp.c
ifb.c
loopback.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-11-29 13:04:52 -08:00
macsec.c net: macsec: fix net device access prior to holding a lock 2022-12-13 18:58:08 -08:00
macvlan.c
macvtap.c
mdio.c
mhi_net.c
mii.c
net_failover.c
netconsole.c netconsole: avoid CON_ENABLED misuse to track registration 2022-12-02 11:25:02 +01:00
nlmon.c
ntb_netdev.c ntb_netdev: Use dev_kfree_skb_any() in interrupt context 2022-12-12 12:56:37 -08:00
rionet.c
sb1000.c
sungem_phy.c
tap.c driver/net/tun: Added features for USO. 2022-12-12 09:29:56 +00:00
thunderbolt.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-08 18:19:59 -08:00
tun.c driver/net/tun: Added features for USO. 2022-12-12 09:29:56 +00:00
veth.c
virtio_net.c drivers/net/virtio_net.c: Added USO support. 2022-12-12 09:29:56 +00:00
vrf.c
vsockmon.c
xen-netfront.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2022-12-08 18:19:59 -08:00