kernel: device_transfer — you may give away what you hold

The mechanism behind delegation, which device-manager.md named as the step
after hello: the device manager claims what discovery seeded and hands each
device to the driver it matched, so assignment stops being
first-come-first-served.

It is a MOVE, not a copy. A claim is exclusive (driver-model.md, invariant
1), so the giver stops holding the device the instant the receiver starts.
That is why this is a new syscall rather than the M13 capability path, where
a passed handle is shared refcounted — exclusivity cannot be expressed that
way.

The kernel's whole rule is that you may give away what you hold. It has no
notion of which task is the device manager and deliberately gains none: a
binary name inside the kernel is not something that cannot safely live in
user space. A recipient that does not exist is refused, because a device
moved to nobody would be unreachable for the rest of the boot — nothing
un-holds a device but task death.

Three errnos, each naming its own rule: ENODEV no such device, EPERM you do
not hold it, ESRCH no such recipient.

Nothing uses it yet. The five claimants move across one at a time in D4-D5,
so the suite stays green throughout and a regression names the driver that
caused it.

Ten assertions, verified to discriminate: removing the ownership check flips
four of them, including the giveaway that an illegal transfer then blocks
the legitimate claim behind it.

Suite 116 -> 117.
This commit is contained in:
Daniel Samson
2026-08-08 17:11:59 +01:00
parent 547d0ec46b
commit 3111c7c5e6
7 changed files with 148 additions and 1 deletions
+8
View File
@@ -1021,6 +1021,14 @@ CASES = [
{"name": "apertures",
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# Delegation's mechanism (docs/os-development/device-authority.md). A claim is
# exclusive, so handing a device on is a MOVE: the giver stops holding it the
# instant the receiver starts - which is why this is not the M13 capability path,
# where a handle is shared refcounted. The kernel's whole rule is "you may give
# away what you hold"; it has no notion of which task is the device manager.
{"name": "device-transfer",
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# IRQ teardown: an exiting driver's line is masked and its slot cleared (so no
# ISR notifies a freed endpoint), and a sibling owner sharing that endpoint
# keeps its own binding. A long-running driver never reaches this teardown path.