| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- use super::{define_syscall32, register_syscall, MapArgument, MapArgumentImpl};
- use crate::{
- kernel::{
- constants::{UserMmapFlags, UserMmapProtocol},
- mem::{Mapping, Permission},
- task::Thread,
- },
- prelude::*,
- };
- use bindings::{EINVAL, ENOMEM};
- use eonix_mm::address::{Addr as _, AddrOps as _, VAddr};
- use eonix_runtime::task::Task;
- /// Check whether we are doing an implemented function.
- /// If `condition` is false, return `Err(err)`.
- fn check_impl(condition: bool, err: u32) -> KResult<()> {
- if !condition {
- Err(err)
- } else {
- Ok(())
- }
- }
- fn do_mmap_pgoff(
- addr: usize,
- len: usize,
- prot: UserMmapProtocol,
- flags: UserMmapFlags,
- fd: u32,
- pgoffset: usize,
- ) -> KResult<usize> {
- let addr = VAddr::from(addr);
- if !addr.is_page_aligned() || len == 0 {
- return Err(EINVAL);
- }
- let len = (len + 0xfff) & !0xfff;
- check_impl(flags.contains(UserMmapFlags::MAP_ANONYMOUS), ENOMEM)?;
- check_impl(flags.contains(UserMmapFlags::MAP_PRIVATE), EINVAL)?;
- if fd != u32::MAX || pgoffset != 0 {
- return Err(EINVAL);
- }
- let mm_list = &Thread::current().process.mm_list;
- // PROT_NONE, we do unmapping.
- if prot.is_empty() {
- Task::block_on(mm_list.unmap(addr, len)).map(|_| 0)?;
- return Ok(0);
- }
- // Otherwise, do mmapping.
- // TODO!!!: If we are doing mmap's in 32-bit mode, we should check whether
- // `addr` is above user reachable memory.
- let addr = if flags.contains(UserMmapFlags::MAP_FIXED) {
- mm_list.mmap_fixed(
- addr,
- len,
- Mapping::Anonymous,
- Permission {
- write: prot.contains(UserMmapProtocol::PROT_WRITE),
- execute: prot.contains(UserMmapProtocol::PROT_EXEC),
- },
- )
- } else {
- mm_list.mmap_hint(
- addr,
- len,
- Mapping::Anonymous,
- Permission {
- write: prot.contains(UserMmapProtocol::PROT_WRITE),
- execute: prot.contains(UserMmapProtocol::PROT_EXEC),
- },
- )
- };
- addr.map(|addr| addr.addr())
- }
- fn do_munmap(addr: usize, len: usize) -> KResult<usize> {
- let addr = VAddr::from(addr);
- if !addr.is_page_aligned() || len == 0 {
- return Err(EINVAL);
- }
- let len = (len + 0xfff) & !0xfff;
- Task::block_on(Thread::current().process.mm_list.unmap(addr, len)).map(|_| 0)
- }
- fn do_brk(addr: usize) -> KResult<usize> {
- let vaddr = if addr == 0 { None } else { Some(VAddr::from(addr)) };
- Ok(Thread::current().process.mm_list.set_break(vaddr).addr())
- }
- impl MapArgument<'_, UserMmapProtocol> for MapArgumentImpl {
- fn map_arg(value: u64) -> UserMmapProtocol {
- UserMmapProtocol::from_bits_truncate(value as u32)
- }
- }
- impl MapArgument<'_, UserMmapFlags> for MapArgumentImpl {
- fn map_arg(value: u64) -> UserMmapFlags {
- UserMmapFlags::from_bits_truncate(value as u32)
- }
- }
- #[allow(unused_variables)]
- fn do_madvise(addr: usize, len: usize, advice: u32) -> KResult<()> {
- Ok(())
- }
- define_syscall32!(sys_brk, do_brk, addr: usize);
- define_syscall32!(sys_munmap, do_munmap, addr: usize, len: usize);
- define_syscall32!(sys_madvise, do_madvise, addr: usize, len: usize, advice: u32);
- define_syscall32!(sys_mmap_pgoff, do_mmap_pgoff,
- addr: usize, len: usize,
- prot: UserMmapProtocol,
- flags: UserMmapFlags,
- fd: u32, pgoffset: usize);
- pub(super) fn register() {
- register_syscall!(0x2d, brk);
- register_syscall!(0x5b, munmap);
- register_syscall!(0xc0, mmap_pgoff);
- register_syscall!(0xdb, madvise);
- }
|