kernel: the device table has no ceiling; a runaway is charged to whoever caused it

maximum_devices = 64 is gone. It was a guess about someone else's computer,
and because it was shared, one driver's enumeration starved every other —
which is how an AMD Ryzen booted with a working display, no USB and no
storage. The table now grows from the kernel heap. It was always built after
heap.init; nothing ever prevented this except it having been written static
first.

What replaces it is an allowance charged to the registrar, so a driver
looping device_register exhausts its own and every other driver carries on.
It is declared as what it is — a runaway detector, NOT a security boundary.
A quota generous enough never to bite a real machine is still generous
enough to be unpleasant, and it is not trying to be the defence; delegation
is. What this catches is a legitimate driver in a loop, early, attributably,
and without collateral. Reaching 4096 is a bug report, not a tuning request.

The initial block is 8, deliberately small. Sizing it for a typical machine
would mean the growth path never ran on the hardware we test on and only
woke up on someone else's larger machine — the exact failure shape this
track exists to stop. At 8 it grows several times every boot; disabling
growth now fails the suite with the HPET not fitting, which is the Ryzen
failure in miniature.

The comptime coupling assert added earlier fired, and was right to. confined
(one slot per device id) and domains (the IOMMU's own translation pool) were
sized by the same constant only because device ids happened to stop at 64
too. Two unrelated quantities: confined now grows with the device table,
while maximum_domains stays as the hardware's number — both VT-d and AMD-Vi
report how many domains they support, and reading it is phase 4. The assert
existed for exactly this and did its job.

Suite 118/118.
This commit is contained in:
Daniel Samson
2026-08-08 18:40:20 +01:00
parent 5492607a61
commit f7151ed577
4 changed files with 142 additions and 41 deletions
+5 -1
View File
@@ -47,7 +47,11 @@ that cannot safely run in user space.**
| D6 | `device_claim` refuses a device the caller was not handed; the hole is closed | not started |
| D7 | Zero-resource devices stop being kernel objects — inventory moves to the manager | **blocked** — nothing else mints their ids; see question 8 |
| D8 | **`maximum_children_per_parent` deleted** — the authorisation it stood in for exists | **blocked on D6**, and now ordered after D9 |
| D9 | The device table becomes dynamic; **`maximum_devices` deleted**; per-holder quota declared | not started — **runs before D8** |
| D9 | The device table becomes dynamic; **`maximum_devices` deleted**; per-holder quota declared | **done** — one of the two invented numbers is gone |
**Run 2 stops here.** D1, D2, D4, D5 (`pci-bus` only) and D9 landed; D6, D7, D8 and the
rest of D5 are blocked on questions 6, 7 and 8 below. Suite 118/118, and
`maximum_devices` no longer exists.
Ordering is load-bearing. D1–D2 build and prove the mechanism with nothing depending on
it. D4–D5 move each claimant across one at a time, so the suite stays green throughout