Skip to content

Commit 6fc2589

Browse files
jhovoldgregkh
authored andcommitted
wifi: ath11k: fix dest ring-buffer corruption when ring is full
commit aa69561 upstream. Add the missing memory barriers to make sure that destination ring descriptors are read before updating the tail pointer (and passing ownership to the device) to avoid memory corruption on weakly ordered architectures like aarch64 when the ring is full. Tested-on: WCN6855 hw2.1 WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 Fixes: d5c6515 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Cc: stable@vger.kernel.org # 5.6 Signed-off-by: Johan Hovold <johan+linaro@kernel.org> Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com> Link: https://patch.msgid.link/20250604143457.26032-6-johan+linaro@kernel.org Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent eed5fcf commit 6fc2589

File tree

1 file changed

+9
-2
lines changed
  • drivers/net/wireless/ath/ath11k

1 file changed

+9
-2
lines changed

drivers/net/wireless/ath/ath11k/hal.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,6 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng)
854854
{
855855
lockdep_assert_held(&srng->lock);
856856

857-
/* TODO: See if we need a write memory barrier here */
858857
if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) {
859858
/* For LMAC rings, ring pointer updates are done through FW and
860859
* hence written to a shared memory location that is read by FW
@@ -869,7 +868,11 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng)
869868
WRITE_ONCE(*srng->u.src_ring.hp_addr, srng->u.src_ring.hp);
870869
} else {
871870
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
872-
*srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;
871+
/* Make sure descriptor is read before updating the
872+
* tail pointer.
873+
*/
874+
dma_mb();
875+
WRITE_ONCE(*srng->u.dst_ring.tp_addr, srng->u.dst_ring.tp);
873876
}
874877
} else {
875878
if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
@@ -885,6 +888,10 @@ void ath11k_hal_srng_access_end(struct ath11k_base *ab, struct hal_srng *srng)
885888
srng->u.src_ring.hp);
886889
} else {
887890
srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;
891+
/* Make sure descriptor is read before updating the
892+
* tail pointer.
893+
*/
894+
mb();
888895
ath11k_hif_write32(ab,
889896
(unsigned long)srng->u.dst_ring.tp_addr -
890897
(unsigned long)ab->mem,

0 commit comments

Comments
 (0)