| From e75f88efac05bf4e107e4171d8db6d8c3937252d Mon Sep 17 00:00:00 2001 |
| From: Andrei Lalaev <andrei.lalaev@emlid.com> |
| Date: Fri, 15 Apr 2022 10:07:11 +0300 |
| Subject: gpiolib: of: fix bounds check for 'gpio-reserved-ranges' |
| |
| From: Andrei Lalaev <andrei.lalaev@emlid.com> |
| |
| commit e75f88efac05bf4e107e4171d8db6d8c3937252d upstream. |
| |
| Gpiolib interprets the elements of "gpio-reserved-ranges" as "start,size" |
| because it clears "size" bits starting from the "start" bit in the according |
| bitmap. So it has to use "greater" instead of "greater or equal" when performs |
| bounds check to make sure that GPIOs are in the available range. |
| Previous implementation skipped ranges that include the last GPIO in |
| the range. |
| |
| I wrote the mail to the maintainers |
| (https://lore.kernel.org/linux-gpio/20220412115554.159435-1-andrei.lalaev@emlid.com/T/#u) |
| of the questioned DTSes (because I couldn't understand how the maintainers |
| interpreted this property), but I haven't received a response. |
| Since the questioned DTSes use "gpio-reserved-ranges = <0 4>" |
| (i.e., the beginning of the range), this patch doesn't affect these DTSes at all. |
| TBH this patch doesn't break any existing DTSes because none of them |
| reserve gpios at the end of range. |
| |
| Fixes: 726cb3ba4969 ("gpiolib: Support 'gpio-reserved-ranges' property") |
| Signed-off-by: Andrei Lalaev <andrei.lalaev@emlid.com> |
| Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> |
| Reviewed-by: Linus Walleij <linus.walleij@linaro.org> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpio/gpiolib-of.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/gpio/gpiolib-of.c |
| +++ b/drivers/gpio/gpiolib-of.c |
| @@ -912,7 +912,7 @@ static void of_gpiochip_init_valid_mask( |
| i, &start); |
| of_property_read_u32_index(np, "gpio-reserved-ranges", |
| i + 1, &count); |
| - if (start >= chip->ngpio || start + count >= chip->ngpio) |
| + if (start >= chip->ngpio || start + count > chip->ngpio) |
| continue; |
| |
| bitmap_clear(chip->valid_mask, start, count); |