[PATCH] bnx2x: clean up VF PCI resources on probe failure

From: Haoxiang Li

Date: Wed Jun 03 2026 - 03:40:33 EST


bnx2x_init_one() allocates VF PCI resources by calling
bnx2x_vf_pci_alloc(), but later error paths fall through
the common cleanup path without calling bnx2x_vf_pci_dealloc().

This can leak the VF PCI resources allocated for the VF
when probe fails after bnx2x_vf_pci_alloc() succeeds.

Add a VF-specific error label to call bnx2x_vf_pci_dealloc()
before falling through to the existing common cleanup path.

Fixes: 6411280ac94d ("bnx2x: Segregate SR-IOV code")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Haoxiang Li <lihaoxiang@xxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index da0f8c353e6a..acb0379d94b9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13932,13 +13932,13 @@ static int bnx2x_init_one(struct pci_dev *pdev,
dev_err(&bp->pdev->dev,
"Cannot map doorbell space, aborting\n");
rc = -ENOMEM;
- goto init_one_freemem;
+ goto init_one_vf_pci_dealloc;
}

if (IS_VF(bp)) {
rc = bnx2x_vfpf_acquire(bp, tx_count, rx_count);
if (rc)
- goto init_one_freemem;
+ goto init_one_vf_pci_dealloc;

#ifdef CONFIG_BNX2X_SRIOV
/* VF with OLD Hypervisor or old PF do not support filtering */
@@ -13952,7 +13952,7 @@ static int bnx2x_init_one(struct pci_dev *pdev,
/* Enable SRIOV if capability found in configuration space */
rc = bnx2x_iov_init_one(bp, int_mode, BNX2X_MAX_NUM_OF_VFS);
if (rc)
- goto init_one_freemem;
+ goto init_one_vf_pci_dealloc;

/* calc qm_cid_count */
bp->qm_cid_count = bnx2x_set_qm_cid_count(bp);
@@ -13971,7 +13971,7 @@ static int bnx2x_init_one(struct pci_dev *pdev,
rc = bnx2x_set_int_mode(bp);
if (rc) {
dev_err(&pdev->dev, "Cannot set interrupts\n");
- goto init_one_freemem;
+ goto init_one_vf_pci_dealloc;
}
BNX2X_DEV_INFO("set interrupts successfully\n");

@@ -13979,7 +13979,7 @@ static int bnx2x_init_one(struct pci_dev *pdev,
rc = register_netdev(dev);
if (rc) {
dev_err(&pdev->dev, "Cannot register net device\n");
- goto init_one_freemem;
+ goto init_one_vf_pci_dealloc;
}
BNX2X_DEV_INFO("device name after netdev register %s\n", dev->name);

@@ -14001,6 +14001,10 @@ static int bnx2x_init_one(struct pci_dev *pdev,

return 0;

+init_one_vf_pci_dealloc:
+ if (IS_VF(bp))
+ bnx2x_vf_pci_dealloc(bp);
+
init_one_freemem:
bnx2x_free_mem_bp(bp);

--
2.25.1