GETUNIQUE AND SETVERSION STORY(9)
🐉 getunique and setversion story ✨
okay so this is the Kernel API Manual page for the whole getunique and setversion story(9) saga, and bestie, it is a whole lore drop. Buckle in, because we’re about to read the kernel tea. 🫖💅
BEWARE THE DRAGONS! MIND THE TRAPDOORS!
fr fr. In an attempt to warn anyone else who’s trying to figure out what’s going on here, I’ll try to summarize the story. First things first, let’s clear up the names, because the kernel internals, libdrm and the ioctls are all named differently:
GET_UNIQUEioctl — implemented bydrm_getunique, and wrapped up in libdrm through thedrmGetBusidfunction. 👑- the libdrm
drmSetBusidfunction — backed by theSET_UNIQUEioctl. All that code is nerved in the kernel withdrm_invalid_op. - the internal
set_busidkernel functions and driver callbacks — exclusively used by theSET_VERSIONioctl, because only drm 1.0 (which is nerved) allowed userspace to set the busid through the above ioctl. - other ioctls and functions involved — named consistently.
For anyone wondering what’s the difference between drm 1.1 and 1.4: correctly handling pci domains in the busid on ppc. Doing this correctly was only implemented in libdrm in 2010, hence can’t be nerved yet. No one knows what’s special with drm 1.2 and 1.3. the mystery is real 🕵️♀️
Now the actual horror story of how device lookup in drm works. At large, there’s 2 different ways, either by busid, or by device driver name.
Opening by busid is fairly simple:
- First call
SET_VERSIONto make sure pci domains are handled properly. As a side-effect this fills out the unique name in the master structure. - Call
GET_UNIQUEto read out the unique name from the master structure, which matches the busid thanks to step 1. If it doesn’t, proceed to try the next device node.
Opening by name is slightly different:
- Directly call
VERSIONto get the version and to match against the driver name returned by that ioctl. Note thatSET_VERSIONis not called, which means the unique name for the master node just opening is _not_ filled out. This despite that with current drm device nodes are always bound to one device, and can’t be runtime assigned like with drm 1.0. - Match driver name. If it mismatches, proceed to the next device node.
- Call
GET_UNIQUE, and check whether the unique name has length zero (by checking that the first byte in the string is 0). If that’s not the case libdrm skips and proceeds to the next device node. Probably this is just copypasta from drm 1.0 times where a set unique name meant that the driver was in use already, but that’s just conjecture. 🍵
Long story short: to keep the open by name logic working, GET_UNIQUE must _not_ return a unique string when SET_VERSION hasn’t been called yet, otherwise libdrm breaks. Even when that unique string can’t ever change, and is totally irrelevant for actually opening the device because runtime assignable device instances were only support in drm 1.0, which is long dead. But the libdrm code in drmOpenByName somehow survived, hence this can’t be broken. 😭👑
👀 SEE ALSO
Kernel file ./drivers/gpu/drm/drm_ioctl.c — plus the whole squad: drm_noop(9), drm_invalid_op(9), driver specific ioctls(9), drm_ioctl(9), drm_ioctl_flags(9).
byeee, this absolute icon of a page came from ./drivers/gpu/drm, dated October 2026, and it’s filed under getunique and setversion story(9) — mwah 💅✨🦋🍓
📦 where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms