BATCH BUFFER COMMAND PARSER(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸŽ€ batch buffer command parser(9) πŸŽ€

okay bestie, welcome to the Kernel API Manual entry for the batch buffer command parser β€” section 9, she's a driver-internals girlie and she ATE πŸ’…


✨ DESCRIPTION ✨

πŸ’– Motivation (aka why does this even exist)

so. certain OpenGL features (e.g. transform feedback, performance monitoring) require userspace code to submit batches containing commands such as MI_LOAD_REGISTER_IMM to access various registers. literally just trying to live her life 🫢

but unfortunately 😭 some generations of the hardware will noop these commands in "unsecure" batches (which includes all userspace batches submitted via i915) β€” even though the commands may be safe and represent the intended programming model of the device. rude, honestly.

the software command parser is similar in operation to the command parsing done in hardware for unsecure batches. BUT ✨ the software parser allows some operations that would be noop'd by hardware, if the parser determines the operation is safe, and submits the batch as "secure" to prevent hardware parsing. she's got main character energy and a security clearance πŸ’€


πŸ¦‹ Threats (the vibe check)

at a high level, the hardware (and software) checks attempt to prevent granting userspace undue privileges. there are three categories of privilege, and yes we're gonna list them all because details are the whole point πŸ‘‘

First β€” commands which are explicitly defined as privileged or which should only be used by the kernel driver. the parser rejects such commands. blocked. 🚫

Second β€” commands which access registers. to support correct/enhanced userspace functionality, particularly certain OpenGL extensions, the parser provides a whitelist of registers which userspace may safely access. iykyk 🌸

Third β€” commands which access privileged memory (i.e. GGTT, HWS page, etc). the parser always rejects such commands. no exceptions, periodt. πŸ’€

the majority of the problematic commands fall in the MI_* range, with only a few specific commands on each engine (e.g. PIPE_CONTROL and MI_FLUSH_DW).


🌈 Implementation (how she actually does it)

each engine maintains tables of commands and registers which the parser uses in scanning batch buffers submitted to that engine. very organized, very demure πŸŽ€

since the set of commands that the parser must check for is significantly smaller than the number of commands supported, the parser tables contain only those commands required by the parser. this generally works because command opcode ranges have standard command length encodings. so for commands that the parser does not need to check, it can easily skip them. this is implemented via a per-engine length decoding vfunc. slay πŸ”₯

unfortunately 😭 there are a number of commands that do not follow the standard length encoding for their opcode range, primarily amongst the MI_* commands. to handle this, the parser provides a way to define explicit "skip" entries in the per-engine command tables. problem solved, we move 🧚

other command table entries map fairly directly to the high level categories mentioned above: rejected, register whitelist. the parser implements a number of checks, including the privileged memory checks, via a general bitmasking mechanism. iconic bit manipulation behavior honestly ⭐


πŸ’œ SEE ALSO πŸ’œ


ngl this whole page is about kernel driver internals for i915, so be careful out there β€” the parser is literally the bouncer at the club and she is not letting privileged commands in πŸ’…

and that's the page!! πŸ’– brought to you by ./drivers/gpu/drm/i915, dated October 2026 β€” mwah, go touch some registers (the whitelisted ones only) πŸŒΈβœ¨πŸŽ€

πŸ“¦ where this page comes from