mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-05 09:16:44 +07:00
wil6210: prevent access to vring_tx_data lock during its init
wil_tx_vring locks the vring_tx_data lock before accessing the TX vring to check if it is enabled and valid for use. In case of quick disconnect / connect events for the same station, spin_lock(&txdata->lock) can be called during the lock initialization in the vring init function. To prevent such a race, the TX vrings spin lock should be initialized once during wil6210 driver initialization. Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
1286558e45
commit
875e94392a
@ -438,6 +438,9 @@ int wil_priv_init(struct wil6210_priv *wil)
|
||||
for (i = 0; i < WIL6210_MAX_CID; i++)
|
||||
spin_lock_init(&wil->sta[i].tid_rx_lock);
|
||||
|
||||
for (i = 0; i < WIL6210_MAX_TX_RINGS; i++)
|
||||
spin_lock_init(&wil->vring_tx_data[i].lock);
|
||||
|
||||
mutex_init(&wil->mutex);
|
||||
mutex_init(&wil->wmi_mutex);
|
||||
mutex_init(&wil->back_rx_mutex);
|
||||
|
@ -717,6 +717,21 @@ void wil_rx_fini(struct wil6210_priv *wil)
|
||||
wil_vring_free(wil, vring, 0);
|
||||
}
|
||||
|
||||
static inline void wil_tx_data_init(struct vring_tx_data *txdata)
|
||||
{
|
||||
spin_lock_bh(&txdata->lock);
|
||||
txdata->dot1x_open = 0;
|
||||
txdata->enabled = 0;
|
||||
txdata->idle = 0;
|
||||
txdata->last_idle = 0;
|
||||
txdata->begin = 0;
|
||||
txdata->agg_wsize = 0;
|
||||
txdata->agg_timeout = 0;
|
||||
txdata->agg_amsdu = 0;
|
||||
txdata->addba_in_progress = false;
|
||||
spin_unlock_bh(&txdata->lock);
|
||||
}
|
||||
|
||||
int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
|
||||
int cid, int tid)
|
||||
{
|
||||
@ -758,8 +773,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(txdata, 0, sizeof(*txdata));
|
||||
spin_lock_init(&txdata->lock);
|
||||
wil_tx_data_init(txdata);
|
||||
vring->size = size;
|
||||
rc = wil_vring_alloc(wil, vring);
|
||||
if (rc)
|
||||
@ -791,8 +805,10 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
|
||||
|
||||
return 0;
|
||||
out_free:
|
||||
spin_lock_bh(&txdata->lock);
|
||||
txdata->dot1x_open = false;
|
||||
txdata->enabled = 0;
|
||||
spin_unlock_bh(&txdata->lock);
|
||||
wil_vring_free(wil, vring, 1);
|
||||
wil->vring2cid_tid[id][0] = WIL6210_MAX_CID;
|
||||
wil->vring2cid_tid[id][1] = 0;
|
||||
@ -834,8 +850,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(txdata, 0, sizeof(*txdata));
|
||||
spin_lock_init(&txdata->lock);
|
||||
wil_tx_data_init(txdata);
|
||||
vring->size = size;
|
||||
rc = wil_vring_alloc(wil, vring);
|
||||
if (rc)
|
||||
@ -865,8 +880,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
|
||||
|
||||
return 0;
|
||||
out_free:
|
||||
spin_lock_bh(&txdata->lock);
|
||||
txdata->enabled = 0;
|
||||
txdata->dot1x_open = false;
|
||||
spin_unlock_bh(&txdata->lock);
|
||||
wil_vring_free(wil, vring, 1);
|
||||
out:
|
||||
|
||||
@ -894,7 +911,6 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
|
||||
napi_synchronize(&wil->napi_tx);
|
||||
|
||||
wil_vring_free(wil, vring, 1);
|
||||
memset(txdata, 0, sizeof(*txdata));
|
||||
}
|
||||
|
||||
static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
|
||||
|
Loading…
Reference in New Issue
Block a user