wifi: ath11k: Fix SKB corruption in REO destination ring
authorNagarajan Maran <quic_nmaran@quicinc.com>
Mon, 17 Apr 2023 10:35:02 +0000 (13:35 +0300)
committerKalle Valo <quic_kvalo@quicinc.com>
Wed, 19 Apr 2023 14:24:10 +0000 (17:24 +0300)
While running traffics for a long time, randomly an RX descriptor
filled with value "0" from REO destination ring is received.
This descriptor which is invalid causes the wrong SKB (SKB stored in
the IDR lookup with buffer id "0") to be fetched which in turn
causes SKB memory corruption issue and the same leads to crash
after some time.

Changed the start id for idr allocation to "1" and the buffer id "0"
is reserved for error validation. Introduced Sanity check to validate
the descriptor, before processing the SKB.

Crash Signature :

Unable to handle kernel paging request at virtual address 3f004900
PC points to "b15_dma_inv_range+0x30/0x50"
LR points to "dma_cache_maint_page+0x8c/0x128".
The Backtrace obtained is as follows:
[<8031716c>] (b15_dma_inv_range) from [<80313a4c>] (dma_cache_maint_page+0x8c/0x128)
[<80313a4c>] (dma_cache_maint_page) from [<80313b90>] (__dma_page_dev_to_cpu+0x28/0xcc)
[<80313b90>] (__dma_page_dev_to_cpu) from [<7fb5dd68>] (ath11k_dp_process_rx+0x1e8/0x4a4 [ath11k])
[<7fb5dd68>] (ath11k_dp_process_rx [ath11k]) from [<7fb53c20>] (ath11k_dp_service_srng+0xb0/0x2ac [ath11k])
[<7fb53c20>] (ath11k_dp_service_srng [ath11k]) from [<7f67bba4>] (ath11k_pci_ext_grp_napi_poll+0x1c/0x78 [ath11k_pci])
[<7f67bba4>] (ath11k_pci_ext_grp_napi_poll [ath11k_pci]) from [<807d5cf4>] (__napi_poll+0x28/0xb8)
[<807d5cf4>] (__napi_poll) from [<807d5f28>] (net_rx_action+0xf0/0x280)
[<807d5f28>] (net_rx_action) from [<80302148>] (__do_softirq+0xd0/0x280)
[<80302148>] (__do_softirq) from [<80320408>] (irq_exit+0x74/0xd4)
[<80320408>] (irq_exit) from [<803638a4>] (__handle_domain_irq+0x90/0xb4)
[<803638a4>] (__handle_domain_irq) from [<805bedec>] (gic_handle_irq+0x58/0x90)
[<805bedec>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c)

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1

Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20230403191533.28114-1-quic_nmaran@quicinc.com
drivers/net/wireless/ath/ath11k/dp_rx.c

index a4934bd799692d98b624ec679e2485bce7412322..f67ce62b2b48d2629bcf361ac476ce9fefd1a46b 100644 (file)
@@ -389,10 +389,10 @@ int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id,
                        goto fail_free_skb;
 
                spin_lock_bh(&rx_ring->idr_lock);
-               buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
-                                  rx_ring->bufs_max * 3, GFP_ATOMIC);
+               buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1,
+                                  (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC);
                spin_unlock_bh(&rx_ring->idr_lock);
-               if (buf_id < 0)
+               if (buf_id <= 0)
                        goto fail_dma_unmap;
 
                desc = ath11k_hal_srng_src_get_next_entry(ab, srng);
@@ -2665,6 +2665,9 @@ try_again:
                                   cookie);
                mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
 
+               if (unlikely(buf_id == 0))
+                       continue;
+
                ar = ab->pdevs[mac_id].ar;
                rx_ring = &ar->dp.rx_refill_buf_ring;
                spin_lock_bh(&rx_ring->idr_lock);