Takashi Iwai 0dfcdf
From f9fff67d2d7ca6fa8066132003a3deef654c55b1 Mon Sep 17 00:00:00 2001
Takashi Iwai 0dfcdf
From: Nagarajan Maran <quic_nmaran@quicinc.com>
Takashi Iwai 0dfcdf
Date: Mon, 17 Apr 2023 13:35:02 +0300
Takashi Iwai 0dfcdf
Subject: [PATCH] wifi: ath11k: Fix SKB corruption in REO destination ring
Takashi Iwai 0dfcdf
Git-commit: f9fff67d2d7ca6fa8066132003a3deef654c55b1
Takashi Iwai 0dfcdf
Patch-mainline: v6.4-rc1
Takashi Iwai 0dfcdf
References: git-fixes
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
While running traffics for a long time, randomly an RX descriptor
Takashi Iwai 0dfcdf
filled with value "0" from REO destination ring is received.
Takashi Iwai 0dfcdf
This descriptor which is invalid causes the wrong SKB (SKB stored in
Takashi Iwai 0dfcdf
the IDR lookup with buffer id "0") to be fetched which in turn
Takashi Iwai 0dfcdf
causes SKB memory corruption issue and the same leads to crash
Takashi Iwai 0dfcdf
after some time.
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
Changed the start id for idr allocation to "1" and the buffer id "0"
Takashi Iwai 0dfcdf
is reserved for error validation. Introduced Sanity check to validate
Takashi Iwai 0dfcdf
the descriptor, before processing the SKB.
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
Crash Signature :
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
Unable to handle kernel paging request at virtual address 3f004900
Takashi Iwai 0dfcdf
PC points to "b15_dma_inv_range+0x30/0x50"
Takashi Iwai 0dfcdf
LR points to "dma_cache_maint_page+0x8c/0x128".
Takashi Iwai 0dfcdf
The Backtrace obtained is as follows:
Takashi Iwai 0dfcdf
[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128)
Takashi Iwai 0dfcdf
[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc)
Takashi Iwai 0dfcdf
[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k])
Takashi Iwai 0dfcdf
[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k])
Takashi Iwai 0dfcdf
[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci])
Takashi Iwai 0dfcdf
[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8)
Takashi Iwai 0dfcdf
[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280)
Takashi Iwai 0dfcdf
[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280)
Takashi Iwai 0dfcdf
[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4)
Takashi Iwai 0dfcdf
[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4)
Takashi Iwai 0dfcdf
[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90)
Takashi Iwai 0dfcdf
[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c)
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
Takashi Iwai 0dfcdf
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Takashi Iwai 0dfcdf
Link: https://lore.kernel.org/r/20230403191533.28114-1-quic_nmaran@quicinc.com
Takashi Iwai 0dfcdf
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
---
Takashi Iwai 0dfcdf
 drivers/net/wireless/ath/ath11k/dp_rx.c | 9 ++++++---
Takashi Iwai 0dfcdf
 1 file changed, 6 insertions(+), 3 deletions(-)
Takashi Iwai 0dfcdf
Takashi Iwai 0dfcdf
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
Takashi Iwai 0dfcdf
index a4934bd79969..f67ce62b2b48 100644
Takashi Iwai 0dfcdf
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
Takashi Iwai 0dfcdf
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
Takashi Iwai 0dfcdf
@@ -389,10 +389,10 @@ int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
Takashi Iwai 0dfcdf
 			goto fail_free_skb;
Takashi Iwai 0dfcdf
 
Takashi Iwai 0dfcdf
 		spin_lock_bh(&rx_ring->idr_lock);
Takashi Iwai 0dfcdf
-		buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
Takashi Iwai 0dfcdf
-				   rx_ring->bufs_max * 3, GFP_ATOMIC);
Takashi Iwai 0dfcdf
+		buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1,
Takashi Iwai 0dfcdf
+				   (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC);
Takashi Iwai 0dfcdf
 		spin_unlock_bh(&rx_ring->idr_lock);
Takashi Iwai 0dfcdf
-		if (buf_id < 0)
Takashi Iwai 0dfcdf
+		if (buf_id <= 0)
Takashi Iwai 0dfcdf
 			goto fail_dma_unmap;
Takashi Iwai 0dfcdf
 
Takashi Iwai 0dfcdf
 		desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
Takashi Iwai 0dfcdf
@@ -2665,6 +2665,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
Takashi Iwai 0dfcdf
 				   cookie);
Takashi Iwai 0dfcdf
 		mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
Takashi Iwai 0dfcdf
 
Takashi Iwai 0dfcdf
+		if (unlikely(buf_id == 0))
Takashi Iwai 0dfcdf
+			continue;
Takashi Iwai 0dfcdf
+
Takashi Iwai 0dfcdf
 		ar = ab->pdevs[mac_id].ar;
Takashi Iwai 0dfcdf
 		rx_ring = &ar->dp.rx_refill_buf_ring;
Takashi Iwai 0dfcdf
 		spin_lock_bh(&rx_ring->idr_lock);
Takashi Iwai 0dfcdf
-- 
Takashi Iwai 0dfcdf
2.35.3
Takashi Iwai 0dfcdf