Skip to content

Commit 046cc2e

Browse files
jerome-pouillergregkh
authored andcommitted
staging: wfx: fix RCU usage in wfx_join_finalize()
Access to sta->ht_cap is protected by RCU. However, hif_set_association_mode() may sleep, so it can't be called in RCU. This patch fix this behavior by handling sta and its RCU directly from function hif_set_association_mode(). Signed-off-by: Jérôme Pouiller <[email protected]> Fixes: d001490 ("staging: wfx: fix RCU usage") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4bbc6a3 commit 046cc2e

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

drivers/staging/wfx/hif_tx_mib.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ static inline int hif_set_block_ack_policy(struct wfx_vif *wvif,
191191
}
192192

193193
static inline int hif_set_association_mode(struct wfx_vif *wvif,
194-
struct ieee80211_bss_conf *info,
195-
struct ieee80211_sta_ht_cap *ht_cap)
194+
struct ieee80211_bss_conf *info)
196195
{
197196
int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
197+
struct ieee80211_sta *sta = NULL;
198198
struct hif_mib_set_association_mode val = {
199199
.preambtype_use = 1,
200200
.mode = 1,
@@ -204,12 +204,17 @@ static inline int hif_set_association_mode(struct wfx_vif *wvif,
204204
.basic_rate_set = cpu_to_le32(basic_rates)
205205
};
206206

207+
rcu_read_lock(); // protect sta
208+
if (info->bssid && !info->ibss_joined)
209+
sta = ieee80211_find_sta(wvif->vif, info->bssid);
210+
207211
// FIXME: it is strange to not retrieve all information from bss_info
208-
if (ht_cap && ht_cap->ht_supported) {
209-
val.mpdu_start_spacing = ht_cap->ampdu_density;
212+
if (sta && sta->ht_cap.ht_supported) {
213+
val.mpdu_start_spacing = sta->ht_cap.ampdu_density;
210214
if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
211-
val.greenfield = !!(ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD);
215+
val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
212216
}
217+
rcu_read_unlock();
213218

214219
return hif_write_mib(wvif->wdev, wvif->id,
215220
HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));

drivers/staging/wfx/sta.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
691691
wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
692692
else
693693
wvif->bss_params.operational_rate_set = -1;
694+
rcu_read_unlock();
694695
if (sta &&
695696
info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
696697
hif_dual_cts_protection(wvif, true);
@@ -703,8 +704,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
703704
wvif->bss_params.beacon_lost_count = 20;
704705
wvif->bss_params.aid = info->aid;
705706

706-
hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL);
707-
rcu_read_unlock();
707+
hif_set_association_mode(wvif, info);
708708

709709
if (!info->ibss_joined) {
710710
hif_keep_alive_period(wvif, 30 /* sec */);

0 commit comments

Comments
 (0)