mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
101 lines
3.2 KiB
Diff
101 lines
3.2 KiB
Diff
From 3d445af13641dced4a555b7ef60e4d5b7fba8aa1 Mon Sep 17 00:00:00 2001
|
|
From: Karthik M <quic_karm@quicinc.com>
|
|
Date: Thu, 9 Jun 2022 16:44:12 +0530
|
|
Subject: [PATCH] ath12k: Avoid NULL ptr access during mgmt tx cleanup
|
|
|
|
Currently 'ar' reference is not added in skb_cb during
|
|
WMI mgmt tx. Though this is generally not used during tx completion
|
|
callbacks, on interface removal the remaining idr cleanup callback
|
|
uses the ar ptr from skb_cb from mgmt txmgmt_idr. Hence
|
|
fill them during tx call for proper usage.
|
|
|
|
Also free the skb which is missing currently in these callbacks.
|
|
|
|
Crash_info:
|
|
|
|
[19282.489476] Unable to handle kernel NULL pointer dereference at virtual address 00000000
|
|
[19282.489515] pgd = 91eb8000
|
|
[19282.496702] [00000000] *pgd=00000000
|
|
[19282.502524] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
|
|
[19282.783728] PC is at ath12k_mac_vif_txmgmt_idr_remove+0x28/0xd8 [ath12k]
|
|
[19282.789170] LR is at idr_for_each+0xa0/0xc8
|
|
|
|
Link: https://lore.kernel.org/r/1637832614-13831-1-git-send-email-quic_srirrama@quicinc.com
|
|
|
|
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
|
|
Signed-off-by: Karthik M <quic_karm@quicinc.com>
|
|
---
|
|
drivers/net/wireless/ath/ath12k/mac.c | 33 ++++++++++++++++++---------------
|
|
1 file changed, 18 insertions(+), 15 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath12k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath12k/mac.c
|
|
@@ -5962,24 +5962,33 @@ static void ath12k_mgmt_over_wmi_tx_drop
|
|
wake_up(&ar->txmgmt_empty_waitq);
|
|
}
|
|
|
|
-int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
|
|
+static void ath12k_mac_tx_mgmt_free(struct ath12k *ar, int buf_id)
|
|
{
|
|
- struct sk_buff *msdu = skb;
|
|
+ struct sk_buff *msdu;
|
|
struct ieee80211_tx_info *info;
|
|
- struct ath12k *ar = ctx;
|
|
- struct ath12k_base *ab = ar->ab;
|
|
|
|
spin_lock_bh(&ar->txmgmt_idr_lock);
|
|
- idr_remove(&ar->txmgmt_idr, buf_id);
|
|
+ msdu = idr_remove(&ar->txmgmt_idr, buf_id);
|
|
spin_unlock_bh(&ar->txmgmt_idr_lock);
|
|
- dma_unmap_single(ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len,
|
|
+
|
|
+ if (!msdu)
|
|
+ return;
|
|
+
|
|
+ dma_unmap_single(ar->ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len,
|
|
DMA_TO_DEVICE);
|
|
|
|
info = IEEE80211_SKB_CB(msdu);
|
|
memset(&info->status, 0, sizeof(info->status));
|
|
|
|
- ath12k_mgmt_over_wmi_tx_drop(ar, skb);
|
|
+ ath12k_mgmt_over_wmi_tx_drop(ar, msdu);
|
|
+}
|
|
+
|
|
+int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx)
|
|
+{
|
|
+ struct ath12k *ar = ctx;
|
|
|
|
+ ath12k_mac_tx_mgmt_free(ar, buf_id);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -5987,16 +5996,10 @@ static int ath12k_mac_vif_txmgmt_idr_rem
|
|
{
|
|
struct ieee80211_vif *vif = ctx;
|
|
struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB((struct sk_buff *)skb);
|
|
- struct sk_buff *msdu = skb;
|
|
struct ath12k *ar = skb_cb->ar;
|
|
- struct ath12k_base *ab = ar->ab;
|
|
|
|
if (skb_cb->vif == vif) {
|
|
- spin_lock_bh(&ar->txmgmt_idr_lock);
|
|
- idr_remove(&ar->txmgmt_idr, buf_id);
|
|
- spin_unlock_bh(&ar->txmgmt_idr_lock);
|
|
- dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len,
|
|
- DMA_TO_DEVICE);
|
|
+ ath12k_mac_tx_mgmt_free(ar, buf_id);
|
|
}
|
|
|
|
return 0;
|
|
@@ -6134,7 +6137,7 @@ static int ath12k_mac_mgmt_tx(struct ath
|
|
|
|
skb_queue_tail(q, skb);
|
|
atomic_inc(&ar->num_pending_mgmt_tx);
|
|
- ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
|
|
+ queue_work(ar->ab->workqueue_aux, &ar->wmi_mgmt_tx_work);
|
|
|
|
return 0;
|
|
}
|