]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe/lrc: document sentinel and make CTX_TIMESTAMP read TOCTOU-safe
authorGajendra Uttamchand <gajendra.uttamchand@intel.com>
Mon, 10 Aug 2026 07:18:14 +0000 (07:18 +0000)
committerThomas Hellström <thomas.hellstrom@linux.intel.com>
Thu, 13 Aug 2026 12:56:33 +0000 (14:56 +0200)
Problem: CTX_TIMESTAMP MMIO reads could be stale if a context
switched out between check and read; LRC stores a sentinel while
a context starts that must not be treated as a real timestamp.

Fix: Check the LRC-stored sentinel before and after the MMIO read;
return the LRC value if the context switched out to avoid TOCTOU.

Note: Keep XE_LRC_CTX_TIMESTAMP_ACTIVE in xe_lrc.h as the
canonical sentinel.

Fixes: d243ef6a39c6 ("drm/xe/lrc: Refactor xe_lrc_timestamp to simplify logic")
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/7956
Assisted-by: GitHub-Copilot:claude-sonnet-5
Signed-off-by: Gajendra Uttamchand <gajendra.uttamchand@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Acked-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Link: https://patch.msgid.link/20260810071812.213358-4-gajendra.uttamchand@intel.com
(cherry picked from commit a806534474df071a730d930df479976a812b699d)
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
drivers/gpu/drm/xe/xe_lrc.c
drivers/gpu/drm/xe/xe_lrc.h

index 78969d3e59048105fe3011e98de9775fd350ff88..9f8217ff1904cacaf9ce8f401526eb952ec5746c 100644 (file)
@@ -1096,7 +1096,7 @@ static void xe_lrc_finish(struct xe_lrc *lrc)
  * on until it is scheduled, we also read the ENGINE_ID MMIO in the WA BB and
  * store it in the PPHSWP.
  */
-#define CONTEXT_ACTIVE 1ULL
+#define CONTEXT_ACTIVE XE_LRC_CTX_TIMESTAMP_ACTIVE
 static ssize_t setup_utilization_wa(struct xe_lrc *lrc,
                                    struct xe_hw_engine *hwe,
                                    u32 *batch,
@@ -2727,21 +2727,27 @@ static u64 xe_lrc_update_multi_queue_timestamp(struct xe_lrc *lrc, u64 *old_ts)
 static u64 xe_lrc_context_timestamp(struct xe_lrc *lrc)
 {
        u64 reg_ts, new_ts = lrc->ctx_timestamp;
+       u64 stored;
 
        /* CTX_TIMESTAMP mmio read is invalid on VF, so return the LRC value */
        if (IS_SRIOV_VF(lrc_to_xe(lrc)))
                return xe_lrc_ctx_timestamp(lrc);
 
-       if (context_active(lrc) &&
-           !get_ctx_timestamp(lrc, xe_lrc_engine_id(lrc), &reg_ts))
+       /* Safely read CTX_TIMESTAMP: Avoid TOCTOU on LRC-stored CONTEXT_ACTIVE sentinel */
+       stored = xe_lrc_ctx_timestamp(lrc);
+       if (stored != CONTEXT_ACTIVE)
+               return stored;
+
+       /* Context is active: read the live timestamp from the engine's MMIO register */
+       if (!get_ctx_timestamp(lrc, xe_lrc_engine_id(lrc), &reg_ts))
                new_ts = reg_ts;
 
-       /*
-        * If context swicthed out while we were here, just return the latest
-        * LRC CTX TIMESTAMP value.
+       /* If the context switched out prefer using the value
+        * from context-save over the stale MMIO read.
         */
-       if (!context_active(lrc))
-               return xe_lrc_ctx_timestamp(lrc);
+       stored = xe_lrc_ctx_timestamp(lrc);
+       if (stored != CONTEXT_ACTIVE)
+               return stored;
 
        return new_ts;
 }
index 0a3a611391ee0b562392ebc24f2925a66f90053e..7be5e3da8bc800bc942cd8466f8048fde60acfbb 100644 (file)
@@ -9,6 +9,13 @@
 
 #include "xe_lrc_types.h"
 
+/*
+ * Sentinel value stored in lrc->ctx_timestamp while a context is starting.
+ * The hardware hasn't yet written the real CTX_TIMESTAMP, so this is not a
+ * valid elapsed-time sample and must not be used as one.
+ */
+#define XE_LRC_CTX_TIMESTAMP_ACTIVE 1ULL
+
 struct drm_printer;
 struct xe_bb;
 struct xe_device;