diff --git a/services/libs/jinux-std/src/vm/vmar/vm_mapping.rs b/services/libs/jinux-std/src/vm/vmar/vm_mapping.rs index 098df8e8c..d71159fa7 100644 --- a/services/libs/jinux-std/src/vm/vmar/vm_mapping.rs +++ b/services/libs/jinux-std/src/vm/vmar/vm_mapping.rs @@ -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(); diff --git a/services/libs/jinux-std/src/vm/vmo/options.rs b/services/libs/jinux-std/src/vm/vmo/options.rs index 3f68b95f6..4bd58e20f 100644 --- a/services/libs/jinux-std/src/vm/vmo/options.rs +++ b/services/libs/jinux-std/src/vm/vmo/options.rs @@ -293,7 +293,34 @@ impl VmoChildOptions { } } +impl VmoChildOptions { + /// 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 VmoChildOptions { + /// 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 VmoChildOptions { marker: PhantomData, } } -} - -impl VmoChildOptions { - /// 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 VmoChildOptions { /// /// 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 } }