]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: airoha: Move ndesc initialization at end of airoha_qdma_init_tx()
authorLorenzo Bianconi <lorenzo@kernel.org>
Fri, 17 Apr 2026 06:36:31 +0000 (08:36 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 23 Apr 2026 07:07:57 +0000 (09:07 +0200)
If queue entry list allocation fails in airoha_qdma_init_tx_queue routine,
airoha_qdma_cleanup_tx_queue() will trigger a NULL pointer dereference
accessing the queue entry array. The issue is due to the early ndesc
initialization in airoha_qdma_init_tx_queue(). Fix the issue moving ndesc
initialization at end of airoha_qdma_init_tx routine.

Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260417-airoha_qdma_cleanup_tx_queue-fix-net-v4-1-e04bcc2c9642@kernel.org
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/airoha/airoha_eth.c

index 376d91df5441155ed02dc5e9a22905fc3f217ccb..11c8d3589c45c5f9084dba18eea7fc0053a95f00 100644 (file)
@@ -978,27 +978,27 @@ static int airoha_qdma_init_tx_queue(struct airoha_queue *q,
        dma_addr_t dma_addr;
 
        spin_lock_init(&q->lock);
-       q->ndesc = size;
        q->qdma = qdma;
        q->free_thr = 1 + MAX_SKB_FRAGS;
        INIT_LIST_HEAD(&q->tx_list);
 
-       q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
+       q->entry = devm_kzalloc(eth->dev, size * sizeof(*q->entry),
                                GFP_KERNEL);
        if (!q->entry)
                return -ENOMEM;
 
-       q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
+       q->desc = dmam_alloc_coherent(eth->dev, size * sizeof(*q->desc),
                                      &dma_addr, GFP_KERNEL);
        if (!q->desc)
                return -ENOMEM;
 
-       for (i = 0; i < q->ndesc; i++) {
+       for (i = 0; i < size; i++) {
                u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1);
 
                list_add_tail(&q->entry[i].list, &q->tx_list);
                WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
        }
+       q->ndesc = size;
 
        /* xmit ring drop default setting */
        airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid),