mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 10:00:03 -04:00
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:
committed by
Thomas Hellström
parent
51afaf53e0
commit
cb4afddf9e
@@ -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), ®_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), ®_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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user