Private tier (file descriptors for R2), segmap check, pollhead drop rule #5
Loading…
Reference in a new issue
No description provided.
Delete branch "r2-private-fd"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The private tier planned in
docs/DESIGN.mdsection 4 adds what milestone R2 of the Rust DRM core needs to hand kernel objects to user space as file descriptors (illumos-drm WI-454). This PR also adds two public-tier pieces and the fixes for two findings of that work.Stacked on PR 4 (
r3-kms-glue, R3'schpoll(9E)glue); the base of this PR is that branch. Merge PR 4 first. The illumos-drm R2 pull request pins this branch's head.Reconciliation with R3
R2 had its own
chpoll(9E)API. After the rebase ontor3-kms-glueit uses R3's (a!UnpinPollHead,Pinregistrations,PollHeads, the glue deciding when to register) and drops its own. The two changes R2's review required are separate commits on top of R3's API:POLLNVALnow passes through likePOLLERRandPOLLHUP(PollEvents::NVAL,PollEvents::ALWAYS).PollHeadis now!Send. R3 hadunsafe impl Send.PollBox(a pinnedKBoxhead that isSend/Sync, withnew,try_new,headandrelease(&Sleepable)) or in aPollHeadsarray.pollhead_clean(9F)there;poll::leaked_headscounts them.PollHead::registration_unchecked(unsafe) registers a head the instance does not own, such as a sync file's head.What was built
crates/illumos-kernel-private-sys: pinned to gatecda5b9a49f. The crate is empty unless the featureunstable-gate-cda5b9a49fis enabled. It binds:file_t,falloc,unfalloc,setf,getf,releasef,f_setfd_or(os/fio.c,sys/file.h)vnode_t,caller_context_t,fop_open,fop_close,vn_copypath,vn_rele(sys/vnode.h)makespecvp,specfind(sys/fs/snode.h, modulefs/specfs)servicing_interrupt(sys/disp.h)ufallocis left unbound on purpose:falloccalls it, and nothing needs a descriptor without a file.Gate citations instead of manual pages: the first doc line of every item is
`name`. Private, `path:line`..xtask lint-man --gatechecks that the cited line exists and names the item, and keeps the crate out of the manual-page checks. Result: 19 citations, 0 errors against a checkout at0fb1d5d8d3, which has not changed any cited file sincecda5b9a49f.ddi::private::fd(featureunstable-gate-cda5b9a49f):NewFd::opengives the calling process a reserved descriptor for one of the calling driver's own minor numbers:makespecvp, the caller's path throughspecfind+vn_copypath,VOP_OPEN,falloc.installusessetfandf_setfd_or;Dropundoes everything.FileRefholds a descriptor (getf/releasef) and names the driver's minor if the descriptor is one of them.IoctlArgof the ioctl being served, and both refuse LDI callers and kernel threads.segmap(9E)check:ops: [char, devmap]installs glue that runsCharDevice::segmap_check(MapRequest)beforeddi_devmap_segmap(9F). A mapping thatdevmap_map(9E)refuses would otherwise stay in the process until it exits, becausedevmap_setupdoes not unmap it.IoctlArgrecords the device number of the ioctl; only the glue can set it.rselftestgains the featureprivate-gateand the ioctlRSELFTEST_IOC_ANONFD, with 6 descriptor checks and 2 poll-head guard checks. CI builds it with-N fs/specfsand runs clippy with the feature.Panics made impossible (docs/DESIGN.md section 5.12)
segdev_create+0xe4on the firstmmap(2)of a dma-buf descriptor.makespecvpvnode had no path.segdev_createcallsspecfind, which only returns vnodes whose path is visible in the caller's zone, and does not check the result.IoctlArg(compile_fail,E0624doctest), andNewFd::opencopies the caller's file path.EINVALfor an argument that does not come from the glue. The devmap glue returnsENXIOwhenspecfindfinds nothing. This also covers descriptors passed into another zone, which panic any devmap driver today.ENODEV) was prepared but is not filed.PollHeadis!Send, andPollBox/PollHeadscarry heads across threads (compile_fail,E0277doctest: aPin<KBox<PollHead>>in a soft interrupt handler's state, with aPollBoxtwin that compiles).PollBoxis not leaked, and that aPollBoxplus a two-headPollHeadsdropped in a soft interrupt are leaked (3 heads), with the two warnings in/var/adm/messages.Verification
Kernel runs used a fresh disposable guest (Hephaistos, golden overlay, illumos
cda5b9a49f, 2 vCPU, 3 GiB) and this branch's headfaec57598b.cargo clippy --workspace, and again with the feature and with rselftest'sprivate-gatecargo fmtcargo doccargo test -p ddi --lib: 9 testsnightly-2026-04-16(error codes checked)xtask kernel-check:illumos-kernel-private-sys: sizes 2/2, offsets 21/21, symbols 13/13(makespecvpandspecfindcome fromspecfs, the rest fromgenunix).ddi-sysgives the same answers as before:ddi_ncpus_expectedis not in this kernel.private-gate: all 57 checks passed (42 at attach, 7 LDI, 8 private).Logs (workspace):
logs/hephaistos/illumos-drm/20260929-r2-rebased-rselftest-private.log,20260929-r2-rebased-kernel-check.log,20260929-r2-panic-*.log. Notes:notes/illumos-drm-segdev-panic-20260929.md,notes/illumos-gate-segdev-specfind-proposal.md. Dump on Hephaistos:~/illumos-drm-test/20260928/dumps/r2-segdev-20260929/.Open issues
servicing_interruptis private. The type rule (!Send) still applies. This is documented.devmap_setupleaving a refused mapping in place is an upstream issue. It is only noted in the local gate proposal.ddi_ncpus_expectedis missing from thecda5b9a49fkernel (existingddi-sysbinding, unrelated to this PR).