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

Commit fe47f125 authored by Dmitry Tarnyagin's avatar Dmitry Tarnyagin Committed by David S. Miller
Browse files

caif-hsi: Fixing a race condition in the caif_hsi code



cfhsi->tx_state was not protected by a spin lock. TX soft-irq could interrupt
cfhsi_tx_done_work work leading to inconsistent state of the driver.

Signed-off-by: default avatarSjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 94230feb
Loading
Loading
Loading
Loading
+18 −7
Original line number Original line Diff line number Diff line
@@ -304,14 +304,22 @@ static void cfhsi_tx_done_work(struct work_struct *work)
		spin_unlock_bh(&cfhsi->lock);
		spin_unlock_bh(&cfhsi->lock);


		/* Create HSI frame. */
		/* Create HSI frame. */
		do {
			len = cfhsi_tx_frm(desc, cfhsi);
			len = cfhsi_tx_frm(desc, cfhsi);
			if (!len) {
			if (!len) {
				spin_lock_bh(&cfhsi->lock);
				if (unlikely(skb_peek(&cfhsi->qhead))) {
					spin_unlock_bh(&cfhsi->lock);
					continue;
				}
				cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
				cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
				/* Start inactivity timer. */
				/* Start inactivity timer. */
				mod_timer(&cfhsi->timer,
				mod_timer(&cfhsi->timer,
					jiffies + CFHSI_INACTIVITY_TOUT);
					jiffies + CFHSI_INACTIVITY_TOUT);
			break;
				spin_unlock_bh(&cfhsi->lock);
				goto done;
			}
			}
		} while (!len);


		/* Set up new transfer. */
		/* Set up new transfer. */
		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
		res = cfhsi->dev->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->dev);
@@ -320,6 +328,9 @@ static void cfhsi_tx_done_work(struct work_struct *work)
				__func__, res);
				__func__, res);
		}
		}
	} while (res < 0);
	} while (res < 0);

done:
	return;
}
}


static void cfhsi_tx_done_cb(struct cfhsi_drv *drv)
static void cfhsi_tx_done_cb(struct cfhsi_drv *drv)