Linux CXL
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: alejandro.lucero-palau@amd.com
Cc: linux-cxl@vger.kernel.org
Subject: Re: [RFC 1/2] cxl/memdev: add support for mutipf device
Date: Sat, 22 Aug 2026 14:43:52 +0000	[thread overview]
Message-ID: <20260822144353.76E571F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260821155134.260053-2-alejandro.lucero-palau@amd.com>

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
- [High] `cxl_get_pf0_memdev()` returns a pointer after dropping its device reference via `__free()`, causing a Use-After-Free.
- [High] Flawed execution context detection using `mutex_trylock()` leads to silently skipped driver releases.
- [High] `cxl_get_pf0_memdev()` leaves the sibling device in the xarray on the `-EPROBE_DEFER` error path.
- [High] Unconditional dereference of `attach->hpa_range.end` causes a kernel panic if `cxlmd->attach` is NULL.
- [High] Sibling device pointers are stored in the `cxlmd->siblings` xarray without taking a reference count.
- [Medium] The return value of `xa_store()` is ignored, potentially leaving siblings unregistered.
- [Medium] Missing `xa_destroy()` for the `cxlmd->siblings` xarray leads to leaked internal nodes.
--

--- Patch [1]: [RFC 1/2] cxl/memdev: add support for mutipf device ---
commit be73e6cb4711f45100bc8fb00094b292d5fbc718
Author: Alejandro Lucero <alucerop@amd.com>

cxl/memdev: add support for mutipf device

A PCI device can present multiple Physical Functions(PFs) but the CXL
specs restrict to the first one, PF0, the discovery and management of
CXL capabilities accessed through a PF0 BAR. Other non-PF0 PFs need to
obtain the CXL.mem range to work with somehow.

> diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c
> index b3419df586b9c..327c4da3208fe 100644
> --- a/drivers/cxl/core/memdev.c
> +++ b/drivers/cxl/core/memdev.c
> @@ -26,6 +26,35 @@ static void cxl_memdev_release(struct device *dev)
>  {
>  	struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
>  	struct device *parent = dev->parent;
> +	struct device *sibling;
> +	unsigned long index;
> +
> +	/*
> +	 * Type2 multipf support implies other non-PF0 PFs could be having a

[ ... ]

> +		/* Several possibilities trigger a memdev release with one being
> +		 * its parent device (Type2 device) released from its driver. If
> +		 * so, such release is the context for this function, precluding
> +		 * the mutex lock and therefore safely avoiding to invoke the
> +		 * release again which would trigger a deadlock.
> +		 */
> +		if (mutex_trylock(&cxlmd->dev.parent->mutex)) {

[Severity: High]
Does this trylock reliably detect if it's executing within the context of the
parent device's release callback? If the trylock fails, the code assumes it
is already on the parent release path and skips calling
device_release_driver(). However, couldn't the lock be held by a completely
unrelated thread performing sysfs access, hotplug operations, or power
management? If lock contention occurs, the parent driver release might be
skipped entirely, leaving the parent device permanently bound.

> +			mutex_unlock(&cxlmd->dev.parent->mutex);
> +			device_release_driver(cxlmd->dev.parent);
> +		}
> +	}
>  
>  	ida_free(&cxl_memdev_ida, cxlmd->id);

[Severity: Medium]
Is it necessary to call xa_destroy() for the cxlmd->siblings xarray before
freeing the struct? The xarray is dynamically initialized during alloc, and
if it allocates memory for internal tree nodes, skipping xa_destroy() could
lead to leaked internal nodes even if all entries were logically erased.

>  	kfree(cxlmd);
>  	put_device(parent);
>  }

[ ... ]

> @@ -802,6 +832,98 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds,

[ ... ]

> +struct cxl_memdev *cxl_get_pf0_memdev(struct device *pf0, struct device *pfx,
> +				      unsigned long index, struct range *range)
> +{
> +	struct cxl_attach_region *attach;
> +	struct cxl_memdev *cxlmd;
> +	struct device *mem_dev __free(put_device) =
> +		bus_find_device(&cxl_bus_type, NULL, pf0,
> +				match_memdev_by_parent_device);
> +
> +	if (!mem_dev)
> +		return ERR_PTR(-ENODEV);
> +
> +	cxlmd = to_cxl_memdev(mem_dev);
> +
> +	/*
> +	 * we got the cxl_memdev and the implicit get_device in bus_find_device
> +	 * makes the next steps safe.
> +	 */
> +
> +	xa_store(&cxlmd->siblings, index, pfx, GFP_KERNEL);

[Severity: High]
Should this xarray store take a reference count on the pfx device before
storing it? Since cxl_get_pf0_memdev() registers the pfx sibling device but
doesn't increment its reference count, if the sibling device is independently
removed and freed, the xarray could retain a dangling pointer. When
cxl_memdev_release() later iterates the xarray and invokes
device_release_driver(sibling), it would dereference this dangling pointer
and cause a use-after-free.

[Severity: Medium]
Is it safe to ignore the return value of xa_store()? Since xa_store()
dynamically allocates memory for new elements and can fail returning an error
pointer, an unhandled failure means the sibling device would be omitted from
the xarray while the function returns success. This might silently compromise
cross-device unbinding logic.

> +	attach = container_of(cxlmd->attach, struct cxl_attach_region, attach);
> +
> +	/*
> +	 * The cxlmd object does exist and it can be found in the cxl bus after
> +	 * creation but before attach probe setting the proper HPA range. If so,
> +	 * the caller will need to try later.
> +	 */
> +	if (attach->hpa_range.end == -1)

[Severity: High]
Can this unconditionally dereference a NULL attach pointer? Because attach is
at offset 0 within struct cxl_attach_region, if cxlmd->attach is NULL, the
attach pointer evaluates identically to NULL. Standard Type 3 CXL memdevs
lack an attach region, so cxlmd->attach would be NULL, causing an immediate
kernel panic when trying to access attach->hpa_range.end.

[Severity: High]
Does this error path need to clean up the xarray entry before returning?
Since the sibling device was already inserted into cxlmd->siblings, returning
-EPROBE_DEFER here without calling xa_erase() leaves a stale pointer in the
xarray. Later, cxl_memdev_release() could iterate over the xarray and invoke
device_release_driver() on a dangling pointer.

> +		return ERR_PTR(-EPROBE_DEFER);
> +
> +	range->start =  attach->hpa_range.start;
> +	range->end =  attach->hpa_range.end;
> +
> +	return to_cxl_memdev(mem_dev);

[Severity: High]
Could this return a pointer after dropping its device reference, causing a
use-after-free? bus_find_device() acquires a reference to the matched device
stored in mem_dev, which is decorated with __free(put_device). Because this
return statement does not inhibit cleanup (for example, by using
no_free_ptr() or return_ptr()), put_device(mem_dev) is automatically executed
at scope exit, instantly dropping the reference while returning an unpinned
pointer.

> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260821155134.260053-1-alejandro.lucero-palau@amd.com?part=1

  reply	other threads:[~2026-08-22 14:43 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 15:51 [RFC 0/2] Type2 multipf support alejandro.lucero-palau
2026-08-21 15:51 ` [RFC 1/2] cxl/memdev: add support for mutipf device alejandro.lucero-palau
2026-08-22 14:43   ` sashiko-bot [this message]
2026-08-24  8:33   ` Richard Cheng
2026-08-25  7:37     ` Lucero Palau, Alejandro
2026-08-21 15:51 ` [RFC 2/2] sfc: add multipf support alejandro.lucero-palau
2026-08-22 14:43   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260822144353.76E571F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alejandro.lucero-palau@amd.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox