mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 03:13:23 +00:00
Modify the Vmar APIs to fit the modifications of VmMapping
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
ff842cb778
commit
9f9169adfe
@ -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()?;
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user