drm/xe/lrc: document sentinel and make CTX_TIMESTAMP read TOCTOU-safe

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: d243ef6a39 ("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>
This commit is contained in:
Gajendra Uttamchand
2026-08-10 07:18:14 +00:00
committed by Thomas Hellström
parent 51afaf53e0
commit cb4afddf9e
2 changed files with 21 additions and 8 deletions

View 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;
}

View 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;