Skip to content

Commit ac44ff7

Browse files
committed
Merge tag 'drm-xe-fixes-2024-10-10' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes
Driver Changes: - Fix error checking with xa_store() (Matthe Auld) - Fix missing freq restore on GSC load error (Vinay) - Fix wedged_mode file permission (Matt Roper) - Fix use-after-free in ct communication (Matthew Auld) Signed-off-by: Dave Airlie <[email protected]> From: Lucas De Marchi <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/jri65tmv3bjbhqhxs5smv45nazssxzhtwphojem4uufwtjuliy@gsdhlh6kzsdy
2 parents b634acb + 1badf48 commit ac44ff7

File tree

4 files changed

+33
-26
lines changed

4 files changed

+33
-26
lines changed

drivers/gpu/drm/xe/xe_debugfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ void xe_debugfs_register(struct xe_device *xe)
187187
debugfs_create_file("forcewake_all", 0400, root, xe,
188188
&forcewake_all_fops);
189189

190-
debugfs_create_file("wedged_mode", 0400, root, xe,
190+
debugfs_create_file("wedged_mode", 0600, root, xe,
191191
&wedged_mode_fops);
192192

193193
for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {

drivers/gpu/drm/xe/xe_gt.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,9 @@ int xe_gt_sanitize_freq(struct xe_gt *gt)
874874
int ret = 0;
875875

876876
if ((!xe_uc_fw_is_available(&gt->uc.gsc.fw) ||
877-
xe_uc_fw_is_loaded(&gt->uc.gsc.fw)) && XE_WA(gt, 22019338487))
877+
xe_uc_fw_is_loaded(&gt->uc.gsc.fw) ||
878+
xe_uc_fw_is_in_error_state(&gt->uc.gsc.fw)) &&
879+
XE_WA(gt, 22019338487))
878880
ret = xe_guc_pc_restore_stashed_freq(&gt->uc.guc.pc);
879881

880882
return ret;

drivers/gpu/drm/xe/xe_guc_ct.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -667,16 +667,12 @@ static int __guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action,
667667
num_g2h = 1;
668668

669669
if (g2h_fence_needs_alloc(g2h_fence)) {
670-
void *ptr;
671-
672670
g2h_fence->seqno = next_ct_seqno(ct, true);
673-
ptr = xa_store(&ct->fence_lookup,
674-
g2h_fence->seqno,
675-
g2h_fence, GFP_ATOMIC);
676-
if (IS_ERR(ptr)) {
677-
ret = PTR_ERR(ptr);
671+
ret = xa_err(xa_store(&ct->fence_lookup,
672+
g2h_fence->seqno, g2h_fence,
673+
GFP_ATOMIC));
674+
if (ret)
678675
goto out;
679-
}
680676
}
681677

682678
seqno = g2h_fence->seqno;
@@ -879,14 +875,11 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
879875
retry_same_fence:
880876
ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence);
881877
if (unlikely(ret == -ENOMEM)) {
882-
void *ptr;
883-
884878
/* Retry allocation /w GFP_KERNEL */
885-
ptr = xa_store(&ct->fence_lookup,
886-
g2h_fence.seqno,
887-
&g2h_fence, GFP_KERNEL);
888-
if (IS_ERR(ptr))
889-
return PTR_ERR(ptr);
879+
ret = xa_err(xa_store(&ct->fence_lookup, g2h_fence.seqno,
880+
&g2h_fence, GFP_KERNEL));
881+
if (ret)
882+
return ret;
890883

891884
goto retry_same_fence;
892885
} else if (unlikely(ret)) {
@@ -903,16 +896,26 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
903896
}
904897

905898
ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ);
899+
900+
/*
901+
* Ensure we serialize with completion side to prevent UAF with fence going out of scope on
902+
* the stack, since we have no clue if it will fire after the timeout before we can erase
903+
* from the xa. Also we have some dependent loads and stores below for which we need the
904+
* correct ordering, and we lack the needed barriers.
905+
*/
906+
mutex_lock(&ct->lock);
906907
if (!ret) {
907-
xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x",
908-
g2h_fence.seqno, action[0]);
908+
xe_gt_err(gt, "Timed out wait for G2H, fence %u, action %04x, done %s",
909+
g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done));
909910
xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno);
911+
mutex_unlock(&ct->lock);
910912
return -ETIME;
911913
}
912914

913915
if (g2h_fence.retry) {
914916
xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n",
915917
action[0], g2h_fence.reason);
918+
mutex_unlock(&ct->lock);
916919
goto retry;
917920
}
918921
if (g2h_fence.fail) {
@@ -921,7 +924,12 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
921924
ret = -EIO;
922925
}
923926

924-
return ret > 0 ? response_buffer ? g2h_fence.response_len : g2h_fence.response_data : ret;
927+
if (ret > 0)
928+
ret = response_buffer ? g2h_fence.response_len : g2h_fence.response_data;
929+
930+
mutex_unlock(&ct->lock);
931+
932+
return ret;
925933
}
926934

927935
/**

drivers/gpu/drm/xe/xe_guc_submit.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ static void __release_guc_id(struct xe_guc *guc, struct xe_exec_queue *q, u32 xa
320320
static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
321321
{
322322
int ret;
323-
void *ptr;
324323
int i;
325324

326325
/*
@@ -340,12 +339,10 @@ static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
340339
q->guc->id = ret;
341340

342341
for (i = 0; i < q->width; ++i) {
343-
ptr = xa_store(&guc->submission_state.exec_queue_lookup,
344-
q->guc->id + i, q, GFP_NOWAIT);
345-
if (IS_ERR(ptr)) {
346-
ret = PTR_ERR(ptr);
342+
ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup,
343+
q->guc->id + i, q, GFP_NOWAIT));
344+
if (ret)
347345
goto err_release;
348-
}
349346
}
350347

351348
return 0;

0 commit comments

Comments
 (0)