use platform::Platform; use super::{SyscallOutcome, SyscallResult}; use crate::Kernel; impl Kernel

{ pub(crate) fn handle_request_pages( &mut self, pid: types::id::ProcessId, count: types::bounded::PageCount, ) -> SyscallOutcome { let pages = count.value() as usize; if let Some(pm) = &mut self.process_memory[pid.raw() as usize] { if pm.grant(pages).is_err() { return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::OutOfMemory, )); } } else { return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::InvalidProcess(pid), )); } let addr = match self.page_pool.allocate(pages) { Some(a) => a, None => { if let Some(pm) = &mut self.process_memory[pid.raw() as usize] { let _ = pm.release(pages); } return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::OutOfMemory, )); } }; let region = domain::memory::MemoryRegion::new( types::id::RegionId::from_raw(0), pid, addr, count, types::generation::Generation::initial(), ); let region_id = match self.regions.insert(region) { Some(id) => id, None => { self.page_pool.free(addr, pages); if let Some(pm) = &mut self.process_memory[pid.raw() as usize] { let _ = pm.release(pages); } return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::OutOfMemory, )); } }; let slot = match self.grant_cap( pid, domain::resource::Resource::Memory(region_id), types::permission::PermissionSet::empty() .with(types::permission::Permission::Read) .with(types::permission::Permission::Write), ) { Ok(s) => s, Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)), }; SyscallOutcome::Complete(SyscallResult::Slot(slot)) } pub(crate) fn handle_release_pages( &mut self, pid: types::id::ProcessId, addr: types::address::VirtualAddress, count: types::bounded::PageCount, ) -> SyscallOutcome { let pages = count.value() as usize; let phys = types::address::PhysicalAddress::from_raw(addr.raw()); let region_id = match self.regions.find_by_base(pid, phys) { Some((rid, _)) => rid, None => return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::OutOfMemory, )), }; if !self.page_pool.free(phys, pages) { return SyscallOutcome::Complete(SyscallResult::Error( domain::error::KernelError::OutOfMemory, )); } let _ = self.regions.remove(region_id); if let Some(pm) = &mut self.process_memory[pid.raw() as usize] { let _ = pm.release(pages); } SyscallOutcome::Complete(SyscallResult::Ok) } }