mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 13:48:06 +00:00
kernel: 4.19: fix crash when setting up spi-gpio
If an spi-gpio was specified with num-chipselects = <0> in dts, kernel will crash: Unable to handle kernel paging request at virtual address 32697073 pgd = (ptrval) [32697073] *pgd=00000000 Internal error: Oops: 5 [# 1] SMP ARM Modules linked in: CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.19.72 #0 Hardware name: Generic DT based system PC is at validate_desc+0x28/0x80 LR is at gpiod_direction_output+0x14/0x128 ... [<c0544db4>] (validate_desc) from [<c0545228>] (gpiod_direction_output+0x14/0x128) [<c0545228>] (gpiod_direction_output) from [<c05fa714>] (spi_gpio_setup+0x58/0x64) [<c05fa714>] (spi_gpio_setup) from [<c05f7258>] (spi_setup+0x12c/0x148) [<c05f7258>] (spi_setup) from [<c05f7330>] (spi_add_device+0xbc/0x12c) [<c05f7330>] (spi_add_device) from [<c05f7f74>] (spi_register_controller+0x838/0x924) [<c05f7f74>] (spi_register_controller) from [<c05fa494>] (spi_bitbang_start+0x108/0x120) [<c05fa494>] (spi_bitbang_start) from [<c05faa34>] (spi_gpio_probe+0x314/0x338) [<c05faa34>] (spi_gpio_probe) from [<c05a844c>] (platform_drv_probe+0x34/0x70) The cause is spi_gpio_setup() did not check if the spi-gpio has chipselect pins before setting their direction and results in derefing an invalid pointer. The bug is spotted in kernel 4.19.72 and does not occur in 4.14. There is a similar fix upstream in kernel 5.2 in commit 249e2632dcd0 ("spi: gpio: Don't request CS GPIO in DT use-case"). Ref: https://patchwork.kernel.org/patch/11150619/ Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn> [use upstream patch, moved from hack to pending dir, commit facelift] Signed-off-by: Petr Štetiar <ynezz@true.cz>
This commit is contained in:
parent
c933b6d224
commit
1979af10ca
@ -0,0 +1,66 @@
|
||||
From 0f76408d8c1cb0979f4286dd23912e6e59784b35 Mon Sep 17 00:00:00 2001
|
||||
From: DENG Qingfang <dqfext@gmail.com>
|
||||
Date: Thu, 19 Sep 2019 11:42:55 +0200
|
||||
Subject: [PATCH] spi: spi-gpio: fix crash when num-chipselects is 0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If an spi-gpio was specified with num-chipselects = <0> in dts, kernel will crash:
|
||||
|
||||
Unable to handle kernel paging request at virtual address 32697073
|
||||
pgd = (ptrval)
|
||||
[32697073] *pgd=00000000
|
||||
Internal error: Oops: 5 [# 1] SMP ARM
|
||||
Modules linked in:
|
||||
CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.19.72 #0
|
||||
Hardware name: Generic DT based system
|
||||
PC is at validate_desc+0x28/0x80
|
||||
LR is at gpiod_direction_output+0x14/0x128
|
||||
...
|
||||
[<c0544db4>] (validate_desc) from [<c0545228>] (gpiod_direction_output+0x14/0x128)
|
||||
[<c0545228>] (gpiod_direction_output) from [<c05fa714>] (spi_gpio_setup+0x58/0x64)
|
||||
[<c05fa714>] (spi_gpio_setup) from [<c05f7258>] (spi_setup+0x12c/0x148)
|
||||
[<c05f7258>] (spi_setup) from [<c05f7330>] (spi_add_device+0xbc/0x12c)
|
||||
[<c05f7330>] (spi_add_device) from [<c05f7f74>] (spi_register_controller+0x838/0x924)
|
||||
[<c05f7f74>] (spi_register_controller) from [<c05fa494>] (spi_bitbang_start+0x108/0x120)
|
||||
[<c05fa494>] (spi_bitbang_start) from [<c05faa34>] (spi_gpio_probe+0x314/0x338)
|
||||
[<c05faa34>] (spi_gpio_probe) from [<c05a844c>] (platform_drv_probe+0x34/0x70)
|
||||
|
||||
The cause is spi_gpio_setup() did not check if the spi-gpio has chipselect pins
|
||||
before setting their direction and results in derefing an invalid pointer.
|
||||
|
||||
The bug is spotted in kernel 4.19.72 on OpenWrt, and does not occur in 4.14.
|
||||
|
||||
There is a similar fix upstream 249e2632dcd0509b8f8f296f5aabf4d48dfd6da8.
|
||||
|
||||
Ref: https://patchwork.kernel.org/patch/11150619/
|
||||
Cc: Linus Walleij <linus.walleij@linaro.org>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: DENG Qingfang <dqfext@gmail.com>
|
||||
Signed-off-by: Petr Štetiar <ynezz@true.cz>
|
||||
---
|
||||
drivers/spi/spi-gpio.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
|
||||
index 088772ebef9b..57d5b6dc0dd0 100644
|
||||
--- a/drivers/spi/spi-gpio.c
|
||||
+++ b/drivers/spi/spi-gpio.c
|
||||
@@ -242,10 +242,12 @@ static int spi_gpio_setup(struct spi_device *spi)
|
||||
* The CS GPIOs have already been
|
||||
* initialized from the descriptor lookup.
|
||||
*/
|
||||
- cs = spi_gpio->cs_gpios[spi->chip_select];
|
||||
- if (!spi->controller_state && cs)
|
||||
- status = gpiod_direction_output(cs,
|
||||
- !(spi->mode & SPI_CS_HIGH));
|
||||
+ if (spi_gpio->has_cs) {
|
||||
+ cs = spi_gpio->cs_gpios[spi->chip_select];
|
||||
+ if (!spi->controller_state && cs)
|
||||
+ status = gpiod_direction_output(cs,
|
||||
+ !(spi->mode & SPI_CS_HIGH));
|
||||
+ }
|
||||
|
||||
if (!status)
|
||||
status = spi_bitbang_setup(spi);
|
Loading…
Reference in New Issue
Block a user