feat(kernel): seL4-style IPC, notifications, status ABI

- badges + Mint, Call/Reply/ReplyRecv w/ gen-checked reply slot
- cap transfer (1/msg, copy, needs Delegate, rechecked at delivery)
- notifications: signal/wait/poll/bind, irq -> notification routing
- WaitAny/WaitForInterrupt removed; a0=status, ErrorCode
- libkos: single ecall primitive, compat wrappers + typed new api
- fix: trap return clobbered user t0 on every trap
- fix: wait queues FIFO, delegate keeps badge, fault cap checked
- docs/ipc.md spec, ipc tests, ipc fuzz, kani ntfn + waitqueue
This commit is contained in:
2026-10-26 20:27:38 +01:00
parent d43421e33e
commit 76f10ff1f1
46 changed files with 3339 additions and 1296 deletions

View File

@@ -11,13 +11,17 @@ impl<P: Platform> Kernel<P> {
to_endpoint: types::bounded::CapSlot,
restrict: types::permission::PermissionSet,
) -> SyscallOutcome {
let (resource, permissions) =
match self.check_cap(caller_pid, slot, types::permission::Permission::Delegate) {
Ok(cap) => (cap.resource().clone(), *cap.permissions()),
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
};
let restricted = permissions.restrict_to(&restrict);
// A copy of the capability itself, so its badge and generation
// travel with it; only the permissions narrow.
let copy = match self.check_cap(caller_pid, slot, types::permission::Permission::Delegate) {
Ok(cap) => domain::capability::Capability::new(
cap.resource().clone(),
cap.permissions().restrict_to(&restrict),
*cap.generation(),
)
.with_badge(cap.badge()),
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
};
let target_pid = match self.check_cap(
caller_pid,
@@ -38,7 +42,11 @@ impl<P: Platform> Kernel<P> {
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
};
if let Err(e) = self.grant_cap(target_pid, resource, restricted) {
let inserted = self
.processes
.get_mut(target_pid)
.and_then(|p| p.capabilities_mut().insert(copy));
if let Err(e) = inserted {
return SyscallOutcome::Complete(SyscallResult::Error(e));
}