Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e262ad36 authored by Maya Erez's avatar Maya Erez Committed by Maya Erez
Browse files

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.

Change-Id: I11fa67f7040c4a728f0cd7633f4fbb829ac165d0
Signed-off-by: default avatarMaya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
git-commit: 875e94392ad2be9776c8325d3573160eb1455a2b
Git-repo: https://github.com/kvalo/ath.git


CRs-Fixed: 982882
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
parent 0dbc4061
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
+21 −5
Original line number Diff line number Diff line
@@ -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,