PT-2026-121982

CVE-2026-99005

·

Published

2026-10-23

·

Updated

2026-10-23

Description by

Score
N/A
Not available

No severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.

In the Linux kernel, the following vulnerability has been resolved:
drm/i915/gt: Unmask interrupts only when ACTIVE is true
There is a small race window between intel rps boost() reading a stale ACTIVE state and queuing rps->work, where ACTIVE may be changed via asynchronous calls triggered by wakeref drop. This means that rps work() could be triggered after the GT has been parked, so unmasking RPS PM interrupts would happen without holding PM wakelock. This sequence of events may be observed during live rc6 ctx wa() selftest:
  1. live rc6 ctx wa() -> intel engine pm put() -> wakeref put()
ASYNC1) wakeref put() callback -> engine park() -> intel gt pm put async() -> intel gt pm put async untracked() -> intel wakeref put async()
ASYNC2) wakeref put async() callback -> gt park() -> intel rps park() -> intel rps clear active() [clear ACTIVE] WITH INTERRUPTS: -> rps disable interrupts() -> cancel work sync(rps->work) -> rps reset interrupts() [rps->pm iir = 0] WITHOUT INTERRUPTS (TIMER mode): -> rps stop timer() -> cancel work sync(rps->work)
  1. live rc6 ctx wa() -> intel gt wait for idle() -> intel gt retire requests timeout() -> dma fence wait timeout() -> ops->wait() [i915 fence wait()] -> i915 request wait timeout() -> intel rps boost() -> intel rps is active() [check ACTIVE] [OPEN RACE WINDOW] -> queue work(rps->work) -> retire requests() -> i915 request retire() -> intel rps dec waiters() [from 1 to 0]
If ASYNC1 and ASYNC2 would execute during [OPEN RACE WINDOW], then:
  1. rps work() executes from the workqueue and may satisfy "(!pm iir && !client boost)" test (in TIMER mode rps->pm iir is zeroed by an earlier rps work() call or never gets a new value after previous intel rps unpark() event), so it jumps to "out" label, bypassing intel rps is active() guard and executes gen6 gt pm unmask irq();
  2. GT is parked and runtime PM wakelock is dropped, so only a raw reference in gt park() -> intel display power put async() remains for 100ms, then the MMIO write in gen6 gt pm unmask irq() detects missing wakelock via assert rpm wakelock held() and emits "RPM wakelock ref not held during HW access" tainting kernel.
Commit 3e7abf814193 ("drm/i915: Extract GT render power state management") dropped the "if (rps->interrupts enabled)" guard that gen6 pm rps work() had around this unmask in i915 irq.c. INTEL RPS ACTIVE brackets the same window, since it is set in intel rps unpark() before rps enable interrupts() and rps start timer() and cleared in intel rps park() before rps stop timer() and rps disable interrupts().
Skip unmasking when RPS is no longer active (reaching unmask operation is independent of INTERRUPT mode). This does not prevent RPS operation from resuming on the next unpark. In interrupt mode, intel rps unpark() calls rps enable interrupts(), which enables and unmasks the PM interrupts. In timer mode, it calls rps start timer(), restarting periodic engine-busyness evaluation. The timer generates software RPS events and queues rps work() directly, independently of PM interrupt delivery. Neither mode requires the late worker to unmask interrupts while the GT is parked
(cherry picked from commit ca4a6deadad15b91ee083afe445fa6bdbfb68206)
Vendors
Affected products
Related identifiers
Found an issue in the description? Have something to add? Feel free to write us 👾