* [PATCH v5 0/3] Fix kernel crash during driver teardown
@ 2026-10-12 5:50 Satyanarayana K V P
2026-10-12 5:50 ` [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine Satyanarayana K V P
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Satyanarayana K V P @ 2026-10-12 5:50 UTC (permalink / raw)
To: intel-xe; +Cc: Satyanarayana K V P, Matthew Brost, Piotr Piórkowski
During driver release, the hardware engine is only partially invalidated
during teardown. Its name remains set, so the memory IRQ handler can still
identify the engine and access its state after teardown. This can result
in a NULL pointer dereference.
Invalidate the hardware engine name during teardown so the IRQ handler no
longer treats the engine as available.
The crash log below shows an example of the failure.
BUG: kernel NULL pointer dereference, address: 0000000000000000
PF: supervisor read access in kernel mode
PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: Oops: 0000 [#1] SMP NOPTI
Tainted: [U]=USER
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
2025.11-3ubuntu7 03/31/2026
RIP: 0010:xe_hw_engine_handle_irq+0x18/0x70 [xe]
Code: 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f
44 00 00 55 48 89 e5 41 54 41 89 f4 48 89 d6 53 48 8b 07 48 89 fb <48> 8b 00 48
8b 38 e8 5d 84 08 00 48 8b 83 b8 00 00 00 48 85 c0 74
RSP: 0018:ffffd07840003e80 EFLAGS: 00010046
RAX: 0000000000000000 RBX: ffff8904657fa740 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8904657fa740
RBP: ffffd07840003e90 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000001
R13: ffff89046a490000 R14: ffff89046a491af8 R15: ffff8904657faf20
FS: 0000000000000000(0000) GS:ffff8905fd219000(0000)
knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000103705005 CR4: 0000000000772ef0
PKRU: 55555554
Call Trace:
<IRQ>
xe_memirq_handler+0xc3/0x200 [xe]
vf_mem_irq_handler+0x46/0x90 [xe]
__handle_irq_event_percpu+0x59/0x200
handle_irq_event+0x36/0x90
handle_edge_irq+0xc5/0x190
__common_interrupt+0x50/0x160
? irq_enter_rcu+0x84/0xb0
common_interrupt+0xb0/0xe0
</IRQ>
---
V4 -> V5:
- Return DRM_GPU_SCHED_STAT_ENODEV instead of DRM_GPU_SCHED_STAT_NO_HANG
(Sashiko).
V3 -> V4:
- Fix race condition reported by LLM (Sashiko).
V2 -> V3:
- Fixed race condition with guc_exec_queue_timedout_job(). (Sashiko).
- Disable GT reset worker before engine teardown (LLM).
V1 -> V2:
- Fix race with xe_memirq_handler() and hw_engine_fini() (Sashiko & Piotr).
Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
Assisted-by: LLM
Satyanarayana K V P (3):
drm/xe: Prevent VF memory IRQ from accessing a torn-down engine
drm/xe/guc: Protect timeout handling from device unplug
drm/xe/gt: Disable GT reset worker before engine teardown
drivers/gpu/drm/xe/xe_gt.c | 29 ++++++++++++++++++++++-------
drivers/gpu/drm/xe/xe_guc_submit.c | 12 +++++++++++-
drivers/gpu/drm/xe/xe_hw_engine.c | 17 ++++++++++++++---
drivers/gpu/drm/xe/xe_irq.c | 3 +++
drivers/gpu/drm/xe/xe_memirq.c | 3 +++
5 files changed, 53 insertions(+), 11 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine
2026-10-12 5:50 [PATCH v5 0/3] Fix kernel crash during driver teardown Satyanarayana K V P
@ 2026-10-12 5:50 ` Satyanarayana K V P
2026-10-12 6:07 ` sashiko-bot
2026-10-12 8:29 ` Piotr Piórkowski
2026-10-12 5:50 ` [PATCH v5 2/3] drm/xe/guc: Protect timeout handling from device unplug Satyanarayana K V P
2026-10-12 5:50 ` [PATCH v5 3/3] drm/xe/gt: Disable GT reset worker before engine teardown Satyanarayana K V P
2 siblings, 2 replies; 8+ messages in thread
From: Satyanarayana K V P @ 2026-10-12 5:50 UTC (permalink / raw)
To: intel-xe; +Cc: Satyanarayana K V P, Matthew Brost, Piotr Piórkowski
The VF memory IRQ handler iterates over HW engines whose names are set.
Engine teardown clears hwe->gt but leaves hwe->name set, so the handler
can select an engine whose GT has already been invalidated. This can
cause a NULL pointer dereference in xe_hw_engine_handle_irq().
Invalidate the engine name during teardown so subsequent engine scans
skip it.
Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
Fixes: 6eb2aad402cc ("drm/xe: Move hw_engine_fini to devm managed")
---
V3 -> V4:
- Fix issue with xe_execlist_port_destroy() with V3 version (Sashiko).
V2 -> V3:
- Updated spin_lock_irq() to spin_lock_irqsave().
V1 -> V2:
- Fix race with xe_memirq_handler() and hw_engine_fini() (Sashiko & Piotr).
---
drivers/gpu/drm/xe/xe_hw_engine.c | 17 ++++++++++++++---
drivers/gpu/drm/xe/xe_irq.c | 3 +++
drivers/gpu/drm/xe/xe_memirq.c | 3 +++
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
index 265f95c0c899..55ee0c892c1e 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine.c
@@ -275,11 +275,22 @@ static const struct engine_info engine_infos[] = {
static void hw_engine_fini(void *arg)
{
struct xe_hw_engine *hwe = arg;
+ struct xe_gt *gt = hwe->gt;
+
+ if (gt) {
+ struct xe_device *xe = gt_to_xe(gt);
+ unsigned long flags;
- if (hwe->exl_port)
- xe_execlist_port_destroy(hwe->exl_port);
+ if (hwe->exl_port)
+ xe_execlist_port_destroy(hwe->exl_port);
- hwe->gt = NULL;
+ spin_lock_irqsave(&xe->irq.lock, flags);
+ hwe->name = NULL;
+ hwe->gt = NULL;
+ spin_unlock_irqrestore(&xe->irq.lock, flags);
+ } else {
+ hwe->name = NULL;
+ }
}
/**
diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
index 9e49e2241da4..b394c8edf89c 100644
--- a/drivers/gpu/drm/xe/xe_irq.c
+++ b/drivers/gpu/drm/xe/xe_irq.c
@@ -908,6 +908,7 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
struct xe_hw_engine *hwe;
enum xe_hw_engine_id id;
struct xe_tile *tile;
+ unsigned long flags;
struct xe_gt *gt;
if (!atomic_read(&xe->irq.enabled))
@@ -922,8 +923,10 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
if (gt->tile != tile)
continue;
+ spin_lock_irqsave(&xe->irq.lock, flags);
for_each_hw_engine(hwe, gt, id)
xe_memirq_hwe_handler(memirq, hwe);
+ spin_unlock_irqrestore(&xe->irq.lock, flags);
}
}
diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c
index 9dfe965cb46e..1073132f2ded 100644
--- a/drivers/gpu/drm/xe/xe_memirq.c
+++ b/drivers/gpu/drm/xe/xe_memirq.c
@@ -555,6 +555,7 @@ void xe_memirq_handler(struct xe_memirq *memirq)
struct xe_hw_engine *hwe;
enum xe_hw_engine_id id;
struct iosys_map map;
+ unsigned long flags;
unsigned int gtid;
struct xe_gt *gt;
@@ -568,8 +569,10 @@ void xe_memirq_handler(struct xe_memirq *memirq)
if (gt->tile != tile)
continue;
+ spin_lock_irqsave(&xe->irq.lock, flags);
for_each_hw_engine(hwe, gt, id)
xe_memirq_hwe_handler(memirq, hwe);
+ spin_unlock_irqrestore(&xe->irq.lock, flags);
}
/* GuC and media GuC (if present) must be checked separately */
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 2/3] drm/xe/guc: Protect timeout handling from device unplug
2026-10-12 5:50 [PATCH v5 0/3] Fix kernel crash during driver teardown Satyanarayana K V P
2026-10-12 5:50 ` [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine Satyanarayana K V P
@ 2026-10-12 5:50 ` Satyanarayana K V P
2026-10-12 6:00 ` sashiko-bot
2026-10-12 5:50 ` [PATCH v5 3/3] drm/xe/gt: Disable GT reset worker before engine teardown Satyanarayana K V P
2 siblings, 1 reply; 8+ messages in thread
From: Satyanarayana K V P @ 2026-10-12 5:50 UTC (permalink / raw)
To: intel-xe; +Cc: Satyanarayana K V P, Matthew Brost, Piotr Piórkowski
The GuC scheduler timeout callback accesses device and GT state while
handling a timed-out job. Guard the callback with drm_dev_enter() and
drm_dev_exit() so device unplug waits for in-flight timeout handling.
If unplug has already started, mark the job with -ENODEV and return it
to the scheduler for cleanup.
Fixes: 6eb2aad402cc ("drm/xe: Move hw_engine_fini to devm managed")
Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
Assisted-by: LLM
---
V4 -> V5:
- Return DRM_GPU_SCHED_STAT_ENODEV instead of DRM_GPU_SCHED_STAT_NO_HANG
(Sashiko).
V3 -> V4:
- None.
V2 -> V3:
- Fixed race condition with guc_exec_queue_timedout_job(). (Sashiko).
---
drivers/gpu/drm/xe/xe_guc_submit.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 7ce73489c35f..082c94340b41 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -1599,6 +1599,12 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
int err = -ETIME;
pid_t pid = -1;
bool wedged = false, wedge_device = false, skip_timeout_check;
+ int idx;
+
+ if (!drm_dev_enter(&xe->drm, &idx)) {
+ xe_sched_job_set_error(job, -ENODEV);
+ return DRM_GPU_SCHED_STAT_ENODEV;
+ }
xe_gt_assert(guc_to_gt(guc), !exec_queue_destroyed(q));
@@ -1611,8 +1617,10 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
* lost.
*/
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &job->fence->flags) ||
- vf_recovery(guc))
+ vf_recovery(guc)) {
+ drm_dev_exit(idx);
return DRM_GPU_SCHED_STAT_NO_HANG;
+ }
/* Kill the run_job entry point */
if (xe_exec_queue_is_multi_queue(q))
@@ -1786,6 +1794,7 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
* We want the job added back to the pending list so it gets freed; this
* is what DRM_GPU_SCHED_STAT_NO_HANG does.
*/
+ drm_dev_exit(idx);
return DRM_GPU_SCHED_STAT_NO_HANG;
rearm:
@@ -1799,6 +1808,7 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
else
xe_sched_submission_start(sched);
handle_vf_resume:
+ drm_dev_exit(idx);
return DRM_GPU_SCHED_STAT_NO_HANG;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v5 3/3] drm/xe/gt: Disable GT reset worker before engine teardown
2026-10-12 5:50 [PATCH v5 0/3] Fix kernel crash during driver teardown Satyanarayana K V P
2026-10-12 5:50 ` [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine Satyanarayana K V P
2026-10-12 5:50 ` [PATCH v5 2/3] drm/xe/guc: Protect timeout handling from device unplug Satyanarayana K V P
@ 2026-10-12 5:50 ` Satyanarayana K V P
2026-10-12 8:40 ` Piotr Piórkowski
2 siblings, 1 reply; 8+ messages in thread
From: Satyanarayana K V P @ 2026-10-12 5:50 UTC (permalink / raw)
To: intel-xe
Cc: Satyanarayana K V P, Matthew Brost, Piotr Piórkowski,
Balasubramani Vivekanandan
During tear-down process, a reset queued from Guc timeout handler can
still access hwe after hwe is freed. Register a separate devm
action that disables and drains the reset worker, so it runs before
any engine is torn down.
Fixes: 09c452d1171f ("drm/xe/gt: Synchronize GT reset with device unbind")
Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
Cc: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
Assisted-by: LLM
---
V3 -> V4:
- Fix race condition reported by LLM (Sashiko).
---
drivers/gpu/drm/xe/xe_gt.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index 775c826b68b4..bc9bf6f0b5a7 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -630,8 +630,21 @@ static int gt_init_with_gt_forcewake(struct xe_gt *gt)
return 0;
}
+static void gt_reset_worker_disable(void *arg)
+{
+ struct xe_gt *gt = arg;
+
+ if (disable_work_sync(>->reset.worker))
+ /*
+ * If gt_reset_worker was halted from executing, take care of
+ * releasing the rpm reference here.
+ */
+ xe_pm_runtime_put(gt_to_xe(gt));
+}
+
static int gt_init_with_all_forcewake(struct xe_gt *gt)
{
+ struct xe_device *xe = gt_to_xe(gt);
int err;
CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FORCEWAKE_ALL);
@@ -698,6 +711,11 @@ static int gt_init_with_all_forcewake(struct xe_gt *gt)
if (IS_SRIOV_PF(gt_to_xe(gt)))
xe_gt_sriov_pf_init_hw(gt);
+ /* Last action registered here so devres drains resets before teardown */
+ err = devm_add_action_or_reset(xe->drm.dev, gt_reset_worker_disable, gt);
+ if (err)
+ return err;
+
return 0;
}
@@ -706,12 +724,7 @@ static void xe_gt_fini(void *arg)
struct xe_gt *gt = arg;
int i;
- if (disable_work_sync(>->reset.worker))
- /*
- * If gt_reset_worker was halted from executing, take care of
- * releasing the rpm reference here.
- */
- xe_pm_runtime_put(gt_to_xe(gt));
+ gt_reset_worker_disable(gt);
for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i)
xe_hw_fence_irq_finish(>->fence_irq[i]);
@@ -754,8 +767,10 @@ int xe_gt_init(struct xe_gt *gt)
xe_force_wake_init_engines(gt, gt_to_fw(gt));
err = gt_init_with_all_forcewake(gt);
- if (err)
+ if (err) {
+ gt_reset_worker_disable(gt);
return err;
+ }
xe_gt_record_user_engines(gt);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v5 2/3] drm/xe/guc: Protect timeout handling from device unplug
2026-10-12 5:50 ` [PATCH v5 2/3] drm/xe/guc: Protect timeout handling from device unplug Satyanarayana K V P
@ 2026-10-12 6:00 ` sashiko-bot
0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-10-12 6:00 UTC (permalink / raw)
To: Satyanarayana K V P; +Cc: intel-xe
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] drm/scheduler: Memory leak of timed-out job when returning ENODEV
--
commit 17e9fcf9241e0bec8edf4a488366f62c46a0e6dc
Author: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
drm/xe/guc: Protect timeout handling from device unplug
This commit guards the GuC scheduler timeout callback with drm_dev_enter()
and drm_dev_exit() to handle concurrent device unplug. If an unplug has
started, it marks the job with -ENODEV and returns a corresponding status
to the scheduler.
> diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
> index 7ce73489c35fc..082c94340b41d 100644
> --- a/drivers/gpu/drm/xe/xe_guc_submit.c
> +++ b/drivers/gpu/drm/xe/xe_guc_submit.c
> @@ -1599,6 +1599,12 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
> int err = -ETIME;
> pid_t pid = -1;
> bool wedged = false, wedge_device = false, skip_timeout_check;
> + int idx;
> +
> + if (!drm_dev_enter(&xe->drm, &idx)) {
> + xe_sched_job_set_error(job, -ENODEV);
> + return DRM_GPU_SCHED_STAT_ENODEV;
[Severity: Medium]
Does returning DRM_GPU_SCHED_STAT_ENODEV here cause a memory leak of the
struct xe_sched_job and its associated resources?
When a job times out concurrently with device unplug, the DRM scheduler core
in drm_sched_job_timedout() explicitly drops the job from its pending list
before invoking this backend timeout callback. It only reinserts the job into
the pending list if the callback returns DRM_GPU_SCHED_STAT_NO_HANG.
By returning DRM_GPU_SCHED_STAT_ENODEV, the job remains unlinked. Even though
the fence is signaled via xe_sched_job_set_error(), the scheduler's cleanup
worker (drm_sched_free_job_work()) and teardown sequences only search
sched->pending_list.
Because the job is neither manually freed in this early return path nor
reinserted for automatic scheduler cleanup, the job structure appears to be
permanently orphaned.
> + }
>
> xe_gt_assert(guc_to_gt(guc), !exec_queue_destroyed(q));
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012055053.964468-5-satyanarayana.k.v.p@intel.com?part=2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine
2026-10-12 5:50 ` [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine Satyanarayana K V P
@ 2026-10-12 6:07 ` sashiko-bot
2026-10-12 8:29 ` Piotr Piórkowski
1 sibling, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-10-12 6:07 UTC (permalink / raw)
To: Satyanarayana K V P; +Cc: intel-xe
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] drm/xe: NULL pointer dereference due to incomplete locking in hw_engine_fini
--
commit 888f9d1be166404e1216f8d0d23505412e283b23
Author: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
drm/xe: Prevent VF memory IRQ from accessing a torn-down engine
This commit fixes a NULL pointer dereference by invalidating the engine
name and GT pointer during teardown in hw_engine_fini() under the
irq.lock, preventing the VF memory IRQ handler from scanning it.
> diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
> index 265f95c0c8993..55ee0c892c1e8 100644
> --- a/drivers/gpu/drm/xe/xe_hw_engine.c
> +++ b/drivers/gpu/drm/xe/xe_hw_engine.c
[ ... ]
> @@ -275,11 +275,22 @@ static const struct engine_info engine_infos[] = {
> static void hw_engine_fini(void *arg)
> {
> struct xe_hw_engine *hwe = arg;
> + struct xe_gt *gt = hwe->gt;
> +
> + if (gt) {
> + struct xe_device *xe = gt_to_xe(gt);
> + unsigned long flags;
>
> - if (hwe->exl_port)
> - xe_execlist_port_destroy(hwe->exl_port);
> + if (hwe->exl_port)
> + xe_execlist_port_destroy(hwe->exl_port);
>
> - hwe->gt = NULL;
> + spin_lock_irqsave(&xe->irq.lock, flags);
> + hwe->name = NULL;
> + hwe->gt = NULL;
[Severity: High]
Can this still cause a NULL pointer dereference for lockless IOCTL callers?
Unprivileged userspace can call the DRM_IOCTL_XE_DEVICE_QUERY ioctl
(specifically query_engine_cycles) concurrently with device unbind or unplug.
Since the ioctl is not guarded by drm_dev_enter(), it can proceed
concurrently with devres_release_all() and hw_engine_fini().
The ioctl looks up the hardware engine via xe_gt_hw_engine() in
query_engine_cycles():
drivers/gpu/drm/xe/xe_query.c:query_engine_cycles() {
...
hwe = xe_gt_hw_engine(gt, user_to_xe_engine_class[eci->engine_class],
eci->engine_instance, true);
if (!hwe)
return -EINVAL;
...
}
Immediately after this check, hw_engine_fini() can execute and clear
hwe->gt = NULL (guarded only by xe->irq.lock, which the ioctl does not hold).
The ioctl then calls hwe_read_timestamp(), which dereferences hwe->gt:
drivers/gpu/drm/xe/xe_query.c:hwe_read_timestamp() {
struct xe_mmio *mmio = &hwe->gt->mmio;
...
}
Does this lockless path need additional protection against concurrent
teardown?
> + spin_unlock_irqrestore(&xe->irq.lock, flags);
> + } else {
> + hwe->name = NULL;
> + }
> }
>
> /**
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012055053.964468-5-satyanarayana.k.v.p@intel.com?part=1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine
2026-10-12 5:50 ` [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine Satyanarayana K V P
2026-10-12 6:07 ` sashiko-bot
@ 2026-10-12 8:29 ` Piotr Piórkowski
1 sibling, 0 replies; 8+ messages in thread
From: Piotr Piórkowski @ 2026-10-12 8:29 UTC (permalink / raw)
To: Satyanarayana K V P; +Cc: intel-xe, Matthew Brost
Satyanarayana K V P <satyanarayana.k.v.p@intel.com> wrote on pon [2026-paź-12 05:50:55 +0000]:
> The VF memory IRQ handler iterates over HW engines whose names are set.
> Engine teardown clears hwe->gt but leaves hwe->name set, so the handler
> can select an engine whose GT has already been invalidated. This can
> cause a NULL pointer dereference in xe_hw_engine_handle_irq().
>
> Invalidate the engine name during teardown so subsequent engine scans
> skip it.
>
> Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
> Fixes: 6eb2aad402cc ("drm/xe: Move hw_engine_fini to devm managed")
> ---
> V3 -> V4:
> - Fix issue with xe_execlist_port_destroy() with V3 version (Sashiko).
>
> V2 -> V3:
> - Updated spin_lock_irq() to spin_lock_irqsave().
>
> V1 -> V2:
> - Fix race with xe_memirq_handler() and hw_engine_fini() (Sashiko & Piotr).
> ---
> drivers/gpu/drm/xe/xe_hw_engine.c | 17 ++++++++++++++---
> drivers/gpu/drm/xe/xe_irq.c | 3 +++
> drivers/gpu/drm/xe/xe_memirq.c | 3 +++
> 3 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
> index 265f95c0c899..55ee0c892c1e 100644
> --- a/drivers/gpu/drm/xe/xe_hw_engine.c
> +++ b/drivers/gpu/drm/xe/xe_hw_engine.c
> @@ -275,11 +275,22 @@ static const struct engine_info engine_infos[] = {
> static void hw_engine_fini(void *arg)
> {
> struct xe_hw_engine *hwe = arg;
> + struct xe_gt *gt = hwe->gt;
> +
> + if (gt) {
> + struct xe_device *xe = gt_to_xe(gt);
> + unsigned long flags;
>
> - if (hwe->exl_port)
> - xe_execlist_port_destroy(hwe->exl_port);
> + if (hwe->exl_port)
> + xe_execlist_port_destroy(hwe->exl_port);
>
> - hwe->gt = NULL;
> + spin_lock_irqsave(&xe->irq.lock, flags);
> + hwe->name = NULL;
> + hwe->gt = NULL;
> + spin_unlock_irqrestore(&xe->irq.lock, flags);
> + } else {
> + hwe->name = NULL;
> + }
NIT: I don't think the !gt branch can ever be taken. hwe->gt is set in
hw_engine_init_early(), long before hw_engine_init() registers
hw_engine_fini() via devm_add_action_or_reset(). Both the normal devm
release and the _or_reset error path therefore always see a valid
hwe->gt, and the original code relied on that as well
(xe_execlist_port_destroy() dereferences port->hwe->gt unconditionally).
> }
>
> /**
> diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
> index 9e49e2241da4..b394c8edf89c 100644
> --- a/drivers/gpu/drm/xe/xe_irq.c
> +++ b/drivers/gpu/drm/xe/xe_irq.c
> @@ -908,6 +908,7 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
> struct xe_hw_engine *hwe;
> enum xe_hw_engine_id id;
> struct xe_tile *tile;
> + unsigned long flags;
> struct xe_gt *gt;
>
> if (!atomic_read(&xe->irq.enabled))
> @@ -922,8 +923,10 @@ static irqreturn_t xe_irq_msix_default_hwe_handler(int irq, void *arg)
> if (gt->tile != tile)
> continue;
>
> + spin_lock_irqsave(&xe->irq.lock, flags);
> for_each_hw_engine(hwe, gt, id)
> xe_memirq_hwe_handler(memirq, hwe);
> + spin_unlock_irqrestore(&xe->irq.lock, flags);
> }
> }
>
> diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c
> index 9dfe965cb46e..1073132f2ded 100644
> --- a/drivers/gpu/drm/xe/xe_memirq.c
> +++ b/drivers/gpu/drm/xe/xe_memirq.c
> @@ -555,6 +555,7 @@ void xe_memirq_handler(struct xe_memirq *memirq)
> struct xe_hw_engine *hwe;
> enum xe_hw_engine_id id;
> struct iosys_map map;
> + unsigned long flags;
> unsigned int gtid;
> struct xe_gt *gt;
>
> @@ -568,8 +569,10 @@ void xe_memirq_handler(struct xe_memirq *memirq)
> if (gt->tile != tile)
> continue;
>
> + spin_lock_irqsave(&xe->irq.lock, flags);
> for_each_hw_engine(hwe, gt, id)
> xe_memirq_hwe_handler(memirq, hwe);
> + spin_unlock_irqrestore(&xe->irq.lock, flags);
> }
>
> /* GuC and media GuC (if present) must be checked separately */
> --
> 2.43.0
>
LGTM, one NIT above:
Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
--
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 3/3] drm/xe/gt: Disable GT reset worker before engine teardown
2026-10-12 5:50 ` [PATCH v5 3/3] drm/xe/gt: Disable GT reset worker before engine teardown Satyanarayana K V P
@ 2026-10-12 8:40 ` Piotr Piórkowski
0 siblings, 0 replies; 8+ messages in thread
From: Piotr Piórkowski @ 2026-10-12 8:40 UTC (permalink / raw)
To: Satyanarayana K V P; +Cc: intel-xe, Matthew Brost, Balasubramani Vivekanandan
Satyanarayana K V P <satyanarayana.k.v.p@intel.com> wrote on pon [2026-paź-12 05:50:57 +0000]:
> During tear-down process, a reset queued from Guc timeout handler can
> still access hwe after hwe is freed. Register a separate devm
> action that disables and drains the reset worker, so it runs before
> any engine is torn down.
>
> Fixes: 09c452d1171f ("drm/xe/gt: Synchronize GT reset with device unbind")
> Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com>
> Cc: Matthew Brost <matthew.brost@intel.com>
> Cc: Piotr Piórkowski <piotr.piorkowski@intel.com>
> Cc: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
> Assisted-by: LLM
> ---
> V3 -> V4:
> - Fix race condition reported by LLM (Sashiko).
> ---
> drivers/gpu/drm/xe/xe_gt.c | 29 ++++++++++++++++++++++-------
> 1 file changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
> index 775c826b68b4..bc9bf6f0b5a7 100644
> --- a/drivers/gpu/drm/xe/xe_gt.c
> +++ b/drivers/gpu/drm/xe/xe_gt.c
> @@ -630,8 +630,21 @@ static int gt_init_with_gt_forcewake(struct xe_gt *gt)
> return 0;
> }
>
> +static void gt_reset_worker_disable(void *arg)
> +{
> + struct xe_gt *gt = arg;
> +
> + if (disable_work_sync(>->reset.worker))
> + /*
> + * If gt_reset_worker was halted from executing, take care of
> + * releasing the rpm reference here.
> + */
> + xe_pm_runtime_put(gt_to_xe(gt));
> +}
> +
> static int gt_init_with_all_forcewake(struct xe_gt *gt)
> {
> + struct xe_device *xe = gt_to_xe(gt);
> int err;
>
> CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FORCEWAKE_ALL);
> @@ -698,6 +711,11 @@ static int gt_init_with_all_forcewake(struct xe_gt *gt)
> if (IS_SRIOV_PF(gt_to_xe(gt)))
> xe_gt_sriov_pf_init_hw(gt);
>
> + /* Last action registered here so devres drains resets before teardown */
> + err = devm_add_action_or_reset(xe->drm.dev, gt_reset_worker_disable, gt);
> + if (err)
> + return err;
> +
> return 0;
> }
>
> @@ -706,12 +724,7 @@ static void xe_gt_fini(void *arg)
> struct xe_gt *gt = arg;
> int i;
>
> - if (disable_work_sync(>->reset.worker))
> - /*
> - * If gt_reset_worker was halted from executing, take care of
> - * releasing the rpm reference here.
> - */
> - xe_pm_runtime_put(gt_to_xe(gt));
> + gt_reset_worker_disable(gt);
>
> for (i = 0; i < XE_ENGINE_CLASS_MAX; ++i)
> xe_hw_fence_irq_finish(>->fence_irq[i]);
> @@ -754,8 +767,10 @@ int xe_gt_init(struct xe_gt *gt)
> xe_force_wake_init_engines(gt, gt_to_fw(gt));
>
> err = gt_init_with_all_forcewake(gt);
> - if (err)
> + if (err) {
> + gt_reset_worker_disable(gt);
> return err;
> + }
>
> xe_gt_record_user_engines(gt);
>
LGTM:
Reviewed-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
> --
> 2.43.0
>
--
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-10-12 8:40 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-12 5:50 [PATCH v5 0/3] Fix kernel crash during driver teardown Satyanarayana K V P
2026-10-12 5:50 ` [PATCH v5 1/3] drm/xe: Prevent VF memory IRQ from accessing a torn-down engine Satyanarayana K V P
2026-10-12 6:07 ` sashiko-bot
2026-10-12 8:29 ` Piotr Piórkowski
2026-10-12 5:50 ` [PATCH v5 2/3] drm/xe/guc: Protect timeout handling from device unplug Satyanarayana K V P
2026-10-12 6:00 ` sashiko-bot
2026-10-12 5:50 ` [PATCH v5 3/3] drm/xe/gt: Disable GT reset worker before engine teardown Satyanarayana K V P
2026-10-12 8:40 ` Piotr Piórkowski
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.