feat(kernel): per-process budgets (pages, endpoints, notifs, regions) carved from creator, returned on death; init owns pool
This commit is contained in:
@@ -301,6 +301,7 @@ impl<P: Platform> Kernel<P> {
|
||||
Ok(slot) => SyscallOutcome::Complete(SyscallResult::Slot(slot)),
|
||||
Err(e) => {
|
||||
self.endpoints.destroy(id);
|
||||
self.uncharge_object(pid, crate::budget::ENDPOINTS);
|
||||
SyscallOutcome::Complete(SyscallResult::Error(e))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,11 @@ impl<P: Platform> Kernel<P> {
|
||||
|
||||
pub fn create_notification(&mut self, owner: ProcessId) -> Result<NotificationId, KernelError> {
|
||||
self.processes.get(owner)?;
|
||||
self.charge_object(owner, crate::budget::NOTIFICATIONS)?;
|
||||
self.notifications
|
||||
.create(owner)
|
||||
.ok_or(KernelError::NoFreeSlot)
|
||||
.inspect_err(|_| self.uncharge_object(owner, crate::budget::NOTIFICATIONS))
|
||||
}
|
||||
|
||||
pub(crate) fn create_notification_cap(
|
||||
@@ -51,6 +53,7 @@ impl<P: Platform> Kernel<P> {
|
||||
self.grant_cap(pid, Resource::Notification(id), rw_delegate())
|
||||
.inspect_err(|_| {
|
||||
self.notifications.destroy(id);
|
||||
self.uncharge_object(pid, crate::budget::NOTIFICATIONS);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ impl<P: Platform> Kernel<P> {
|
||||
caller_pid: types::id::ProcessId,
|
||||
create_cap: types::bounded::CapSlot,
|
||||
_image: types::address::DataRef,
|
||||
limits: domain::budget::Limits,
|
||||
) -> SyscallOutcome {
|
||||
if let Err(e) = self.check_cap(
|
||||
caller_pid,
|
||||
@@ -50,19 +51,11 @@ impl<P: Platform> Kernel<P> {
|
||||
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
||||
}
|
||||
|
||||
let new_pid = match self
|
||||
.processes
|
||||
.create(domain::capability::CapabilityTable::new(), None)
|
||||
{
|
||||
let new_pid = match self.new_process(Some(caller_pid), limits) {
|
||||
Ok(p) => p,
|
||||
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
};
|
||||
|
||||
if let Err(e) = self.create_address_space(new_pid) {
|
||||
let _ = self.processes.destroy(new_pid);
|
||||
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
||||
}
|
||||
|
||||
match self.grant_cap(
|
||||
caller_pid,
|
||||
domain::resource::Resource::Process(new_pid),
|
||||
@@ -75,9 +68,7 @@ impl<P: Platform> Kernel<P> {
|
||||
) {
|
||||
Ok(slot) => SyscallOutcome::Complete(SyscallResult::Slot(slot)),
|
||||
Err(e) => {
|
||||
// Rollback: destroy orphaned process
|
||||
self.teardown_memory(new_pid);
|
||||
let _ = self.processes.destroy(new_pid);
|
||||
self.destroy_process(new_pid);
|
||||
SyscallOutcome::Complete(SyscallResult::Error(e))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,9 +83,11 @@ impl<P: Platform> Kernel<P> {
|
||||
Syscall::SpawnThread { entry, stack, arg } => {
|
||||
self.handle_spawn_thread(pid, entry, stack, arg)
|
||||
}
|
||||
Syscall::CreateProcess { create_cap, image } => {
|
||||
self.handle_create_process(pid, create_cap, image)
|
||||
}
|
||||
Syscall::CreateProcess {
|
||||
create_cap,
|
||||
image,
|
||||
limits,
|
||||
} => self.handle_create_process(pid, create_cap, image, limits),
|
||||
Syscall::Kill { process } => self.handle_kill(pid, process),
|
||||
Syscall::Revoke { slot } => self.handle_revoke(pid, slot),
|
||||
Syscall::DropCap { slot } => self.handle_drop_cap(pid, slot),
|
||||
|
||||
Reference in New Issue
Block a user