* Re: [PATCH] drm/xe/oa: Check managed mutex initialization errors
2026-07-13 8:30 [PATCH] drm/xe/oa: Check managed mutex initialization errors Linmao Li
@ 2026-07-13 8:45 ` sashiko-bot
2026-07-14 18:15 ` Umesh Nerlige Ramappa
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-07-13 8:45 UTC (permalink / raw)
To: Linmao Li; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing drm_dev_enter/drm_dev_exit protection in OA stream file operations leads to NULL pointer dereferences and UAF on device unbind.
- [High] Sync entries and memory are permanently leaked when xe_oa_emit_oa_config() fails in xe_oa_config_locked().
- [High] Concurrent execution of xe_oa_fini and xe_oa_add_config_ioctl can cause radix tree corruption and a memory leak because the ioctl lacks drm_dev_enter() protection.
--
--- Patch [1]: [PATCH] drm/xe/oa: Check managed mutex initialization errors ---
commit 6dc1dc862e4088df59048042e54f422ac372d344
Author: Linmao Li <lilinmao@kylinos.cn>
drm/xe/oa: Check managed mutex initialization errors
drmm_mutex_init() can fail while registering its managed cleanup action.
On failure, the reset path destroys the mutex, so continuing OA setup
leaves an unusable lock that later paths may acquire.
Return the error from per-GT OA initialization and abort device-wide OA
initialization if the metrics lock cannot be initialized.
Fixes: a9f905ae7b6f ("drm/xe/oa/uapi: Initialize OA units")
Fixes: cdf02fe1a94a ("drm/xe/oa/uapi: Add/remove OA config perf ops")
> diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
> index b3acbcd678b7c..302a2ef4494be 100644
> --- a/drivers/gpu/drm/xe/xe_oa.c
> +++ b/drivers/gpu/drm/xe/xe_oa.c
> @@ -2718,9 +2718,7 @@ static int xe_oa_init_gt(struct xe_gt *gt)
>
> __xe_oa_init_oa_units(gt);
>
> - drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock);
> -
> - return 0;
> + return drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock);
> }
>
> static void xe_oa_print_gt_oa_units(struct xe_gt *gt)
> @@ -2860,7 +2858,10 @@ int xe_oa_init(struct xe_device *xe)
> oa->xe = xe;
> oa->oa_formats = oa_formats;
>
> - drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock);
> + ret = drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock);
> + if (ret)
> + goto exit;
> +
> idr_init_base(&oa->metrics_idr, 1);
>
> ret = xe_oa_init_oa_units(oa);
While reviewing this patch, I noticed a few pre-existing issues in this file:
[ ... ]
> static ssize_t xe_oa_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> struct xe_oa_stream *stream = file->private_data;
[ ... ]
> mutex_lock(&stream->stream_lock);
> ret = __xe_oa_read(stream, buf, count, &offset);
^^^^^^^^^^^^
[Severity: High]
This is a pre-existing issue, but does xe_oa_read() lack
drm_dev_enter/drm_dev_exit protection?
File operations like xe_oa_read() and xe_oa_ioctl() operate on an independent
file descriptor. When the device unbinds, devm-managed mappings like
stream->gt->mmio are released.
If a local user calls read() or ioctl() on the open stream file descriptor after
the device is hot-unplugged or unbound, can this cause a NULL pointer
dereference or a kernel crash when accessing unmapped MMIO memory?
[ ... ]
> stream->num_syncs = param.num_syncs;
> stream->syncs = param.syncs;
>
> err = xe_oa_emit_oa_config(stream, config);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
This is a pre-existing issue, but if xe_oa_emit_oa_config() fails, does this
permanently leak the stream->syncs memory and the dma_fence references?
If the user provides valid sync entries but xe_oa_emit_oa_config() fails
due to memory pressure or batch buffer submission failures, the error is
propagated without cleaning up stream->syncs.
Since xe_oa_emit_oa_config() only frees stream->syncs on the success path, and
xe_oa_stream_destroy() does not free stream->syncs, is there any path that
cleans up these references after a failure?
[ ... ]
> static void xe_oa_fini(void *arg)
> {
> struct xe_device *xe = arg;
> struct xe_oa *oa = &xe->oa;
>
> if (!oa->xe)
> return;
>
> idr_for_each(&oa->metrics_idr, destroy_config, oa);
> idr_destroy(&oa->metrics_idr);
>
> oa->xe = NULL;
> }
> int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file)
> {
[ ... ]
> if (!oa->xe) {
> drm_dbg(&xe->drm, "xe oa interface not available for this system\n");
> return -ENODEV;
> }
[ ... ]
> id = idr_alloc(&oa->metrics_idr, oa_config, 2, 0, GFP_KERNEL);
^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
This is a pre-existing issue, but does concurrent execution of xe_oa_fini() and
xe_oa_add_config_ioctl() cause radix tree corruption?
xe_oa_add_config_ioctl() checks if (!oa->xe) locklessly and does not use
drm_dev_enter() to guarantee the hardware device remains bound.
Concurrently, driver unbind invokes xe_oa_fini(), which calls
idr_destroy(&oa->metrics_idr) before setting oa->xe = NULL.
If the ioctl evaluates !oa->xe before xe_oa_fini() nullifies it, could it
proceed to call idr_alloc() on a concurrently destroyed IDR structure?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260713083053.321091-1-lilinmao@kylinos.cn?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] drm/xe/oa: Check managed mutex initialization errors
2026-07-13 8:30 [PATCH] drm/xe/oa: Check managed mutex initialization errors Linmao Li
2026-07-13 8:45 ` sashiko-bot
@ 2026-07-14 18:15 ` Umesh Nerlige Ramappa
1 sibling, 0 replies; 3+ messages in thread
From: Umesh Nerlige Ramappa @ 2026-07-14 18:15 UTC (permalink / raw)
To: Linmao Li
Cc: Ashutosh Dixit, Matthew Brost, Thomas Hellström,
Rodrigo Vivi, David Airlie, Simona Vetter,
José Roberto de Souza, intel-xe, dri-devel, linux-kernel
On Mon, Jul 13, 2026 at 04:30:53PM +0800, Linmao Li wrote:
>drmm_mutex_init() can fail while registering its managed cleanup action.
>On failure, the reset path destroys the mutex, so continuing OA setup
>leaves an unusable lock that later paths may acquire.
>
>Return the error from per-GT OA initialization and abort device-wide OA
>initialization if the metrics lock cannot be initialized.
>
>Fixes: a9f905ae7b6f ("drm/xe/oa/uapi: Initialize OA units")
>Fixes: cdf02fe1a94a ("drm/xe/oa/uapi: Add/remove OA config perf ops")
>Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Thanks for addressing this. LGTM,
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
>---
> drivers/gpu/drm/xe/xe_oa.c | 9 +++++----
> 1 file changed, 5 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
>index 2dce6a47202c..f3a0d5bf7894 100644
>--- a/drivers/gpu/drm/xe/xe_oa.c
>+++ b/drivers/gpu/drm/xe/xe_oa.c
>@@ -2713,9 +2713,7 @@ static int xe_oa_init_gt(struct xe_gt *gt)
>
> __xe_oa_init_oa_units(gt);
>
>- drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock);
>-
>- return 0;
>+ return drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock);
> }
>
> static void xe_oa_print_gt_oa_units(struct xe_gt *gt)
>@@ -2855,7 +2853,10 @@ int xe_oa_init(struct xe_device *xe)
> oa->xe = xe;
> oa->oa_formats = oa_formats;
>
>- drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock);
>+ ret = drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock);
>+ if (ret)
>+ goto exit;
>+
> idr_init_base(&oa->metrics_idr, 1);
>
> ret = xe_oa_init_oa_units(oa);
>--
>2.25.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread