From d4b2f785058411eb2b3695ac357c3de941be1670 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Wed, 22 May 2024 14:45:19 +0800 Subject: [PATCH] chore: add conversion between `PageError` and `SysError` --- kernel/src/objects/frame.rs | 21 +++++++++++---------- kernel/src/objects/table.rs | 13 +++++-------- kernel/src/vspace/error.rs | 20 ++++++++++++++++++++ kernel/src/vspace/mod.rs | 2 ++ kernel/src/vspace/table.rs | 12 +----------- 5 files changed, 39 insertions(+), 29 deletions(-) create mode 100644 kernel/src/vspace/error.rs diff --git a/kernel/src/objects/frame.rs b/kernel/src/objects/frame.rs index 6551c0a..7c4d7a6 100644 --- a/kernel/src/objects/frame.rs +++ b/kernel/src/objects/frame.rs @@ -1,5 +1,9 @@ use super::{cap::RawCap, Cap, KernelObject}; -use crate::{arch::layout::mmap_phys_to_virt, objects::cap::CapEntry, vspace::*}; +use crate::{ + arch::layout::{mmap_phys_to_virt, PAGE_SIZE}, + objects::cap::CapEntry, + vspace::*, +}; use uapi::{ cap::ObjectType, error::{SysError, SysResult}, @@ -50,8 +54,7 @@ impl<'a> FrameCap<'a> { pub fn mint(ptr: PhysAddr, size: usize, attr: MapAttr, is_device: bool) -> RawCap { let size_bits = size.ilog2() as usize; debug_assert!(size_bits <= FrameCap::FRAME_SIZE_BITS); - - // NOTE: we are not checking frame size + assert!(size >= PAGE_SIZE); let arg0 = 0 | ((attr.bits() & Self::VM_RIGHT_MASK) << Self::VM_RIGHT_OFFSET) @@ -126,14 +129,10 @@ impl<'a> FrameCap<'a> { self.as_object_mut().fill(fill.unwrap_or(0)); } - pub fn map_page(&self, root: &mut Table, vaddr: VirtAddr, attr: MapAttr) -> SysResult { + pub fn map(&self, root: &mut Table, vaddr: VirtAddr, attr: MapAttr) -> SysResult { let masked_attr = attr & self.attr(); - root.map(vaddr, self.cte.cap.get().ptr, masked_attr).map_err(|e| match e { - PageError::AlreadyMapped => SysError::AlreadyMapped, - PageError::MissingEntry => SysError::MissingEntry, - PageError::NotAligned => SysError::InvalidArgument, - })?; + root.map(vaddr, self.cte.cap.get().ptr, masked_attr)?; self.set_mapped_asid(0); self.set_mapped_vaddr(vaddr); @@ -147,11 +146,13 @@ impl<'a> FrameCap<'a> { return Err(SysError::NotMapped); } - match root.lookup_mut(self.mapped_vaddr()) { + match root.lookup_mut(vaddr) { Some(entry) if entry.is_leaf() && entry.paddr() == self.cte.cap.get().ptr => { entry.set_paddr(PhysAddr::default()); entry.set_attr(MapAttr::empty()); + // todo: sfence.vma + self.set_mapped_asid(0); self.set_mapped_vaddr(VirtAddr(0)); Ok(()) diff --git a/kernel/src/objects/table.rs b/kernel/src/objects/table.rs index 1ff287c..d508f89 100644 --- a/kernel/src/objects/table.rs +++ b/kernel/src/objects/table.rs @@ -100,13 +100,8 @@ impl<'a> TableCap<'a> { array.fill(0); } - pub fn map_table(&self, root: &mut Table, vaddr: VirtAddr) -> SysResult { - root.map(vaddr, self.cte.cap.get().ptr, MapAttr::PAGE_TABLE) - .map_err(|e| match e { - PageError::AlreadyMapped => SysError::AlreadyMapped, - PageError::MissingEntry => SysError::MissingEntry, - PageError::NotAligned => SysError::InvalidArgument, - })?; + pub fn map(&self, root: &mut Table, vaddr: VirtAddr) -> SysResult { + root.map(vaddr, self.cte.cap.get().ptr, MapAttr::PAGE_TABLE)?; self.set_mapped_asid(0); self.set_mapped_vaddr(vaddr); @@ -120,11 +115,13 @@ impl<'a> TableCap<'a> { return Err(SysError::NotMapped); } - match root.lookup_mut(self.mapped_vaddr()) { + match root.lookup_mut(vaddr) { Some(entry) if !entry.is_leaf() && entry.paddr() == self.cte.cap.get().ptr => { entry.set_paddr(PhysAddr::default()); entry.set_attr(MapAttr::empty()); + // todo: sfence.vma + self.set_mapped_asid(0); self.set_mapped_vaddr(VirtAddr(0)); Ok(()) diff --git a/kernel/src/vspace/error.rs b/kernel/src/vspace/error.rs new file mode 100644 index 0000000..56dece4 --- /dev/null +++ b/kernel/src/vspace/error.rs @@ -0,0 +1,20 @@ +use uapi::error::SysError; + +#[derive(Debug)] +pub enum PageError { + AlreadyMapped, + MissingEntry, + NotAligned, +} + +pub type PageResult = Result; + +impl From for SysError { + fn from(e: PageError) -> Self { + match e { + PageError::AlreadyMapped => SysError::AlreadyMapped, + PageError::MissingEntry => SysError::MissingEntry, + PageError::NotAligned => SysError::InvalidArgument, + } + } +} diff --git a/kernel/src/vspace/mod.rs b/kernel/src/vspace/mod.rs index c48cebb..10db790 100644 --- a/kernel/src/vspace/mod.rs +++ b/kernel/src/vspace/mod.rs @@ -1,9 +1,11 @@ mod addr; mod entry; +mod error; mod level; mod table; pub use addr::*; pub use entry::*; +pub use error::*; pub use level::*; pub use table::*; diff --git a/kernel/src/vspace/table.rs b/kernel/src/vspace/table.rs index 863f898..86e1023 100644 --- a/kernel/src/vspace/table.rs +++ b/kernel/src/vspace/table.rs @@ -1,16 +1,6 @@ -use super::{MapAttr, TableLevel}; -use core::fmt::Debug; +use super::{MapAttr, PageResult, TableLevel}; use utils::addr::{PhysAddr, VirtAddr}; -#[derive(Debug)] -pub enum PageError { - AlreadyMapped, - MissingEntry, - NotAligned, -} - -pub type PageResult = Result; - pub trait TableOps<'a, T: TableLevel> { /// # Safety /// `location` must be a page-aligned virtual address and will not be dropped.