mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 11:23:25 +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,
|
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()?;
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user