]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dibs: initialise dibs->lock in dibs_dev_alloc()
authorHidayath Khan <hidayath@linux.ibm.com>
Thu, 30 Jul 2026 12:42:27 +0000 (14:42 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Aug 2026 00:41:38 +0000 (17:41 -0700)
dibs->lock is initialised by dibs_dev_add(), but a dibs device can
already take interrupts before that call: ism_probe() runs
ism_dev_init(), and hence request_irq(), before it calls
dibs_dev_add(). No client can have registered a dmb at that point, so
no dmb interrupt can occur, but a GID event interrupt can, and
ism_handle_irq() takes dibs->lock unconditionally on entry, before it
inspects anything else.

Initialise the lock in dibs_dev_alloc() instead, so that it is valid as
soon as a driver can publish the device to its interrupt handler.

Fixes: cc21191b584c ("dibs: Move data path to dibs layer")
Cc: stable@vger.kernel.org
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Link: https://patch.msgid.link/20260730124227.167829-1-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/dibs/dibs_main.c
include/linux/dibs.h

index 14c3e2d84902e0fcb88766f8bd1315e462f02838..4c26fd06973f7c26fd68fe205486033302e35c31 100644 (file)
@@ -138,6 +138,7 @@ struct dibs_dev *dibs_dev_alloc(void)
        dibs = kzalloc_obj(*dibs);
        if (!dibs)
                return dibs;
+       spin_lock_init(&dibs->lock);
        dibs->dev.release = dibs_dev_release;
        dibs->dev.class = &dibs_class;
        device_initialize(&dibs->dev);
@@ -186,7 +187,6 @@ int dibs_dev_add(struct dibs_dev *dibs)
        int i, ret;
 
        max_dmbs = dibs->ops->max_dmbs();
-       spin_lock_init(&dibs->lock);
        dibs->dmb_clientid_arr = kzalloc(max_dmbs, GFP_KERNEL);
        if (!dibs->dmb_clientid_arr)
                return -ENOMEM;
index c75607f8a5cf9866984737f230e566b1780e9bee..d3e0777f25ae0900404f7518c17338948366313b 100644 (file)
@@ -439,7 +439,7 @@ static inline void *dibs_get_priv(struct dibs_dev *dev,
 /**
  * dibs_dev_alloc() - allocate and reference device structure
  *
- * The following fields will be valid upon successful return: dev
+ * The following fields will be valid upon successful return: dev, lock
  * NOTE: Use put_device(dibs_get_dev(@dibs)) to give up your reference instead
  * of freeing @dibs @dev directly once you have successfully called this
  * function.