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,
max_size: self.max_size,
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;
debug_assert!(map_addr % PAGE_SIZE == 0);
root_vmar
.new_map(self.vmo.dup().to_dyn(), perms)?
.new_map(self.max_size, perms)?
.offset(map_addr)
.vmo(self.vmo.dup().to_dyn())
};
vmar_map_options.build()?;

View File

@ -3,15 +3,11 @@
use core::ops::Range;
use aster_rights::Rights;
use ostd::mm::VmIo;
use super::{
options::VmarChildOptions, vm_mapping::VmarMapOptions, VmPerms, Vmar, VmarRightsOp, Vmar_,
};
use crate::{
prelude::*,
vm::{page_fault_handler::PageFaultHandler, vmo::Vmo},
};
use crate::{prelude::*, vm::page_fault_handler::PageFaultHandler};
impl Vmar<Rights> {
/// Creates a root VMAR.
@ -21,7 +17,7 @@ impl Vmar<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
///
@ -30,13 +26,18 @@ impl Vmar<Rights> {
/// use aster_nix::vm::{PAGE_SIZE, Vmar, VmoOptions};
///
/// 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 real_vaddr = vmar
/// // Map the VMO to create a read-only mapping
/// .new_map(vmo, VmPerms::READ)
/// // Create a 4 * PAGE_SIZE bytes, read-only mapping
/// .new_map(PAGE_SIZE * 4, VmPerms::READ)
/// // Provide an optional offset for the mapping inside the VMAR
/// .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()
/// .unwrap();
/// assert!(real_vaddr == target_vaddr);
@ -56,13 +57,9 @@ impl Vmar<Rights> {
/// Memory permissions may be changed through the `protect` method,
/// which ensures that any updated memory permissions do not go beyond
/// the access rights of the underlying VMOs.
pub fn new_map(
&self,
vmo: Vmo<Rights>,
perms: VmPerms,
) -> Result<VmarMapOptions<Rights, Rights>> {
pub fn new_map(&self, size: usize, perms: VmPerms) -> Result<VmarMapOptions<Rights, Rights>> {
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.
@ -98,10 +95,6 @@ impl Vmar<Rights> {
///
/// The VMAR must have the rights corresponding to the specified memory
/// 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<()> {
self.check_rights(perms.into())?;
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> {
fn handle_page_fault(
&self,

View File

@ -179,22 +179,12 @@ mod test {
let map_offset = 0x1000_0000;
let vmo_dup = vmo.dup().unwrap();
root_vmar
.new_map(vmo_dup, perms)
.new_map(PAGE_SIZE, perms)
.unwrap()
.vmo(vmo_dup)
.offset(map_offset)
.build()
.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]
@ -208,8 +198,9 @@ mod test {
let perms = VmPerms::READ;
let vmo_dup = vmo.dup().unwrap();
root_vmar
.new_map(vmo_dup, perms)
.new_map(PAGE_SIZE, perms)
.unwrap()
.vmo(vmo_dup)
.offset(OFFSET)
.build()
.unwrap();

View File

@ -4,15 +4,11 @@ use core::ops::Range;
use aster_rights::{Dup, Rights, TRightSet, TRights};
use aster_rights_proc::require;
use ostd::mm::VmIo;
use super::{
options::VmarChildOptions, vm_mapping::VmarMapOptions, VmPerms, Vmar, VmarRightsOp, Vmar_,
};
use crate::{
prelude::*,
vm::{page_fault_handler::PageFaultHandler, vmo::Vmo},
};
use crate::{prelude::*, vm::page_fault_handler::PageFaultHandler};
impl<R: TRights> Vmar<TRightSet<R>> {
/// Creates a root VMAR.
@ -26,7 +22,7 @@ impl<R: TRights> Vmar<TRightSet<R>> {
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
///
@ -35,13 +31,18 @@ impl<R: TRights> Vmar<TRightSet<R>> {
/// use aster_nix::vm::{PAGE_SIZE, Vmar, VmoOptions};
///
/// 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 real_vaddr = vmar
/// // Map the VMO to create a read-only mapping
/// .new_map(vmo, VmPerms::READ)
/// // Create a 4 * PAGE_SIZE bytes, read-only mapping
/// .new_map(PAGE_SIZE * 4, VmPerms::READ)
/// // Provide an optional offset for the mapping inside the VMAR
/// .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()
/// .unwrap();
/// assert!(real_vaddr == target_vaddr);
@ -64,11 +65,11 @@ impl<R: TRights> Vmar<TRightSet<R>> {
#[require(R > Dup)]
pub fn new_map(
&self,
vmo: Vmo<Rights>,
size: usize,
perms: VmPerms,
) -> Result<VmarMapOptions<TRightSet<R>, Rights>> {
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.
@ -105,10 +106,6 @@ impl<R: TRights> Vmar<TRightSet<R>> {
///
/// The VMAR must have the rights corresponding to the specified memory
/// 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<()> {
self.check_rights(perms.into())?;
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>> {
fn handle_page_fault(
&self,