From: Jeff Disher <disher@xxxxxxxxxxxx> Since mwifiex_ds_misc_subsc_evt is used in an asynchronous case, store the structure in the long-lived mwifiex_private instead of on the calling stack. This fixes a problem where the response of the asynchronous operation would corrupt a stack frame potentially in use by a different thread. Signed-off-by: Jeff Disher <disher@xxxxxxxxxxxx> Reviewed-by: Sam Leffler <sleffler@xxxxxxxxxxxx> Tested-by: Jeff Disher <disher@xxxxxxxxxxxx> Acked-by: Bing Zhao <bzhao@xxxxxxxxxxx> --- drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index ede0c65..bb75390 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -484,6 +484,7 @@ struct mwifiex_private { s32 cqm_rssi_thold; u32 cqm_rssi_hyst; u8 subsc_evt_rssi_state; + struct mwifiex_ds_misc_subsc_evt async_subsc_evt_storage; struct mwifiex_ie mgmt_ie[MAX_MGMT_IE_INDEX]; u16 beacon_idx; u16 proberesp_idx; diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 0b09004..6536356 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -123,7 +123,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = &resp->params.rssi_info_rsp; - struct mwifiex_ds_misc_subsc_evt subsc_evt; + struct mwifiex_ds_misc_subsc_evt *subsc_evt = + &priv->async_subsc_evt_storage; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -140,26 +141,27 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, if (priv->subsc_evt_rssi_state == EVENT_HANDLED) return 0; + memset(subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt)); + /* Resubscribe low and high rssi events with new thresholds */ - memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt)); - subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH; - subsc_evt.action = HostCmd_ACT_BITWISE_SET; + subsc_evt->events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH; + subsc_evt->action = HostCmd_ACT_BITWISE_SET; if (priv->subsc_evt_rssi_state == RSSI_LOW_RECVD) { - subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg - + subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg - priv->cqm_rssi_hyst); - subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); + subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); } else if (priv->subsc_evt_rssi_state == RSSI_HIGH_RECVD) { - subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); - subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg + + subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold); + subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg + priv->cqm_rssi_hyst); } - subsc_evt.bcn_l_rssi_cfg.evt_freq = 1; - subsc_evt.bcn_h_rssi_cfg.evt_freq = 1; + subsc_evt->bcn_l_rssi_cfg.evt_freq = 1; + subsc_evt->bcn_h_rssi_cfg.evt_freq = 1; priv->subsc_evt_rssi_state = EVENT_HANDLED; mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT, - 0, 0, &subsc_evt); + 0, 0, subsc_evt); return 0; } -- 1.7.0.2 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html