mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-25 10:23:23 +00:00
Fix mmap flags
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
901cbebe44
commit
6b87ff03ac
@ -1,13 +1,25 @@
|
|||||||
|
//! Definition of MMap flags, conforming to the linux mmap interface:
|
||||||
|
//! https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||||
|
//!
|
||||||
|
//! The first 4 bits of the flag value represents the type of memory map,
|
||||||
|
//! while other bits are used as memory map flags.
|
||||||
|
//!
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
// The definition of MMapFlags is from occlum
|
// The map type mask
|
||||||
|
const MAP_TYPE: u32 = 0xf;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub enum MMapType {
|
||||||
|
MapFile = 0x0,
|
||||||
|
MapShared = 0x1,
|
||||||
|
MapPrivate = 0x2,
|
||||||
|
MapSharedValidate = 0x3,
|
||||||
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct MMapFlags : u32 {
|
pub struct MMapFlags : u32 {
|
||||||
const MAP_FILE = 0x0;
|
|
||||||
const MAP_SHARED = 0x1;
|
|
||||||
const MAP_PRIVATE = 0x2;
|
|
||||||
const MAP_SHARED_VALIDATE = 0x3;
|
|
||||||
const MAP_TYPE = 0xf;
|
|
||||||
const MAP_FIXED = 0x10;
|
const MAP_FIXED = 0x10;
|
||||||
const MAP_ANONYMOUS = 0x20;
|
const MAP_ANONYMOUS = 0x20;
|
||||||
const MAP_GROWSDOWN = 0x100;
|
const MAP_GROWSDOWN = 0x100;
|
||||||
@ -24,11 +36,42 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u64> for MMapFlags {
|
#[derive(Debug)]
|
||||||
|
pub struct MMapOption {
|
||||||
|
typ: MMapType,
|
||||||
|
flags: MMapFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u64> for MMapOption {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(value: u64) -> Result<Self> {
|
fn try_from(value: u64) -> Result<Self> {
|
||||||
MMapFlags::from_bits(value as u32)
|
let typ_raw = value as u32 & MAP_TYPE;
|
||||||
.ok_or_else(|| Error::with_message(Errno::EINVAL, "unknown mmap flags"))
|
let flags_raw = value as u32 & !MAP_TYPE;
|
||||||
|
let typ = match typ_raw {
|
||||||
|
0x0 => MMapType::MapFile,
|
||||||
|
0x1 => MMapType::MapShared,
|
||||||
|
0x2 => MMapType::MapPrivate,
|
||||||
|
0x3 => MMapType::MapSharedValidate,
|
||||||
|
_ => return Err(Error::with_message(Errno::EINVAL, "unknown mmap flags")),
|
||||||
|
};
|
||||||
|
if let Some(flags) = MMapFlags::from_bits(flags_raw) {
|
||||||
|
Ok(MMapOption {
|
||||||
|
typ: typ,
|
||||||
|
flags: flags,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(Error::with_message(Errno::EINVAL, "unknown mmap flags"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MMapOption {
|
||||||
|
pub fn typ(&self) -> MMapType {
|
||||||
|
self.typ
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flags(&self) -> MMapFlags {
|
||||||
|
self.flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! This mod defines mmap flags and the handler to syscall mmap
|
//! This mod defines mmap flags and the handler to syscall mmap
|
||||||
|
|
||||||
use crate::fs::file_table::FileDescripter;
|
use crate::fs::file_table::FileDescripter;
|
||||||
use crate::process::process_vm::mmap_flags::MMapFlags;
|
use crate::process::process_vm::mmap_flags::{MMapFlags, MMapOption, MMapType};
|
||||||
use crate::vm::perms::VmPerms;
|
use crate::vm::perms::VmPerms;
|
||||||
use crate::vm::vmo::{VmoChildOptions, VmoOptions, VmoRightsOp};
|
use crate::vm::vmo::{VmoChildOptions, VmoOptions, VmoRightsOp};
|
||||||
use crate::{log_syscall_entry, prelude::*};
|
use crate::{log_syscall_entry, prelude::*};
|
||||||
@ -23,12 +23,12 @@ pub fn sys_mmap(
|
|||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
log_syscall_entry!(SYS_MMAP);
|
log_syscall_entry!(SYS_MMAP);
|
||||||
let perms = VmPerm::try_from(perms).unwrap();
|
let perms = VmPerm::try_from(perms).unwrap();
|
||||||
let flags = MMapFlags::try_from(flags).unwrap();
|
let option = MMapOption::try_from(flags).unwrap();
|
||||||
let res = do_sys_mmap(
|
let res = do_sys_mmap(
|
||||||
addr as usize,
|
addr as usize,
|
||||||
len as usize,
|
len as usize,
|
||||||
perms,
|
perms,
|
||||||
flags,
|
option,
|
||||||
fd as _,
|
fd as _,
|
||||||
offset as usize,
|
offset as usize,
|
||||||
)?;
|
)?;
|
||||||
@ -39,13 +39,13 @@ pub fn do_sys_mmap(
|
|||||||
addr: Vaddr,
|
addr: Vaddr,
|
||||||
len: usize,
|
len: usize,
|
||||||
vm_perm: VmPerm,
|
vm_perm: VmPerm,
|
||||||
flags: MMapFlags,
|
option: MMapOption,
|
||||||
fd: FileDescripter,
|
fd: FileDescripter,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) -> Result<Vaddr> {
|
) -> Result<Vaddr> {
|
||||||
debug!(
|
debug!(
|
||||||
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}, flags = {:?}, fd = {}, offset = 0x{:x}",
|
"addr = 0x{:x}, len = 0x{:x}, perms = {:?}, option = {:?}, fd = {}, offset = 0x{:x}",
|
||||||
addr, len, vm_perm, flags, fd, offset
|
addr, len, vm_perm, option, fd, offset
|
||||||
);
|
);
|
||||||
|
|
||||||
let len = len.align_up(PAGE_SIZE);
|
let len = len.align_up(PAGE_SIZE);
|
||||||
@ -55,11 +55,10 @@ pub fn do_sys_mmap(
|
|||||||
}
|
}
|
||||||
let perms = VmPerms::from(vm_perm);
|
let perms = VmPerms::from(vm_perm);
|
||||||
|
|
||||||
if flags.contains(MMapFlags::MAP_ANONYMOUS) {
|
if option.flags().contains(MMapFlags::MAP_ANONYMOUS) {
|
||||||
// only support map anonymous areas.
|
mmap_anonymous_vmo(addr, len, offset, perms, option)
|
||||||
mmap_anonymous_vmo(addr, len, offset, perms, flags)
|
|
||||||
} else {
|
} else {
|
||||||
mmap_filebacked_vmo(addr, fd, len, offset, perms, flags)
|
mmap_filebacked_vmo(addr, fd, len, offset, perms, option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,23 +67,23 @@ fn mmap_anonymous_vmo(
|
|||||||
len: usize,
|
len: usize,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
perms: VmPerms,
|
perms: VmPerms,
|
||||||
flags: MMapFlags,
|
option: MMapOption,
|
||||||
) -> Result<Vaddr> {
|
) -> Result<Vaddr> {
|
||||||
// TODO: how to respect flags?
|
assert!(option.flags().contains(MMapFlags::MAP_ANONYMOUS));
|
||||||
if flags.complement().contains(MMapFlags::MAP_ANONYMOUS)
|
|
||||||
| flags.complement().contains(MMapFlags::MAP_PRIVATE)
|
|
||||||
{
|
|
||||||
panic!("Unsupported mmap flags {:?} now", flags);
|
|
||||||
}
|
|
||||||
debug_assert!(offset == 0);
|
debug_assert!(offset == 0);
|
||||||
|
|
||||||
|
// TODO: implement features presented by other flags.
|
||||||
|
if option.typ() != MMapType::MapPrivate {
|
||||||
|
panic!("Unsupported mmap flags {:?} now", option);
|
||||||
|
}
|
||||||
|
|
||||||
let vmo_options: VmoOptions<Rights> = VmoOptions::new(len);
|
let vmo_options: VmoOptions<Rights> = VmoOptions::new(len);
|
||||||
let vmo = vmo_options.alloc()?;
|
let vmo = vmo_options.alloc()?;
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let root_vmar = current.root_vmar();
|
let root_vmar = current.root_vmar();
|
||||||
|
|
||||||
let mut vmar_map_options = root_vmar.new_map(vmo, perms)?;
|
let mut vmar_map_options = root_vmar.new_map(vmo, perms)?;
|
||||||
if flags.contains(MMapFlags::MAP_FIXED) {
|
if option.flags().contains(MMapFlags::MAP_FIXED) {
|
||||||
vmar_map_options = vmar_map_options.offset(addr).can_overwrite(true);
|
vmar_map_options = vmar_map_options.offset(addr).can_overwrite(true);
|
||||||
}
|
}
|
||||||
let map_addr = vmar_map_options.build()?;
|
let map_addr = vmar_map_options.build()?;
|
||||||
@ -98,7 +97,7 @@ fn mmap_filebacked_vmo(
|
|||||||
len: usize,
|
len: usize,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
perms: VmPerms,
|
perms: VmPerms,
|
||||||
flags: MMapFlags,
|
option: MMapOption,
|
||||||
) -> Result<Vaddr> {
|
) -> Result<Vaddr> {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
let page_cache_vmo = {
|
let page_cache_vmo = {
|
||||||
@ -111,7 +110,7 @@ fn mmap_filebacked_vmo(
|
|||||||
))?
|
))?
|
||||||
};
|
};
|
||||||
|
|
||||||
let vmo = if flags.contains(MMapFlags::MAP_PRIVATE) {
|
let vmo = if option.typ() == MMapType::MapPrivate {
|
||||||
// map private
|
// map private
|
||||||
VmoChildOptions::new_cow(page_cache_vmo, offset..(offset + len)).alloc()?
|
VmoChildOptions::new_cow(page_cache_vmo, offset..(offset + len)).alloc()?
|
||||||
} else {
|
} else {
|
||||||
@ -123,7 +122,7 @@ fn mmap_filebacked_vmo(
|
|||||||
let root_vmar = current.root_vmar();
|
let root_vmar = current.root_vmar();
|
||||||
let vm_map_options = {
|
let vm_map_options = {
|
||||||
let mut options = root_vmar.new_map(vmo.to_dyn(), perms)?;
|
let mut options = root_vmar.new_map(vmo.to_dyn(), perms)?;
|
||||||
if flags.contains(MMapFlags::MAP_FIXED) {
|
if option.flags().contains(MMapFlags::MAP_FIXED) {
|
||||||
options = options.offset(addr).can_overwrite(true);
|
options = options.offset(addr).can_overwrite(true);
|
||||||
}
|
}
|
||||||
options
|
options
|
||||||
|
Reference in New Issue
Block a user