summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2026-04-23 13:21:12 +0300
committerPaolo Abeni <pabeni@redhat.com>2026-04-23 13:21:12 +0300
commit063571ab9f80bed51e5ebf888b949827348f2b92 (patch)
treea27a7fa988636a3245a54e601c6f977b886f09d4
parent7dddc74af369478ba7f9bc136d0fc1dc4570cb66 (diff)
parent4b91cb65789b794bfc8d50554b8994f8e0f16309 (diff)
downloadlinux-063571ab9f80bed51e5ebf888b949827348f2b92.tar.xz
Merge branch 'net-airoha-fix-null-pointer-derefrences-in-airoha_qdma_cleanup'
Lorenzo Bianconi says: ==================== net: airoha: Fix NULL pointer derefrences in airoha_qdma_cleanup() Fix two possible NULL pointer derefrences in airoha_qdma_cleanup routine if airoha_qdma_init() fails. v1: https://lore.kernel.org/r/20260417-airoha_qdma_init_rx_queue-fix-v1-0-db9fa5e468e5@kernel.org ==================== Link: https://patch.msgid.link/20260420-airoha_qdma_init_rx_queue-fix-v2-0-d99347e5c18d@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--drivers/net/ethernet/airoha/airoha_eth.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index e17e40a2090d..2bb0a3ff9810 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -745,14 +745,18 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
dma_addr_t dma_addr;
q->buf_size = PAGE_SIZE / 2;
- q->ndesc = ndesc;
q->qdma = qdma;
- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
+ q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
GFP_KERNEL);
if (!q->entry)
return -ENOMEM;
+ q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc),
+ &dma_addr, GFP_KERNEL);
+ if (!q->desc)
+ return -ENOMEM;
+
q->page_pool = page_pool_create(&pp_params);
if (IS_ERR(q->page_pool)) {
int err = PTR_ERR(q->page_pool);
@@ -761,11 +765,7 @@ static int airoha_qdma_init_rx_queue(struct airoha_queue *q,
return err;
}
- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
- &dma_addr, GFP_KERNEL);
- if (!q->desc)
- return -ENOMEM;
-
+ q->ndesc = ndesc;
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
@@ -1020,8 +1020,6 @@ static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q,
struct airoha_eth *eth = qdma->eth;
dma_addr_t dma_addr;
- netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
- airoha_qdma_tx_napi_poll);
irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32),
&dma_addr, GFP_KERNEL);
if (!irq_q->q)
@@ -1031,6 +1029,9 @@ static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q,
irq_q->size = size;
irq_q->qdma = qdma;
+ netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
+ airoha_qdma_tx_napi_poll);
+
airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr);
airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
FIELD_PREP(TX_IRQ_DEPTH_MASK, size));
@@ -1450,8 +1451,12 @@ static void airoha_qdma_cleanup(struct airoha_qdma *qdma)
}
}
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
+ if (!qdma->q_tx_irq[i].size)
+ continue;
+
netif_napi_del(&qdma->q_tx_irq[i].napi);
+ }
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
if (!qdma->q_tx[i].ndesc)