Comment by quotemstr
3 days ago
> The code waits for all cores to enter SMM, or for up to 1 second, whichever occurs first.
See, this is why the mantra that all blocking operations should have a timeout is stupid and short-sighted no matter how many times junior devs and AIs bleat it in code review. Continuing after arbitrary timeouts usually violates invariants, and failing after arbitrary timeouts introduces hard-to-debug failures under load.
Better for the system to hang so you can debug it --- and maybe reboot as a whole via a watchdog --- than for the code to say "Oh, this operation is supposed to be done after one second, but isn't. Situation normal, everything fine. We continue."
No. That situation is very much not fine.
> failing after arbitrary timeouts introduces hard-to-debug failures under load
What needs to fail here is the instruction doing insanely slow MMIO. That's not going to be too hard to debug; none of the examples of suitably slow instructions are anywhere close to reasonable, and a fault on a vmovdqu in MMIO address space is a big red flag.
And this attack requires enough ridiculous behavior from coordinating software beyond just the single super-slow instruction that it's hard to imagine any reasonable workload being affected if this case starts causing a fault.
I initially agreed with your idea, but realized the problem.
At the bus/inter agent communication level, the CPU has sent a read request and is expecting a response. These protocols are usually synchronous with no clear cancellation semantics. There are probably core resources tracking then expected response and if you just freed one of those up and ended the instruction with an exception, you could later have what appears to be an unsolicited response.
This dynamic probably repeats between the core and the pci root complex and then again between the root complex and the device implementing the mmio. Severing the request from the response is probably too complicated for such an unusual case.
The MMIO itself is probably so slow because it's not implemented at some level and the level before it is timing out.