rsi: fix error path handling in SDIO probe
PATCH 1/2 rsi: fix error path handling in SDIO probe
From: Amitkumar Karwar <[email protected]>
We miss to release IRQ in certain error path in SDIO probe which causes following kernel panic. This patch corrects error path handling
BUG: unable to handle kernel NULL pointer dereference at (null) IP: (null) PGD 0 P4D 0 Oops: 0010 [#1] SMP PTI Call Trace: <IRQ> ? call_timer_fn+0x29/0x120 ? run_timer_softirq+0x1da/0x420 ? timer_interrupt+0x11/0x20 ? __do_softirq+0xef/0x26e ? irq_exit+0xbe/0xd0 ? do_IRQ+0x4a/0xc0 ? common_interrupt+0xa2/0xa2 </IRQ> ? cpuidle_enter_state+0x118/0x250 ? do_idle+0x186/0x1e0 ? cpu_startup_entry+0x6f/0x80 ? start_kernel+0x47c/0x49c ? secondary_startup_64+0xa5/0xb0
--- drivers/net/wireless/rsi/rsi_91x_sdio.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/net/wireless/rsi/rsi_91x_sdio.c +8 -5
@@ -967,7 +967,7 @@ static int rsi_probe(struct sdio_func *pfunction, rsi_sdio_rx_thread, "SDIO-RX-Thread");if (status) {rsi_dbg (ERR_ZONE ,"%s: Unable to init rx thrd\n" , __func__); - goto fail_free_adapter; + goto fail_kill_thread; }skb_queue_head_init (&sdev->rx_q.head); sdev->rx_q.num_rx_pkts =0 ;
@@ -977,7 +977,7 @@ static int rsi_probe(struct sdio_func *pfunction,rsi_dbg (ERR_ZONE ,"%s: Failed to request IRQ\n" , __func__);sdio_release_host (pfunction); status = -EIO ; - goto fail_kill_thread; + goto fail_claim_irq; }sdio_release_host (pfunction);rsi_dbg (INIT_ZONE ,"%s: Registered Interrupt handler\n" , __func__);
@@ -985,7 +985,7 @@ static int rsi_probe(struct sdio_func *pfunction,if (rsi_hal_device_init (adapter)) {rsi_dbg (ERR_ZONE ,"%s: Failed in device init\n" , __func__); status = -EINVAL ; - goto fail_kill_thread; + goto fail_dev_init; }rsi_dbg (INFO_ZONE ,"===> RSI Device Init Done <===\n" );
@@ -1002,10 +1002,13 @@ static int rsi_probe(struct sdio_func *pfunction, fail_dev_init:sdio_claim_host (pfunction);sdio_release_irq (pfunction); -sdio_disable_func (pfunction);sdio_release_host (pfunction); -fail_kill_thread: +fail_claim_irq:rsi_kill_thread (&sdev->rx_thread); +fail_kill_thread: +sdio_claim_host (pfunction); +sdio_disable_func (pfunction); +sdio_release_host (pfunction); fail_free_adapter:rsi_91x_deinit (adapter);rsi_dbg (ERR_ZONE ,"%s: Failed in probe...Exiting\n" , __func__);
Signature · 1 line
2.7.4
PATCH 2/2 rsi: fix kernel panic observed on 64bit machine
From: Amitkumar Karwar <[email protected]>
Following kernel panic is observed on 64bit machine while loading the driver. It is fixed if we pass dynamically allocated memory to SDIO for DMA.
BUG: unable to handle kernel paging request at ffffeb04000172e0 IP: sg_miter_stop+0x56/0x70 PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI Modules linked in: rsi_sdio(OE+) rsi_91x(OE) btrsi(OE) rfcomm bluetooth ecdh_generic mac80211 mmc_block fuse xt_CHECKSUM iptable_mangle drm_kms_helper mmc_core serio_raw drm firewire_ohci tg3 CPU: 0 PID: 4003 Comm: insmod Tainted: G OE 4.16.0-rc1+ #27 Hardware name: Dell Inc. Latitude E5500 /0DW634, BIOS A19 06/13/2013 RIP: 0010:sg_miter_stop+0x56/0x70 RSP: 0018:ffff88007d003e78 EFLAGS: 00010002 RAX: 0000000000000003 RBX: 0000000000000004 RCX: 0000000000000000 RDX: ffffeb04000172c0 RSI: ffff88002f58002c RDI: ffff88007d003e80 RBP: 0000000000000004 R08: ffff88007d003e80 R09: 0000000000000008 R10: 0000000000000003 R11: 0000000000000001 R12: 0000000000000004 R13: ffff88002f580028 R14: 0000000000000000 R15: 0000000000000004 FS: 00007f35c29db700(0000) GS:ffff88007d000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffeb04000172e0 CR3: 000000007038e000 CR4: 00000000000406f0 Call Trace: <IRQ> sg_copy_buffer+0xc6/0xf0 sdhci_tasklet_finish+0x170/0x260 [sdhci] tasklet_action+0xf4/0x100 __do_softirq+0xef/0x26e irq_exit+0xbe/0xd0 do_IRQ+0x4a/0xc0 common_interrupt+0xa2/0xa2 </IRQ>
--- drivers/net/wireless/rsi/rsi_91x_sdio.c | 32 +++++++++++++++++++++----------- drivers/net/wireless/rsi/rsi_sdio.h | 2 ++ 2 files changed, 23 insertions(+), 11 deletions(-)
drivers/net/wireless/rsi/rsi_91x_sdio.c +21 -11
@@ -653,11 +653,14 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, u32 *read_buf, u16 size) {u32 addr_on_bus, *data; -u32 align[2 ] = {};u16 ms_addr;int status; - data =PTR_ALIGN (&align[0 ],8 ); + data =kzalloc (RSI_MASTER_REG_BUF_SIZE ,GFP_KERNEL ); +if (!data) +return -ENOMEM ; + + data =PTR_ALIGN (data,8 ); ms_addr = (addr >>16 ); status =rsi_sdio_master_access_msword (adapter, ms_addr);
@@ -665,7 +668,7 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,rsi_dbg (ERR_ZONE ,"%s: Unable to set ms word to common reg\n" , __func__); -return status; + goto err; } addr &=0xFFFF ;
@@ -683,7 +686,7 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, (u8 *)data, 4);if (status <0 ) {rsi_dbg (ERR_ZONE ,"%s: AHB register read failed\n" , __func__); -return status; + goto err; }if (size ==2 ) {if ((addr &0x3 ) ==0 )
@@ -705,17 +708,23 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr, *read_buf = *data; } -return 0 ; +err: +kfree (data); +return status; }static int rsi_sdio_master_reg_write (struct rsi_hw *adapter,unsigned long addr,unsigned long data,u16 size) { -unsigned long data1[2 ], *data_aligned; +unsigned long *data_aligned;int status; - data_aligned =PTR_ALIGN (&data1[0 ],8 ); + data_aligned =kzalloc (RSI_MASTER_REG_BUF_SIZE ,GFP_KERNEL ); +if (!data_aligned) +return -ENOMEM ; + + data_aligned =PTR_ALIGN (data_aligned,8 );if (size ==2 ) { *data_aligned = ((data <<16 ) | (data &0xFFFF ));
@@ -734,6 +743,7 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,rsi_dbg (ERR_ZONE ,"%s: Unable to set ms word to common reg\n" , __func__); +kfree (data_aligned);return -EIO ; } addr = addr &0xFFFF ;
@@ -743,12 +753,12 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter, (adapter, (addr |RSI_SD_REQUEST_MASTER ), (u8 *)data_aligned, size); -if (status <0 ) { +if (status <0 )rsi_dbg (ERR_ZONE ,"%s: Unable to do AHB reg write\n" , __func__); -return status; - } -return 0 ; + +kfree (data_aligned); +return status; }/**
drivers/net/wireless/rsi/rsi_sdio.h +2 -0
@@ -46,6 +46,8 @@ enum sdio_interrupt_type {#define PKT_BUFF_AVAILABLE 1#define FW_ASSERT_IND 2 +#define RSI_MASTER_REG_BUF_SIZE 12 +#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3#define RSI_FN1_INT_REGISTER 0xf9#define RSI_INT_ENABLE_REGISTER 0x04
Signature · 1 line
2.7.4
Quoted 26 lines · Amitkumar Karwar
From: Amitkumar Karwar <[email protected]>
We miss to release IRQ in certain error path in SDIO probe which causes following kernel panic. This patch corrects error path handling
BUG: unable to handle kernel NULL pointer dereference at (null) IP: (null) PGD 0 P4D 0 Oops: 0010 [#1] SMP PTI Call Trace: <IRQ> ? call_timer_fn+0x29/0x120 ? run_timer_softirq+0x1da/0x420 ? timer_interrupt+0x11/0x20 ? __do_softirq+0xef/0x26e ? irq_exit+0xbe/0xd0 ? do_IRQ+0x4a/0xc0 ? common_interrupt+0xa2/0xa2 </IRQ> ? cpuidle_enter_state+0x118/0x250 ? do_idle+0x186/0x1e0 ? cpu_startup_entry+0x6f/0x80 ? start_kernel+0x47c/0x49c ? secondary_startup_64+0xa5/0xb0
Quoted 2 lines
Fixes 50117605770c ("rsi: improve RX handling in SDIO interface")Signed-off-by Amitkumar Karwar <[email protected]>
2 patches applied to wireless-drivers-next.git, thanks.
90b12aebe54b rsi: fix error path handling in SDIO probe 864db4d50853 rsi: fix kernel panic observed on 64bit machine
Signature · 3 lines
https://patchwork.kernel.org/patch/10297201/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches