2018-04-11 06:56:54

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 1/2] rsi: fix nommu_map_sg overflow kernel panic

From: Siva Rebbagondla <[email protected]>

Following overflow kernel panic is observed on some platforms while
loading the driver. It is fixed if dynamically allocated memory is
passed to SDIO instead of static one

[ 927.513963] nommu_map_sg: overflow 17d54064ba7c+20 of device mask ffffffff
[ 927.517712] Modules linked in: rsi_sdio(+) cmac bnep arc4 rsi_91x mac80211 cfg80211
btrsi rfcomm bluetooth ecdh_generic snd_soc_sst_bytcr_rt5660
[ 927.517861] CPU: 0 PID: 1624 Comm: insmod Tainted: G W 4.15.0-1000 #1
[ 927.517870] RIP: 0010:sdhci_send_command+0x5f0/0xa90 [sdhci]
[ 927.517873] RSP: 0000:ffffac3fc064b6d8 EFLAGS: 00010086
[ 927.517895] Call Trace:
[ 927.517908] ? __schedule+0x3cd/0x890
[ 927.517915] ? mod_timer+0x17b/0x3c0
[ 927.517922] sdhci_request+0x7c/0xf0 [sdhci]
[ 927.517928] __mmc_start_request+0x5a/0x170
[ 927.517932] mmc_start_request+0x74/0x90
[ 927.517936] mmc_wait_for_req+0x87/0xe0
[ 927.517940] mmc_io_rw_extended+0x2fd/0x330
[ 927.517946] ? mmc_wait_data_done+0x30/0x30
[ 927.517951] sdio_io_rw_ext_helper+0x160/0x210
[ 927.517956] sdio_writesb+0x1d/0x20
[ 927.517966] rsi_sdio_write_register_multiple+0x68/0x110 [rsi_sdio]
[ 927.517976] rsi_hal_device_init+0x357/0x910 [rsi_91x]
[ 927.517983] ? rsi_hal_device_init+0x357/0x910 [rsi_91x]
[ 927.517990] rsi_probe+0x2c6/0x450 [rsi_sdio]
[ 927.517995] sdio_bus_probe+0xfc/0x110
[ 927.518000] driver_probe_device+0x2b3/0x490
[ 927.518005] __driver_attach+0xdf/0xf0
[ 927.518008] ? driver_probe_device+0x490/0x490
[ 927.518014] bus_for_each_dev+0x6c/0xc0
[ 927.518018] driver_attach+0x1e/0x20
[ 927.518021] bus_add_driver+0x1f4/0x270
[ 927.518028] ? rsi_sdio_ack_intr+0x50/0x50 [rsi_sdio]
[ 927.518031] driver_register+0x60/0xe0
[ 927.518038] ? rsi_sdio_ack_intr+0x50/0x50 [rsi_sdio]
[ 927.518041] sdio_register_driver+0x20/0x30
[ 927.518047] rsi_module_init+0x16/0x40 [rsi_sdio]

Signed-off-by: Siva Rebbagondla <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 35 ++++++++++++++++++++-------------
drivers/net/wireless/rsi/rsi_91x_sdio.c | 21 +++++++++++++-------
drivers/net/wireless/rsi/rsi_sdio.h | 2 +-
3 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index b7c5403..0761e61 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -635,28 +635,32 @@ static int bl_write_header(struct rsi_hw *adapter, u8 *flash_content,
u32 content_size)
{
struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
- struct bl_header bl_hdr;
+ struct bl_header *bl_hdr;
u32 write_addr, write_len;
int status;

- bl_hdr.flags = 0;
- bl_hdr.image_no = cpu_to_le32(adapter->priv->coex_mode);
- bl_hdr.check_sum = cpu_to_le32(
- *(u32 *)&flash_content[CHECK_SUM_OFFSET]);
- bl_hdr.flash_start_address = cpu_to_le32(
- *(u32 *)&flash_content[ADDR_OFFSET]);
- bl_hdr.flash_len = cpu_to_le32(*(u32 *)&flash_content[LEN_OFFSET]);
+ bl_hdr = kzalloc(sizeof(*bl_hdr), GFP_KERNEL);
+ if (!bl_hdr)
+ return -ENOMEM;
+
+ bl_hdr->flags = 0;
+ bl_hdr->image_no = cpu_to_le32(adapter->priv->coex_mode);
+ bl_hdr->check_sum =
+ cpu_to_le32(*(u32 *)&flash_content[CHECK_SUM_OFFSET]);
+ bl_hdr->flash_start_address =
+ cpu_to_le32(*(u32 *)&flash_content[ADDR_OFFSET]);
+ bl_hdr->flash_len = cpu_to_le32(*(u32 *)&flash_content[LEN_OFFSET]);
write_len = sizeof(struct bl_header);

if (adapter->rsi_host_intf == RSI_HOST_INTF_USB) {
write_addr = PING_BUFFER_ADDRESS;
status = hif_ops->write_reg_multiple(adapter, write_addr,
- (u8 *)&bl_hdr, write_len);
+ (u8 *)bl_hdr, write_len);
if (status < 0) {
rsi_dbg(ERR_ZONE,
"%s: Failed to load Version/CRC structure\n",
__func__);
- return status;
+ goto fail;
}
} else {
write_addr = PING_BUFFER_ADDRESS >> 16;
@@ -665,20 +669,23 @@ static int bl_write_header(struct rsi_hw *adapter, u8 *flash_content,
rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
- return status;
+ goto fail;
}
write_addr = RSI_SD_REQUEST_MASTER |
(PING_BUFFER_ADDRESS & 0xFFFF);
status = hif_ops->write_reg_multiple(adapter, write_addr,
- (u8 *)&bl_hdr, write_len);
+ (u8 *)bl_hdr, write_len);
if (status < 0) {
rsi_dbg(ERR_ZONE,
"%s: Failed to load Version/CRC structure\n",
__func__);
- return status;
+ goto fail;
}
}
- return 0;
+ status = 0;
+fail:
+ kfree(bl_hdr);
+ return status;
}

static u32 read_flash_capacity(struct rsi_hw *adapter)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 8ef0058..f7f2820 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1038,17 +1038,21 @@ static void ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
/*This function resets and re-initializes the chip.*/
static void rsi_reset_chip(struct rsi_hw *adapter)
{
- __le32 data;
+ u8 *data;
u8 sdio_interrupt_status = 0;
u8 request = 1;
int ret;

+ data = kzalloc(sizeof(u32), GFP_KERNEL);
+ if (!data)
+ return;
+
rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
ret = rsi_sdio_write_register(adapter, 0, SDIO_WAKEUP_REG, &request);
if (ret < 0) {
rsi_dbg(ERR_ZONE,
"%s: Failed to write SDIO wakeup register\n", __func__);
- return;
+ goto err;
}
msleep(20);
ret = rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
@@ -1056,7 +1060,7 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
if (ret < 0) {
rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
__func__);
- return;
+ goto err;
}
rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d\n",
__func__, sdio_interrupt_status);
@@ -1066,17 +1070,17 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
rsi_dbg(ERR_ZONE,
"%s: Unable to set ms word to common reg\n",
__func__);
- return;
+ goto err;
}

- data = TA_HOLD_THREAD_VALUE;
+ put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
RSI_SD_REQUEST_MASTER,
- (u8 *)&data, 4)) {
+ data, 4)) {
rsi_dbg(ERR_ZONE,
"%s: Unable to hold Thread-Arch processor threads\n",
__func__);
- return;
+ goto err;
}

/* This msleep will ensure Thread-Arch processor to go to hold
@@ -1097,6 +1101,9 @@ static void rsi_reset_chip(struct rsi_hw *adapter)
* read write operations to complete for chip reset.
*/
msleep(500);
+err:
+ kfree(data);
+ return;
}

/**
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index ead8e7c..353dbdf 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -87,7 +87,7 @@ enum sdio_interrupt_type {
#define TA_SOFT_RST_CLR 0
#define TA_SOFT_RST_SET BIT(0)
#define TA_PC_ZERO 0
-#define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF)
+#define TA_HOLD_THREAD_VALUE 0xF
#define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF)
#define TA_BASE_ADDR 0x2200
#define MISC_CFG_BASE_ADDR 0x4105
--
2.7.4


2018-04-24 17:26:16

by Kalle Valo

[permalink] [raw]
Subject: Re: [1/2] rsi: fix nommu_map_sg overflow kernel panic

Amitkumar Karwar <[email protected]> wrote:

> From: Siva Rebbagondla <[email protected]>
>
> Following overflow kernel panic is observed on some platforms while
> loading the driver. It is fixed if dynamically allocated memory is
> passed to SDIO instead of static one
>
> [ 927.513963] nommu_map_sg: overflow 17d54064ba7c+20 of device mask ffffffff
> [ 927.517712] Modules linked in: rsi_sdio(+) cmac bnep arc4 rsi_91x mac80211 cfg80211
> btrsi rfcomm bluetooth ecdh_generic snd_soc_sst_bytcr_rt5660
> [ 927.517861] CPU: 0 PID: 1624 Comm: insmod Tainted: G W 4.15.0-1000 #1
> [ 927.517870] RIP: 0010:sdhci_send_command+0x5f0/0xa90 [sdhci]
> [ 927.517873] RSP: 0000:ffffac3fc064b6d8 EFLAGS: 00010086
> [ 927.517895] Call Trace:
> [ 927.517908] ? __schedule+0x3cd/0x890
> [ 927.517915] ? mod_timer+0x17b/0x3c0
> [ 927.517922] sdhci_request+0x7c/0xf0 [sdhci]
> [ 927.517928] __mmc_start_request+0x5a/0x170
> [ 927.517932] mmc_start_request+0x74/0x90
> [ 927.517936] mmc_wait_for_req+0x87/0xe0
> [ 927.517940] mmc_io_rw_extended+0x2fd/0x330
> [ 927.517946] ? mmc_wait_data_done+0x30/0x30
> [ 927.517951] sdio_io_rw_ext_helper+0x160/0x210
> [ 927.517956] sdio_writesb+0x1d/0x20
> [ 927.517966] rsi_sdio_write_register_multiple+0x68/0x110 [rsi_sdio]
> [ 927.517976] rsi_hal_device_init+0x357/0x910 [rsi_91x]
> [ 927.517983] ? rsi_hal_device_init+0x357/0x910 [rsi_91x]
> [ 927.517990] rsi_probe+0x2c6/0x450 [rsi_sdio]
> [ 927.517995] sdio_bus_probe+0xfc/0x110
> [ 927.518000] driver_probe_device+0x2b3/0x490
> [ 927.518005] __driver_attach+0xdf/0xf0
> [ 927.518008] ? driver_probe_device+0x490/0x490
> [ 927.518014] bus_for_each_dev+0x6c/0xc0
> [ 927.518018] driver_attach+0x1e/0x20
> [ 927.518021] bus_add_driver+0x1f4/0x270
> [ 927.518028] ? rsi_sdio_ack_intr+0x50/0x50 [rsi_sdio]
> [ 927.518031] driver_register+0x60/0xe0
> [ 927.518038] ? rsi_sdio_ack_intr+0x50/0x50 [rsi_sdio]
> [ 927.518041] sdio_register_driver+0x20/0x30
> [ 927.518047] rsi_module_init+0x16/0x40 [rsi_sdio]
>
> Signed-off-by: Siva Rebbagondla <[email protected]>
> Signed-off-by: Amitkumar Karwar <[email protected]>

2 patches applied to wireless-drivers-next.git, thanks.

f700546682a6 rsi: fix nommu_map_sg overflow kernel panic
78e450719c70 rsi: Fix 'invalid vdd' warning in mmc

--
https://patchwork.kernel.org/patch/10334889/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2018-04-11 06:56:58

by Amitkumar Karwar

[permalink] [raw]
Subject: [PATCH 2/2] rsi: Fix 'invalid vdd' warning in mmc

From: Siva Rebbagondla <[email protected]>

While performing cleanup, driver is messing with card->ocr
value by not masking rocr against ocr_avail. Below panic
is observed with some of the SDIO host controllers due to
this. Issue is resolved by reverting incorrect modifications
to vdd.

[ 927.423821] mmc1: Invalid vdd 0x1f
[ 927.423925] Modules linked in: rsi_sdio(+) cmac bnep arc4 rsi_91x
mac80211 cfg80211 btrsi rfcomm bluetooth ecdh_generic
[ 927.424073] CPU: 0 PID: 1624 Comm: insmod Tainted: G W 4.15.0-1000-caracalla #1
[ 927.424075] Hardware name: Dell Inc. Edge Gateway 3003/ , BIOS 01.00.06 01/22/2018
[ 927.424082] RIP: 0010:sdhci_set_power_noreg+0xdd/0x190[sdhci]
[ 927.424085] RSP: 0018:ffffac3fc064b930 EFLAGS: 00010282
[ 927.424107] Call Trace:
[ 927.424118] sdhci_set_power+0x5a/0x60 [sdhci]
[ 927.424125] sdhci_set_ios+0x360/0x3b0 [sdhci]
[ 927.424133] mmc_set_initial_state+0x92/0x120
[ 927.424137] mmc_power_up.part.34+0x33/0x1d0
[ 927.424141] mmc_power_up+0x17/0x20
[ 927.424147] mmc_sdio_runtime_resume+0x2d/0x50
[ 927.424151] mmc_runtime_resume+0x17/0x20
[ 927.424156] __rpm_callback+0xc4/0x200
[ 927.424161] ? idr_alloc_cyclic+0x57/0xd0
[ 927.424165] ? mmc_runtime_suspend+0x20/0x20
[ 927.424169] rpm_callback+0x24/0x80
[ 927.424172] ? mmc_runtime_suspend+0x20/0x20
[ 927.424176] rpm_resume+0x4b3/0x6c0
[ 927.424181] __pm_runtime_resume+0x4e/0x80
[ 927.424188] driver_probe_device+0x41/0x490
[ 927.424192] __driver_attach+0xdf/0xf0
[ 927.424196] ? driver_probe_device+0x490/0x490
[ 927.424201] bus_for_each_dev+0x6c/0xc0
[ 927.424205] driver_attach+0x1e/0x20
[ 927.424209] bus_add_driver+0x1f4/0x270
[ 927.424217] ? rsi_sdio_ack_intr+0x50/0x50 [rsi_sdio]
[ 927.424221] driver_register+0x60/0xe0
[ 927.424227] ? rsi_sdio_ack_intr+0x50/0x50 [rsi_sdio]
[ 927.424231] sdio_register_driver+0x20/0x30
[ 927.424237] rsi_module_init+0x16/0x40 [rsi_sdio]

Signed-off-by: Siva Rebbagondla <[email protected]>
Signed-off-by: Amitkumar Karwar <[email protected]>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index f7f2820..416981d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -170,7 +170,6 @@ static void rsi_reset_card(struct sdio_func *pfunction)
int err;
struct mmc_card *card = pfunction->card;
struct mmc_host *host = card->host;
- s32 bit = (fls(host->ocr_avail) - 1);
u8 cmd52_resp;
u32 clock, resp, i;
u16 rca;
@@ -190,7 +189,6 @@ static void rsi_reset_card(struct sdio_func *pfunction)
msleep(20);

/* Initialize the SDIO card */
- host->ios.vdd = bit;
host->ios.chip_select = MMC_CS_DONTCARE;
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.power_mode = MMC_POWER_UP;
--
2.7.4