diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index b318a660..35f9a8da 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -6,7 +6,6 @@ #![no_std] #![no_main] #![deny(unsafe_code)] -#![expect(incomplete_features)] #![feature(btree_cursors)] #![feature(btree_extract_if)] #![feature(debug_closure_helpers)] @@ -22,10 +21,6 @@ #![feature(negative_impls)] #![feature(panic_can_unwind)] #![feature(register_tool)] -// FIXME: This feature is used to support vm capbility now as a work around. -// Since this is an incomplete feature, use this feature is unsafe. -// We should find a proper method to replace this feature with min_specialization, which is a sound feature. -#![feature(specialization)] #![feature(step_trait)] #![feature(trait_alias)] #![feature(trait_upcasting)] diff --git a/kernel/src/vm/vmar/dyn_cap.rs b/kernel/src/vm/vmar/dyn_cap.rs index e6c98ee2..8dad1af6 100644 --- a/kernel/src/vm/vmar/dyn_cap.rs +++ b/kernel/src/vm/vmar/dyn_cap.rs @@ -109,7 +109,7 @@ impl Vmar { /// # Access rights /// /// The method requires the Read right. - pub fn fork_from(vmar: &Vmar) -> Result { + pub fn fork_from(vmar: &Self) -> Result { vmar.check_rights(Rights::READ)?; let vmar_ = vmar.0.new_fork_root()?; Ok(Vmar(vmar_, Rights::all())) diff --git a/kernel/src/vm/vmar/mod.rs b/kernel/src/vm/vmar/mod.rs index e6453585..a0d0efbd 100644 --- a/kernel/src/vm/vmar/mod.rs +++ b/kernel/src/vm/vmar/mod.rs @@ -17,7 +17,6 @@ use self::{ interval_set::{Interval, IntervalSet}, vm_mapping::{MappedVmo, VmMapping}, }; -use super::page_fault_handler::PageFaultHandler; use crate::{ prelude::*, process::{Process, ResourceType}, @@ -50,8 +49,15 @@ pub struct Vmar(Arc, R); pub trait VmarRightsOp { /// Returns the access rights. fn rights(&self) -> Rights; + /// Checks whether current rights meet the input `rights`. - fn check_rights(&self, rights: Rights) -> Result<()>; + fn check_rights(&self, rights: Rights) -> Result<()> { + if self.rights().contains(rights) { + Ok(()) + } else { + return_errno_with_message!(Errno::EACCES, "VMAR rights are insufficient"); + } + } } impl PartialEq for Vmar { @@ -60,26 +66,6 @@ impl PartialEq for Vmar { } } -impl VmarRightsOp for Vmar { - default fn rights(&self) -> Rights { - unimplemented!() - } - - default fn check_rights(&self, rights: Rights) -> Result<()> { - if self.rights().contains(rights) { - Ok(()) - } else { - return_errno_with_message!(Errno::EACCES, "Rights check failed"); - } - } -} - -impl PageFaultHandler for Vmar { - default fn handle_page_fault(&self, _page_fault_info: &PageFaultInfo) -> Result<()> { - unimplemented!() - } -} - impl Vmar { /// FIXME: This function should require access control pub fn vm_space(&self) -> &Arc { @@ -608,7 +594,12 @@ impl<'a, R1, R2> VmarMapOptions<'a, R1, R2> { self.handle_page_faults_around = true; self } +} +impl<'a, R1, R2> VmarMapOptions<'a, R1, R2> +where + Vmo: VmoRightsOp, +{ /// Creates the mapping and adds it to the parent VMAR. /// /// All options will be checked at this point. diff --git a/kernel/src/vm/vmar/static_cap.rs b/kernel/src/vm/vmar/static_cap.rs index ba905f3a..1e723404 100644 --- a/kernel/src/vm/vmar/static_cap.rs +++ b/kernel/src/vm/vmar/static_cap.rs @@ -2,7 +2,7 @@ use core::ops::Range; -use aster_rights::{Dup, Rights, TRightSet, TRights, Write}; +use aster_rights::{Dup, Read, Rights, TRightSet, TRights, Write}; use aster_rights_proc::require; use super::{VmPerms, Vmar, VmarMapOptions, VmarRightsOp, Vmar_}; @@ -120,8 +120,8 @@ impl Vmar> { /// # Access rights /// /// The method requires the Read right. - pub fn fork_from(vmar: &Vmar) -> Result { - vmar.check_rights(Rights::READ)?; + #[require(R > Read)] + pub fn fork_from(vmar: &Self) -> Result { let vmar_ = vmar.0.new_fork_root()?; Ok(Vmar(vmar_, TRightSet(R::new()))) } diff --git a/kernel/src/vm/vmo/mod.rs b/kernel/src/vm/vmo/mod.rs index 7d14ad16..3ff249d5 100644 --- a/kernel/src/vm/vmo/mod.rs +++ b/kernel/src/vm/vmo/mod.rs @@ -82,12 +82,12 @@ pub trait VmoRightsOp { /// Returns the access rights. fn rights(&self) -> Rights; - /// Check whether rights is included in self + /// Checks whether current rights meet the input `rights`. fn check_rights(&self, rights: Rights) -> Result<()> { if self.rights().contains(rights) { Ok(()) } else { - return_errno_with_message!(Errno::EINVAL, "vmo rights check failed"); + return_errno_with_message!(Errno::EACCES, "VMO rights are insufficient"); } } @@ -97,21 +97,6 @@ pub trait VmoRightsOp { Self: Sized; } -// We implement this trait for VMO, so we can use functions on type like Vmo without trait bounds. -// FIXME: This requires the incomplete feature specialization, which should be fixed further. -impl VmoRightsOp for Vmo { - default fn rights(&self) -> Rights { - unimplemented!() - } - - default fn to_dyn(self) -> Vmo - where - Self: Sized, - { - unimplemented!() - } -} - bitflags! { /// VMO flags. pub struct VmoFlags: u32 {