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

Commit d9ac2d99 authored by Ganesh Goudar's avatar Ganesh Goudar Committed by David S. Miller
Browse files

cxgb4: fix possible deadlock



t4_wr_mbox_meat_timeout() can be called from both softirq
context and process context, hence protect the mbox with
spin_lock_bh() instead of simple spin_lock()

Signed-off-by: default avatarGanesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 955ec4cb
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -317,9 +317,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
	 * wait [for a while] till we're at the front [or bail out with an
	 * EBUSY] ...
	 */
	spin_lock(&adap->mbox_lock);
	spin_lock_bh(&adap->mbox_lock);
	list_add_tail(&entry.list, &adap->mlist.list);
	spin_unlock(&adap->mbox_lock);
	spin_unlock_bh(&adap->mbox_lock);

	delay_idx = 0;
	ms = delay[0];
@@ -332,9 +332,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
		 */
		pcie_fw = t4_read_reg(adap, PCIE_FW_A);
		if (i > FW_CMD_MAX_TIMEOUT || (pcie_fw & PCIE_FW_ERR_F)) {
			spin_lock(&adap->mbox_lock);
			spin_lock_bh(&adap->mbox_lock);
			list_del(&entry.list);
			spin_unlock(&adap->mbox_lock);
			spin_unlock_bh(&adap->mbox_lock);
			ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -EBUSY;
			t4_record_mbox(adap, cmd, size, access, ret);
			return ret;
@@ -365,9 +365,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
	for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
		v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
	if (v != MBOX_OWNER_DRV) {
		spin_lock(&adap->mbox_lock);
		spin_lock_bh(&adap->mbox_lock);
		list_del(&entry.list);
		spin_unlock(&adap->mbox_lock);
		spin_unlock_bh(&adap->mbox_lock);
		ret = (v == MBOX_OWNER_FW) ? -EBUSY : -ETIMEDOUT;
		t4_record_mbox(adap, cmd, size, access, ret);
		return ret;
@@ -418,9 +418,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
			execute = i + ms;
			t4_record_mbox(adap, cmd_rpl,
				       MBOX_LEN, access, execute);
			spin_lock(&adap->mbox_lock);
			spin_lock_bh(&adap->mbox_lock);
			list_del(&entry.list);
			spin_unlock(&adap->mbox_lock);
			spin_unlock_bh(&adap->mbox_lock);
			return -FW_CMD_RETVAL_G((int)res);
		}
	}
@@ -430,9 +430,9 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
	dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
		*(const u8 *)cmd, mbox);
	t4_report_fw_error(adap);
	spin_lock(&adap->mbox_lock);
	spin_lock_bh(&adap->mbox_lock);
	list_del(&entry.list);
	spin_unlock(&adap->mbox_lock);
	spin_unlock_bh(&adap->mbox_lock);
	t4_fatal_err(adap);
	return ret;
}