lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHUa44EG+SPt8QgMfLmEgLgGyu-EUhd8NL-9R+nbqk9Zf_bFvQ@mail.gmail.com>
Date: Wed, 28 May 2025 17:33:38 +0200
From: Jens Wiklander <jens.wiklander@...aro.org>
To: Sudeep Holla <sudeep.holla@....com>
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org, 
	Jérôme Forissier <jerome.forissier@...aro.org>
Subject: Re: [PATCH 2/3] firmware: arm_ffa: Move memory allocation outside the
 mutex locking

On Wed, May 28, 2025 at 10:50 AM Sudeep Holla <sudeep.holla@....com> wrote:
>
> The notifier callback node allocation is currently done while holding
> the notify_lock mutex. While this is safe even if memory allocation may
> sleep, we need to move the allocation outside the locked region in
> preparation to move from using muxtes to rwlocks.
>
> Move the memory allocation to avoid potential sleeping in atomic context
> once the locks are moved from mutex to rwlocks.
>
> Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
> Signed-off-by: Sudeep Holla <sudeep.holla@....com>
> ---
>  drivers/firmware/arm_ffa/driver.c | 48 +++++++++++++++++++--------------------
>  1 file changed, 24 insertions(+), 24 deletions(-)

Reviewed-by: Jens Wiklander <jens.wiklander@...aro.org>

Cheers,
Jens

>
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index 6f75cdf29720993b1cd95eb7d3a36d01b0fdd1de..44eecb786e67b205161e2d48602e1f1b53533360 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -1250,13 +1250,12 @@ notifier_hnode_get_by_type(u16 notify_id, enum notify_type type)
>         return NULL;
>  }
>
> -static int
> -update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
> -                  void *cb_data, bool is_registration, bool is_framework)
> +static int update_notifier_cb(struct ffa_device *dev, int notify_id,
> +                             struct notifier_cb_info *cb, bool is_framework)
>  {
>         struct notifier_cb_info *cb_info = NULL;
>         enum notify_type type = ffa_notify_type_get(dev->vm_id);
> -       bool cb_found;
> +       bool cb_found, is_registration = !!cb;
>
>         if (is_framework)
>                 cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, dev->vm_id,
> @@ -1270,18 +1269,7 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
>                 return -EINVAL;
>
>         if (is_registration) {
> -               cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
> -               if (!cb_info)
> -                       return -ENOMEM;
> -
> -               cb_info->dev = dev;
> -               cb_info->cb_data = cb_data;
> -               if (is_framework)
> -                       cb_info->fwk_cb = cb;
> -               else
> -                       cb_info->cb = cb;
> -
> -               hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
> +               hash_add(drv_info->notifier_hash, &cb->hnode, notify_id);
>         } else {
>                 hash_del(&cb_info->hnode);
>                 kfree(cb_info);
> @@ -1303,8 +1291,7 @@ static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id,
>
>         mutex_lock(&drv_info->notify_lock);
>
> -       rc = update_notifier_cb(dev, notify_id, NULL, NULL, false,
> -                               is_framework);
> +       rc = update_notifier_cb(dev, notify_id, NULL, is_framework);
>         if (rc) {
>                 pr_err("Could not unregister notification callback\n");
>                 mutex_unlock(&drv_info->notify_lock);
> @@ -1335,6 +1322,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
>  {
>         int rc;
>         u32 flags = 0;
> +       struct notifier_cb_info *cb_info = NULL;
>
>         if (ffa_notifications_disabled())
>                 return -EOPNOTSUPP;
> @@ -1342,6 +1330,17 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
>         if (notify_id >= FFA_MAX_NOTIFICATIONS)
>                 return -EINVAL;
>
> +       cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
> +       if (!cb_info)
> +               return -ENOMEM;
> +
> +       cb_info->dev = dev;
> +       cb_info->cb_data = cb_data;
> +       if (is_framework)
> +               cb_info->fwk_cb = cb;
> +       else
> +               cb_info->cb = cb;
> +
>         mutex_lock(&drv_info->notify_lock);
>
>         if (!is_framework) {
> @@ -1349,21 +1348,22 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
>                         flags = PER_VCPU_NOTIFICATION_FLAG;
>
>                 rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
> -               if (rc) {
> -                       mutex_unlock(&drv_info->notify_lock);
> -                       return rc;
> -               }
> +               if (rc)
> +                       goto out_unlock_free;
>         }
>
> -       rc = update_notifier_cb(dev, notify_id, cb, cb_data, true,
> -                               is_framework);
> +       rc = update_notifier_cb(dev, notify_id, cb_info, is_framework);
>         if (rc) {
>                 pr_err("Failed to register callback for %d - %d\n",
>                        notify_id, rc);
>                 if (!is_framework)
>                         ffa_notification_unbind(dev->vm_id, BIT(notify_id));
>         }
> +
> +out_unlock_free:
>         mutex_unlock(&drv_info->notify_lock);
> +       if (rc)
> +               kfree(cb_info);
>
>         return rc;
>  }
>
> --
> 2.34.1
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ