Modify the Vmar APIs to fit the modifications of VmMapping

This commit is contained in:
Chen Chengjun
2024-08-12 16:12:05 +08:00
committed by Tate, Hongliang Tian
parent ff842cb778
commit 9f9169adfe
4 changed files with 31 additions and 77 deletions

View File

@ -115,7 +115,7 @@ impl Clone for InitStack {
initial_top: self.initial_top, initial_top: self.initial_top,
max_size: self.max_size, max_size: self.max_size,
pos: self.pos.clone(), pos: self.pos.clone(),
vmo: self.vmo.new_cow_child(0..self.max_size).alloc().unwrap(), vmo: self.vmo.dup(),
} }
} }
} }
@ -149,8 +149,9 @@ impl InitStack {
let map_addr = self.initial_top - self.max_size; let map_addr = self.initial_top - self.max_size;
debug_assert!(map_addr % PAGE_SIZE == 0); debug_assert!(map_addr % PAGE_SIZE == 0);
root_vmar root_vmar
.new_map(self.vmo.dup().to_dyn(), perms)? .new_map(self.max_size, perms)?
.offset(map_addr) .offset(map_addr)
.vmo(self.vmo.dup().to_dyn())
}; };
vmar_map_options.build()?; vmar_map_options.build()?;

View File

@ -3,15 +3,11 @@
use core::ops::Range; use core::ops::Range;
use aster_rights::Rights; use aster_rights::Rights;
use ostd::mm::VmIo;
use super::{ use super::{
options::VmarChildOptions, vm_mapping::VmarMapOptions, VmPerms, Vmar, VmarRightsOp, Vmar_, options::VmarChildOptions, vm_mapping::VmarMapOptions, VmPerms, Vmar, VmarRightsOp, Vmar_,
}; };
use crate::{ use crate::{prelude::*, vm::page_fault_handler::PageFaultHandler};
prelude::*,
vm::{page_fault_handler::PageFaultHandler, vmo::Vmo},
};
impl Vmar<Rights> { impl Vmar<Rights> {
/// Creates a root VMAR. /// Creates a root VMAR.
@ -21,7 +17,7 @@ impl Vmar<Rights> {
Self(inner, rights) Self(inner, rights)
} }
/// Maps the given VMO into the VMAR through a set of VMAR mapping options. /// Creates a mapping into the VMAR through a set of VMAR mapping options.
/// ///
/// # Example /// # Example
/// ///
@ -30,13 +26,18 @@ impl Vmar<Rights> {
/// use aster_nix::vm::{PAGE_SIZE, Vmar, VmoOptions}; /// use aster_nix::vm::{PAGE_SIZE, Vmar, VmoOptions};
/// ///
/// let vmar = Vmar::new().unwrap(); /// let vmar = Vmar::new().unwrap();
/// let vmo = VmoOptions::new(PAGE_SIZE).alloc().unwrap(); /// let vmo = VmoOptions::new(10 * PAGE_SIZE).alloc().unwrap();
/// let target_vaddr = 0x1234000; /// let target_vaddr = 0x1234000;
/// let real_vaddr = vmar /// let real_vaddr = vmar
/// // Map the VMO to create a read-only mapping /// // Create a 4 * PAGE_SIZE bytes, read-only mapping
/// .new_map(vmo, VmPerms::READ) /// .new_map(PAGE_SIZE * 4, VmPerms::READ)
/// // Provide an optional offset for the mapping inside the VMAR /// // Provide an optional offset for the mapping inside the VMAR
/// .offset(target_vaddr) /// .offset(target_vaddr)
/// // Specify an optional binding VMO.
/// .vmo(vmo)
/// // Provide an optional offset to indicate the corresponding offset
/// // in the VMO for the mapping
/// .vmo_offset(2 * PAGE_SIZE)
/// .build() /// .build()
/// .unwrap(); /// .unwrap();
/// assert!(real_vaddr == target_vaddr); /// assert!(real_vaddr == target_vaddr);
@ -56,13 +57,9 @@ impl Vmar<Rights> {
/// Memory permissions may be changed through the `protect` method, /// Memory permissions may be changed through the `protect` method,
/// which ensures that any updated memory permissions do not go beyond /// which ensures that any updated memory permissions do not go beyond
/// the access rights of the underlying VMOs. /// the access rights of the underlying VMOs.
pub fn new_map( pub fn new_map(&self, size: usize, perms: VmPerms) -> Result<VmarMapOptions<Rights, Rights>> {
&self,
vmo: Vmo<Rights>,
perms: VmPerms,
) -> Result<VmarMapOptions<Rights, Rights>> {
let dup_self = self.dup()?; let dup_self = self.dup()?;
Ok(VmarMapOptions::new(dup_self, vmo, perms)) Ok(VmarMapOptions::new(dup_self, size, perms))
} }
/// Creates a new child VMAR through a set of VMAR child options. /// Creates a new child VMAR through a set of VMAR child options.
@ -98,10 +95,6 @@ impl Vmar<Rights> {
/// ///
/// The VMAR must have the rights corresponding to the specified memory /// The VMAR must have the rights corresponding to the specified memory
/// permissions. /// permissions.
///
/// The mappings overlapped with the specified range must be backed by
/// VMOs whose rights contain the rights corresponding to the specified
/// memory permissions.
pub fn protect(&self, perms: VmPerms, range: Range<usize>) -> Result<()> { pub fn protect(&self, perms: VmPerms, range: Range<usize>) -> Result<()> {
self.check_rights(perms.into())?; self.check_rights(perms.into())?;
self.0.protect(perms, range) self.0.protect(perms, range)
@ -150,20 +143,6 @@ impl Vmar<Rights> {
} }
} }
impl VmIo for Vmar<Rights> {
fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> ostd::Result<()> {
self.check_rights(Rights::READ)?;
self.0.read(offset, buf)?;
Ok(())
}
fn write_bytes(&self, offset: usize, buf: &[u8]) -> ostd::Result<()> {
self.check_rights(Rights::WRITE)?;
self.0.write(offset, buf)?;
Ok(())
}
}
impl PageFaultHandler for Vmar<Rights> { impl PageFaultHandler for Vmar<Rights> {
fn handle_page_fault( fn handle_page_fault(
&self, &self,

View File

@ -179,22 +179,12 @@ mod test {
let map_offset = 0x1000_0000; let map_offset = 0x1000_0000;
let vmo_dup = vmo.dup().unwrap(); let vmo_dup = vmo.dup().unwrap();
root_vmar root_vmar
.new_map(vmo_dup, perms) .new_map(PAGE_SIZE, perms)
.unwrap() .unwrap()
.vmo(vmo_dup)
.offset(map_offset) .offset(map_offset)
.build() .build()
.unwrap(); .unwrap();
root_vmar.write_val(map_offset, &100u8).unwrap();
assert!(root_vmar.read_val::<u8>(map_offset).unwrap() == 100);
let another_map_offset = 0x1100_0000;
let vmo_dup = vmo.dup().unwrap();
root_vmar
.new_map(vmo_dup, perms)
.unwrap()
.offset(another_map_offset)
.build()
.unwrap();
assert!(root_vmar.read_val::<u8>(another_map_offset).unwrap() == 100);
} }
#[ktest] #[ktest]
@ -208,8 +198,9 @@ mod test {
let perms = VmPerms::READ; let perms = VmPerms::READ;
let vmo_dup = vmo.dup().unwrap(); let vmo_dup = vmo.dup().unwrap();
root_vmar root_vmar
.new_map(vmo_dup, perms) .new_map(PAGE_SIZE, perms)
.unwrap() .unwrap()
.vmo(vmo_dup)
.offset(OFFSET) .offset(OFFSET)
.build() .build()
.unwrap(); .unwrap();

View File

@ -4,15 +4,11 @@ use core::ops::Range;
use aster_rights::{Dup, Rights, TRightSet, TRights}; use aster_rights::{Dup, Rights, TRightSet, TRights};
use aster_rights_proc::require; use aster_rights_proc::require;
use ostd::mm::VmIo;
use super::{ use super::{
options::VmarChildOptions, vm_mapping::VmarMapOptions, VmPerms, Vmar, VmarRightsOp, Vmar_, options::VmarChildOptions, vm_mapping::VmarMapOptions, VmPerms, Vmar, VmarRightsOp, Vmar_,
}; };
use crate::{ use crate::{prelude::*, vm::page_fault_handler::PageFaultHandler};
prelude::*,
vm::{page_fault_handler::PageFaultHandler, vmo::Vmo},
};
impl<R: TRights> Vmar<TRightSet<R>> { impl<R: TRights> Vmar<TRightSet<R>> {
/// Creates a root VMAR. /// Creates a root VMAR.
@ -26,7 +22,7 @@ impl<R: TRights> Vmar<TRightSet<R>> {
Self(inner, TRightSet(rights)) Self(inner, TRightSet(rights))
} }
/// Maps the given VMO into the VMAR through a set of VMAR mapping options. /// Creates a mapping into the VMAR through a set of VMAR mapping options.
/// ///
/// # Example /// # Example
/// ///
@ -35,13 +31,18 @@ impl<R: TRights> Vmar<TRightSet<R>> {
/// use aster_nix::vm::{PAGE_SIZE, Vmar, VmoOptions}; /// use aster_nix::vm::{PAGE_SIZE, Vmar, VmoOptions};
/// ///
/// let vmar = Vmar::<RightsWrapper<Full>>::new().unwrap(); /// let vmar = Vmar::<RightsWrapper<Full>>::new().unwrap();
/// let vmo = VmoOptions::new(PAGE_SIZE).alloc().unwrap(); /// let vmo = VmoOptions::new(10 * PAGE_SIZE).alloc().unwrap();
/// let target_vaddr = 0x1234000; /// let target_vaddr = 0x1234000;
/// let real_vaddr = vmar /// let real_vaddr = vmar
/// // Map the VMO to create a read-only mapping /// // Create a 4 * PAGE_SIZE bytes, read-only mapping
/// .new_map(vmo, VmPerms::READ) /// .new_map(PAGE_SIZE * 4, VmPerms::READ)
/// // Provide an optional offset for the mapping inside the VMAR /// // Provide an optional offset for the mapping inside the VMAR
/// .offset(target_vaddr) /// .offset(target_vaddr)
/// // Specify an optional binding VMO.
/// .vmo(vmo)
/// // Provide an optional offset to indicate the corresponding offset
/// // in the VMO for the mapping
/// .vmo_offset(2 * PAGE_SIZE)
/// .build() /// .build()
/// .unwrap(); /// .unwrap();
/// assert!(real_vaddr == target_vaddr); /// assert!(real_vaddr == target_vaddr);
@ -64,11 +65,11 @@ impl<R: TRights> Vmar<TRightSet<R>> {
#[require(R > Dup)] #[require(R > Dup)]
pub fn new_map( pub fn new_map(
&self, &self,
vmo: Vmo<Rights>, size: usize,
perms: VmPerms, perms: VmPerms,
) -> Result<VmarMapOptions<TRightSet<R>, Rights>> { ) -> Result<VmarMapOptions<TRightSet<R>, Rights>> {
let dup_self = self.dup()?; let dup_self = self.dup()?;
Ok(VmarMapOptions::new(dup_self, vmo, perms)) Ok(VmarMapOptions::new(dup_self, size, perms))
} }
/// Creates a new child VMAR through a set of VMAR child options. /// Creates a new child VMAR through a set of VMAR child options.
@ -105,10 +106,6 @@ impl<R: TRights> Vmar<TRightSet<R>> {
/// ///
/// The VMAR must have the rights corresponding to the specified memory /// The VMAR must have the rights corresponding to the specified memory
/// permissions. /// permissions.
///
/// The mappings overlapped with the specified range must be backed by
/// VMOs whose rights contain the rights corresponding to the specified
/// memory permissions.
pub fn protect(&self, perms: VmPerms, range: Range<usize>) -> Result<()> { pub fn protect(&self, perms: VmPerms, range: Range<usize>) -> Result<()> {
self.check_rights(perms.into())?; self.check_rights(perms.into())?;
self.0.protect(perms, range) self.0.protect(perms, range)
@ -171,20 +168,6 @@ impl<R: TRights> Vmar<TRightSet<R>> {
} }
} }
impl<R: TRights> VmIo for Vmar<TRightSet<R>> {
fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> ostd::Result<()> {
self.check_rights(Rights::READ)?;
self.0.read(offset, buf)?;
Ok(())
}
fn write_bytes(&self, offset: usize, buf: &[u8]) -> ostd::Result<()> {
self.check_rights(Rights::WRITE)?;
self.0.write(offset, buf)?;
Ok(())
}
}
impl<R: TRights> PageFaultHandler for Vmar<TRightSet<R>> { impl<R: TRights> PageFaultHandler for Vmar<TRightSet<R>> {
fn handle_page_fault( fn handle_page_fault(
&self, &self,