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

Commit 8b89ccec authored by Yeshwanth Sriram Guntuka's avatar Yeshwanth Sriram Guntuka Committed by Madan Koyyalamudi
Browse files

qcacmn: Invoke hal_reg_write_need_delay before the register write

hal_reg_write_need_delay is invoked immediately after
q_elem->valid check. The first two instructions in
hal_reg_write_need_delay could be in the CPU instruction
pipeline which could result in possible loading and
dereferencing of NULL srng from an invalid q_elem.

Fix is to invoke hal_reg_write_need_delay just before
hal_process_reg_write_q_elem and also add NULL checks
to avoid the srng NULL pointer dereference.

Change-Id: I2de50b1e78782e3c91a9cb4477f28d91f9c29439
CRs-Fixed: 2973257
parent 0bc1c35c
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -523,10 +523,17 @@ static inline void hal_reg_write_fill_sched_delay_hist(struct hal_soc *hal,
static inline bool hal_reg_write_need_delay(struct hal_reg_write_q_elem *elem)
{
	struct hal_srng *srng = elem->srng;
	struct hal_soc *hal = srng->hal_soc;
	struct hal_soc *hal;
	qdf_time_t now;
	qdf_iomem_t real_addr;

	if (qdf_unlikely(!srng))
		return false;

	hal = srng->hal_soc;
	if (qdf_unlikely(!hal))
		return false;

	/* Check if it is target srng, and valid shadow reg */
	if (qdf_likely(!IS_SRNG_MATCH(srng)))
		return false;
@@ -596,10 +603,6 @@ static void hal_reg_write_work(void *arg)
		if (!q_elem->valid)
			break;

		if (hal_reg_write_need_delay(q_elem))
			hal_verbose_debug("Delay reg writer for srng 0x%x, addr 0x%pK",
					  q_elem->srng->ring_id, q_elem->addr);

		q_elem->dequeue_time = qdf_get_log_timestamp();
		ring_id = q_elem->srng->ring_id;
		addr = q_elem->addr;
@@ -610,6 +613,10 @@ static void hal_reg_write_work(void *arg)
		hal->stats.wstats.dequeues++;
		qdf_atomic_dec(&hal->stats.wstats.q_depth);

		if (hal_reg_write_need_delay(q_elem))
			hal_verbose_debug("Delay reg writer for srng 0x%x, addr 0x%pK",
					  q_elem->srng->ring_id, q_elem->addr);

		write_val = hal_process_reg_write_q_elem(hal, q_elem);
		hal_verbose_debug("read_idx %u srng 0x%x, addr 0x%pK dequeue_val %u sched delay %llu us",
				  hal->read_idx, ring_id, addr, write_val, delta_us);