mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 12:06:43 +00:00
101 lines
3.5 KiB
Rust
101 lines
3.5 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
use align_ext::AlignExt;
|
|
|
|
use super::SyscallReturn;
|
|
use crate::prelude::*;
|
|
|
|
pub fn sys_madvise(
|
|
start: Vaddr,
|
|
len: usize,
|
|
behavior: i32,
|
|
ctx: &Context,
|
|
) -> Result<SyscallReturn> {
|
|
let behavior = MadviseBehavior::try_from(behavior)?;
|
|
debug!(
|
|
"start = 0x{:x}, len = 0x{:x}, behavior = {:?}",
|
|
start, len, behavior
|
|
);
|
|
|
|
if start % PAGE_SIZE != 0 {
|
|
return_errno_with_message!(Errno::EINVAL, "the start address should be page aligned");
|
|
}
|
|
if len > isize::MAX as usize {
|
|
return_errno_with_message!(Errno::EINVAL, "len align overflow");
|
|
}
|
|
if len == 0 {
|
|
return Ok(SyscallReturn::Return(0));
|
|
}
|
|
|
|
let len = len.align_up(PAGE_SIZE);
|
|
let end = start.checked_add(len).ok_or(Error::with_message(
|
|
Errno::EINVAL,
|
|
"integer overflow when (start + len)",
|
|
))?;
|
|
match behavior {
|
|
MadviseBehavior::MADV_NORMAL
|
|
| MadviseBehavior::MADV_SEQUENTIAL
|
|
| MadviseBehavior::MADV_WILLNEED => {
|
|
// perform a read at first
|
|
let mut buffer = vec![0u8; len];
|
|
ctx.user_space()
|
|
.read_bytes(start, &mut VmWriter::from(buffer.as_mut_slice()))?;
|
|
}
|
|
MadviseBehavior::MADV_DONTNEED => {
|
|
warn!("MADV_DONTNEED isn't implemented, do nothing for now.");
|
|
}
|
|
MadviseBehavior::MADV_FREE => madv_free(start, end, ctx)?,
|
|
_ => todo!(),
|
|
}
|
|
Ok(SyscallReturn::Return(0))
|
|
}
|
|
|
|
fn madv_free(start: Vaddr, end: Vaddr, ctx: &Context) -> Result<()> {
|
|
let root_vmar = ctx.process.root_vmar();
|
|
let advised_range = start..end;
|
|
let _ = root_vmar.remove_mapping(advised_range);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[repr(i32)]
|
|
#[derive(Debug, Clone, Copy, TryFromInt)]
|
|
#[expect(non_camel_case_types)]
|
|
/// This definition is the same from linux
|
|
pub enum MadviseBehavior {
|
|
MADV_NORMAL = 0, /* no further special treatment */
|
|
MADV_RANDOM = 1, /* expect random page references */
|
|
MADV_SEQUENTIAL = 2, /* expect sequential page references */
|
|
MADV_WILLNEED = 3, /* will need these pages */
|
|
MADV_DONTNEED = 4, /* don't need these pages */
|
|
|
|
/* common parameters: try to keep these consistent across architectures */
|
|
MADV_FREE = 8, /* free pages only if memory pressure */
|
|
MADV_REMOVE = 9, /* remove these pages & resources */
|
|
MADV_DONTFORK = 10, /* don't inherit across fork */
|
|
MADV_DOFORK = 11, /* do inherit across fork */
|
|
MADV_HWPOISON = 100, /* poison a page for testing */
|
|
MADV_SOFT_OFFLINE = 101, /* soft offline page for testing */
|
|
|
|
MADV_MERGEABLE = 12, /* KSM may merge identical pages */
|
|
MADV_UNMERGEABLE = 13, /* KSM may not merge identical pages */
|
|
|
|
MADV_HUGEPAGE = 14, /* Worth backing with hugepages */
|
|
MADV_NOHUGEPAGE = 15, /* Not worth backing with hugepages */
|
|
|
|
MADV_DONTDUMP = 16, /* Explicitly exclude from the core dump,
|
|
overrides the coredump filter bits */
|
|
MADV_DODUMP = 17, /* Clear the MADV_DONTDUMP flag */
|
|
|
|
MADV_WIPEONFORK = 18, /* Zero memory on fork, child only */
|
|
MADV_KEEPONFORK = 19, /* Undo MADV_WIPEONFORK */
|
|
|
|
MADV_COLD = 20, /* deactivate these pages */
|
|
MADV_PAGEOUT = 21, /* reclaim these pages */
|
|
|
|
MADV_POPULATE_READ = 22, /* populate (prefault) page tables readable */
|
|
MADV_POPULATE_WRITE = 23, /* populate (prefault) page tables writable */
|
|
|
|
MADV_DONTNEED_LOCKED = 24, /* like DONTNEED, but drop locked pages too */
|
|
}
|