[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