Jelajahi Sumber

qcacmn: Add pdev checking when processing the htt completion messages

Add pdev checking when processing the htt completion messages to avoid
NULL pointer dereference both in the dp_tx_process_htt_completion and
dp_tx_comp_handler.

Change-Id: I9e8129cfa297d4f2e180550c50ad8a4f1be20ee0
CRs-Fixed: 3583893
Tiger Yu 1 tahun lalu
induk
melakukan
dbfc30e61b
3 mengubah file dengan 60 tambahan dan 0 penghapusan
  1. 6 0
      dp/wifi3.0/be/dp_be_tx.c
  2. 48 0
      dp/wifi3.0/dp_tx.c
  3. 6 0
      dp/wifi3.0/li/dp_li_tx.c

+ 6 - 0
dp/wifi3.0/be/dp_be_tx.c

@@ -287,6 +287,12 @@ void dp_tx_process_htt_completion_be(struct dp_soc *soc,
 	}
 
 	pdev = tx_desc->pdev;
+	if (qdf_unlikely(!pdev)) {
+		dp_tx_comp_warn("The pdev in TX desc is NULL, dropped.");
+		dp_tx_comp_warn("tx_status: %u", tx_status);
+		tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
+		goto release_tx_desc;
+	}
 
 	if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
 		dp_tx_comp_info_rl("pdev in down state %d", tx_desc->id);

+ 48 - 0
dp/wifi3.0/dp_tx.c

@@ -5770,6 +5770,44 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
 		dp_txrx_peer_unref_delete(txrx_ref_handle, DP_MOD_ID_TX_COMP);
 }
 
+#ifndef WLAN_SOFTUMAC_SUPPORT
+/**
+ * dp_tx_dump_tx_desc() - Dump tx desc for debugging
+ * @tx_desc: software descriptor head pointer
+ *
+ * This function will dump tx desc for further debugging
+ *
+ * Return: none
+ */
+static
+void dp_tx_dump_tx_desc(struct dp_tx_desc_s *tx_desc)
+{
+	if (tx_desc) {
+		dp_tx_comp_warn("tx_desc->nbuf: %pK", tx_desc->nbuf);
+		dp_tx_comp_warn("tx_desc->flags: 0x%x", tx_desc->flags);
+		dp_tx_comp_warn("tx_desc->id: %u", tx_desc->id);
+		dp_tx_comp_warn("tx_desc->dma_addr: 0x%x",
+				tx_desc->dma_addr);
+		dp_tx_comp_warn("tx_desc->vdev_id: %u",
+				tx_desc->vdev_id);
+		dp_tx_comp_warn("tx_desc->tx_status: %u",
+				tx_desc->tx_status);
+		dp_tx_comp_warn("tx_desc->pdev: %pK",
+				tx_desc->pdev);
+		dp_tx_comp_warn("tx_desc->tx_encap_type: %u",
+				tx_desc->tx_encap_type);
+		dp_tx_comp_warn("tx_desc->buffer_src: %u",
+				tx_desc->buffer_src);
+		dp_tx_comp_warn("tx_desc->frm_type: %u",
+				tx_desc->frm_type);
+		dp_tx_comp_warn("tx_desc->pkt_offset: %u",
+				tx_desc->pkt_offset);
+		dp_tx_comp_warn("tx_desc->pool_id: %u",
+				tx_desc->pool_id);
+	}
+}
+#endif
+
 #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
 static inline
 bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped,
@@ -5991,6 +6029,9 @@ more_data:
 							tx_desc,
 							htt_tx_status,
 							ring_id);
+			if (qdf_unlikely(!tx_desc->pdev)) {
+				dp_tx_dump_tx_desc(tx_desc);
+			}
 		} else {
 			tx_desc->tx_status =
 				hal_tx_comp_get_tx_status(tx_comp_hal_desc);
@@ -6017,6 +6058,13 @@ more_data:
 				continue;
 			}
 
+			if (qdf_unlikely(!tx_desc->pdev)) {
+				dp_tx_comp_warn("The pdev is NULL in TX desc, ignored.");
+				dp_tx_dump_tx_desc(tx_desc);
+				DP_STATS_INC(soc, tx.tx_comp_exception, 1);
+				continue;
+			}
+
 			if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
 				dp_tx_comp_info_rl("pdev in down state %d",
 						   tx_desc->id);

+ 6 - 0
dp/wifi3.0/li/dp_li_tx.c

@@ -130,6 +130,12 @@ void dp_tx_process_htt_completion_li(struct dp_soc *soc,
 	}
 
 	pdev = tx_desc->pdev;
+	if (qdf_unlikely(!pdev)) {
+		dp_tx_comp_warn("The pdev in TX desc is NULL, dropped.");
+		dp_tx_comp_warn("tx_status: %u", tx_status);
+		tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
+		goto release_tx_desc;
+	}
 
 	if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
 		dp_tx_comp_info_rl("pdev in down state %d", tx_desc->id);