diff mbox series

[net,v4] net: b44: set pause params only when interface is up

Message ID 87y192oolj.fsf@a16n.net (mailing list archive)
State Accepted
Commit e3eb7dd47bd4806f00e104eb6da092c435f9fb21
Delegated to: Netdev Maintainers
Headers show
Series [net,v4] net: b44: set pause params only when interface is up | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 926 this patch: 926
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 3 maintainers not CCed: pabeni@redhat.com kuba@kernel.org edumazet@google.com
netdev/build_clang success Errors and warnings before: 939 this patch: 939
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 937 this patch: 937
netdev/checkpatch warning WARNING: Please use correct Fixes: style 'Fixes: <12 chars of sha1> ("<title line>")' - ie: 'Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")'
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-04-24--15-00 (tests: 995)

Commit Message

Peter Münster April 24, 2024, 1:51 p.m. UTC
b44_free_rings() accesses b44::rx_buffers (and ::tx_buffers)
unconditionally, but b44::rx_buffers is only valid when the
device is up (they get allocated in b44_open(), and deallocated
again in b44_close()), any other time these are just a NULL pointers.

So if you try to change the pause params while the network interface
is disabled/administratively down, everything explodes (which likely
netifd tries to do).

Link: https://github.com/openwrt/openwrt/issues/13789
Fixes: 1da177e4c3f4 (Linux-2.6.12-rc2)
Cc: stable@vger.kernel.org
Reported-by: Peter Münster <pm@a16n.net>
Suggested-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Vaclav Svoboda <svoboda@neng.cz>
Tested-by: Peter Münster <pm@a16n.net>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Peter Münster <pm@a16n.net>
---
 drivers/net/ethernet/broadcom/b44.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

Comments

Michael Chan April 24, 2024, 4:37 p.m. UTC | #1
On Wed, Apr 24, 2024 at 6:51 AM Peter Münster <pm@a16n.net> wrote:
>
> b44_free_rings() accesses b44::rx_buffers (and ::tx_buffers)
> unconditionally, but b44::rx_buffers is only valid when the
> device is up (they get allocated in b44_open(), and deallocated
> again in b44_close()), any other time these are just a NULL pointers.
>
> So if you try to change the pause params while the network interface
> is disabled/administratively down, everything explodes (which likely
> netifd tries to do).
>
> Link: https://github.com/openwrt/openwrt/issues/13789
> Fixes: 1da177e4c3f4 (Linux-2.6.12-rc2)
> Cc: stable@vger.kernel.org
> Reported-by: Peter Münster <pm@a16n.net>
> Suggested-by: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Vaclav Svoboda <svoboda@neng.cz>
> Tested-by: Peter Münster <pm@a16n.net>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Peter Münster <pm@a16n.net>

Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Hariprasad Kelam April 25, 2024, 5:20 a.m. UTC | #2
Understood, this patch fixes the panic issue.
 See inline for few comments,

> b44_free_rings() accesses b44::rx_buffers (and ::tx_buffers) unconditionally,
> but b44::rx_buffers is only valid when the device is up (they get allocated in
> b44_open(), and deallocated again in b44_close()), any other time these are
> just a NULL pointers.
> 
> So if you try to change the pause params while the network interface is
> disabled/administratively down, everything explodes (which likely netifd tries
> to do).
> 
> Link: https://github.com/openwrt/openwrt/issues/13789
> Fixes: 1da177e4c3f4 (Linux-2.6.12-rc2)
> Cc: stable@vger.kernel.org
> Reported-by: Peter Münster <pm@a16n.net>
> Suggested-by: Jonas Gorski <jonas.gorski@gmail.com>
> Signed-off-by: Vaclav Svoboda <svoboda@neng.cz>
> Tested-by: Peter Münster <pm@a16n.net>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Peter Münster <pm@a16n.net>
> ---
>  drivers/net/ethernet/broadcom/b44.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/broadcom/b44.c
> b/drivers/net/ethernet/broadcom/b44.c
> index 3e4fb3c3e834..1be6d14030bc 100644
> --- a/drivers/net/ethernet/broadcom/b44.c
> +++ b/drivers/net/ethernet/broadcom/b44.c
> @@ -2009,12 +2009,14 @@ static int b44_set_pauseparam(struct net_device
> *dev,
>  		bp->flags |= B44_FLAG_TX_PAUSE;
>  	else
>  		bp->flags &= ~B44_FLAG_TX_PAUSE;
> -	if (bp->flags & B44_FLAG_PAUSE_AUTO) {
> -		b44_halt(bp);
> -		b44_init_rings(bp);
> -		b44_init_hw(bp, B44_FULL_RESET);
> -	} else {
> -		__b44_set_flow_ctrl(bp, bp->flags);
> +	if (netif_running(dev)) {
> +		if (bp->flags & B44_FLAG_PAUSE_AUTO) {
> +			b44_halt(bp);
> +			b44_init_rings(bp);
> +			b44_init_hw(bp, B44_FULL_RESET);
> +		} else {
> +			__b44_set_flow_ctrl(bp, bp->flags);
> +		}
>  	}
The actual register config to enable pause frame is protected with "netif_running", does driver need to
reject the request if interface is down.
Otherwise, there is mismatch if someone reads pause frame status (b44_get_pauseparam).


Thanks,
Hariprasad k
>  	spin_unlock_irq(&bp->lock);
> 
> --
> 2.35.3
patchwork-bot+netdevbpf@kernel.org April 25, 2024, 3:40 p.m. UTC | #3
Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Wed, 24 Apr 2024 15:51:52 +0200 you wrote:
> b44_free_rings() accesses b44::rx_buffers (and ::tx_buffers)
> unconditionally, but b44::rx_buffers is only valid when the
> device is up (they get allocated in b44_open(), and deallocated
> again in b44_close()), any other time these are just a NULL pointers.
> 
> So if you try to change the pause params while the network interface
> is disabled/administratively down, everything explodes (which likely
> netifd tries to do).
> 
> [...]

Here is the summary with links:
  - [net,v4] net: b44: set pause params only when interface is up
    https://git.kernel.org/netdev/net/c/e3eb7dd47bd4

You are awesome, thank you!
diff mbox series

Patch

diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 3e4fb3c3e834..1be6d14030bc 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2009,12 +2009,14 @@  static int b44_set_pauseparam(struct net_device *dev,
 		bp->flags |= B44_FLAG_TX_PAUSE;
 	else
 		bp->flags &= ~B44_FLAG_TX_PAUSE;
-	if (bp->flags & B44_FLAG_PAUSE_AUTO) {
-		b44_halt(bp);
-		b44_init_rings(bp);
-		b44_init_hw(bp, B44_FULL_RESET);
-	} else {
-		__b44_set_flow_ctrl(bp, bp->flags);
+	if (netif_running(dev)) {
+		if (bp->flags & B44_FLAG_PAUSE_AUTO) {
+			b44_halt(bp);
+			b44_init_rings(bp);
+			b44_init_hw(bp, B44_FULL_RESET);
+		} else {
+			__b44_set_flow_ctrl(bp, bp->flags);
+		}
 	}
 	spin_unlock_irq(&bp->lock);