establishment: the two-controller proof, and the docs catch up

P4 of docs/establishment-planes-plan.md. The new usb-two-controllers case is
the Ryzen mouse bug pinned in the suite: a second xHCI controller with its
own keyboard while the boot controller keeps the default one — both must
come up, on different device ids, which requires each class driver to reach
ITS OWN controller. Discrimination: at 72807c2 (name-based establishment)
the case fails — one keyboard is unreachable, exactly the bench failure —
verified against a checkout of that merge; with lineage routing it passes.
The existing second-controller cases could not prove this: the boot bus
always carries a keyboard, so their expects were satisfiable by it.

Docs updated with the code: device-manager.md (hello moves the channels,
paged enumerate, delegation as built, reap-and-rebuild in the restart
sequence), device-authority.md (the fourth as-built decision: driver-layer
channels ride the hello; hello is no longer only the liveness handshake).

Full suite: 118/119, the one failure being iommu-fault's fixed 200 ms
fault window under end-of-run host load — 3/3 green standalone, deflake
flagged separately. usb-two-controllers passed inside the full run.
This commit is contained in:
Daniel Samson
2026-08-09 12:48:33 +01:00
parent 8710944a92
commit 3c9f454398
3 changed files with 67 additions and 13 deletions
+22
View File
@@ -692,6 +692,28 @@ CASES = [
r"(?=.*hub slot \d+ port \d+ device:.*0x0627)"
r"(?=.*usb-hid-keyboard: ok \(device 3)",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# Establishment P4 — the Ryzen mouse bug, pinned (docs/establishment-planes-plan.md).
# A real machine carried THREE xHCI controllers; the transfer contract was one
# exclusive registry name, so every class driver reached whichever bus instance
# bound first, and a device behind any other controller was unreachable
# ("could not open device 50"). This case is the minimal reproduction: a second
# controller with its own keyboard, while the boot controller keeps the default
# keyboard — BOTH must come up, on different device ids, which requires each
# driver to reach ITS OWN controller. Under name-based establishment exactly one
# can; under lineage routing (the manager answers each hello with the reporter's
# channel) both do.
{"name": "usb-two-controllers",
"build_case": "usb-hid",
"smp": 4,
"timeout": 150,
"qemu_extra": ["-device", "qemu-xhci,id=xhci2",
"-device", "usb-kbd,bus=xhci2.0,port=1"],
# Two bus delegations, then two keyboards alive with distinct ids: the
# second `ok` must name a different device than the first, so one keyboard
# answering twice can never satisfy it.
"expect": r"(?s)(?=(?:[\s\S]*delegated device \d+ to /system/drivers/usb-xhci-bus){2})"
r"(?=[\s\S]*usb-hid-keyboard: ok \(device (\d+)\b[\s\S]*usb-hid-keyboard: ok \(device (?!\1\b)\d+)",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# The driver must never truncate a configuration block. Its size is the DEVICE's
# choice (wTotalLength, a u16); the driver used to read the first 512 bytes into a
# fixed buffer and parse those, so interfaces past the cut did not exist while