The kernel masks an IRQ line when it delivers the interrupt to userspace
(trigger() -> pic_mask()/ioapic_mask()) and only re-enables it when the
driver writes the count back (kwrite -> acknowledge() -> pic_unmask()/
ioapic_unmask()). That write-back is therefore mandatory, not optional.
ahcid only performed it inside the `is > 0` branch. IRQ lines are shared
(on q35 the AHCI controller sits on IRQ 10 with other devices), so an
interrupt raised by a different device reaches the handler with the HBA
interrupt status register reading 0. In that case ahcid returned without
writing back, leaving the line masked permanently: every subsequent AHCI
completion was lost and all disk I/O blocked forever.
Move the write-back out of the branch so the line is re-armed whether or
not the interrupt turned out to be ours, and keep scheme.tick() gated on
`is > 0` since there is no completion to service otherwise. Device-level
status is still cleared before unmasking, so this cannot cause a storm.
Sync the base fork with 13 upstream commits (xhci event-processing
dedup + IRQ race fix, randd permission simplification, nvmed TimeSpec
fix, /dev/ptmx, fpath legacy-path cleanup, dynamically-linked init
fix, and more). Brings process_one_event into the tree, satisfying the
verify-fork-functions gate for base.
Conflicts resolved (3 of 8 overlapping files; 5 auto-merged):
- drivers/usb/xhcid/src/xhci/irq_reactor.rs: took upstream's
process_one_event/EventProcessResult refactor (b2ed85ea) including
the a01d3ce6 race fix (process events between NoEvent and
unmasking), and re-applied the Red Bear SPURIOUS_REBOOT quirk on the
NoEvent warning (downgrade to debug when quirked).
- randd/src/main.rs: took upstream's permission-handling
simplification (e26db606); re-applied the RB fcntl improvement
(F_GETFL/F_GETFD/F_SETFL/F_SETFD handling, Linux random_fops xref)
and the is_cpu_feature_detected early-return cleanup. Dropped
test_scheme_perms (deleted by upstream's simplification).
- Makefile: kept upstream's new /dev symlink block (dev/null, ptmx,
random, urandom, zero, tty, stdin/stdout/stderr).
Verified: cargo check clean; 57/57 tests pass (xhcid 35, usbhubd 14,
xhci trb 8); verify-fork-functions.sh --no-fetch base reports all
upstream functions present.
- init: add condition_path_exists so optional-daemon units (dbus, seatd,
thermald, evdevd) are silently skipped when their binary is absent in a
minimal image, instead of emitting [FAILED] 'No such file or directory' on
the bare target. Boot-critical units omit the field and still hard-fail.
- ahcid: an empty ATAPI/optical drive (QEMU's default DVD-ROM, most bare-metal
optical bays) failed READ CAPACITY and logged 4 ERROR lines every boot;
register it with a zero block count as a normal no-media state and drop the
HBA register dump to debug level.
- netstack: a machine with no NIC (bare, or an unsupported NIC) logged an ERROR
and exited non-zero; treat 'no network adapter' as a normal idle state
(info + clean exit).
- dhcpd: cut the socket timeout 30s -> 8s so the network stage fails fast when
no DHCP server answers instead of stalling boot.
For fbbootlog, fbcon and the disk drivers there is no load bearing use
of the fpath output. And for chan relibc already handles both the legacy
and new format.