[SRU][J/N:linux-bluefield][PATCH v1 1/1] UBUNTU: SAUCE: mlxbf_pka: fix modprobe/rmmod and IO resource conflicts

Ron Li xiangrongl at nvidia.com
Thu Jan 15 15:54:38 UTC 2026


BugLink: https://bugs.launchpad.net/bugs/2138411

The current PKA module cannot be removed cleanly, which results in the
module cannot be reinstalled. This patch fixes this issue:

- Destroy class on init failure
- Skip ring devices if shim probe fails
- Use devm_request_mem_region to handle memory request
- Bump to v3.1.

Signed-off-by: Ron Li <xiangrongl at nvidia.com>
Reviewed-by: David Thompson <davthompson at nvidia.com>
Reviewed-by: Shih-Yi Chen <shihyic at nvidia.com>
---
 .../mellanox/mlxbf_pka/mlxbf_pka_dev.c        | 13 ++++---
 .../mellanox/mlxbf_pka/mlxbf_pka_dev.h        |  6 ++-
 .../mellanox/mlxbf_pka/mlxbf_pka_drv.c        | 37 +++++++++++++++++--
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.c b/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.c
index 8d0ccaa76a17..6b5dd7b3e21d 100644
--- a/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.c
+++ b/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.c
@@ -224,7 +224,7 @@ static int pka_dev_set_resource_config(pka_dev_shim_t *shim,
                                                    shim->shim_id);
     if (!res_ptr->ioaddr)
     {
-        if (!request_mem_region(res_ptr->base, res_ptr->size, res_ptr->name))
+        if (!devm_request_mem_region(shim->dev, res_ptr->base, res_ptr->size, res_ptr->name))
         {
             PKA_ERROR(PKA_DEV, "failed to get io memory region\n");
             return -EPERM;
@@ -238,7 +238,6 @@ static int pka_dev_set_resource_config(pka_dev_shim_t *shim,
     if (!res_ptr->ioaddr || pka_dev_add_resource(res_ptr, shim->shim_id))
     {
         PKA_ERROR(PKA_DEV, "unable to map io memory\n");
-        release_mem_region(res_ptr->base, res_ptr->size);
         return -ENOMEM;
     }
     return ret;
@@ -257,7 +256,6 @@ static void pka_dev_unset_resource_config(pka_dev_shim_t *shim,
             ret != pka_dev_put_resource(res_ptr, shim->shim_id))
     {
         iounmap(res_ptr->ioaddr);
-        release_mem_region(res_ptr->base, res_ptr->size);
     }
 
     res_ptr->status = PKA_DEV_RES_STATUS_UNMAPPED;
@@ -1966,7 +1964,8 @@ int pka_dev_unregister_ring(pka_dev_ring_t *ring)
 }
 
 static pka_dev_shim_t *__pka_dev_register_shim(uint32_t shim_id,
-                                               struct pka_dev_mem_res *mem_res)
+                                               struct pka_dev_mem_res *mem_res,
+					       struct device *dev)
 {
     pka_dev_shim_t *shim;
 
@@ -1982,6 +1981,7 @@ static pka_dev_shim_t *__pka_dev_register_shim(uint32_t shim_id,
     // Shim state MUST be set to undefined before calling 'pka_dev_create_shim'
     // function
     shim->status = PKA_SHIM_STATUS_UNDEFINED;
+    shim->dev    = dev;
 
     // Set the Window RAM user mode
     split = PKA_SPLIT_WINDOW_RAM_MODE;
@@ -2011,13 +2011,14 @@ static pka_dev_shim_t *__pka_dev_register_shim(uint32_t shim_id,
 }
 
 pka_dev_shim_t *pka_dev_register_shim(uint32_t shim_id, uint8_t shim_fw_id,
-                                      struct pka_dev_mem_res *mem_res)
+                                      struct pka_dev_mem_res *mem_res,
+                                      struct device *dev)
 {
     pka_dev_shim_t *shim;
 
     pka_firmware_set_id(shim_fw_id);
 
-    shim = __pka_dev_register_shim(shim_id, mem_res);
+    shim = __pka_dev_register_shim(shim_id, mem_res, dev);
     if (shim)
     {
         pka_gbl_config.dev_shims[shim->shim_id]  = shim;
diff --git a/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.h b/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.h
index 06ac28623e23..ad153b468bcf 100644
--- a/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.h
+++ b/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_dev.h
@@ -44,6 +44,7 @@
 
 #include <linux/mutex.h>
 #include <linux/types.h>
+#include <linux/device.h>
 #include "mlxbf_pka_firmware.h"
 
 #include <linux/vfio.h>
@@ -178,10 +179,10 @@ struct pka_dev_mem_res
     uint64_t csr_size;            ///< csr area size
 };
 
-
 /// PKA Shim structure
 struct pka_dev_shim_s
 {
+    struct device       *dev;             ///< backing struct device for devm
     struct pka_dev_mem_res mem_res;
 
     uint64_t            trng_err_cycle;   ///< TRNG error cycle
@@ -272,7 +273,8 @@ int pka_dev_unregister_ring(pka_dev_ring_t *ring);
 /// Register PKA IO block. This function initializes a shim and configures its
 /// related resources, and returns a pointer to that ring.
 pka_dev_shim_t *pka_dev_register_shim(uint32_t shim_id, uint8_t shim_fw_id,
-                                      struct pka_dev_mem_res *mem_res);
+                                      struct pka_dev_mem_res *mem_res,
+                                      struct device *dev);
 
 /// Unregister PKA IO block
 int pka_dev_unregister_shim(pka_dev_shim_t *shim);
diff --git a/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_drv.c b/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_drv.c
index 6b171b2a6a14..791e3f9021dd 100644
--- a/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_drv.c
+++ b/drivers/platform/mellanox/mlxbf_pka/mlxbf_pka_drv.c
@@ -20,7 +20,7 @@
 #include "mlxbf_pka_dev.h"
 
 
-#define PKA_DRIVER_VERSION      "v3.0"
+#define PKA_DRIVER_VERSION      "v3.1"
 #define PKA_DRIVER_NAME         "pka-mlxbf"
 
 #define PKA_DRIVER_DESCRIPTION  "BlueField PKA driver"
@@ -762,11 +762,29 @@ static int pka_drv_init_class(void)
 
 static void pka_drv_destroy_class(void)
 {
+	int id;
+	struct pka_ring_device *ring_dev;
+
+	/* Best-effort: destroy any leftover ring devices before tearing down class */
+	if (pka.class) {
+		/*
+		 * Note: device_destroy() might indirectly trigger callbacks that update
+		 * the ring IDR. This loop is used in a module unload/cleanup path where
+		 * best-effort teardown is acceptable.
+		 */
+		idr_for_each_entry(&pka.ring_idr, ring_dev, id) {
+			device_destroy(pka.class, MKDEV(MAJOR(pka.ring_devt),
+							ring_dev->minor));
+		}
+	}
+
 	idr_destroy(&pka.ring_idr);
 	cdev_del(&pka.ring_cdev);
 	unregister_chrdev_region(pka.ring_devt, MINORMASK);
-	class_destroy(pka.class);
-	pka.class = NULL;
+	if (pka.class) {
+		class_destroy(pka.class);
+		pka.class = NULL;
+	}
 }
 #endif
 
@@ -840,7 +858,7 @@ static int pka_drv_register_device(struct pka_device *pka_dev,
 	pka_drv_get_mem_res(pka_dev, &mem_res, wndw_ram_off_mask);
 
 	pka_dev->shim = pka_dev_register_shim(pka_shim_id, pka_shim_fw_id,
-					      &mem_res);
+					      &mem_res, pka_dev->device);
 	if (!pka_dev->shim) {
 		PKA_DEBUG(PKA_DRIVER,
 		  "failed to register shim id=%u\n", pka_shim_id);
@@ -1108,6 +1126,15 @@ static int pka_drv_probe_ring_device(struct pka_info *info)
 	info->flag       = PKA_DRIVER_FLAG_RING_DEVICE;
 	mutex_init(&ring_dev->mutex);
 
+	/* Ensure parent shim exists before creating ring device nodes */
+	if (!pka_dev_get_shim(ring_dev->parent_device_id)) {
+		PKA_DEBUG(PKA_DRIVER,
+			  "parent shim %u not present, skip ring %u\n",
+			  ring_dev->parent_device_id, ring_dev->device_id);
+		kfree(ring_dev);
+		return -ENODEV;
+	}
+
 	ret = pka_drv_add_ring_device(ring_dev);
 	if (ret) {
 		PKA_DEBUG(PKA_DRIVER,
@@ -1397,6 +1424,8 @@ static int __init pka_drv_register(void)
 	ret = platform_driver_register(&pka_drv);
 	if (ret) {
 		PKA_ERROR(PKA_DRIVER, "failed to register platform driver\n");
+		/* Ensure class is destroyed on init failure to avoid -EEXIST on reload */
+		pka_drv_destroy_class();
 		return ret;
 	}
 
-- 
2.43.0




More information about the kernel-team mailing list