140fe15e0SLoGin use core::intrinsics::unlikely; 240fe15e0SLoGin 340fe15e0SLoGin use alloc::sync::Arc; 491e9d4abSLoGin use system_error::SystemError; 540fe15e0SLoGin 6ab5c8ca4Slogin use crate::{ 740fe15e0SLoGin arch::MMArch, 86fc066acSJomo ipc::shm::ShmFlags, 940fe15e0SLoGin kerror, 1040fe15e0SLoGin libs::align::{check_aligned, page_align_up}, 1140fe15e0SLoGin mm::MemoryManagementArch, 1291e9d4abSLoGin syscall::Syscall, 13ab5c8ca4Slogin }; 14ab5c8ca4Slogin 1540fe15e0SLoGin use super::{ 1640fe15e0SLoGin allocator::page_frame::{PageFrameCount, VirtPageFrame}, 1740fe15e0SLoGin ucontext::{AddressSpace, DEFAULT_MMAP_MIN_ADDR}, 184cfa009bSJomo verify_area, VirtAddr, VmFlags, 1940fe15e0SLoGin }; 2040fe15e0SLoGin 2140fe15e0SLoGin bitflags! { 2240fe15e0SLoGin /// Memory protection flags 2340fe15e0SLoGin pub struct ProtFlags: u64 { 2440fe15e0SLoGin const PROT_NONE = 0x0; 2540fe15e0SLoGin const PROT_READ = 0x1; 2640fe15e0SLoGin const PROT_WRITE = 0x2; 2740fe15e0SLoGin const PROT_EXEC = 0x4; 28ab5c8ca4Slogin } 2940fe15e0SLoGin 3040fe15e0SLoGin /// Memory mapping flags 3140fe15e0SLoGin pub struct MapFlags: u64 { 3240fe15e0SLoGin const MAP_NONE = 0x0; 3340fe15e0SLoGin /// share changes 3440fe15e0SLoGin const MAP_SHARED = 0x1; 3540fe15e0SLoGin /// changes are private 3640fe15e0SLoGin const MAP_PRIVATE = 0x2; 3740fe15e0SLoGin /// Interpret addr exactly 3840fe15e0SLoGin const MAP_FIXED = 0x10; 3940fe15e0SLoGin /// don't use a file 4040fe15e0SLoGin const MAP_ANONYMOUS = 0x20; 4140fe15e0SLoGin // linux-6.1-rc5/include/uapi/asm-generic/mman.h#7 4240fe15e0SLoGin /// stack-like segment 4340fe15e0SLoGin const MAP_GROWSDOWN = 0x100; 4440fe15e0SLoGin /// ETXTBSY 4540fe15e0SLoGin const MAP_DENYWRITE = 0x800; 4640fe15e0SLoGin /// Mark it as an executable 4740fe15e0SLoGin const MAP_EXECUTABLE = 0x1000; 4840fe15e0SLoGin /// Pages are locked 4940fe15e0SLoGin const MAP_LOCKED = 0x2000; 5040fe15e0SLoGin /// don't check for reservations 5140fe15e0SLoGin const MAP_NORESERVE = 0x4000; 5240fe15e0SLoGin /// populate (prefault) pagetables 5340fe15e0SLoGin const MAP_POPULATE = 0x8000; 5440fe15e0SLoGin /// do not block on IO 5540fe15e0SLoGin const MAP_NONBLOCK = 0x10000; 5640fe15e0SLoGin /// give out an address that is best suited for process/thread stacks 5740fe15e0SLoGin const MAP_STACK = 0x20000; 5840fe15e0SLoGin /// create a huge page mapping 5940fe15e0SLoGin const MAP_HUGETLB = 0x40000; 6040fe15e0SLoGin /// perform synchronous page faults for the mapping 6140fe15e0SLoGin const MAP_SYNC = 0x80000; 6240fe15e0SLoGin /// MAP_FIXED which doesn't unmap underlying mapping 6340fe15e0SLoGin const MAP_FIXED_NOREPLACE = 0x100000; 6440fe15e0SLoGin 6540fe15e0SLoGin /// For anonymous mmap, memory could be uninitialized 6640fe15e0SLoGin const MAP_UNINITIALIZED = 0x4000000; 674cfa009bSJomo } 6840fe15e0SLoGin 694cfa009bSJomo /// Memory mremapping flags 704cfa009bSJomo pub struct MremapFlags: u8 { 714cfa009bSJomo const MREMAP_MAYMOVE = 1; 724cfa009bSJomo const MREMAP_FIXED = 2; 734cfa009bSJomo const MREMAP_DONTUNMAP = 4; 744cfa009bSJomo } 75*a17651b1SMemoryShore 76*a17651b1SMemoryShore 77*a17651b1SMemoryShore pub struct MadvFlags: u64 { 78*a17651b1SMemoryShore /// 默认行为,系统会进行一定的预读和预写,适用于一般读取场景 79*a17651b1SMemoryShore const MADV_NORMAL = 0; 80*a17651b1SMemoryShore /// 随机访问模式,系统会尽量最小化数据读取量,适用于随机访问的场景 81*a17651b1SMemoryShore const MADV_RANDOM = 1; 82*a17651b1SMemoryShore /// 顺序访问模式,系统会进行积极的预读,访问后的页面可以尽快释放,适用于顺序读取场景 83*a17651b1SMemoryShore const MADV_SEQUENTIAL = 2; 84*a17651b1SMemoryShore /// 通知系统预读某些页面,用于应用程序提前准备数据 85*a17651b1SMemoryShore const MADV_WILLNEED = 3; 86*a17651b1SMemoryShore /// 通知系统应用程序不再需要某些页面,内核可以释放相关资源 87*a17651b1SMemoryShore const MADV_DONTNEED = 4; 88*a17651b1SMemoryShore 89*a17651b1SMemoryShore /// 将指定范围的页面标记为延迟释放,真正的释放会延迟至内存压力发生时 90*a17651b1SMemoryShore const MADV_FREE = 8; 91*a17651b1SMemoryShore /// 应用程序请求释放指定范围的页面和相关的后备存储 92*a17651b1SMemoryShore const MADV_REMOVE = 9; 93*a17651b1SMemoryShore /// 在 fork 时排除指定区域 94*a17651b1SMemoryShore const MADV_DONTFORK = 10; 95*a17651b1SMemoryShore /// 取消 MADV_DONTFORK 的效果,不再在 fork 时排除指定区域 96*a17651b1SMemoryShore const MADV_DOFORK = 11; 97*a17651b1SMemoryShore /// 模拟内存硬件错误,触发内存错误处理器处理 98*a17651b1SMemoryShore const MADV_HWPOISON = 100; 99*a17651b1SMemoryShore /// 尝试软下线指定的内存范围 100*a17651b1SMemoryShore const MADV_SOFT_OFFLINE = 101; 101*a17651b1SMemoryShore 102*a17651b1SMemoryShore /// 应用程序建议内核尝试合并指定范围内内容相同的页面 103*a17651b1SMemoryShore const MADV_MERGEABLE = 12; 104*a17651b1SMemoryShore /// 取消 MADV_MERGEABLE 的效果,不再合并页面 105*a17651b1SMemoryShore const MADV_UNMERGEABLE = 13; 106*a17651b1SMemoryShore 107*a17651b1SMemoryShore /// 应用程序希望将指定范围以透明大页方式支持 108*a17651b1SMemoryShore const MADV_HUGEPAGE = 14; 109*a17651b1SMemoryShore /// 将指定范围标记为不值得用透明大页支持 110*a17651b1SMemoryShore const MADV_NOHUGEPAGE = 15; 111*a17651b1SMemoryShore 112*a17651b1SMemoryShore /// 应用程序请求在核心转储时排除指定范围内的页面 113*a17651b1SMemoryShore const MADV_DONTDUMP = 16; 114*a17651b1SMemoryShore /// 取消 MADV_DONTDUMP 的效果,不再排除核心转储时的页面 115*a17651b1SMemoryShore const MADV_DODUMP = 17; 116*a17651b1SMemoryShore 117*a17651b1SMemoryShore /// 在 fork 时将子进程的该区域内存填充为零 118*a17651b1SMemoryShore const MADV_WIPEONFORK = 18; 119*a17651b1SMemoryShore /// 取消 `MADV_WIPEONFORK` 的效果,不再在 fork 时填充子进程的内存 120*a17651b1SMemoryShore const MADV_KEEPONFORK = 19; 121*a17651b1SMemoryShore 122*a17651b1SMemoryShore /// 应用程序不会立刻使用这些内存,内核将页面设置为非活动状态以便在内存压力发生时轻松回收 123*a17651b1SMemoryShore const MADV_COLD = 20; 124*a17651b1SMemoryShore /// 应用程序不会立刻使用这些内存,内核立即将这些页面换出 125*a17651b1SMemoryShore const MADV_PAGEOUT = 21; 126*a17651b1SMemoryShore 127*a17651b1SMemoryShore /// 预先填充页面表,可读,通过触发读取故障 128*a17651b1SMemoryShore const MADV_POPULATE_READ = 22; 129*a17651b1SMemoryShore /// 预先填充页面表,可写,通过触发写入故障 130*a17651b1SMemoryShore const MADV_POPULATE_WRITE = 23; 131*a17651b1SMemoryShore 132*a17651b1SMemoryShore /// 与 `MADV_DONTNEED` 类似,会将被锁定的页面释放 133*a17651b1SMemoryShore const MADV_DONTNEED_LOCKED = 24; 134*a17651b1SMemoryShore 135*a17651b1SMemoryShore /// 同步将页面合并为新的透明大页 136*a17651b1SMemoryShore const MADV_COLLAPSE = 25; 137*a17651b1SMemoryShore 138*a17651b1SMemoryShore } 1394cfa009bSJomo } 1404cfa009bSJomo 1414cfa009bSJomo impl From<MapFlags> for VmFlags { 1424cfa009bSJomo fn from(map_flags: MapFlags) -> Self { 1434cfa009bSJomo let mut vm_flags = VmFlags::VM_NONE; 1444cfa009bSJomo 1454cfa009bSJomo if map_flags.contains(MapFlags::MAP_GROWSDOWN) { 1464cfa009bSJomo vm_flags |= VmFlags::VM_GROWSDOWN; 1474cfa009bSJomo } 1484cfa009bSJomo 1494cfa009bSJomo if map_flags.contains(MapFlags::MAP_LOCKED) { 1504cfa009bSJomo vm_flags |= VmFlags::VM_LOCKED; 1514cfa009bSJomo } 1524cfa009bSJomo 1534cfa009bSJomo if map_flags.contains(MapFlags::MAP_SYNC) { 1544cfa009bSJomo vm_flags |= VmFlags::VM_SYNC; 1554cfa009bSJomo } 1564cfa009bSJomo 1574cfa009bSJomo vm_flags 1584cfa009bSJomo } 1594cfa009bSJomo } 1604cfa009bSJomo 1614cfa009bSJomo impl From<ProtFlags> for VmFlags { 1624cfa009bSJomo fn from(prot_flags: ProtFlags) -> Self { 1634cfa009bSJomo let mut vm_flags = VmFlags::VM_NONE; 1644cfa009bSJomo 1654cfa009bSJomo if prot_flags.contains(ProtFlags::PROT_READ) { 1664cfa009bSJomo vm_flags |= VmFlags::VM_READ; 1674cfa009bSJomo } 1684cfa009bSJomo 1694cfa009bSJomo if prot_flags.contains(ProtFlags::PROT_WRITE) { 1704cfa009bSJomo vm_flags |= VmFlags::VM_WRITE; 1714cfa009bSJomo } 1724cfa009bSJomo 1734cfa009bSJomo if prot_flags.contains(ProtFlags::PROT_EXEC) { 1744cfa009bSJomo vm_flags |= VmFlags::VM_EXEC; 1754cfa009bSJomo } 1764cfa009bSJomo 1774cfa009bSJomo vm_flags 1784cfa009bSJomo } 1794cfa009bSJomo } 1804cfa009bSJomo 1816fc066acSJomo impl From<ShmFlags> for VmFlags { 1826fc066acSJomo fn from(shm_flags: ShmFlags) -> Self { 1836fc066acSJomo let mut vm_flags = VmFlags::VM_NONE; 1846fc066acSJomo 1856fc066acSJomo if shm_flags.contains(ShmFlags::SHM_RDONLY) { 1866fc066acSJomo vm_flags |= VmFlags::VM_READ; 1876fc066acSJomo } else { 1886fc066acSJomo vm_flags |= VmFlags::VM_READ | VmFlags::VM_WRITE; 1896fc066acSJomo } 1906fc066acSJomo 1916fc066acSJomo if shm_flags.contains(ShmFlags::SHM_EXEC) { 1926fc066acSJomo vm_flags |= VmFlags::VM_EXEC; 1936fc066acSJomo } 1946fc066acSJomo 1956fc066acSJomo if shm_flags.contains(ShmFlags::SHM_HUGETLB) { 1966fc066acSJomo vm_flags |= VmFlags::VM_HUGETLB; 1976fc066acSJomo } 1986fc066acSJomo 1996fc066acSJomo vm_flags 2006fc066acSJomo } 2016fc066acSJomo } 2026fc066acSJomo 203b5b571e0SLoGin impl From<VmFlags> for MapFlags { 204b5b571e0SLoGin fn from(value: VmFlags) -> Self { 2054cfa009bSJomo let mut map_flags = MapFlags::MAP_NONE; 2064cfa009bSJomo 207b5b571e0SLoGin if value.contains(VmFlags::VM_GROWSDOWN) { 2084cfa009bSJomo map_flags |= MapFlags::MAP_GROWSDOWN; 2094cfa009bSJomo } 2104cfa009bSJomo 211b5b571e0SLoGin if value.contains(VmFlags::VM_LOCKED) { 2124cfa009bSJomo map_flags |= MapFlags::MAP_LOCKED; 2134cfa009bSJomo } 2144cfa009bSJomo 215b5b571e0SLoGin if value.contains(VmFlags::VM_SYNC) { 2164cfa009bSJomo map_flags |= MapFlags::MAP_SYNC; 2174cfa009bSJomo } 2184cfa009bSJomo 219b5b571e0SLoGin if value.contains(VmFlags::VM_MAYSHARE) { 2203055390cSJomo map_flags |= MapFlags::MAP_SHARED; 2213055390cSJomo } 2223055390cSJomo 2234cfa009bSJomo map_flags 2244cfa009bSJomo } 2254cfa009bSJomo } 2264cfa009bSJomo 227b5b571e0SLoGin impl From<VmFlags> for ProtFlags { 228b5b571e0SLoGin fn from(value: VmFlags) -> Self { 2294cfa009bSJomo let mut prot_flags = ProtFlags::PROT_NONE; 2304cfa009bSJomo 231b5b571e0SLoGin if value.contains(VmFlags::VM_READ) { 2324cfa009bSJomo prot_flags |= ProtFlags::PROT_READ; 2334cfa009bSJomo } 2344cfa009bSJomo 235b5b571e0SLoGin if value.contains(VmFlags::VM_WRITE) { 2364cfa009bSJomo prot_flags |= ProtFlags::PROT_WRITE; 2374cfa009bSJomo } 2384cfa009bSJomo 239b5b571e0SLoGin if value.contains(VmFlags::VM_EXEC) { 2404cfa009bSJomo prot_flags |= ProtFlags::PROT_EXEC; 2414cfa009bSJomo } 2424cfa009bSJomo 2434cfa009bSJomo prot_flags 24440fe15e0SLoGin } 24540fe15e0SLoGin } 24640fe15e0SLoGin 247ab5c8ca4Slogin impl Syscall { 24840fe15e0SLoGin pub fn brk(new_addr: VirtAddr) -> Result<VirtAddr, SystemError> { 24940fe15e0SLoGin // kdebug!("brk: new_addr={:?}", new_addr); 25040fe15e0SLoGin let address_space = AddressSpace::current()?; 25140fe15e0SLoGin let mut address_space = address_space.write(); 25240fe15e0SLoGin 2536d81180bSLoGin if new_addr < address_space.brk_start || new_addr >= MMArch::USER_END_VADDR { 2546d81180bSLoGin return Ok(address_space.brk); 2556d81180bSLoGin } 2566d81180bSLoGin if new_addr == address_space.brk { 2576d81180bSLoGin return Ok(address_space.brk); 2586d81180bSLoGin } 2596d81180bSLoGin 26040fe15e0SLoGin unsafe { 26140fe15e0SLoGin address_space 26240fe15e0SLoGin .set_brk(VirtAddr::new(page_align_up(new_addr.data()))) 26340fe15e0SLoGin .ok(); 26440fe15e0SLoGin 26540fe15e0SLoGin return Ok(address_space.sbrk(0).unwrap()); 266ab5c8ca4Slogin } 267d8ad0a5eSLoGin } 268d8ad0a5eSLoGin 26940fe15e0SLoGin pub fn sbrk(incr: isize) -> Result<VirtAddr, SystemError> { 27040fe15e0SLoGin let address_space = AddressSpace::current()?; 2711496ba7bSLoGin assert!(address_space.read().user_mapper.utable.is_current()); 27240fe15e0SLoGin let mut address_space = address_space.write(); 27340fe15e0SLoGin let r = unsafe { address_space.sbrk(incr) }; 27440fe15e0SLoGin 27540fe15e0SLoGin return r; 276d8ad0a5eSLoGin } 277d8ad0a5eSLoGin 27840fe15e0SLoGin /// ## mmap系统调用 279d8ad0a5eSLoGin /// 28040fe15e0SLoGin /// 该函数的实现参考了Linux内核的实现,但是并不完全相同。因为有些功能咱们还没实现 28140fe15e0SLoGin /// 28240fe15e0SLoGin /// ## 参数 28340fe15e0SLoGin /// 28440fe15e0SLoGin /// - `start_vaddr`:映射的起始地址 28540fe15e0SLoGin /// - `len`:映射的长度 28640fe15e0SLoGin /// - `prot`:保护标志 28740fe15e0SLoGin /// - `flags`:映射标志 28840fe15e0SLoGin /// - `fd`:文件描述符(暂时不支持) 28940fe15e0SLoGin /// - `offset`:文件偏移量 (暂时不支持) 29040fe15e0SLoGin /// 29140fe15e0SLoGin /// ## 返回值 29240fe15e0SLoGin /// 29340fe15e0SLoGin /// 成功时返回映射的起始地址,失败时返回错误码 29440fe15e0SLoGin pub fn mmap( 29540fe15e0SLoGin start_vaddr: VirtAddr, 29640fe15e0SLoGin len: usize, 29740fe15e0SLoGin prot_flags: usize, 29840fe15e0SLoGin map_flags: usize, 29940fe15e0SLoGin _fd: i32, 30040fe15e0SLoGin _offset: usize, 30140fe15e0SLoGin ) -> Result<usize, SystemError> { 30240fe15e0SLoGin let map_flags = MapFlags::from_bits_truncate(map_flags as u64); 30340fe15e0SLoGin let prot_flags = ProtFlags::from_bits_truncate(prot_flags as u64); 30440fe15e0SLoGin 30540fe15e0SLoGin if start_vaddr < VirtAddr::new(DEFAULT_MMAP_MIN_ADDR) 30640fe15e0SLoGin && map_flags.contains(MapFlags::MAP_FIXED) 30740fe15e0SLoGin { 30840fe15e0SLoGin kerror!( 30940fe15e0SLoGin "mmap: MAP_FIXED is not supported for address below {}", 31040fe15e0SLoGin DEFAULT_MMAP_MIN_ADDR 31140fe15e0SLoGin ); 31240fe15e0SLoGin return Err(SystemError::EINVAL); 313d8ad0a5eSLoGin } 31440fe15e0SLoGin // 暂时不支持除匿名页以外的映射 31540fe15e0SLoGin if !map_flags.contains(MapFlags::MAP_ANONYMOUS) { 31640fe15e0SLoGin kerror!("mmap: not support file mapping"); 3171074eb34SSamuel Dai return Err(SystemError::ENOSYS); 31840fe15e0SLoGin } 31940fe15e0SLoGin 32040fe15e0SLoGin // 暂时不支持巨页映射 32140fe15e0SLoGin if map_flags.contains(MapFlags::MAP_HUGETLB) { 32240fe15e0SLoGin kerror!("mmap: not support huge page mapping"); 3231074eb34SSamuel Dai return Err(SystemError::ENOSYS); 32440fe15e0SLoGin } 32540fe15e0SLoGin let current_address_space = AddressSpace::current()?; 32640fe15e0SLoGin let start_page = current_address_space.write().map_anonymous( 32740fe15e0SLoGin start_vaddr, 32840fe15e0SLoGin len, 32940fe15e0SLoGin prot_flags, 33040fe15e0SLoGin map_flags, 33140fe15e0SLoGin true, 332*a17651b1SMemoryShore true, 33340fe15e0SLoGin )?; 33440fe15e0SLoGin return Ok(start_page.virt_address().data()); 33540fe15e0SLoGin } 33640fe15e0SLoGin 3374cfa009bSJomo /// ## mremap系统调用 3384cfa009bSJomo /// 3394cfa009bSJomo /// 3404cfa009bSJomo /// ## 参数 3414cfa009bSJomo /// 3424cfa009bSJomo /// - `old_vaddr`:原映射的起始地址 3434cfa009bSJomo /// - `old_len`:原映射的长度 3444cfa009bSJomo /// - `new_len`:重新映射的长度 3454cfa009bSJomo /// - `mremap_flags`:重映射标志 3464cfa009bSJomo /// - `new_vaddr`:重新映射的起始地址 3474cfa009bSJomo /// 3484cfa009bSJomo /// ## 返回值 3494cfa009bSJomo /// 3504cfa009bSJomo /// 成功时返回重映射的起始地址,失败时返回错误码 3514cfa009bSJomo pub fn mremap( 3524cfa009bSJomo old_vaddr: VirtAddr, 3534cfa009bSJomo old_len: usize, 3544cfa009bSJomo new_len: usize, 3554cfa009bSJomo mremap_flags: MremapFlags, 3564cfa009bSJomo new_vaddr: VirtAddr, 3574cfa009bSJomo ) -> Result<usize, SystemError> { 3584cfa009bSJomo // 需要重映射到新内存区域的情况下,必须包含MREMAP_MAYMOVE并且指定新地址 3594cfa009bSJomo if mremap_flags.contains(MremapFlags::MREMAP_FIXED) 3604cfa009bSJomo && (!mremap_flags.contains(MremapFlags::MREMAP_MAYMOVE) 3614cfa009bSJomo || new_vaddr == VirtAddr::new(0)) 3624cfa009bSJomo { 3634cfa009bSJomo return Err(SystemError::EINVAL); 3644cfa009bSJomo } 3654cfa009bSJomo 3664cfa009bSJomo // 不取消旧映射的情况下,必须包含MREMAP_MAYMOVE并且新内存大小等于旧内存大小 3674cfa009bSJomo if mremap_flags.contains(MremapFlags::MREMAP_DONTUNMAP) 3684cfa009bSJomo && (!mremap_flags.contains(MremapFlags::MREMAP_MAYMOVE) || old_len != new_len) 3694cfa009bSJomo { 3704cfa009bSJomo return Err(SystemError::EINVAL); 3714cfa009bSJomo } 3724cfa009bSJomo 3734cfa009bSJomo // 旧内存地址必须对齐 3744cfa009bSJomo if !old_vaddr.check_aligned(MMArch::PAGE_SIZE) { 3754cfa009bSJomo return Err(SystemError::EINVAL); 3764cfa009bSJomo } 3774cfa009bSJomo 3784cfa009bSJomo // 将old_len、new_len 对齐页面大小 3794cfa009bSJomo let old_len = page_align_up(old_len); 3804cfa009bSJomo let new_len = page_align_up(new_len); 3814cfa009bSJomo 3824cfa009bSJomo // 不允许重映射内存区域大小为0 3834cfa009bSJomo if new_len == 0 { 3844cfa009bSJomo return Err(SystemError::EINVAL); 3854cfa009bSJomo } 3864cfa009bSJomo 3874cfa009bSJomo let current_address_space = AddressSpace::current()?; 3884cfa009bSJomo let vma = current_address_space.read().mappings.contains(old_vaddr); 3894cfa009bSJomo if vma.is_none() { 3904cfa009bSJomo return Err(SystemError::EINVAL); 3914cfa009bSJomo } 3924cfa009bSJomo let vma = vma.unwrap(); 393b5b571e0SLoGin let vm_flags = *vma.lock().vm_flags(); 3944cfa009bSJomo 3954cfa009bSJomo // 暂时不支持巨页映射 3964cfa009bSJomo if vm_flags.contains(VmFlags::VM_HUGETLB) { 3974cfa009bSJomo kerror!("mmap: not support huge page mapping"); 3984cfa009bSJomo return Err(SystemError::ENOSYS); 3994cfa009bSJomo } 4004cfa009bSJomo 4014cfa009bSJomo // 缩小旧内存映射区域 4024cfa009bSJomo if old_len > new_len { 4034cfa009bSJomo Self::munmap(old_vaddr + new_len, old_len - new_len)?; 4044cfa009bSJomo return Ok(old_vaddr.data()); 4054cfa009bSJomo } 4064cfa009bSJomo 4074cfa009bSJomo // 重映射到新内存区域 4084cfa009bSJomo let r = current_address_space.write().mremap( 4094cfa009bSJomo old_vaddr, 4104cfa009bSJomo old_len, 4114cfa009bSJomo new_len, 4124cfa009bSJomo mremap_flags, 4134cfa009bSJomo new_vaddr, 4144cfa009bSJomo vm_flags, 4154cfa009bSJomo )?; 4164cfa009bSJomo 4174cfa009bSJomo if !mremap_flags.contains(MremapFlags::MREMAP_DONTUNMAP) { 4184cfa009bSJomo Self::munmap(old_vaddr, old_len)?; 4194cfa009bSJomo } 4204cfa009bSJomo 4214cfa009bSJomo return Ok(r.data()); 4224cfa009bSJomo } 4234cfa009bSJomo 42440fe15e0SLoGin /// ## munmap系统调用 42540fe15e0SLoGin /// 42640fe15e0SLoGin /// ## 参数 42740fe15e0SLoGin /// 42840fe15e0SLoGin /// - `start_vaddr`:取消映射的起始地址(已经对齐到页) 42940fe15e0SLoGin /// - `len`:取消映射的字节数(已经对齐到页) 43040fe15e0SLoGin /// 43140fe15e0SLoGin /// ## 返回值 43240fe15e0SLoGin /// 43340fe15e0SLoGin /// 成功时返回0,失败时返回错误码 43440fe15e0SLoGin pub fn munmap(start_vaddr: VirtAddr, len: usize) -> Result<usize, SystemError> { 43540fe15e0SLoGin assert!(start_vaddr.check_aligned(MMArch::PAGE_SIZE)); 43640fe15e0SLoGin assert!(check_aligned(len, MMArch::PAGE_SIZE)); 43740fe15e0SLoGin 43840fe15e0SLoGin if unlikely(verify_area(start_vaddr, len).is_err()) { 43940fe15e0SLoGin return Err(SystemError::EINVAL); 44040fe15e0SLoGin } 44140fe15e0SLoGin if unlikely(len == 0) { 44240fe15e0SLoGin return Err(SystemError::EINVAL); 44340fe15e0SLoGin } 44440fe15e0SLoGin 44540fe15e0SLoGin let current_address_space: Arc<AddressSpace> = AddressSpace::current()?; 44640fe15e0SLoGin let start_frame = VirtPageFrame::new(start_vaddr); 44740fe15e0SLoGin let page_count = PageFrameCount::new(len / MMArch::PAGE_SIZE); 44840fe15e0SLoGin 44940fe15e0SLoGin current_address_space 45040fe15e0SLoGin .write() 45140fe15e0SLoGin .munmap(start_frame, page_count) 45240fe15e0SLoGin .map_err(|_| SystemError::EINVAL)?; 4534cfa009bSJomo 45440fe15e0SLoGin return Ok(0); 45540fe15e0SLoGin } 45640fe15e0SLoGin 45740fe15e0SLoGin /// ## mprotect系统调用 45840fe15e0SLoGin /// 45940fe15e0SLoGin /// ## 参数 46040fe15e0SLoGin /// 46140fe15e0SLoGin /// - `start_vaddr`:起始地址(已经对齐到页) 46240fe15e0SLoGin /// - `len`:长度(已经对齐到页) 46340fe15e0SLoGin /// - `prot_flags`:保护标志 46440fe15e0SLoGin pub fn mprotect( 46540fe15e0SLoGin start_vaddr: VirtAddr, 46640fe15e0SLoGin len: usize, 46740fe15e0SLoGin prot_flags: usize, 46840fe15e0SLoGin ) -> Result<usize, SystemError> { 46940fe15e0SLoGin assert!(start_vaddr.check_aligned(MMArch::PAGE_SIZE)); 47040fe15e0SLoGin assert!(check_aligned(len, MMArch::PAGE_SIZE)); 47140fe15e0SLoGin 47240fe15e0SLoGin if unlikely(verify_area(start_vaddr, len).is_err()) { 47340fe15e0SLoGin return Err(SystemError::EINVAL); 47440fe15e0SLoGin } 47540fe15e0SLoGin if unlikely(len == 0) { 47640fe15e0SLoGin return Err(SystemError::EINVAL); 47740fe15e0SLoGin } 47840fe15e0SLoGin 47940fe15e0SLoGin let prot_flags = ProtFlags::from_bits(prot_flags as u64).ok_or(SystemError::EINVAL)?; 48040fe15e0SLoGin 48140fe15e0SLoGin let current_address_space: Arc<AddressSpace> = AddressSpace::current()?; 48240fe15e0SLoGin let start_frame = VirtPageFrame::new(start_vaddr); 48340fe15e0SLoGin let page_count = PageFrameCount::new(len / MMArch::PAGE_SIZE); 48440fe15e0SLoGin 48540fe15e0SLoGin current_address_space 48640fe15e0SLoGin .write() 48740fe15e0SLoGin .mprotect(start_frame, page_count, prot_flags) 48840fe15e0SLoGin .map_err(|_| SystemError::EINVAL)?; 48940fe15e0SLoGin return Ok(0); 490ab5c8ca4Slogin } 491*a17651b1SMemoryShore 492*a17651b1SMemoryShore /// ## madvise系统调用 493*a17651b1SMemoryShore /// 494*a17651b1SMemoryShore /// ## 参数 495*a17651b1SMemoryShore /// 496*a17651b1SMemoryShore /// - `start_vaddr`:起始地址(已经对齐到页) 497*a17651b1SMemoryShore /// - `len`:长度(已经对齐到页) 498*a17651b1SMemoryShore /// - `madv_flags`:建议标志 499*a17651b1SMemoryShore pub fn madvise( 500*a17651b1SMemoryShore start_vaddr: VirtAddr, 501*a17651b1SMemoryShore len: usize, 502*a17651b1SMemoryShore madv_flags: usize, 503*a17651b1SMemoryShore ) -> Result<usize, SystemError> { 504*a17651b1SMemoryShore if !start_vaddr.check_aligned(MMArch::PAGE_SIZE) || !check_aligned(len, MMArch::PAGE_SIZE) { 505*a17651b1SMemoryShore return Err(SystemError::EINVAL); 506*a17651b1SMemoryShore } 507*a17651b1SMemoryShore 508*a17651b1SMemoryShore if unlikely(verify_area(start_vaddr, len).is_err()) { 509*a17651b1SMemoryShore return Err(SystemError::EINVAL); 510*a17651b1SMemoryShore } 511*a17651b1SMemoryShore if unlikely(len == 0) { 512*a17651b1SMemoryShore return Err(SystemError::EINVAL); 513*a17651b1SMemoryShore } 514*a17651b1SMemoryShore 515*a17651b1SMemoryShore let madv_flags = MadvFlags::from_bits(madv_flags as u64).ok_or(SystemError::EINVAL)?; 516*a17651b1SMemoryShore 517*a17651b1SMemoryShore let current_address_space: Arc<AddressSpace> = AddressSpace::current()?; 518*a17651b1SMemoryShore let start_frame = VirtPageFrame::new(start_vaddr); 519*a17651b1SMemoryShore let page_count = PageFrameCount::new(len / MMArch::PAGE_SIZE); 520*a17651b1SMemoryShore 521*a17651b1SMemoryShore current_address_space 522*a17651b1SMemoryShore .write() 523*a17651b1SMemoryShore .madvise(start_frame, page_count, madv_flags) 524*a17651b1SMemoryShore .map_err(|_| SystemError::EINVAL)?; 525*a17651b1SMemoryShore return Ok(0); 526*a17651b1SMemoryShore } 527ab5c8ca4Slogin } 528