Fix: fork vmo should be resizable if parent is resizable

This commit is contained in:
Jianfeng Jiang
2023-07-04 11:18:23 +08:00
committed by Tate, Hongliang Tian
parent 149e169b2c
commit 38a78cc3ce
2 changed files with 38 additions and 11 deletions

View File

@ -12,7 +12,7 @@ use crate::vm::{
use super::{is_intersected, Vmar, Vmar_};
use crate::vm::perms::VmPerms;
use crate::vm::vmar::Rights;
use crate::vm::vmo::VmoRightsOp;
use crate::vm::vmo::{VmoFlags, VmoRightsOp};
/// A VmMapping represents mapping a vmo into a vmar.
/// A vmar can has multiple VmMappings, which means multiple vmos are mapped to a vmar.
@ -276,7 +276,14 @@ impl VmMapping {
"fork vmo, parent size = 0x{:x}, map_to_addr = 0x{:x}",
vmo_size, map_to_addr
);
let child_vmo = VmoChildOptions::new_cow(parent_vmo, 0..vmo_size).alloc()?;
let child_vmo = {
let parent_flags = parent_vmo.flags();
let mut options = VmoChildOptions::new_cow(parent_vmo, 0..vmo_size);
if parent_flags.contains(VmoFlags::RESIZABLE) {
options = options.flags(VmoFlags::RESIZABLE);
}
options.alloc()?
};
let parent_vmar = new_parent.upgrade().unwrap();
let vm_space = parent_vmar.vm_space();

View File

@ -293,7 +293,34 @@ impl VmoChildOptions<Rights, VmoSliceChild> {
}
}
impl<R> VmoChildOptions<R, VmoSliceChild> {
/// Flags that a VMO child inherits from its parent.
pub const PARENT_FLAGS_MASK: VmoFlags =
VmoFlags::from_bits(VmoFlags::CONTIGUOUS.bits | VmoFlags::DMA.bits).unwrap();
/// Flags that a VMO child may differ from its parent.
pub const CHILD_FLAGS_MASK: VmoFlags = VmoFlags::empty();
/// Sets the VMO flags.
///
/// Only the flags among `Self::CHILD_FLAGS_MASK` may be set through this
/// method.
///
/// To set `VmoFlags::RESIZABLE`, the child must be COW.
///
/// The default value is `VmoFlags::empty()`.
pub fn flags(mut self, flags: VmoFlags) -> Self {
let inherited_flags = self.flags & Self::PARENT_FLAGS_MASK;
self.flags = inherited_flags | (flags & Self::CHILD_FLAGS_MASK);
self
}
}
impl<R> VmoChildOptions<R, VmoCowChild> {
/// Flags that a VMO child inherits from its parent.
pub const PARENT_FLAGS_MASK: VmoFlags =
VmoFlags::from_bits(VmoFlags::CONTIGUOUS.bits | VmoFlags::DMA.bits).unwrap();
/// Flags that a VMO child may differ from its parent.
pub const CHILD_FLAGS_MASK: VmoFlags = VmoFlags::RESIZABLE;
/// Creates a default set of options for creating a copy-on-write (COW)
/// VMO child.
///
@ -311,14 +338,6 @@ impl<R> VmoChildOptions<R, VmoCowChild> {
marker: PhantomData,
}
}
}
impl<R, C> VmoChildOptions<R, C> {
/// Flags that a VMO child inherits from its parent.
pub const PARENT_FLAGS_MASK: VmoFlags =
VmoFlags::from_bits(VmoFlags::CONTIGUOUS.bits | VmoFlags::DMA.bits).unwrap();
/// Flags that a VMO child may differ from its parent.
pub const CHILD_FLAGS_MASK: VmoFlags = VmoFlags::RESIZABLE;
/// Sets the VMO flags.
///
@ -329,7 +348,8 @@ impl<R, C> VmoChildOptions<R, C> {
///
/// The default value is `VmoFlags::empty()`.
pub fn flags(mut self, flags: VmoFlags) -> Self {
self.flags = flags & Self::CHILD_FLAGS_MASK;
let inherited_flags = self.flags & Self::PARENT_FLAGS_MASK;
self.flags = inherited_flags | (flags & Self::CHILD_FLAGS_MASK);
self
}
}