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

Commit 6352ab82 authored by Rakesh Pillai's avatar Rakesh Pillai Committed by snandini
Browse files

qcacmn: Invalidate ring desc cookie after processing

Currently all the rx ring descriptor contents are left
intact even after these entries are processed. This can,
at times, lead to stale entries being processed, if the
head pointer of any ring is updated before the updated
contents of the ring descriptor gets reflected in the memory.

This can lead to scenarios where the host driver reads a
stale value of sw_cookie, and free/unmap a currently in-use
buffer, thereby leading to the hardware accessing unmapped
memory region.

The sw_cookie is the integral part of al the rx ring
processing. Hence we always mark the sw_cookie as invalid
after dequeuing an entry from the REO2SW ring. Every time
we check for the validity of the sw_cookie before we try to
process an entry from REO2SW ring. if the invalid bit in the
sw_cookie is set, we just skip this entry and move on to the
next entry in the ring.

Change-Id: I0e78fa662b8ba33e64687a4dee4d1a5875ddb4bf
CRs-Fixed: 2730718
parent 6684defa
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1992,6 +1992,10 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl,
		}

		rx_buf_cookie = HAL_RX_REO_BUF_COOKIE_GET(ring_desc);
		status = dp_rx_cookie_check_and_invalidate(ring_desc);
		if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) {
			break;
		}

		rx_desc = dp_rx_cookie_2_va_rxdma_buf(soc, rx_buf_cookie);
		status = dp_rx_desc_sanity(soc, hal_soc, hal_ring_hdl,
+18 −0
Original line number Diff line number Diff line
@@ -535,6 +535,24 @@ void *dp_rx_cookie_2_va_mon_status(struct dp_soc *soc, uint32_t cookie)
}
#endif /* RX_DESC_MULTI_PAGE_ALLOC */

#ifdef DP_RX_DESC_COOKIE_INVALIDATE
static inline QDF_STATUS
dp_rx_cookie_check_and_invalidate(hal_ring_desc_t ring_desc)
{
	if (qdf_unlikely(HAL_RX_REO_BUF_COOKIE_INVALID_GET(ring_desc)))
		return QDF_STATUS_E_FAILURE;

	HAL_RX_REO_BUF_COOKIE_INVALID_SET(ring_desc);
	return QDF_STATUS_SUCCESS;
}
#else
static inline QDF_STATUS
dp_rx_cookie_check_and_invalidate(hal_ring_desc_t ring_desc)
{
	return QDF_STATUS_SUCCESS;
}
#endif

void dp_rx_add_desc_list_to_free_list(struct dp_soc *soc,
				union dp_rx_desc_list_elem_t **local_desc_list,
				union dp_rx_desc_list_elem_t **tail,
+28 −0
Original line number Diff line number Diff line
@@ -227,6 +227,24 @@ enum hal_rx_ret_buf_manager {
		(paddr_hi << BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_LSB) & \
		BUFFER_ADDR_INFO_1_BUFFER_ADDR_39_32_MASK)

#define HAL_RX_COOKIE_INVALID_MASK	0x80000000

/*
 * macro to get the invalid bit for sw cookie
 */
#define HAL_RX_BUF_COOKIE_INVALID_GET(buff_addr_info) \
		((*(((unsigned int *) buff_addr_info) + \
		(BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) & \
		HAL_RX_COOKIE_INVALID_MASK)

/*
 * macro to set the invalid bit for sw cookie
 */
#define HAL_RX_BUF_COOKIE_INVALID_SET(buff_addr_info) \
		((*(((unsigned int *) buff_addr_info) + \
		(BUFFER_ADDR_INFO_1_SW_BUFFER_COOKIE_OFFSET >> 2))) |= \
		HAL_RX_COOKIE_INVALID_MASK)

/*
 * macro to set the cookie into the rxdma ring entry
 */
@@ -293,6 +311,16 @@ enum hal_rx_ret_buf_manager {
	(((struct reo_destination_ring *)		\
		reo_desc)->buf_or_link_desc_addr_info)))

#define HAL_RX_REO_BUF_COOKIE_INVALID_GET(reo_desc)	\
	(HAL_RX_BUF_COOKIE_INVALID_GET(&		\
	(((struct reo_destination_ring *)	\
		reo_desc)->buf_or_link_desc_addr_info)))

#define HAL_RX_REO_BUF_COOKIE_INVALID_SET(reo_desc)	\
	(HAL_RX_BUF_COOKIE_INVALID_SET(&		\
	(((struct reo_destination_ring *)	\
		reo_desc)->buf_or_link_desc_addr_info)))

#define HAL_RX_REO_BUF_COOKIE_GET(reo_desc)	\
	(HAL_RX_BUF_COOKIE_GET(&		\
	(((struct reo_destination_ring *)	\