diff mbox series

[v2] wifi: bcma/brcm80211: Use the proper include

Message ID 20221026075653.105387-1-linus.walleij@linaro.org (mailing list archive)
State Changes Requested
Delegated to: Kalle Valo
Headers show
Series [v2] wifi: bcma/brcm80211: Use the proper include | expand

Commit Message

Linus Walleij Oct. 26, 2022, 7:56 a.m. UTC
The <linux/bcma/bcma_driver_chipcommon.h> is including the legacy
header <linux/gpio.h> to obtain struct gpio_chip. Instead, include
<linux/gpio/driver.h> where this struct is defined.

It turns out that the brcm80211 brcmsmac depends on this to
bring in the symbol gpio_is_valid().

The driver looks up the BCMA parent GPIO driver and checks that
this succeeds, but then it goes on to use the deprecated GPIO
call gpio_is_valid() to check the consistency of the .base
member of the BCMA GPIO struct. Surely this belongs in the
BCMA driver: we cannot have all drivers performing cosistency
checks on the internals of things they are passed.

Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Combine two co-dependent patches
- Collect Arend's ACK
---
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c | 2 +-
 include/linux/bcma/bcma_driver_chipcommon.h            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Comments

Jonas Gorski Oct. 27, 2022, 3:20 p.m. UTC | #1
On Wed, 26 Oct 2022 at 10:05, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> The <linux/bcma/bcma_driver_chipcommon.h> is including the legacy
> header <linux/gpio.h> to obtain struct gpio_chip. Instead, include
> <linux/gpio/driver.h> where this struct is defined.
>
> It turns out that the brcm80211 brcmsmac depends on this to
> bring in the symbol gpio_is_valid().
>
> The driver looks up the BCMA parent GPIO driver and checks that
> this succeeds, but then it goes on to use the deprecated GPIO
> call gpio_is_valid() to check the consistency of the .base
> member of the BCMA GPIO struct. Surely this belongs in the
> BCMA driver: we cannot have all drivers performing cosistency
> checks on the internals of things they are passed.
>
> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Combine two co-dependent patches
> - Collect Arend's ACK
> ---
>  drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c | 2 +-
>  include/linux/bcma/bcma_driver_chipcommon.h            | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
> index c1b9ac692d26..1cce92c5780f 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
> @@ -63,7 +63,7 @@ int brcms_led_register(struct brcms_info *wl)
>         int hwnum = -1;
>         enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH;
>
> -       if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
> +       if (!bcma_gpio)
>                 return -ENODEV;

A few lines above bcma_gpio is initialized with

     struct gpio_chip *bcma_gpio = &cc_drv->gpio;

and thus can never be NULL, so the whole condition can be then dropped.

I guess the intention here was to make sure the the gpio chip was
registered successfully. The bcma bus driver ignores any gpio chip
init/registration failures, so this is (in theory) a possible state.

Doing no validity check can then theoretically lead to a NULL pointer
access further down. brcms_led_register() calls
gpiochip_request_own_desc(), which calls gpiochip_get_desc() which
tries to access gc->gpiodev->ngpio. If the gpio_chip registration
failed for any reason, gc->gpiodev will be NULL => oops. The
gpio_is_valid() might have caught that as base might have been left as
-1, depending on where it failed.

So adding a check to gpiochip_get_desc() for gc->gpiodev being
populated should avoid this issue, and gpiochip_get_desc() doesn't
look like a function used in hot paths where the check would add a
performance degradation.

Regards
Jonas
Johannes Berg Oct. 28, 2022, 9:09 a.m. UTC | #2
On Wed, 2022-10-26 at 09:56 +0200, Linus Walleij wrote:
> Surely this belongs in the
> BCMA driver: we cannot have all drivers performing cosistency
> checks on the internals of things they are passed.
> 

"Surely this doesn't belong"?

johannes
Linus Walleij Oct. 28, 2022, 9:22 a.m. UTC | #3
On Thu, Oct 27, 2022 at 5:20 PM Jonas Gorski <jonas.gorski@gmail.com> wrote:

> A few lines above bcma_gpio is initialized with
>
>      struct gpio_chip *bcma_gpio = &cc_drv->gpio;
>
> and thus can never be NULL, so the whole condition can be then dropped.

I will send a v3 deleting the whole check.

> I guess the intention here was to make sure the the gpio chip was
> registered successfully. The bcma bus driver ignores any gpio chip
> init/registration failures, so this is (in theory) a possible state.
>
> Doing no validity check can then theoretically lead to a NULL pointer
> access further down. brcms_led_register() calls
> gpiochip_request_own_desc(), which calls gpiochip_get_desc() which
> tries to access gc->gpiodev->ngpio. If the gpio_chip registration
> failed for any reason, gc->gpiodev will be NULL => oops. The
> gpio_is_valid() might have caught that as base might have been left as
> -1, depending on where it failed.
>
> So adding a check to gpiochip_get_desc() for gc->gpiodev being
> populated should avoid this issue, and gpiochip_get_desc() doesn't
> look like a function used in hot paths where the check would add a
> performance degradation.

Hmmm that sounds like adding consistency checks to gpiolib for
fixing the fact that the BCMA driver ignores registration failures.
I would rather fix the BCMA driver to not do that, I'll check if I can make
a separate patch for this.

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
index c1b9ac692d26..1cce92c5780f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.c
@@ -63,7 +63,7 @@  int brcms_led_register(struct brcms_info *wl)
 	int hwnum = -1;
 	enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH;
 
-	if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
+	if (!bcma_gpio)
 		return -ENODEV;
 
 	/* find radio enabled LED */
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 2d94c30ed439..0cb6638b55e5 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -4,7 +4,7 @@ 
 
 #include <linux/platform_device.h>
 #include <linux/platform_data/brcmnand.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 
 /** ChipCommon core registers. **/
 #define BCMA_CC_ID			0x0000