]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
octeontx2-af: npc: Fix size of entry2cntr_map
authorRatheesh Kannoth <rkannoth@marvell.com>
Wed, 10 Jun 2026 02:23:44 +0000 (07:53 +0530)
committerPaolo Abeni <pabeni@redhat.com>
Sat, 13 Jun 2026 08:48:13 +0000 (10:48 +0200)
KASAN prints below splat. This is caused by allocating counter for
reserved mcam entry for cpt 2nd pass entry. But mcam->entry2cntr_map
is not allocated for reserved entries.

BUG: KASAN: slab-out-of-bounds in npc_map_mcam_entry_and_cntr+0xb0/0x1a0
Write of size 2 at addr ffff0001033e7ffe by task kworker/0:1/14

CPU: 0 PID: 14 Comm: kworker/0:1 Not tainted 6.1.67 #1
Hardware name: Marvell CN106XX board (DT)
Workqueue: events work_for_cpu_fn
Call trace:
 dump_backtrace.part.0+0xe4/0xf0
 show_stack+0x18/0x30
 dump_stack_lvl+0x88/0xb4
 print_report+0x154/0x458
 kasan_report+0xb8/0x194
 __asan_store2+0x7c/0xa0
 npc_map_mcam_entry_and_cntr+0xb0/0x1a0
 rvu_mbox_handler_npc_mcam_write_entry+0x268/0x280
 npc_install_flow+0x840/0xfe0
 rvu_npc_install_cpt_pass2_entry+0x138/0x190
 rvu_nix_init+0x148c/0x2880
 rvu_probe+0x1800/0x30b0
 local_pci_probe+0x78/0xe0
 work_for_cpu_fn+0x30/0x50
 process_one_work+0x4cc/0x97c
 worker_thread+0x360/0x630
 kthread+0x1a0/0x1b0
 ret_from_fork+0x10/0x20

Fixes: 55307fcb9258 ("octeontx2-af: Add mbox messages to install and delete MCAM rules")
Cc: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Link: https://patch.msgid.link/20260610022344.969774-1-rkannoth@marvell.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c

index d301a3f0f87a86d277f16d6662cf53095523f656..4994385a822b72de12e0d4c9e923d4a8f655dac9 100644 (file)
@@ -2181,7 +2181,7 @@ int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
        /* Alloc memory for MCAM entry to counter mapping and for tracking
         * counter's reference count.
         */
-       mcam->entry2cntr_map = kcalloc(mcam->bmap_entries, sizeof(u16),
+       mcam->entry2cntr_map = kcalloc(mcam->total_entries, sizeof(u16),
                                       GFP_KERNEL);
        if (!mcam->entry2cntr_map)
                goto free_cntr_map;
@@ -2197,10 +2197,11 @@ int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
        if (!mcam->entry2target_pffunc)
                goto free_cntr_refcnt;
 
-       for (index = 0; index < mcam->bmap_entries; index++) {
+       for (index = 0; index < mcam->bmap_entries; index++)
                mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
+
+       for (index = 0; index < mcam->total_entries; index++)
                mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP;
-       }
 
        for (cntr = 0; cntr < mcam->counters.max; cntr++)
                mcam->cntr2pfvf_map[cntr] = NPC_MCAM_INVALID_MAP;
@@ -3531,7 +3532,7 @@ static int __npc_mcam_free_counter(struct rvu *rvu,
                                   struct msg_rsp *rsp)
 {
        struct npc_mcam *mcam = &rvu->hw->mcam;
-       u16 index, entry = 0;
+       u16 index;
        int blkaddr, err;
 
        blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
@@ -3547,20 +3548,16 @@ static int __npc_mcam_free_counter(struct rvu *rvu,
        mcam->cntr2pfvf_map[req->cntr] = NPC_MCAM_INVALID_MAP;
        rvu_free_rsrc(&mcam->counters, req->cntr);
 
-       /* Disable all MCAM entry's stats which are using this counter */
-       while (entry < mcam->bmap_entries) {
+       /* Disable all MCAM entry's stats which are using this counter.
+        * Scan the full MCAM index range: AF-reserved rules (e.g. CPT pass-2)
+        */
+       for (index = 0; index < mcam->total_entries; index++) {
                if (!mcam->cntr_refcnt[req->cntr])
                        break;
-
-               index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);
-               if (index >= mcam->bmap_entries)
-                       break;
-               entry = index + 1;
                if (mcam->entry2cntr_map[index] != req->cntr)
                        continue;
-
-               npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
-                                             index, req->cntr);
+               npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index,
+                                             req->cntr);
        }
 
        return 0;
@@ -3631,7 +3628,7 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
                struct npc_mcam_unmap_counter_req *req, struct msg_rsp *rsp)
 {
        struct npc_mcam *mcam = &rvu->hw->mcam;
-       u16 index, entry = 0;
+       u16 index;
        int blkaddr, rc;
 
        /* Counter is not supported for CN20K */
@@ -3658,20 +3655,13 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
        }
 
        /* Disable all MCAM entry's stats which are using this counter */
-       while (entry < mcam->bmap_entries) {
+       for (index = 0; index < mcam->total_entries; index++) {
                if (!mcam->cntr_refcnt[req->cntr])
                        break;
-
-               index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);
-               if (index >= mcam->bmap_entries)
-                       break;
-               entry = index + 1;
-
                if (mcam->entry2cntr_map[index] != req->cntr)
                        continue;
-
-               npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
-                                             index, req->cntr);
+               npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index,
+                                             req->cntr);
        }
 exit:
        mutex_unlock(&mcam->lock);