Skip to content

Commit fe39b22

Browse files
lucasdemarchiThomas Hellström
authored andcommitted
drm/xe: Fix fault on fd close after unbind
If userspace holds an fd open, unbinds the device and then closes it, the driver shouldn't try to access the hardware. Protect it by using drm_dev_enter()/drm_dev_exit(). This fixes the following page fault: <6> [IGT] xe_wedged: exiting, ret=98 <1> BUG: unable to handle page fault for address: ffffc901bc5e508c <1> #PF: supervisor read access in kernel mode <1> #PF: error_code(0x0000) - not-present page ... <4> xe_lrc_update_timestamp+0x1c/0xd0 [xe] <4> xe_exec_queue_update_run_ticks+0x50/0xb0 [xe] <4> xe_exec_queue_fini+0x16/0xb0 [xe] <4> __guc_exec_queue_fini_async+0xc4/0x190 [xe] <4> guc_exec_queue_fini_async+0xa0/0xe0 [xe] <4> guc_exec_queue_fini+0x23/0x40 [xe] <4> xe_exec_queue_destroy+0xb3/0xf0 [xe] <4> xe_file_close+0xd4/0x1a0 [xe] <4> drm_file_free+0x210/0x280 [drm] <4> drm_close_helper.isra.0+0x6d/0x80 [drm] <4> drm_release_noglobal+0x20/0x90 [drm] Fixes: 514447a ("drm/xe: Stop accumulating LRC timestamp on job_free") Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/3421 Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241218053122.2730195-1-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> (cherry picked from commit 4ca1fd4) Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
1 parent af12ba6 commit fe39b22

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

drivers/gpu/drm/xe/xe_exec_queue.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/nospec.h>
99

1010
#include <drm/drm_device.h>
11+
#include <drm/drm_drv.h>
1112
#include <drm/drm_file.h>
1213
#include <uapi/drm/xe_drm.h>
1314

@@ -762,9 +763,11 @@ bool xe_exec_queue_is_idle(struct xe_exec_queue *q)
762763
*/
763764
void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
764765
{
766+
struct xe_device *xe = gt_to_xe(q->gt);
765767
struct xe_file *xef;
766768
struct xe_lrc *lrc;
767769
u32 old_ts, new_ts;
770+
int idx;
768771

769772
/*
770773
* Jobs that are run during driver load may use an exec_queue, but are
@@ -774,6 +777,10 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
774777
if (!q->vm || !q->vm->xef)
775778
return;
776779

780+
/* Synchronize with unbind while holding the xe file open */
781+
if (!drm_dev_enter(&xe->drm, &idx))
782+
return;
783+
777784
xef = q->vm->xef;
778785

779786
/*
@@ -787,6 +794,8 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
787794
lrc = q->lrc[0];
788795
new_ts = xe_lrc_update_timestamp(lrc, &old_ts);
789796
xef->run_ticks[q->class] += (new_ts - old_ts) * q->width;
797+
798+
drm_dev_exit(idx);
790799
}
791800

792801
/**

0 commit comments

Comments
 (0)