Skip to content

Commit b652092

Browse files
Amitkumar Karwargregkh
Amitkumar Karwar
authored andcommitted
rsi: fix kernel panic observed on 64bit machine
[ Upstream commit 864db4d ] 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 [hardkernel#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+ hardkernel#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> Signed-off-by: Amitkumar Karwar <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 31dbd9c commit b652092

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

drivers/net/wireless/rsi/rsi_91x_sdio.c

+21-11
Original file line numberDiff line numberDiff line change
@@ -636,19 +636,22 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
636636
u32 *read_buf, u16 size)
637637
{
638638
u32 addr_on_bus, *data;
639-
u32 align[2] = {};
640639
u16 ms_addr;
641640
int status;
642641

643-
data = PTR_ALIGN(&align[0], 8);
642+
data = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
643+
if (!data)
644+
return -ENOMEM;
645+
646+
data = PTR_ALIGN(data, 8);
644647

645648
ms_addr = (addr >> 16);
646649
status = rsi_sdio_master_access_msword(adapter, ms_addr);
647650
if (status < 0) {
648651
rsi_dbg(ERR_ZONE,
649652
"%s: Unable to set ms word to common reg\n",
650653
__func__);
651-
return status;
654+
goto err;
652655
}
653656
addr &= 0xFFFF;
654657

@@ -666,7 +669,7 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
666669
(u8 *)data, 4);
667670
if (status < 0) {
668671
rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
669-
return status;
672+
goto err;
670673
}
671674
if (size == 2) {
672675
if ((addr & 0x3) == 0)
@@ -688,17 +691,23 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
688691
*read_buf = *data;
689692
}
690693

691-
return 0;
694+
err:
695+
kfree(data);
696+
return status;
692697
}
693698

694699
static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
695700
unsigned long addr,
696701
unsigned long data, u16 size)
697702
{
698-
unsigned long data1[2], *data_aligned;
703+
unsigned long *data_aligned;
699704
int status;
700705

701-
data_aligned = PTR_ALIGN(&data1[0], 8);
706+
data_aligned = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
707+
if (!data_aligned)
708+
return -ENOMEM;
709+
710+
data_aligned = PTR_ALIGN(data_aligned, 8);
702711

703712
if (size == 2) {
704713
*data_aligned = ((data << 16) | (data & 0xFFFF));
@@ -717,6 +726,7 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
717726
rsi_dbg(ERR_ZONE,
718727
"%s: Unable to set ms word to common reg\n",
719728
__func__);
729+
kfree(data_aligned);
720730
return -EIO;
721731
}
722732
addr = addr & 0xFFFF;
@@ -726,12 +736,12 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
726736
(adapter,
727737
(addr | RSI_SD_REQUEST_MASTER),
728738
(u8 *)data_aligned, size);
729-
if (status < 0) {
739+
if (status < 0)
730740
rsi_dbg(ERR_ZONE,
731741
"%s: Unable to do AHB reg write\n", __func__);
732-
return status;
733-
}
734-
return 0;
742+
743+
kfree(data_aligned);
744+
return status;
735745
}
736746

737747
/**

drivers/net/wireless/rsi/rsi_sdio.h

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ enum sdio_interrupt_type {
4646
#define PKT_BUFF_AVAILABLE 1
4747
#define FW_ASSERT_IND 2
4848

49+
#define RSI_MASTER_REG_BUF_SIZE 12
50+
4951
#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3
5052
#define RSI_FN1_INT_REGISTER 0xf9
5153
#define RSI_SD_REQUEST_MASTER 0x10000

0 commit comments

Comments
 (0)