HARDWARE WORKAROUNDS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… HARDWARE WORKAROUNDS πŸ’…

okay bestie, so this is a page from the Kernel API Manual (that's the (9) in the corner, iykyk) and it's all about hardware workarounds ✨ β€” which are register programming that's documented to be executed in the driver, and that falls outside of the normal programming sequences for a platform. basically the "the spec says one thing but the silicon says another" collection 🫢

there are a few basic categories of workarounds, and which one you're in depends on how/when they get applied. buckle up πŸŽ€

  • LRC workarounds β€” these are the WAs that touch registers which are saved/restored to/from the HW context image. the list is emitted (via Load Register Immediate commands) once when initializing the device, and saved in the default context. that default context is then used on every context creation so you get a "primed golden context" β€” i.e. a context image that already contains the changes needed for all the registers. πŸ‘‘ see drivers/gpu/drm/xe/xe_lrc.c for default context handling.
  • Engine workarounds β€” this list of WAs gets applied whenever the specific engine is reset. it's also possible that a set of engine classes share a common power domain and get reset together β€” this happens on some platforms with render and compute engines. in that case (at least) one of them needs to keep the workaround programming: the approach taken in the driver is to tie those workarounds to the first compute/render engine that is registered. when executing with GuC submission, engine resets are outside of kernel driver control, hence the list of registers involved is written once, on engine initialization, and then passed to GuC, which saves/restores their values before/after the reset takes place. 🌈 see drivers/gpu/drm/xe/xe_guc_ads.c for reference.
  • GT workarounds β€” this list of WAs gets applied whenever these registers revert to their default values: on GPU reset, suspend/resume [1]_, etc. πŸ’œ
  • Register whitelist β€” some workarounds need to be implemented in userspace, but they need to touch privileged registers. the whitelist in the kernel instructs the hardware to allow the access to happen. from the kernel side this is just a special case of a MMIO workaround (because we write the list of these to/be-whitelisted registers to some special HW registers). πŸ¦‹
  • Workaround batchbuffers β€” buffers that get executed automatically by the hardware on every HW context restore. these buffers are created and programmed in the default context so the hardware always goes through those programming sequences when switching contexts. support for workaround batchbuffers is enabled via these hardware mechanisms:
    1. INDIRECT_CTX (also known as mid context restore bb): a batchbuffer and an offset are provided in the default context, pointing the hardware to jump to that location when that offset is reached in the context restore. when a context is being restored, this is executed after the ring context, in the middle (or beginning) of the engine context image. ⭐
    2. BB_PER_CTX_PTR (also known as post context restore bb): a batchbuffer is provided in the default context, pointing the hardware to a buffer to continue executing after the engine registers are restored in a context restore sequence. πŸ”₯

below is the timeline for a context restore sequence πŸ‘‡

                     INDIRECT_CTX_OFFSET
                |----------->|
   .------------.------------.-------------.------------.--------------.-----------.
   |Ring        | Engine     | Mid-context | Engine     | Post-context | Ring      |
   |Restore     | Restore (1)| BB Restore  | Restore (2)| BB Restore   | Execution |
   `------------'------------'-------------'------------'--------------'-----------'
  • Other/OOB β€” there are WAs that, due to their nature, cannot be applied from a central place. those are peppered around the rest of the code, as needed. πŸ™ˆ there's a central place to control which workarounds are enabled: drivers/gpu/drm/xe/xe_wa_oob.rules for GT workarounds and drivers/gpu/drm/xe/xe_device_wa_oob.rules for device/SoC workarounds. these files only record which workarounds are enabled: during early device initialization those rules are evaluated and recorded by the driver. then later the driver checks with XE_GT_WA and XE_DEVICE_WA to implement them. πŸ’–
[1] Technically, some registers are powercontext saved & restored, so they survive a suspend/resume. in practice, writing them again is not too costly and simplifies things, so it's the approach taken in the driver. 🧚
NOTE: πŸŽ€ Hardware workarounds in xe work the same way as in i915, with the difference of how they are maintained in the code. in xe it uses the xe_rtp infrastructure so the workarounds can be kept in tables, following a more declarative approach rather than procedural.
NOTE: 🌸 When a workaround applies to every single known IP version in a range, the preferred handling is to use a single range-based RTP entry rather than individual entries for each version, even if some of the intermediate version numbers are currently unused. if a new intermediate IP version appears in the future and is enabled in the driver, any existing range-based entries that contain the new version number will need to be analyzed to determine whether their workarounds should apply to the new version, or whether any existing range based entries needs to be split into two entries that do not include the new intermediate version. 😭 (yes, future-you's problem. sorry bestie.)

🌈 SEE ALSO 🌈

Kernel file ./drivers/gpu/drm/xe/xe_wa.c xe_wa_process_device_oob(9), xe_wa_process_gt_oob(9), xe_wa_process_gt(9), xe_wa_process_engine(9), xe_wa_process_lrc(9), xe_wa_device_init(9), xe_wa_gt_init(9), xe_wa_gt_dump(9) πŸ’«


that's the whole vibe check bestie, no cap 🫢 this one lives over in ./drivers/gpu/drm/xe and the version you're reading is dated October 2026 β€” go forth and slay those registers πŸ’…πŸ‘‘

πŸ“¦ where this page comes from