Skip to content

Commit

Permalink
rsi: fix kernel panic observed on 64bit machine
Browse files Browse the repository at this point in the history
[ 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 <amit.karwar@redpinesignals.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Amitkumar Karwar authored and gregkh committed May 30, 2018
1 parent 31dbd9c commit b652092
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
32 changes: 21 additions & 11 deletions drivers/net/wireless/rsi/rsi_91x_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,19 +636,22 @@ 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);
if (status < 0) {
rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
return status;
goto err;
}
addr &= 0xFFFF;

Expand All @@ -666,7 +669,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)
Expand All @@ -688,17 +691,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));
Expand All @@ -717,6 +726,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;
Expand All @@ -726,12 +736,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;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/rsi/rsi_sdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_SD_REQUEST_MASTER 0x10000
Expand Down

0 comments on commit b652092

Please sign in to comment.