140fe15e0SLoGin // 进程的用户空间内存管理 240fe15e0SLoGin 340fe15e0SLoGin use core::{ 440fe15e0SLoGin cmp, 540fe15e0SLoGin hash::Hasher, 640fe15e0SLoGin intrinsics::unlikely, 740fe15e0SLoGin ops::Add, 840fe15e0SLoGin sync::atomic::{compiler_fence, Ordering}, 940fe15e0SLoGin }; 1040fe15e0SLoGin 1140fe15e0SLoGin use alloc::{ 1240fe15e0SLoGin collections::BTreeMap, 1340fe15e0SLoGin sync::{Arc, Weak}, 1440fe15e0SLoGin vec::Vec, 1540fe15e0SLoGin }; 1640fe15e0SLoGin use hashbrown::HashSet; 1756cc4dbeSJomo use ida::IdAllocator; 1891e9d4abSLoGin use system_error::SystemError; 1940fe15e0SLoGin 2040fe15e0SLoGin use crate::{ 211496ba7bSLoGin arch::{mm::PageMapper, CurrentIrqArch, MMArch}, 2240fe15e0SLoGin exception::InterruptArch, 2340fe15e0SLoGin libs::{ 2440fe15e0SLoGin align::page_align_up, 25a17651b1SMemoryShore rwlock::RwLock, 2640fe15e0SLoGin spinlock::{SpinLock, SpinLockGuard}, 2740fe15e0SLoGin }, 286fc066acSJomo mm::page::page_manager_lock_irqsave, 291496ba7bSLoGin process::ProcessManager, 304cfa009bSJomo syscall::user_access::{UserBufferReader, UserBufferWriter}, 3140fe15e0SLoGin }; 3240fe15e0SLoGin 3340fe15e0SLoGin use super::{ 3440fe15e0SLoGin allocator::page_frame::{ 3540fe15e0SLoGin deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter, 3640fe15e0SLoGin }, 3740fe15e0SLoGin page::{Flusher, InactiveFlusher, PageFlags, PageFlushAll}, 38a17651b1SMemoryShore syscall::{MadvFlags, MapFlags, MremapFlags, ProtFlags}, 394cfa009bSJomo MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, VmFlags, 4040fe15e0SLoGin }; 4140fe15e0SLoGin 4240fe15e0SLoGin /// MMAP_MIN_ADDR的默认值 4340fe15e0SLoGin /// 以下内容来自linux-5.19: 4440fe15e0SLoGin /// This is the portion of low virtual memory which should be protected 4540fe15e0SLoGin // from userspace allocation. Keeping a user from writing to low pages 4640fe15e0SLoGin // can help reduce the impact of kernel NULL pointer bugs. 4740fe15e0SLoGin // For most ia64, ppc64 and x86 users with lots of address space 4840fe15e0SLoGin // a value of 65536 is reasonable and should cause no problems. 4940fe15e0SLoGin // On arm and other archs it should not be higher than 32768. 5040fe15e0SLoGin // Programs which use vm86 functionality or have some need to map 5140fe15e0SLoGin // this low address space will need CAP_SYS_RAWIO or disable this 5240fe15e0SLoGin // protection by setting the value to 0. 5340fe15e0SLoGin pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536; 5440fe15e0SLoGin 5556cc4dbeSJomo /// LockedVMA的id分配器 5656cc4dbeSJomo static LOCKEDVMA_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, usize::MAX); 5756cc4dbeSJomo 5840fe15e0SLoGin #[derive(Debug)] 5940fe15e0SLoGin pub struct AddressSpace { 6040fe15e0SLoGin inner: RwLock<InnerAddressSpace>, 6140fe15e0SLoGin } 6240fe15e0SLoGin 6340fe15e0SLoGin impl AddressSpace { 6440fe15e0SLoGin pub fn new(create_stack: bool) -> Result<Arc<Self>, SystemError> { 6540fe15e0SLoGin let inner = InnerAddressSpace::new(create_stack)?; 6640fe15e0SLoGin let result = Self { 6740fe15e0SLoGin inner: RwLock::new(inner), 6840fe15e0SLoGin }; 6940fe15e0SLoGin return Ok(Arc::new(result)); 7040fe15e0SLoGin } 7140fe15e0SLoGin 7240fe15e0SLoGin /// 从pcb中获取当前进程的地址空间结构体的Arc指针 7340fe15e0SLoGin pub fn current() -> Result<Arc<AddressSpace>, SystemError> { 741496ba7bSLoGin let vm = ProcessManager::current_pcb() 751496ba7bSLoGin .basic() 761496ba7bSLoGin .user_vm() 7740fe15e0SLoGin .expect("Current process has no address space"); 781496ba7bSLoGin 791496ba7bSLoGin return Ok(vm); 8040fe15e0SLoGin } 8140fe15e0SLoGin 8240fe15e0SLoGin /// 判断某个地址空间是否为当前进程的地址空间 8340fe15e0SLoGin pub fn is_current(self: &Arc<Self>) -> bool { 8440fe15e0SLoGin let current = Self::current(); 8540fe15e0SLoGin if let Ok(current) = current { 8640fe15e0SLoGin return Arc::ptr_eq(¤t, self); 8740fe15e0SLoGin } 8840fe15e0SLoGin return false; 8940fe15e0SLoGin } 9040fe15e0SLoGin } 9140fe15e0SLoGin 9240fe15e0SLoGin impl core::ops::Deref for AddressSpace { 9340fe15e0SLoGin type Target = RwLock<InnerAddressSpace>; 9440fe15e0SLoGin 9540fe15e0SLoGin fn deref(&self) -> &Self::Target { 9640fe15e0SLoGin &self.inner 9740fe15e0SLoGin } 9840fe15e0SLoGin } 9940fe15e0SLoGin 10040fe15e0SLoGin impl core::ops::DerefMut for AddressSpace { 10140fe15e0SLoGin fn deref_mut(&mut self) -> &mut Self::Target { 10240fe15e0SLoGin &mut self.inner 10340fe15e0SLoGin } 10440fe15e0SLoGin } 10540fe15e0SLoGin 10640fe15e0SLoGin /// @brief 用户地址空间结构体(每个进程都有一个) 10740fe15e0SLoGin #[derive(Debug)] 10840fe15e0SLoGin pub struct InnerAddressSpace { 10940fe15e0SLoGin pub user_mapper: UserMapper, 11040fe15e0SLoGin pub mappings: UserMappings, 11140fe15e0SLoGin pub mmap_min: VirtAddr, 11240fe15e0SLoGin /// 用户栈信息结构体 11340fe15e0SLoGin pub user_stack: Option<UserStack>, 11440fe15e0SLoGin 11540fe15e0SLoGin pub elf_brk_start: VirtAddr, 11640fe15e0SLoGin pub elf_brk: VirtAddr, 11740fe15e0SLoGin 11840fe15e0SLoGin /// 当前进程的堆空间的起始地址 11940fe15e0SLoGin pub brk_start: VirtAddr, 12040fe15e0SLoGin /// 当前进程的堆空间的结束地址(不包含) 12140fe15e0SLoGin pub brk: VirtAddr, 12240fe15e0SLoGin 12340fe15e0SLoGin pub start_code: VirtAddr, 12440fe15e0SLoGin pub end_code: VirtAddr, 12540fe15e0SLoGin pub start_data: VirtAddr, 12640fe15e0SLoGin pub end_data: VirtAddr, 12740fe15e0SLoGin } 12840fe15e0SLoGin 12940fe15e0SLoGin impl InnerAddressSpace { 13040fe15e0SLoGin pub fn new(create_stack: bool) -> Result<Self, SystemError> { 13140fe15e0SLoGin let mut result = Self { 13240fe15e0SLoGin user_mapper: MMArch::setup_new_usermapper()?, 13340fe15e0SLoGin mappings: UserMappings::new(), 13440fe15e0SLoGin mmap_min: VirtAddr(DEFAULT_MMAP_MIN_ADDR), 13540fe15e0SLoGin elf_brk_start: VirtAddr::new(0), 13640fe15e0SLoGin elf_brk: VirtAddr::new(0), 13740fe15e0SLoGin brk_start: MMArch::USER_BRK_START, 13840fe15e0SLoGin brk: MMArch::USER_BRK_START, 13940fe15e0SLoGin user_stack: None, 14040fe15e0SLoGin start_code: VirtAddr(0), 14140fe15e0SLoGin end_code: VirtAddr(0), 14240fe15e0SLoGin start_data: VirtAddr(0), 14340fe15e0SLoGin end_data: VirtAddr(0), 14440fe15e0SLoGin }; 14540fe15e0SLoGin if create_stack { 1462eab6dd7S曾俊 // debug!("to create user stack."); 14740fe15e0SLoGin result.new_user_stack(UserStack::DEFAULT_USER_STACK_SIZE)?; 14840fe15e0SLoGin } 14940fe15e0SLoGin 15040fe15e0SLoGin return Ok(result); 15140fe15e0SLoGin } 15240fe15e0SLoGin 15340fe15e0SLoGin /// 尝试克隆当前进程的地址空间,包括这些映射都会被克隆 15440fe15e0SLoGin /// 15540fe15e0SLoGin /// # Returns 15640fe15e0SLoGin /// 15740fe15e0SLoGin /// 返回克隆后的,新的地址空间的Arc指针 1584fda81ceSLoGin #[inline(never)] 15940fe15e0SLoGin pub fn try_clone(&mut self) -> Result<Arc<AddressSpace>, SystemError> { 16040fe15e0SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 16140fe15e0SLoGin let new_addr_space = AddressSpace::new(false)?; 16240fe15e0SLoGin let mut new_guard = new_addr_space.write(); 163a17651b1SMemoryShore unsafe { 164a17651b1SMemoryShore new_guard 165a17651b1SMemoryShore .user_mapper 166a17651b1SMemoryShore .clone_from(&mut self.user_mapper, MMArch::PAGE_FAULT_ENABLED) 167a17651b1SMemoryShore }; 16840fe15e0SLoGin 16940fe15e0SLoGin // 拷贝用户栈的结构体信息,但是不拷贝用户栈的内容(因为后面VMA的拷贝会拷贝用户栈的内容) 17040fe15e0SLoGin unsafe { 17140fe15e0SLoGin new_guard.user_stack = Some(self.user_stack.as_ref().unwrap().clone_info_only()); 17240fe15e0SLoGin } 17340fe15e0SLoGin let _current_stack_size = self.user_stack.as_ref().unwrap().stack_size(); 17440fe15e0SLoGin 175ea8ad4d4SLoGin // 拷贝空洞 176ea8ad4d4SLoGin new_guard.mappings.vm_holes = self.mappings.vm_holes.clone(); 177ea8ad4d4SLoGin 17840fe15e0SLoGin for vma in self.mappings.vmas.iter() { 17940fe15e0SLoGin // TODO: 增加对VMA是否为文件映射的判断,如果是的话,就跳过 18040fe15e0SLoGin 18140fe15e0SLoGin let vma_guard: SpinLockGuard<'_, VMA> = vma.lock(); 18240fe15e0SLoGin 183a17651b1SMemoryShore // 仅拷贝VMA信息并添加反向映射,因为UserMapper克隆时已经分配了新的物理页 184a17651b1SMemoryShore let new_vma = LockedVMA::new(vma_guard.clone_info_only()); 18540fe15e0SLoGin new_guard.mappings.vmas.insert(new_vma.clone()); 1862eab6dd7S曾俊 // debug!("new vma: {:x?}", new_vma); 187a17651b1SMemoryShore let new_vma_guard = new_vma.lock(); 188a17651b1SMemoryShore let new_mapper = &new_guard.user_mapper.utable; 189a17651b1SMemoryShore let mut anon_vma_guard = page_manager_lock_irqsave(); 19040fe15e0SLoGin for page in new_vma_guard.pages().map(|p| p.virt_address()) { 191a17651b1SMemoryShore if let Some((paddr, _)) = new_mapper.translate(page) { 192a17651b1SMemoryShore let page = anon_vma_guard.get_mut(&paddr); 193a17651b1SMemoryShore page.insert_vma(new_vma.clone()); 19440fe15e0SLoGin } 195a17651b1SMemoryShore } 19640fe15e0SLoGin 197a17651b1SMemoryShore drop(anon_vma_guard); 19840fe15e0SLoGin drop(vma_guard); 19940fe15e0SLoGin drop(new_vma_guard); 20040fe15e0SLoGin } 20140fe15e0SLoGin drop(new_guard); 20240fe15e0SLoGin drop(irq_guard); 20340fe15e0SLoGin return Ok(new_addr_space); 20440fe15e0SLoGin } 20540fe15e0SLoGin 206a17651b1SMemoryShore /// 拓展用户栈 207a17651b1SMemoryShore /// ## 参数 208a17651b1SMemoryShore /// 209a17651b1SMemoryShore /// - `bytes`: 拓展大小 210a17651b1SMemoryShore #[allow(dead_code)] 211a17651b1SMemoryShore pub fn extend_stack(&mut self, mut bytes: usize) -> Result<(), SystemError> { 2122eab6dd7S曾俊 // debug!("extend user stack"); 213a17651b1SMemoryShore let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 214a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN; 215a17651b1SMemoryShore let stack = self.user_stack.as_mut().unwrap(); 216a17651b1SMemoryShore 217a17651b1SMemoryShore bytes = page_align_up(bytes); 218a17651b1SMemoryShore stack.mapped_size += bytes; 219a17651b1SMemoryShore let len = stack.stack_bottom - stack.mapped_size; 220a17651b1SMemoryShore self.map_anonymous(len, bytes, prot_flags, map_flags, false, false)?; 221a17651b1SMemoryShore return Ok(()); 222a17651b1SMemoryShore } 223a17651b1SMemoryShore 22440fe15e0SLoGin /// 判断当前的地址空间是否是当前进程的地址空间 22540fe15e0SLoGin #[inline] 22640fe15e0SLoGin pub fn is_current(&self) -> bool { 22740fe15e0SLoGin return self.user_mapper.utable.is_current(); 22840fe15e0SLoGin } 22940fe15e0SLoGin 23040fe15e0SLoGin /// 进行匿名页映射 23140fe15e0SLoGin /// 23240fe15e0SLoGin /// ## 参数 23340fe15e0SLoGin /// 23440fe15e0SLoGin /// - `start_vaddr`:映射的起始地址 23540fe15e0SLoGin /// - `len`:映射的长度 23640fe15e0SLoGin /// - `prot_flags`:保护标志 23740fe15e0SLoGin /// - `map_flags`:映射标志 23840fe15e0SLoGin /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界 239a17651b1SMemoryShore /// - `allocate_at_once`:是否立即分配物理空间 2401496ba7bSLoGin /// 2411496ba7bSLoGin /// ## 返回 2421496ba7bSLoGin /// 2431496ba7bSLoGin /// 返回映射的起始虚拟页帧 24440fe15e0SLoGin pub fn map_anonymous( 24540fe15e0SLoGin &mut self, 24640fe15e0SLoGin start_vaddr: VirtAddr, 24740fe15e0SLoGin len: usize, 24840fe15e0SLoGin prot_flags: ProtFlags, 24940fe15e0SLoGin map_flags: MapFlags, 25040fe15e0SLoGin round_to_min: bool, 251a17651b1SMemoryShore allocate_at_once: bool, 25240fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 253a17651b1SMemoryShore let allocate_at_once = if MMArch::PAGE_FAULT_ENABLED { 254a17651b1SMemoryShore allocate_at_once 255a17651b1SMemoryShore } else { 256a17651b1SMemoryShore true 257a17651b1SMemoryShore }; 25840fe15e0SLoGin // 用于对齐hint的函数 25940fe15e0SLoGin let round_hint_to_min = |hint: VirtAddr| { 26040fe15e0SLoGin // 先把hint向下对齐到页边界 26140fe15e0SLoGin let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK); 2622eab6dd7S曾俊 // debug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint); 26340fe15e0SLoGin // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR 26440fe15e0SLoGin if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) { 26540fe15e0SLoGin Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR))) 26640fe15e0SLoGin } else if addr == 0 { 26740fe15e0SLoGin None 26840fe15e0SLoGin } else { 26940fe15e0SLoGin Some(VirtAddr::new(addr)) 27040fe15e0SLoGin } 27140fe15e0SLoGin }; 2722eab6dd7S曾俊 // debug!("map_anonymous: start_vaddr = {:?}", start_vaddr); 2732eab6dd7S曾俊 // debug!("map_anonymous: len(no align) = {}", len); 27440fe15e0SLoGin 27540fe15e0SLoGin let len = page_align_up(len); 27640fe15e0SLoGin 2774cfa009bSJomo let vm_flags = VmFlags::from(prot_flags) 2784cfa009bSJomo | VmFlags::from(map_flags) 2794cfa009bSJomo | VmFlags::VM_MAYREAD 2804cfa009bSJomo | VmFlags::VM_MAYWRITE 2814cfa009bSJomo | VmFlags::VM_MAYEXEC; 2824cfa009bSJomo 2832eab6dd7S曾俊 // debug!("map_anonymous: len = {}", len); 28440fe15e0SLoGin 285a17651b1SMemoryShore let start_page: VirtPageFrame = if allocate_at_once { 286a17651b1SMemoryShore self.mmap( 28740fe15e0SLoGin round_hint_to_min(start_vaddr), 28840fe15e0SLoGin PageFrameCount::from_bytes(len).unwrap(), 28940fe15e0SLoGin prot_flags, 29040fe15e0SLoGin map_flags, 29140fe15e0SLoGin move |page, count, flags, mapper, flusher| { 292b5b571e0SLoGin VMA::zeroed(page, count, vm_flags, flags, mapper, flusher) 29340fe15e0SLoGin }, 294a17651b1SMemoryShore )? 295a17651b1SMemoryShore } else { 296a17651b1SMemoryShore self.mmap( 297a17651b1SMemoryShore round_hint_to_min(start_vaddr), 298a17651b1SMemoryShore PageFrameCount::from_bytes(len).unwrap(), 299a17651b1SMemoryShore prot_flags, 300a17651b1SMemoryShore map_flags, 301a17651b1SMemoryShore move |page, count, flags, _mapper, _flusher| { 30217dc5589SMemoryShore Ok(LockedVMA::new(VMA::new( 30317dc5589SMemoryShore VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE), 304a17651b1SMemoryShore vm_flags, 305a17651b1SMemoryShore flags, 30617dc5589SMemoryShore false, 30717dc5589SMemoryShore ))) 308a17651b1SMemoryShore }, 309a17651b1SMemoryShore )? 310a17651b1SMemoryShore }; 31140fe15e0SLoGin 31240fe15e0SLoGin return Ok(start_page); 31340fe15e0SLoGin } 31440fe15e0SLoGin 31540fe15e0SLoGin /// 向进程的地址空间映射页面 31640fe15e0SLoGin /// 31740fe15e0SLoGin /// # 参数 31840fe15e0SLoGin /// 31940fe15e0SLoGin /// - `addr`:映射的起始地址,如果为`None`,则由内核自动分配 32040fe15e0SLoGin /// - `page_count`:映射的页面数量 32140fe15e0SLoGin /// - `prot_flags`:保护标志 32240fe15e0SLoGin /// - `map_flags`:映射标志 32340fe15e0SLoGin /// - `map_func`:映射函数,用于创建VMA 32440fe15e0SLoGin /// 32540fe15e0SLoGin /// # Returns 32640fe15e0SLoGin /// 32740fe15e0SLoGin /// 返回映射的起始虚拟页帧 32840fe15e0SLoGin /// 32940fe15e0SLoGin /// # Errors 33040fe15e0SLoGin /// 33140fe15e0SLoGin /// - `EINVAL`:参数错误 33240fe15e0SLoGin pub fn mmap< 33340fe15e0SLoGin F: FnOnce( 33440fe15e0SLoGin VirtPageFrame, 33540fe15e0SLoGin PageFrameCount, 33640fe15e0SLoGin PageFlags<MMArch>, 33740fe15e0SLoGin &mut PageMapper, 33840fe15e0SLoGin &mut dyn Flusher<MMArch>, 33940fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError>, 34040fe15e0SLoGin >( 34140fe15e0SLoGin &mut self, 34240fe15e0SLoGin addr: Option<VirtAddr>, 34340fe15e0SLoGin page_count: PageFrameCount, 34440fe15e0SLoGin prot_flags: ProtFlags, 34540fe15e0SLoGin map_flags: MapFlags, 34640fe15e0SLoGin map_func: F, 34740fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 34840fe15e0SLoGin if page_count == PageFrameCount::new(0) { 34940fe15e0SLoGin return Err(SystemError::EINVAL); 35040fe15e0SLoGin } 3512eab6dd7S曾俊 // debug!("mmap: addr: {addr:?}, page_count: {page_count:?}, prot_flags: {prot_flags:?}, map_flags: {map_flags:?}"); 35240fe15e0SLoGin 35340fe15e0SLoGin // 找到未使用的区域 35440fe15e0SLoGin let region = match addr { 35540fe15e0SLoGin Some(vaddr) => { 35640fe15e0SLoGin self.mappings 35740fe15e0SLoGin .find_free_at(self.mmap_min, vaddr, page_count.bytes(), map_flags)? 35840fe15e0SLoGin } 35940fe15e0SLoGin None => self 36040fe15e0SLoGin .mappings 36140fe15e0SLoGin .find_free(self.mmap_min, page_count.bytes()) 36240fe15e0SLoGin .ok_or(SystemError::ENOMEM)?, 36340fe15e0SLoGin }; 36440fe15e0SLoGin 36540fe15e0SLoGin let page = VirtPageFrame::new(region.start()); 36640fe15e0SLoGin 3672eab6dd7S曾俊 // debug!("mmap: page: {:?}, region={region:?}", page.virt_address()); 36840fe15e0SLoGin 36940fe15e0SLoGin compiler_fence(Ordering::SeqCst); 37040fe15e0SLoGin let (mut active, mut inactive); 37140fe15e0SLoGin let flusher = if self.is_current() { 37240fe15e0SLoGin active = PageFlushAll::new(); 37340fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 37440fe15e0SLoGin } else { 37540fe15e0SLoGin inactive = InactiveFlusher::new(); 37640fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 37740fe15e0SLoGin }; 37840fe15e0SLoGin compiler_fence(Ordering::SeqCst); 37940fe15e0SLoGin // 映射页面,并将VMA插入到地址空间的VMA列表中 38040fe15e0SLoGin self.mappings.insert_vma(map_func( 38140fe15e0SLoGin page, 38240fe15e0SLoGin page_count, 38340fe15e0SLoGin PageFlags::from_prot_flags(prot_flags, true), 38440fe15e0SLoGin &mut self.user_mapper.utable, 38540fe15e0SLoGin flusher, 38640fe15e0SLoGin )?); 38740fe15e0SLoGin 38840fe15e0SLoGin return Ok(page); 38940fe15e0SLoGin } 39040fe15e0SLoGin 3914cfa009bSJomo /// 重映射内存区域 3924cfa009bSJomo /// 3934cfa009bSJomo /// # 参数 3944cfa009bSJomo /// 3954cfa009bSJomo /// - `old_vaddr`:原映射的起始地址 3964cfa009bSJomo /// - `old_len`:原映射的长度 3974cfa009bSJomo /// - `new_len`:重新映射的长度 3984cfa009bSJomo /// - `mremap_flags`:重映射标志 3994cfa009bSJomo /// - `new_vaddr`:重新映射的起始地址 4004cfa009bSJomo /// - `vm_flags`:旧内存区域标志 4014cfa009bSJomo /// 4024cfa009bSJomo /// # Returns 4034cfa009bSJomo /// 4044cfa009bSJomo /// 返回重映射的起始虚拟页帧地址 4054cfa009bSJomo /// 4064cfa009bSJomo /// # Errors 4074cfa009bSJomo /// 4084cfa009bSJomo /// - `EINVAL`:参数错误 4094cfa009bSJomo pub fn mremap( 4104cfa009bSJomo &mut self, 4114cfa009bSJomo old_vaddr: VirtAddr, 4124cfa009bSJomo old_len: usize, 4134cfa009bSJomo new_len: usize, 4144cfa009bSJomo mremap_flags: MremapFlags, 4154cfa009bSJomo new_vaddr: VirtAddr, 4164cfa009bSJomo vm_flags: VmFlags, 4174cfa009bSJomo ) -> Result<VirtAddr, SystemError> { 4184cfa009bSJomo // 检查新内存地址是否对齐 4194cfa009bSJomo if !new_vaddr.check_aligned(MMArch::PAGE_SIZE) { 4204cfa009bSJomo return Err(SystemError::EINVAL); 4214cfa009bSJomo } 4224cfa009bSJomo 4234cfa009bSJomo // 检查新、旧内存区域是否冲突 4244cfa009bSJomo let old_region = VirtRegion::new(old_vaddr, old_len); 4254cfa009bSJomo let new_region = VirtRegion::new(new_vaddr, new_len); 4264cfa009bSJomo if old_region.collide(&new_region) { 4274cfa009bSJomo return Err(SystemError::EINVAL); 4284cfa009bSJomo } 4294cfa009bSJomo 4303055390cSJomo // 初始化映射标志 4313055390cSJomo let mut map_flags: MapFlags = vm_flags.into(); 4323055390cSJomo // 初始化内存区域保护标志 4333055390cSJomo let prot_flags: ProtFlags = vm_flags.into(); 4343055390cSJomo 4354cfa009bSJomo // 取消新内存区域的原映射 4364cfa009bSJomo if mremap_flags.contains(MremapFlags::MREMAP_FIXED) { 4373055390cSJomo map_flags |= MapFlags::MAP_FIXED; 4384cfa009bSJomo let start_page = VirtPageFrame::new(new_vaddr); 4394cfa009bSJomo let page_count = PageFrameCount::from_bytes(new_len).unwrap(); 4404cfa009bSJomo self.munmap(start_page, page_count)?; 4414cfa009bSJomo } 4424cfa009bSJomo 4434cfa009bSJomo // 获取映射后的新内存页面 444a17651b1SMemoryShore let new_page = self.map_anonymous(new_vaddr, new_len, prot_flags, map_flags, true, true)?; 4454cfa009bSJomo let new_page_vaddr = new_page.virt_address(); 4464cfa009bSJomo 4474cfa009bSJomo // 拷贝旧内存区域内容到新内存区域 4484cfa009bSJomo let old_buffer_reader = 4494cfa009bSJomo UserBufferReader::new(old_vaddr.data() as *const u8, old_len, true)?; 4504cfa009bSJomo let old_buf: &[u8] = old_buffer_reader.read_from_user(0)?; 4514cfa009bSJomo let mut new_buffer_writer = 4524cfa009bSJomo UserBufferWriter::new(new_page_vaddr.data() as *mut u8, new_len, true)?; 4534cfa009bSJomo let new_buf: &mut [u8] = new_buffer_writer.buffer(0)?; 4544cfa009bSJomo let len = old_buf.len().min(new_buf.len()); 455b5b571e0SLoGin new_buf[..len].copy_from_slice(&old_buf[..len]); 4564cfa009bSJomo 4574cfa009bSJomo return Ok(new_page_vaddr); 4584cfa009bSJomo } 4594cfa009bSJomo 46040fe15e0SLoGin /// 取消进程的地址空间中的映射 46140fe15e0SLoGin /// 46240fe15e0SLoGin /// # 参数 46340fe15e0SLoGin /// 46440fe15e0SLoGin /// - `start_page`:起始页帧 46540fe15e0SLoGin /// - `page_count`:取消映射的页帧数量 46640fe15e0SLoGin /// 46740fe15e0SLoGin /// # Errors 46840fe15e0SLoGin /// 46940fe15e0SLoGin /// - `EINVAL`:参数错误 47040fe15e0SLoGin /// - `ENOMEM`:内存不足 47140fe15e0SLoGin pub fn munmap( 47240fe15e0SLoGin &mut self, 47340fe15e0SLoGin start_page: VirtPageFrame, 47440fe15e0SLoGin page_count: PageFrameCount, 47540fe15e0SLoGin ) -> Result<(), SystemError> { 47640fe15e0SLoGin let to_unmap = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 47740fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 47840fe15e0SLoGin 47940fe15e0SLoGin let regions: Vec<Arc<LockedVMA>> = self.mappings.conflicts(to_unmap).collect::<Vec<_>>(); 48040fe15e0SLoGin 48140fe15e0SLoGin for r in regions { 48240fe15e0SLoGin let r = r.lock().region; 48340fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 48440fe15e0SLoGin let intersection = r.lock().region().intersect(&to_unmap).unwrap(); 48556cc4dbeSJomo let split_result = r.extract(intersection, &self.user_mapper.utable).unwrap(); 48640fe15e0SLoGin 48740fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 48840fe15e0SLoGin 489b5b571e0SLoGin if let Some(before) = split_result.prev { 49040fe15e0SLoGin // 如果前面有VMA,则需要将前面的VMA重新插入到地址空间的VMA列表中 49140fe15e0SLoGin self.mappings.insert_vma(before); 49240fe15e0SLoGin } 49340fe15e0SLoGin 494b5b571e0SLoGin if let Some(after) = split_result.after { 49540fe15e0SLoGin // 如果后面有VMA,则需要将后面的VMA重新插入到地址空间的VMA列表中 49640fe15e0SLoGin self.mappings.insert_vma(after); 49740fe15e0SLoGin } 49840fe15e0SLoGin 49940fe15e0SLoGin r.unmap(&mut self.user_mapper.utable, &mut flusher); 50040fe15e0SLoGin } 50140fe15e0SLoGin 50240fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 50340fe15e0SLoGin 50440fe15e0SLoGin return Ok(()); 50540fe15e0SLoGin } 50640fe15e0SLoGin 50740fe15e0SLoGin pub fn mprotect( 50840fe15e0SLoGin &mut self, 50940fe15e0SLoGin start_page: VirtPageFrame, 51040fe15e0SLoGin page_count: PageFrameCount, 51140fe15e0SLoGin prot_flags: ProtFlags, 51240fe15e0SLoGin ) -> Result<(), SystemError> { 5132eab6dd7S曾俊 // debug!( 51440fe15e0SLoGin // "mprotect: start_page: {:?}, page_count: {:?}, prot_flags:{prot_flags:?}", 51540fe15e0SLoGin // start_page, 51640fe15e0SLoGin // page_count 51740fe15e0SLoGin // ); 51840fe15e0SLoGin let (mut active, mut inactive); 519*bd70d2d1SLoGin let flusher = if self.is_current() { 52040fe15e0SLoGin active = PageFlushAll::new(); 52140fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 52240fe15e0SLoGin } else { 52340fe15e0SLoGin inactive = InactiveFlusher::new(); 52440fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 52540fe15e0SLoGin }; 52640fe15e0SLoGin 52740fe15e0SLoGin let mapper = &mut self.user_mapper.utable; 52840fe15e0SLoGin let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 5292eab6dd7S曾俊 // debug!("mprotect: region: {:?}", region); 53040fe15e0SLoGin 53140fe15e0SLoGin let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 5322eab6dd7S曾俊 // debug!("mprotect: regions: {:?}", regions); 53340fe15e0SLoGin 53440fe15e0SLoGin for r in regions { 5352eab6dd7S曾俊 // debug!("mprotect: r: {:?}", r); 536b5b571e0SLoGin let r = *r.lock().region(); 53740fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 53840fe15e0SLoGin 53940fe15e0SLoGin let intersection = r.lock().region().intersect(®ion).unwrap(); 54056cc4dbeSJomo let split_result = r 54156cc4dbeSJomo .extract(intersection, mapper) 54256cc4dbeSJomo .expect("Failed to extract VMA"); 54340fe15e0SLoGin 544b5b571e0SLoGin if let Some(before) = split_result.prev { 54540fe15e0SLoGin self.mappings.insert_vma(before); 54640fe15e0SLoGin } 547b5b571e0SLoGin if let Some(after) = split_result.after { 54840fe15e0SLoGin self.mappings.insert_vma(after); 54940fe15e0SLoGin } 55040fe15e0SLoGin 55140fe15e0SLoGin let mut r_guard = r.lock(); 55240fe15e0SLoGin // 如果VMA的保护标志不允许指定的修改,则返回错误 55340fe15e0SLoGin if !r_guard.can_have_flags(prot_flags) { 55440fe15e0SLoGin drop(r_guard); 55540fe15e0SLoGin self.mappings.insert_vma(r.clone()); 55640fe15e0SLoGin return Err(SystemError::EACCES); 55740fe15e0SLoGin } 55840fe15e0SLoGin 55938458c72SMemoryShore r_guard.set_vm_flags(VmFlags::from(prot_flags)); 56038458c72SMemoryShore 56140fe15e0SLoGin let new_flags: PageFlags<MMArch> = r_guard 56240fe15e0SLoGin .flags() 56340fe15e0SLoGin .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC)) 56440fe15e0SLoGin .set_write(prot_flags.contains(ProtFlags::PROT_WRITE)); 56540fe15e0SLoGin 566*bd70d2d1SLoGin r_guard.remap(new_flags, mapper, &mut *flusher)?; 56740fe15e0SLoGin drop(r_guard); 56840fe15e0SLoGin self.mappings.insert_vma(r); 56940fe15e0SLoGin } 57040fe15e0SLoGin 57140fe15e0SLoGin return Ok(()); 57240fe15e0SLoGin } 57340fe15e0SLoGin 574a17651b1SMemoryShore pub fn madvise( 575a17651b1SMemoryShore &mut self, 576a17651b1SMemoryShore start_page: VirtPageFrame, 577a17651b1SMemoryShore page_count: PageFrameCount, 578a17651b1SMemoryShore behavior: MadvFlags, 579a17651b1SMemoryShore ) -> Result<(), SystemError> { 580a17651b1SMemoryShore let (mut active, mut inactive); 581*bd70d2d1SLoGin let flusher = if self.is_current() { 582a17651b1SMemoryShore active = PageFlushAll::new(); 583a17651b1SMemoryShore &mut active as &mut dyn Flusher<MMArch> 584a17651b1SMemoryShore } else { 585a17651b1SMemoryShore inactive = InactiveFlusher::new(); 586a17651b1SMemoryShore &mut inactive as &mut dyn Flusher<MMArch> 587a17651b1SMemoryShore }; 588a17651b1SMemoryShore 589a17651b1SMemoryShore let mapper = &mut self.user_mapper.utable; 590a17651b1SMemoryShore 591a17651b1SMemoryShore let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 592a17651b1SMemoryShore let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 593a17651b1SMemoryShore 594a17651b1SMemoryShore for r in regions { 595a17651b1SMemoryShore let r = *r.lock().region(); 596a17651b1SMemoryShore let r = self.mappings.remove_vma(&r).unwrap(); 597a17651b1SMemoryShore 598a17651b1SMemoryShore let intersection = r.lock().region().intersect(®ion).unwrap(); 599a17651b1SMemoryShore let split_result = r 600a17651b1SMemoryShore .extract(intersection, mapper) 601a17651b1SMemoryShore .expect("Failed to extract VMA"); 602a17651b1SMemoryShore 603a17651b1SMemoryShore if let Some(before) = split_result.prev { 604a17651b1SMemoryShore self.mappings.insert_vma(before); 605a17651b1SMemoryShore } 606a17651b1SMemoryShore if let Some(after) = split_result.after { 607a17651b1SMemoryShore self.mappings.insert_vma(after); 608a17651b1SMemoryShore } 609*bd70d2d1SLoGin r.do_madvise(behavior, mapper, &mut *flusher)?; 610a17651b1SMemoryShore self.mappings.insert_vma(r); 611a17651b1SMemoryShore } 612a17651b1SMemoryShore Ok(()) 613a17651b1SMemoryShore } 614a17651b1SMemoryShore 61540fe15e0SLoGin /// 创建新的用户栈 61640fe15e0SLoGin /// 61740fe15e0SLoGin /// ## 参数 61840fe15e0SLoGin /// 61940fe15e0SLoGin /// - `size`:栈的大小 62040fe15e0SLoGin pub fn new_user_stack(&mut self, size: usize) -> Result<(), SystemError> { 62140fe15e0SLoGin assert!(self.user_stack.is_none(), "User stack already exists"); 62240fe15e0SLoGin let stack = UserStack::new(self, None, size)?; 62340fe15e0SLoGin self.user_stack = Some(stack); 62440fe15e0SLoGin return Ok(()); 62540fe15e0SLoGin } 62640fe15e0SLoGin 62740fe15e0SLoGin #[inline(always)] 62840fe15e0SLoGin pub fn user_stack_mut(&mut self) -> Option<&mut UserStack> { 62940fe15e0SLoGin return self.user_stack.as_mut(); 63040fe15e0SLoGin } 63140fe15e0SLoGin 63240fe15e0SLoGin /// 取消用户空间内的所有映射 63340fe15e0SLoGin pub unsafe fn unmap_all(&mut self) { 63440fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 63540fe15e0SLoGin for vma in self.mappings.iter_vmas() { 6366fc066acSJomo if vma.mapped() { 63740fe15e0SLoGin vma.unmap(&mut self.user_mapper.utable, &mut flusher); 63840fe15e0SLoGin } 63940fe15e0SLoGin } 6406fc066acSJomo } 64140fe15e0SLoGin 64240fe15e0SLoGin /// 设置进程的堆的内存空间 64340fe15e0SLoGin /// 64440fe15e0SLoGin /// ## 参数 64540fe15e0SLoGin /// 64640fe15e0SLoGin /// - `new_brk`:新的堆的结束地址。需要满足页对齐要求,并且是用户空间地址,且大于等于当前的堆的起始地址 64740fe15e0SLoGin /// 64840fe15e0SLoGin /// ## 返回值 64940fe15e0SLoGin /// 65040fe15e0SLoGin /// 返回旧的堆的结束地址 65140fe15e0SLoGin pub unsafe fn set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError> { 65240fe15e0SLoGin assert!(new_brk.check_aligned(MMArch::PAGE_SIZE)); 65340fe15e0SLoGin 65440fe15e0SLoGin if !new_brk.check_user() || new_brk < self.brk_start { 65540fe15e0SLoGin return Err(SystemError::EFAULT); 65640fe15e0SLoGin } 65740fe15e0SLoGin 65840fe15e0SLoGin let old_brk = self.brk; 6591496ba7bSLoGin 66040fe15e0SLoGin if new_brk > self.brk { 66140fe15e0SLoGin let len = new_brk - self.brk; 66240fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 66340fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED; 664a17651b1SMemoryShore self.map_anonymous(old_brk, len, prot_flags, map_flags, true, false)?; 6651496ba7bSLoGin 66640fe15e0SLoGin self.brk = new_brk; 66740fe15e0SLoGin return Ok(old_brk); 66840fe15e0SLoGin } else { 66940fe15e0SLoGin let unmap_len = self.brk - new_brk; 67040fe15e0SLoGin let unmap_start = new_brk; 67140fe15e0SLoGin if unmap_len == 0 { 67240fe15e0SLoGin return Ok(old_brk); 67340fe15e0SLoGin } 67440fe15e0SLoGin self.munmap( 67540fe15e0SLoGin VirtPageFrame::new(unmap_start), 67640fe15e0SLoGin PageFrameCount::from_bytes(unmap_len).unwrap(), 67740fe15e0SLoGin )?; 67840fe15e0SLoGin self.brk = new_brk; 67940fe15e0SLoGin return Ok(old_brk); 68040fe15e0SLoGin } 68140fe15e0SLoGin } 68240fe15e0SLoGin 68340fe15e0SLoGin pub unsafe fn sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError> { 68440fe15e0SLoGin if incr == 0 { 68540fe15e0SLoGin return Ok(self.brk); 68640fe15e0SLoGin } 68740fe15e0SLoGin 68840fe15e0SLoGin let new_brk = if incr > 0 { 68940fe15e0SLoGin self.brk + incr as usize 69040fe15e0SLoGin } else { 691b5b571e0SLoGin self.brk - incr.unsigned_abs() 69240fe15e0SLoGin }; 69340fe15e0SLoGin 69440fe15e0SLoGin let new_brk = VirtAddr::new(page_align_up(new_brk.data())); 69540fe15e0SLoGin 69640fe15e0SLoGin return self.set_brk(new_brk); 69740fe15e0SLoGin } 69840fe15e0SLoGin } 69940fe15e0SLoGin 70040fe15e0SLoGin impl Drop for InnerAddressSpace { 70140fe15e0SLoGin fn drop(&mut self) { 70240fe15e0SLoGin unsafe { 70340fe15e0SLoGin self.unmap_all(); 70440fe15e0SLoGin } 70540fe15e0SLoGin } 70640fe15e0SLoGin } 70740fe15e0SLoGin 70840fe15e0SLoGin #[derive(Debug, Hash)] 70940fe15e0SLoGin pub struct UserMapper { 71040fe15e0SLoGin pub utable: PageMapper, 71140fe15e0SLoGin } 71240fe15e0SLoGin 71340fe15e0SLoGin impl UserMapper { 71440fe15e0SLoGin pub fn new(utable: PageMapper) -> Self { 71540fe15e0SLoGin return Self { utable }; 71640fe15e0SLoGin } 717a17651b1SMemoryShore 718a17651b1SMemoryShore /// 拷贝用户空间映射 719a17651b1SMemoryShore /// ## 参数 720a17651b1SMemoryShore /// 721a17651b1SMemoryShore /// - `umapper`: 要拷贝的用户空间 722a17651b1SMemoryShore /// - `copy_on_write`: 是否写时复制 723a17651b1SMemoryShore pub unsafe fn clone_from(&mut self, umapper: &mut Self, copy_on_write: bool) { 724a17651b1SMemoryShore self.utable 725a17651b1SMemoryShore .clone_user_mapping(&mut umapper.utable, copy_on_write); 726a17651b1SMemoryShore } 72740fe15e0SLoGin } 72840fe15e0SLoGin 72940fe15e0SLoGin impl Drop for UserMapper { 73040fe15e0SLoGin fn drop(&mut self) { 73140fe15e0SLoGin if self.utable.is_current() { 73240fe15e0SLoGin // 如果当前要被销毁的用户空间的页表是当前进程的页表,那么就切换回初始内核页表 73340fe15e0SLoGin unsafe { MMArch::set_table(PageTableKind::User, MMArch::initial_page_table()) } 73440fe15e0SLoGin } 73540fe15e0SLoGin // 释放用户空间顶层页表占用的页帧 73640fe15e0SLoGin // 请注意,在释放这个页帧之前,用户页表应该已经被完全释放,否则会产生内存泄露 73740fe15e0SLoGin unsafe { 73840fe15e0SLoGin deallocate_page_frames( 73940fe15e0SLoGin PhysPageFrame::new(self.utable.table().phys()), 74040fe15e0SLoGin PageFrameCount::new(1), 7416fc066acSJomo &mut page_manager_lock_irqsave(), 74240fe15e0SLoGin ) 74340fe15e0SLoGin }; 74440fe15e0SLoGin } 74540fe15e0SLoGin } 74640fe15e0SLoGin 74740fe15e0SLoGin /// 用户空间映射信息 74840fe15e0SLoGin #[derive(Debug)] 74940fe15e0SLoGin pub struct UserMappings { 75040fe15e0SLoGin /// 当前用户空间的虚拟内存区域 75140fe15e0SLoGin vmas: HashSet<Arc<LockedVMA>>, 75240fe15e0SLoGin /// 当前用户空间的VMA空洞 75340fe15e0SLoGin vm_holes: BTreeMap<VirtAddr, usize>, 75440fe15e0SLoGin } 75540fe15e0SLoGin 75640fe15e0SLoGin impl UserMappings { 75740fe15e0SLoGin pub fn new() -> Self { 75840fe15e0SLoGin return Self { 75940fe15e0SLoGin vmas: HashSet::new(), 76040fe15e0SLoGin vm_holes: core::iter::once((VirtAddr::new(0), MMArch::USER_END_VADDR.data())) 76140fe15e0SLoGin .collect::<BTreeMap<_, _>>(), 76240fe15e0SLoGin }; 76340fe15e0SLoGin } 76440fe15e0SLoGin 76540fe15e0SLoGin /// 判断当前进程的VMA内,是否有包含指定的虚拟地址的VMA。 76640fe15e0SLoGin /// 76740fe15e0SLoGin /// 如果有,返回包含指定虚拟地址的VMA的Arc指针,否则返回None。 76840fe15e0SLoGin #[allow(dead_code)] 76940fe15e0SLoGin pub fn contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 77040fe15e0SLoGin for v in self.vmas.iter() { 77140fe15e0SLoGin let guard = v.lock(); 77240fe15e0SLoGin if guard.region.contains(vaddr) { 77340fe15e0SLoGin return Some(v.clone()); 77440fe15e0SLoGin } 77540fe15e0SLoGin } 77640fe15e0SLoGin return None; 77740fe15e0SLoGin } 77840fe15e0SLoGin 779a17651b1SMemoryShore /// 向下寻找距离虚拟地址最近的VMA 780a17651b1SMemoryShore /// ## 参数 781a17651b1SMemoryShore /// 782a17651b1SMemoryShore /// - `vaddr`: 虚拟地址 783a17651b1SMemoryShore /// 784a17651b1SMemoryShore /// ## 返回值 785a17651b1SMemoryShore /// - Some(Arc<LockedVMA>): 虚拟地址所在的或最近的下一个VMA 786a17651b1SMemoryShore /// - None: 未找到VMA 787a17651b1SMemoryShore #[allow(dead_code)] 788a17651b1SMemoryShore pub fn find_nearest(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 789a17651b1SMemoryShore let mut nearest: Option<Arc<LockedVMA>> = None; 790a17651b1SMemoryShore for v in self.vmas.iter() { 791a17651b1SMemoryShore let guard = v.lock(); 792a17651b1SMemoryShore if guard.region.contains(vaddr) { 793a17651b1SMemoryShore return Some(v.clone()); 794a17651b1SMemoryShore } 795a17651b1SMemoryShore if guard.region.start > vaddr 796a17651b1SMemoryShore && if let Some(ref nearest) = nearest { 797a17651b1SMemoryShore guard.region.start < nearest.lock().region.start 798a17651b1SMemoryShore } else { 799a17651b1SMemoryShore true 800a17651b1SMemoryShore } 801a17651b1SMemoryShore { 802a17651b1SMemoryShore nearest = Some(v.clone()); 803a17651b1SMemoryShore } 804a17651b1SMemoryShore } 805a17651b1SMemoryShore return nearest; 806a17651b1SMemoryShore } 807a17651b1SMemoryShore 80840fe15e0SLoGin /// 获取当前进程的地址空间中,与给定虚拟地址范围有重叠的VMA的迭代器。 80940fe15e0SLoGin pub fn conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_ { 81040fe15e0SLoGin let r = self 81140fe15e0SLoGin .vmas 81240fe15e0SLoGin .iter() 813b5b571e0SLoGin .filter(move |v| v.lock().region.intersect(&request).is_some()) 81440fe15e0SLoGin .cloned(); 81540fe15e0SLoGin return r; 81640fe15e0SLoGin } 81740fe15e0SLoGin 81840fe15e0SLoGin /// 在当前进程的地址空间中,寻找第一个符合条件的空闲的虚拟内存范围。 81940fe15e0SLoGin /// 82040fe15e0SLoGin /// @param min_vaddr 最小的起始地址 82140fe15e0SLoGin /// @param size 请求的大小 82240fe15e0SLoGin /// 82340fe15e0SLoGin /// @return 如果找到了,返回虚拟内存范围,否则返回None 82440fe15e0SLoGin pub fn find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion> { 82540fe15e0SLoGin let _vaddr = min_vaddr; 82640fe15e0SLoGin let mut iter = self 82740fe15e0SLoGin .vm_holes 82840fe15e0SLoGin .iter() 82940fe15e0SLoGin .skip_while(|(hole_vaddr, hole_size)| hole_vaddr.add(**hole_size) <= min_vaddr); 83040fe15e0SLoGin 83140fe15e0SLoGin let (hole_vaddr, size) = iter.find(|(hole_vaddr, hole_size)| { 83240fe15e0SLoGin // 计算当前空洞的可用大小 83340fe15e0SLoGin let available_size: usize = 83440fe15e0SLoGin if hole_vaddr <= &&min_vaddr && min_vaddr <= hole_vaddr.add(**hole_size) { 83540fe15e0SLoGin **hole_size - (min_vaddr - **hole_vaddr) 83640fe15e0SLoGin } else { 83740fe15e0SLoGin **hole_size 83840fe15e0SLoGin }; 83940fe15e0SLoGin 84040fe15e0SLoGin size <= available_size 84140fe15e0SLoGin })?; 84240fe15e0SLoGin 84340fe15e0SLoGin // 创建一个新的虚拟内存范围。 84440fe15e0SLoGin let region = VirtRegion::new(cmp::max(*hole_vaddr, min_vaddr), *size); 8454cfa009bSJomo 84640fe15e0SLoGin return Some(region); 84740fe15e0SLoGin } 84840fe15e0SLoGin 84940fe15e0SLoGin pub fn find_free_at( 85040fe15e0SLoGin &self, 85140fe15e0SLoGin min_vaddr: VirtAddr, 85240fe15e0SLoGin vaddr: VirtAddr, 85340fe15e0SLoGin size: usize, 85440fe15e0SLoGin flags: MapFlags, 85540fe15e0SLoGin ) -> Result<VirtRegion, SystemError> { 85640fe15e0SLoGin // 如果没有指定地址,那么就在当前进程的地址空间中寻找一个空闲的虚拟内存范围。 85740fe15e0SLoGin if vaddr == VirtAddr::new(0) { 85840fe15e0SLoGin return self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM); 85940fe15e0SLoGin } 86040fe15e0SLoGin 86140fe15e0SLoGin // 如果指定了地址,那么就检查指定的地址是否可用。 86240fe15e0SLoGin 86340fe15e0SLoGin let requested = VirtRegion::new(vaddr, size); 86440fe15e0SLoGin 86540fe15e0SLoGin if requested.end() >= MMArch::USER_END_VADDR || !vaddr.check_aligned(MMArch::PAGE_SIZE) { 86640fe15e0SLoGin return Err(SystemError::EINVAL); 86740fe15e0SLoGin } 86840fe15e0SLoGin 86940fe15e0SLoGin if let Some(_x) = self.conflicts(requested).next() { 87040fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED_NOREPLACE) { 87140fe15e0SLoGin // 如果指定了 MAP_FIXED_NOREPLACE 标志,由于所指定的地址无法成功建立映射,则放弃映射,不对地址做修正 87240fe15e0SLoGin return Err(SystemError::EEXIST); 87340fe15e0SLoGin } 87440fe15e0SLoGin 87540fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED) { 87640fe15e0SLoGin // todo: 支持MAP_FIXED标志对已有的VMA进行覆盖 8771074eb34SSamuel Dai return Err(SystemError::ENOSYS); 87840fe15e0SLoGin } 87940fe15e0SLoGin 88040fe15e0SLoGin // 如果没有指定MAP_FIXED标志,那么就对地址做修正 88140fe15e0SLoGin let requested = self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM)?; 88240fe15e0SLoGin return Ok(requested); 88340fe15e0SLoGin } 88440fe15e0SLoGin 88540fe15e0SLoGin return Ok(requested); 88640fe15e0SLoGin } 88740fe15e0SLoGin 88840fe15e0SLoGin /// 在当前进程的地址空间中,保留一个指定大小的区域,使得该区域不在空洞中。 88940fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 89040fe15e0SLoGin /// 89140fe15e0SLoGin /// @param region 要保留的区域 89240fe15e0SLoGin /// 89340fe15e0SLoGin /// 请注意,在调用本函数之前,必须先确定region所在范围内没有VMA。 89440fe15e0SLoGin fn reserve_hole(&mut self, region: &VirtRegion) { 89540fe15e0SLoGin let prev_hole: Option<(&VirtAddr, &mut usize)> = 896971462beSGnoCiYeH self.vm_holes.range_mut(..=region.start()).next_back(); 89740fe15e0SLoGin 89840fe15e0SLoGin if let Some((prev_hole_vaddr, prev_hole_size)) = prev_hole { 89940fe15e0SLoGin let prev_hole_end = prev_hole_vaddr.add(*prev_hole_size); 90040fe15e0SLoGin 90140fe15e0SLoGin if prev_hole_end > region.start() { 90240fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的起始地址,那么就需要调整前一个空洞的大小。 90340fe15e0SLoGin *prev_hole_size = region.start().data() - prev_hole_vaddr.data(); 90440fe15e0SLoGin } 90540fe15e0SLoGin 90640fe15e0SLoGin if prev_hole_end > region.end() { 90740fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的结束地址,那么就需要增加一个新的空洞。 90840fe15e0SLoGin self.vm_holes 90940fe15e0SLoGin .insert(region.end(), prev_hole_end - region.end()); 91040fe15e0SLoGin } 91140fe15e0SLoGin } 91240fe15e0SLoGin } 91340fe15e0SLoGin 91440fe15e0SLoGin /// 在当前进程的地址空间中,释放一个指定大小的区域,使得该区域成为一个空洞。 91540fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 91640fe15e0SLoGin fn unreserve_hole(&mut self, region: &VirtRegion) { 91740fe15e0SLoGin // 如果将要插入的空洞与后一个空洞相邻,那么就需要合并。 91840fe15e0SLoGin let next_hole_size: Option<usize> = self.vm_holes.remove(®ion.end()); 91940fe15e0SLoGin 92040fe15e0SLoGin if let Some((_prev_hole_vaddr, prev_hole_size)) = self 92140fe15e0SLoGin .vm_holes 92240fe15e0SLoGin .range_mut(..region.start()) 92340fe15e0SLoGin .next_back() 92440fe15e0SLoGin .filter(|(offset, size)| offset.data() + **size == region.start().data()) 92540fe15e0SLoGin { 92640fe15e0SLoGin *prev_hole_size += region.size() + next_hole_size.unwrap_or(0); 92740fe15e0SLoGin } else { 92840fe15e0SLoGin self.vm_holes 92940fe15e0SLoGin .insert(region.start(), region.size() + next_hole_size.unwrap_or(0)); 93040fe15e0SLoGin } 93140fe15e0SLoGin } 93240fe15e0SLoGin 93340fe15e0SLoGin /// 在当前进程的映射关系中,插入一个新的VMA。 93440fe15e0SLoGin pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) { 935b5b571e0SLoGin let region = vma.lock().region; 93640fe15e0SLoGin // 要求插入的地址范围必须是空闲的,也就是说,当前进程的地址空间中,不能有任何与之重叠的VMA。 93740fe15e0SLoGin assert!(self.conflicts(region).next().is_none()); 93840fe15e0SLoGin self.reserve_hole(®ion); 93940fe15e0SLoGin 94040fe15e0SLoGin self.vmas.insert(vma); 94140fe15e0SLoGin } 94240fe15e0SLoGin 94340fe15e0SLoGin /// @brief 删除一个VMA,并把对应的地址空间加入空洞中。 94440fe15e0SLoGin /// 94540fe15e0SLoGin /// 这里不会取消VMA对应的地址的映射 94640fe15e0SLoGin /// 94740fe15e0SLoGin /// @param region 要删除的VMA所在的地址范围 94840fe15e0SLoGin /// 94940fe15e0SLoGin /// @return 如果成功删除了VMA,则返回被删除的VMA,否则返回None 95040fe15e0SLoGin /// 如果没有可以删除的VMA,则不会执行删除操作,并报告失败。 95140fe15e0SLoGin pub fn remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>> { 95240fe15e0SLoGin // 请注意,由于这里会对每个VMA加锁,因此性能很低 95340fe15e0SLoGin let vma: Arc<LockedVMA> = self 95440fe15e0SLoGin .vmas 95540fe15e0SLoGin .drain_filter(|vma| vma.lock().region == *region) 95640fe15e0SLoGin .next()?; 95740fe15e0SLoGin self.unreserve_hole(region); 95840fe15e0SLoGin 95940fe15e0SLoGin return Some(vma); 96040fe15e0SLoGin } 96140fe15e0SLoGin 96240fe15e0SLoGin /// @brief Get the iterator of all VMAs in this process. 96340fe15e0SLoGin pub fn iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>> { 96440fe15e0SLoGin return self.vmas.iter(); 96540fe15e0SLoGin } 96640fe15e0SLoGin } 96740fe15e0SLoGin 96840fe15e0SLoGin impl Default for UserMappings { 96940fe15e0SLoGin fn default() -> Self { 97040fe15e0SLoGin return Self::new(); 97140fe15e0SLoGin } 97240fe15e0SLoGin } 97340fe15e0SLoGin 97440fe15e0SLoGin /// 加了锁的VMA 97540fe15e0SLoGin /// 97640fe15e0SLoGin /// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。 97740fe15e0SLoGin #[derive(Debug)] 97856cc4dbeSJomo pub struct LockedVMA { 97956cc4dbeSJomo /// 用于计算哈希值,避免总是获取vma锁来计算哈希值 98056cc4dbeSJomo id: usize, 98156cc4dbeSJomo vma: SpinLock<VMA>, 98256cc4dbeSJomo } 98340fe15e0SLoGin 98440fe15e0SLoGin impl core::hash::Hash for LockedVMA { 98540fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 98656cc4dbeSJomo self.id.hash(state); 98740fe15e0SLoGin } 98840fe15e0SLoGin } 98940fe15e0SLoGin 99040fe15e0SLoGin impl PartialEq for LockedVMA { 99140fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 99256cc4dbeSJomo self.id.eq(&other.id) 99340fe15e0SLoGin } 99440fe15e0SLoGin } 99540fe15e0SLoGin 99640fe15e0SLoGin impl Eq for LockedVMA {} 99740fe15e0SLoGin 99840fe15e0SLoGin #[allow(dead_code)] 99940fe15e0SLoGin impl LockedVMA { 100040fe15e0SLoGin pub fn new(vma: VMA) -> Arc<Self> { 100156cc4dbeSJomo let r = Arc::new(Self { 100256cc4dbeSJomo id: LOCKEDVMA_ID_ALLOCATOR.alloc().unwrap(), 100356cc4dbeSJomo vma: SpinLock::new(vma), 100456cc4dbeSJomo }); 100556cc4dbeSJomo r.vma.lock().self_ref = Arc::downgrade(&r); 100640fe15e0SLoGin return r; 100740fe15e0SLoGin } 100840fe15e0SLoGin 10096fc066acSJomo pub fn id(&self) -> usize { 10106fc066acSJomo self.id 10116fc066acSJomo } 10126fc066acSJomo 101340fe15e0SLoGin pub fn lock(&self) -> SpinLockGuard<VMA> { 101456cc4dbeSJomo return self.vma.lock(); 101540fe15e0SLoGin } 101640fe15e0SLoGin 101740fe15e0SLoGin /// 调整当前VMA的页面的标志位 101840fe15e0SLoGin /// 101940fe15e0SLoGin /// TODO:增加调整虚拟页映射的物理地址的功能 102040fe15e0SLoGin /// 102140fe15e0SLoGin /// @param flags 新的标志位 102240fe15e0SLoGin /// @param mapper 页表映射器 102340fe15e0SLoGin /// @param flusher 页表项刷新器 102440fe15e0SLoGin /// 102540fe15e0SLoGin pub fn remap( 102640fe15e0SLoGin &self, 102740fe15e0SLoGin flags: PageFlags<MMArch>, 102840fe15e0SLoGin mapper: &mut PageMapper, 102940fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 103040fe15e0SLoGin ) -> Result<(), SystemError> { 103140fe15e0SLoGin let mut guard = self.lock(); 103240fe15e0SLoGin for page in guard.region.pages() { 103340fe15e0SLoGin // 暂时要求所有的页帧都已经映射到页表 103440fe15e0SLoGin // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了 103540fe15e0SLoGin let r = unsafe { 103640fe15e0SLoGin mapper 103740fe15e0SLoGin .remap(page.virt_address(), flags) 103840fe15e0SLoGin .expect("Failed to remap, beacuse of some page is not mapped") 103940fe15e0SLoGin }; 104040fe15e0SLoGin flusher.consume(r); 104140fe15e0SLoGin } 104240fe15e0SLoGin guard.flags = flags; 104340fe15e0SLoGin return Ok(()); 104440fe15e0SLoGin } 104540fe15e0SLoGin 104640fe15e0SLoGin pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>) { 10471a62e776SLoGin // todo: 如果当前vma与文件相关,完善文件相关的逻辑 10481a62e776SLoGin 104940fe15e0SLoGin let mut guard = self.lock(); 105056cc4dbeSJomo 105156cc4dbeSJomo // 获取物理页的anon_vma的守卫 10526fc066acSJomo let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> = 10536fc066acSJomo page_manager_lock_irqsave(); 105440fe15e0SLoGin for page in guard.region.pages() { 1055a17651b1SMemoryShore if mapper.translate(page.virt_address()).is_none() { 1056a17651b1SMemoryShore continue; 1057a17651b1SMemoryShore } 105840fe15e0SLoGin let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) } 105940fe15e0SLoGin .expect("Failed to unmap, beacuse of some page is not mapped"); 106040fe15e0SLoGin 106156cc4dbeSJomo // 从anon_vma中删除当前VMA 10626fc066acSJomo let page = page_manager_guard.get_mut(&paddr); 106356cc4dbeSJomo page.remove_vma(self); 106440fe15e0SLoGin 106556cc4dbeSJomo // 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页. 106656cc4dbeSJomo if page.can_deallocate() { 106756cc4dbeSJomo unsafe { 106856cc4dbeSJomo deallocate_page_frames( 106956cc4dbeSJomo PhysPageFrame::new(paddr), 107056cc4dbeSJomo PageFrameCount::new(1), 10716fc066acSJomo &mut page_manager_guard, 107256cc4dbeSJomo ) 107356cc4dbeSJomo }; 107456cc4dbeSJomo } 107540fe15e0SLoGin 107640fe15e0SLoGin flusher.consume(flush); 107740fe15e0SLoGin } 107840fe15e0SLoGin guard.mapped = false; 107940fe15e0SLoGin } 108040fe15e0SLoGin 108140fe15e0SLoGin pub fn mapped(&self) -> bool { 108256cc4dbeSJomo return self.vma.lock().mapped; 108340fe15e0SLoGin } 108440fe15e0SLoGin 108540fe15e0SLoGin /// 将当前VMA进行切分,切分成3个VMA,分别是: 108640fe15e0SLoGin /// 108740fe15e0SLoGin /// 1. 前面的VMA,如果没有则为None 108840fe15e0SLoGin /// 2. 中间的VMA,也就是传入的Region 108940fe15e0SLoGin /// 3. 后面的VMA,如果没有则为None 109056cc4dbeSJomo pub fn extract(&self, region: VirtRegion, utable: &PageMapper) -> Option<VMASplitResult> { 109140fe15e0SLoGin assert!(region.start().check_aligned(MMArch::PAGE_SIZE)); 109240fe15e0SLoGin assert!(region.end().check_aligned(MMArch::PAGE_SIZE)); 109340fe15e0SLoGin 109440fe15e0SLoGin let mut guard = self.lock(); 109540fe15e0SLoGin { 109640fe15e0SLoGin // 如果传入的region不在当前VMA的范围内,则直接返回None 109740fe15e0SLoGin if unlikely(region.start() < guard.region.start() || region.end() > guard.region.end()) 109840fe15e0SLoGin { 109940fe15e0SLoGin return None; 110040fe15e0SLoGin } 110140fe15e0SLoGin 110240fe15e0SLoGin let intersect: Option<VirtRegion> = guard.region.intersect(®ion); 110340fe15e0SLoGin // 如果当前VMA不包含region,则直接返回None 110440fe15e0SLoGin if unlikely(intersect.is_none()) { 110540fe15e0SLoGin return None; 110640fe15e0SLoGin } 110740fe15e0SLoGin let intersect: VirtRegion = intersect.unwrap(); 110840fe15e0SLoGin if unlikely(intersect == guard.region) { 110940fe15e0SLoGin // 如果当前VMA完全包含region,则直接返回当前VMA 1110b5b571e0SLoGin return Some(VMASplitResult::new( 1111b5b571e0SLoGin None, 1112b5b571e0SLoGin guard.self_ref.upgrade().unwrap(), 1113b5b571e0SLoGin None, 1114b5b571e0SLoGin )); 111540fe15e0SLoGin } 111640fe15e0SLoGin } 111740fe15e0SLoGin 111840fe15e0SLoGin let before: Option<Arc<LockedVMA>> = guard.region.before(®ion).map(|virt_region| { 111940fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 112040fe15e0SLoGin vma.region = virt_region; 1121de199e3cSMemoryShore vma.mapped = false; 112240fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 112340fe15e0SLoGin vma 112440fe15e0SLoGin }); 112540fe15e0SLoGin 112640fe15e0SLoGin let after: Option<Arc<LockedVMA>> = guard.region.after(®ion).map(|virt_region| { 112740fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 112840fe15e0SLoGin vma.region = virt_region; 1129de199e3cSMemoryShore vma.mapped = false; 113040fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 113140fe15e0SLoGin vma 113240fe15e0SLoGin }); 113340fe15e0SLoGin 113456cc4dbeSJomo // 重新设置before、after这两个VMA里面的物理页的anon_vma 11356fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 113656cc4dbeSJomo if let Some(before) = before.clone() { 113756cc4dbeSJomo let virt_iter = before.lock().region.iter_pages(); 113856cc4dbeSJomo for frame in virt_iter { 1139de199e3cSMemoryShore if let Some((paddr, _)) = utable.translate(frame.virt_address()) { 11406fc066acSJomo let page = page_manager_guard.get_mut(&paddr); 114156cc4dbeSJomo page.insert_vma(before.clone()); 114256cc4dbeSJomo page.remove_vma(self); 1143de199e3cSMemoryShore before.lock().mapped = true; 1144de199e3cSMemoryShore } 114556cc4dbeSJomo } 114656cc4dbeSJomo } 114740fe15e0SLoGin 114856cc4dbeSJomo if let Some(after) = after.clone() { 114956cc4dbeSJomo let virt_iter = after.lock().region.iter_pages(); 115056cc4dbeSJomo for frame in virt_iter { 1151de199e3cSMemoryShore if let Some((paddr, _)) = utable.translate(frame.virt_address()) { 11526fc066acSJomo let page = page_manager_guard.get_mut(&paddr); 115356cc4dbeSJomo page.insert_vma(after.clone()); 115456cc4dbeSJomo page.remove_vma(self); 1155de199e3cSMemoryShore after.lock().mapped = true; 1156de199e3cSMemoryShore } 115756cc4dbeSJomo } 115856cc4dbeSJomo } 115956cc4dbeSJomo 116056cc4dbeSJomo guard.region = region; 116140fe15e0SLoGin 1162b5b571e0SLoGin return Some(VMASplitResult::new( 1163b5b571e0SLoGin before, 1164b5b571e0SLoGin guard.self_ref.upgrade().unwrap(), 1165b5b571e0SLoGin after, 1166b5b571e0SLoGin )); 1167b5b571e0SLoGin } 1168a17651b1SMemoryShore 1169a17651b1SMemoryShore /// 判断VMA是否为外部(非当前进程空间)的VMA 1170a17651b1SMemoryShore pub fn is_foreign(&self) -> bool { 1171a17651b1SMemoryShore let guard = self.lock(); 1172a17651b1SMemoryShore if let Some(space) = guard.user_address_space.clone() { 1173a17651b1SMemoryShore if let Some(space) = space.upgrade() { 1174a17651b1SMemoryShore return AddressSpace::is_current(&space); 1175a17651b1SMemoryShore } else { 1176a17651b1SMemoryShore return true; 1177a17651b1SMemoryShore } 1178a17651b1SMemoryShore } else { 1179a17651b1SMemoryShore return true; 1180a17651b1SMemoryShore } 1181a17651b1SMemoryShore } 1182a17651b1SMemoryShore 1183a17651b1SMemoryShore /// 判断VMA是否可访问 1184a17651b1SMemoryShore pub fn is_accessible(&self) -> bool { 1185a17651b1SMemoryShore let guard = self.lock(); 1186a17651b1SMemoryShore let vm_access_flags: VmFlags = VmFlags::VM_READ | VmFlags::VM_WRITE | VmFlags::VM_EXEC; 1187a17651b1SMemoryShore guard.vm_flags().intersects(vm_access_flags) 1188a17651b1SMemoryShore } 1189a17651b1SMemoryShore 1190a17651b1SMemoryShore /// 判断VMA是否为匿名映射 1191a17651b1SMemoryShore pub fn is_anonymous(&self) -> bool { 1192a17651b1SMemoryShore //TODO: 实现匿名映射判断逻辑,目前仅支持匿名映射 1193a17651b1SMemoryShore true 1194a17651b1SMemoryShore } 1195a17651b1SMemoryShore 1196a17651b1SMemoryShore /// 判断VMA是否为大页映射 1197a17651b1SMemoryShore pub fn is_hugepage(&self) -> bool { 1198a17651b1SMemoryShore //TODO: 实现巨页映射判断逻辑,目前不支持巨页映射 1199a17651b1SMemoryShore false 1200a17651b1SMemoryShore } 1201b5b571e0SLoGin } 1202b5b571e0SLoGin 120356cc4dbeSJomo impl Drop for LockedVMA { 120456cc4dbeSJomo fn drop(&mut self) { 120556cc4dbeSJomo LOCKEDVMA_ID_ALLOCATOR.free(self.id); 120656cc4dbeSJomo } 120756cc4dbeSJomo } 120856cc4dbeSJomo 1209b5b571e0SLoGin /// VMA切分结果 1210*bd70d2d1SLoGin #[allow(dead_code)] 1211b5b571e0SLoGin pub struct VMASplitResult { 1212b5b571e0SLoGin pub prev: Option<Arc<LockedVMA>>, 1213b5b571e0SLoGin pub middle: Arc<LockedVMA>, 1214b5b571e0SLoGin pub after: Option<Arc<LockedVMA>>, 1215b5b571e0SLoGin } 1216b5b571e0SLoGin 1217b5b571e0SLoGin impl VMASplitResult { 1218b5b571e0SLoGin pub fn new( 1219b5b571e0SLoGin prev: Option<Arc<LockedVMA>>, 1220b5b571e0SLoGin middle: Arc<LockedVMA>, 1221b5b571e0SLoGin post: Option<Arc<LockedVMA>>, 1222b5b571e0SLoGin ) -> Self { 1223b5b571e0SLoGin Self { 1224b5b571e0SLoGin prev, 1225b5b571e0SLoGin middle, 1226b5b571e0SLoGin after: post, 1227b5b571e0SLoGin } 122840fe15e0SLoGin } 122940fe15e0SLoGin } 123040fe15e0SLoGin 123140fe15e0SLoGin /// @brief 虚拟内存区域 123240fe15e0SLoGin #[derive(Debug)] 123340fe15e0SLoGin pub struct VMA { 123440fe15e0SLoGin /// 虚拟内存区域对应的虚拟地址范围 123540fe15e0SLoGin region: VirtRegion, 12364cfa009bSJomo /// 虚拟内存区域标志 12374cfa009bSJomo vm_flags: VmFlags, 123840fe15e0SLoGin /// VMA内的页帧的标志 123940fe15e0SLoGin flags: PageFlags<MMArch>, 124040fe15e0SLoGin /// VMA内的页帧是否已经映射到页表 124140fe15e0SLoGin mapped: bool, 124240fe15e0SLoGin /// VMA所属的用户地址空间 124340fe15e0SLoGin user_address_space: Option<Weak<AddressSpace>>, 124440fe15e0SLoGin self_ref: Weak<LockedVMA>, 1245971462beSGnoCiYeH 1246971462beSGnoCiYeH provider: Provider, 124740fe15e0SLoGin } 124840fe15e0SLoGin 124940fe15e0SLoGin impl core::hash::Hash for VMA { 125040fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 125140fe15e0SLoGin self.region.hash(state); 125240fe15e0SLoGin self.flags.hash(state); 125340fe15e0SLoGin self.mapped.hash(state); 125440fe15e0SLoGin } 125540fe15e0SLoGin } 125640fe15e0SLoGin 1257971462beSGnoCiYeH /// 描述不同类型的内存提供者或资源 1258971462beSGnoCiYeH #[derive(Debug)] 1259971462beSGnoCiYeH pub enum Provider { 1260971462beSGnoCiYeH Allocated, // TODO:其他 1261971462beSGnoCiYeH } 1262971462beSGnoCiYeH 126340fe15e0SLoGin #[allow(dead_code)] 126440fe15e0SLoGin impl VMA { 12654cfa009bSJomo pub fn new( 12664cfa009bSJomo region: VirtRegion, 12674cfa009bSJomo vm_flags: VmFlags, 12684cfa009bSJomo flags: PageFlags<MMArch>, 12694cfa009bSJomo mapped: bool, 12704cfa009bSJomo ) -> Self { 12714cfa009bSJomo VMA { 12724cfa009bSJomo region, 12734cfa009bSJomo vm_flags, 12744cfa009bSJomo flags, 12754cfa009bSJomo mapped, 12764cfa009bSJomo user_address_space: None, 12774cfa009bSJomo self_ref: Weak::default(), 12784cfa009bSJomo provider: Provider::Allocated, 12794cfa009bSJomo } 12804cfa009bSJomo } 12814cfa009bSJomo 128240fe15e0SLoGin pub fn region(&self) -> &VirtRegion { 128340fe15e0SLoGin return &self.region; 128440fe15e0SLoGin } 128540fe15e0SLoGin 12864cfa009bSJomo pub fn vm_flags(&self) -> &VmFlags { 12874cfa009bSJomo return &self.vm_flags; 12884cfa009bSJomo } 12894cfa009bSJomo 12904cfa009bSJomo pub fn set_vm_flags(&mut self, vm_flags: VmFlags) { 12914cfa009bSJomo self.vm_flags = vm_flags; 12924cfa009bSJomo } 12934cfa009bSJomo 12944cfa009bSJomo pub fn set_region_size(&mut self, new_region_size: usize) { 12954cfa009bSJomo self.region.set_size(new_region_size); 12964cfa009bSJomo } 12974cfa009bSJomo 12986fc066acSJomo pub fn set_mapped(&mut self, mapped: bool) { 12996fc066acSJomo self.mapped = mapped; 13006fc066acSJomo } 13016fc066acSJomo 130240fe15e0SLoGin /// # 拷贝当前VMA的内容 130340fe15e0SLoGin /// 130440fe15e0SLoGin /// ### 安全性 130540fe15e0SLoGin /// 130640fe15e0SLoGin /// 由于这样操作可能由于错误的拷贝,导致内存泄露、内存重复释放等问题,所以需要小心使用。 130740fe15e0SLoGin pub unsafe fn clone(&self) -> Self { 130840fe15e0SLoGin return Self { 130940fe15e0SLoGin region: self.region, 13104cfa009bSJomo vm_flags: self.vm_flags, 131140fe15e0SLoGin flags: self.flags, 131240fe15e0SLoGin mapped: self.mapped, 131340fe15e0SLoGin user_address_space: self.user_address_space.clone(), 131440fe15e0SLoGin self_ref: self.self_ref.clone(), 1315971462beSGnoCiYeH provider: Provider::Allocated, 131640fe15e0SLoGin }; 131740fe15e0SLoGin } 131840fe15e0SLoGin 1319a17651b1SMemoryShore pub fn clone_info_only(&self) -> Self { 1320a17651b1SMemoryShore return Self { 1321a17651b1SMemoryShore region: self.region, 1322a17651b1SMemoryShore vm_flags: self.vm_flags, 1323a17651b1SMemoryShore flags: self.flags, 1324a17651b1SMemoryShore mapped: self.mapped, 1325a17651b1SMemoryShore user_address_space: None, 1326a17651b1SMemoryShore self_ref: Weak::default(), 1327a17651b1SMemoryShore provider: Provider::Allocated, 1328a17651b1SMemoryShore }; 1329a17651b1SMemoryShore } 1330a17651b1SMemoryShore 133140fe15e0SLoGin #[inline(always)] 133240fe15e0SLoGin pub fn flags(&self) -> PageFlags<MMArch> { 133340fe15e0SLoGin return self.flags; 133440fe15e0SLoGin } 133540fe15e0SLoGin 133640fe15e0SLoGin pub fn pages(&self) -> VirtPageFrameIter { 133740fe15e0SLoGin return VirtPageFrameIter::new( 133840fe15e0SLoGin VirtPageFrame::new(self.region.start()), 133940fe15e0SLoGin VirtPageFrame::new(self.region.end()), 134040fe15e0SLoGin ); 134140fe15e0SLoGin } 134240fe15e0SLoGin 134340fe15e0SLoGin pub fn remap( 134440fe15e0SLoGin &mut self, 134540fe15e0SLoGin flags: PageFlags<MMArch>, 134640fe15e0SLoGin mapper: &mut PageMapper, 134740fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 134840fe15e0SLoGin ) -> Result<(), SystemError> { 134940fe15e0SLoGin for page in self.region.pages() { 13502eab6dd7S曾俊 // debug!("remap page {:?}", page.virt_address()); 1351a17651b1SMemoryShore if mapper.translate(page.virt_address()).is_some() { 135240fe15e0SLoGin let r = unsafe { 135340fe15e0SLoGin mapper 135440fe15e0SLoGin .remap(page.virt_address(), flags) 1355a17651b1SMemoryShore .expect("Failed to remap") 135640fe15e0SLoGin }; 135740fe15e0SLoGin flusher.consume(r); 1358a17651b1SMemoryShore } 13592eab6dd7S曾俊 // debug!("consume page {:?}", page.virt_address()); 13602eab6dd7S曾俊 // debug!("remap page {:?} done", page.virt_address()); 136140fe15e0SLoGin } 136240fe15e0SLoGin self.flags = flags; 136340fe15e0SLoGin return Ok(()); 136440fe15e0SLoGin } 136540fe15e0SLoGin 136640fe15e0SLoGin /// 检查当前VMA是否可以拥有指定的标志位 136740fe15e0SLoGin /// 136840fe15e0SLoGin /// ## 参数 136940fe15e0SLoGin /// 137040fe15e0SLoGin /// - `prot_flags` 要检查的标志位 137140fe15e0SLoGin pub fn can_have_flags(&self, prot_flags: ProtFlags) -> bool { 1372971462beSGnoCiYeH let is_downgrade = (self.flags.has_write() || !prot_flags.contains(ProtFlags::PROT_WRITE)) 137340fe15e0SLoGin && (self.flags.has_execute() || !prot_flags.contains(ProtFlags::PROT_EXEC)); 1374971462beSGnoCiYeH 1375971462beSGnoCiYeH match self.provider { 1376971462beSGnoCiYeH Provider::Allocated { .. } => true, 1377971462beSGnoCiYeH 1378971462beSGnoCiYeH #[allow(unreachable_patterns)] 1379971462beSGnoCiYeH _ => is_downgrade, 1380971462beSGnoCiYeH } 138140fe15e0SLoGin } 138240fe15e0SLoGin 138340fe15e0SLoGin /// 把物理地址映射到虚拟地址 138440fe15e0SLoGin /// 138540fe15e0SLoGin /// @param phys 要映射的物理地址 138640fe15e0SLoGin /// @param destination 要映射到的虚拟地址 138740fe15e0SLoGin /// @param count 要映射的页帧数量 138840fe15e0SLoGin /// @param flags 页面标志位 138940fe15e0SLoGin /// @param mapper 页表映射器 139040fe15e0SLoGin /// @param flusher 页表项刷新器 139140fe15e0SLoGin /// 139240fe15e0SLoGin /// @return 返回映射后的虚拟内存区域 139340fe15e0SLoGin pub fn physmap( 139440fe15e0SLoGin phys: PhysPageFrame, 139540fe15e0SLoGin destination: VirtPageFrame, 139640fe15e0SLoGin count: PageFrameCount, 13974cfa009bSJomo vm_flags: VmFlags, 139840fe15e0SLoGin flags: PageFlags<MMArch>, 139940fe15e0SLoGin mapper: &mut PageMapper, 140040fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 140140fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 140240fe15e0SLoGin let mut cur_phy = phys; 140340fe15e0SLoGin let mut cur_dest = destination; 140440fe15e0SLoGin 140540fe15e0SLoGin for _ in 0..count.data() { 140640fe15e0SLoGin // 将物理页帧映射到虚拟页帧 140756cc4dbeSJomo let r = 140856cc4dbeSJomo unsafe { mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags) } 140940fe15e0SLoGin .expect("Failed to map phys, may be OOM error"); 141040fe15e0SLoGin 141140fe15e0SLoGin // todo: 增加OOM处理 141240fe15e0SLoGin 141340fe15e0SLoGin // 刷新TLB 141440fe15e0SLoGin flusher.consume(r); 141540fe15e0SLoGin 141640fe15e0SLoGin cur_phy = cur_phy.next(); 141740fe15e0SLoGin cur_dest = cur_dest.next(); 141840fe15e0SLoGin } 141940fe15e0SLoGin 142040fe15e0SLoGin let r: Arc<LockedVMA> = LockedVMA::new(VMA { 142140fe15e0SLoGin region: VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE), 14224cfa009bSJomo vm_flags, 142340fe15e0SLoGin flags, 142440fe15e0SLoGin mapped: true, 142540fe15e0SLoGin user_address_space: None, 142640fe15e0SLoGin self_ref: Weak::default(), 1427971462beSGnoCiYeH provider: Provider::Allocated, 142840fe15e0SLoGin }); 142956cc4dbeSJomo 143056cc4dbeSJomo // 将VMA加入到anon_vma中 14316fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 143256cc4dbeSJomo cur_phy = phys; 143356cc4dbeSJomo for _ in 0..count.data() { 143456cc4dbeSJomo let paddr = cur_phy.phys_address(); 14356fc066acSJomo let page = page_manager_guard.get_mut(&paddr); 143656cc4dbeSJomo page.insert_vma(r.clone()); 143756cc4dbeSJomo cur_phy = cur_phy.next(); 143856cc4dbeSJomo } 143956cc4dbeSJomo 144040fe15e0SLoGin return Ok(r); 144140fe15e0SLoGin } 144240fe15e0SLoGin 144340fe15e0SLoGin /// 从页分配器中分配一些物理页,并把它们映射到指定的虚拟地址,然后创建VMA 144440fe15e0SLoGin /// 144540fe15e0SLoGin /// @param destination 要映射到的虚拟地址 144640fe15e0SLoGin /// @param count 要映射的页帧数量 144740fe15e0SLoGin /// @param flags 页面标志位 144840fe15e0SLoGin /// @param mapper 页表映射器 144940fe15e0SLoGin /// @param flusher 页表项刷新器 145040fe15e0SLoGin /// 145140fe15e0SLoGin /// @return 返回映射后的虚拟内存区域 145240fe15e0SLoGin pub fn zeroed( 145340fe15e0SLoGin destination: VirtPageFrame, 145440fe15e0SLoGin page_count: PageFrameCount, 14554cfa009bSJomo vm_flags: VmFlags, 145640fe15e0SLoGin flags: PageFlags<MMArch>, 145740fe15e0SLoGin mapper: &mut PageMapper, 145840fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 145940fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 146040fe15e0SLoGin let mut cur_dest: VirtPageFrame = destination; 14612eab6dd7S曾俊 // debug!( 146240fe15e0SLoGin // "VMA::zeroed: page_count = {:?}, destination={destination:?}", 146340fe15e0SLoGin // page_count 146440fe15e0SLoGin // ); 146540fe15e0SLoGin for _ in 0..page_count.data() { 14662eab6dd7S曾俊 // debug!( 146740fe15e0SLoGin // "VMA::zeroed: cur_dest={cur_dest:?}, vaddr = {:?}", 146840fe15e0SLoGin // cur_dest.virt_address() 146940fe15e0SLoGin // ); 147040fe15e0SLoGin let r = unsafe { mapper.map(cur_dest.virt_address(), flags) } 147140fe15e0SLoGin .expect("Failed to map zero, may be OOM error"); 147240fe15e0SLoGin // todo: 增加OOM处理 147340fe15e0SLoGin 147440fe15e0SLoGin // 稍后再刷新TLB,这里取消刷新 147540fe15e0SLoGin flusher.consume(r); 147640fe15e0SLoGin cur_dest = cur_dest.next(); 147740fe15e0SLoGin } 147817dc5589SMemoryShore let r = LockedVMA::new(VMA::new( 147917dc5589SMemoryShore VirtRegion::new( 148040fe15e0SLoGin destination.virt_address(), 148140fe15e0SLoGin page_count.data() * MMArch::PAGE_SIZE, 148240fe15e0SLoGin ), 14834cfa009bSJomo vm_flags, 148440fe15e0SLoGin flags, 148517dc5589SMemoryShore true, 148617dc5589SMemoryShore )); 148740fe15e0SLoGin drop(flusher); 14882eab6dd7S曾俊 // debug!("VMA::zeroed: flusher dropped"); 148940fe15e0SLoGin 149056cc4dbeSJomo // 清空这些内存并将VMA加入到anon_vma中 14916fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 14929550910aSChiichen let virt_iter: VirtPageFrameIter = 14939550910aSChiichen VirtPageFrameIter::new(destination, destination.add(page_count)); 149440fe15e0SLoGin for frame in virt_iter { 149540fe15e0SLoGin let paddr = mapper.translate(frame.virt_address()).unwrap().0; 149640fe15e0SLoGin 149756cc4dbeSJomo // 将VMA加入到anon_vma 14986fc066acSJomo let page = page_manager_guard.get_mut(&paddr); 149956cc4dbeSJomo page.insert_vma(r.clone()); 150040fe15e0SLoGin } 15012eab6dd7S曾俊 // debug!("VMA::zeroed: done"); 150240fe15e0SLoGin return Ok(r); 150340fe15e0SLoGin } 150440fe15e0SLoGin } 150540fe15e0SLoGin 150640fe15e0SLoGin impl Drop for VMA { 150740fe15e0SLoGin fn drop(&mut self) { 150840fe15e0SLoGin // 当VMA被释放时,需要确保它已经被从页表中解除映射 150940fe15e0SLoGin assert!(!self.mapped, "VMA is still mapped"); 151040fe15e0SLoGin } 151140fe15e0SLoGin } 151240fe15e0SLoGin 151340fe15e0SLoGin impl PartialEq for VMA { 151440fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 151540fe15e0SLoGin return self.region == other.region; 151640fe15e0SLoGin } 151740fe15e0SLoGin } 151840fe15e0SLoGin 151940fe15e0SLoGin impl Eq for VMA {} 152040fe15e0SLoGin 152140fe15e0SLoGin impl PartialOrd for VMA { 152240fe15e0SLoGin fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 1523b5b571e0SLoGin Some(self.cmp(other)) 152440fe15e0SLoGin } 152540fe15e0SLoGin } 152640fe15e0SLoGin 152740fe15e0SLoGin impl Ord for VMA { 152840fe15e0SLoGin fn cmp(&self, other: &Self) -> cmp::Ordering { 152940fe15e0SLoGin return self.region.cmp(&other.region); 153040fe15e0SLoGin } 153140fe15e0SLoGin } 153240fe15e0SLoGin 153340fe15e0SLoGin #[derive(Debug)] 153440fe15e0SLoGin pub struct UserStack { 153540fe15e0SLoGin // 栈底地址 153640fe15e0SLoGin stack_bottom: VirtAddr, 153740fe15e0SLoGin // 当前已映射的大小 153840fe15e0SLoGin mapped_size: usize, 153940fe15e0SLoGin /// 栈顶地址(这个值需要仔细确定!因为它可能不会实时与用户栈的真实栈顶保持一致!要小心!) 154040fe15e0SLoGin current_sp: VirtAddr, 154140fe15e0SLoGin } 154240fe15e0SLoGin 154340fe15e0SLoGin impl UserStack { 154440fe15e0SLoGin /// 默认的用户栈底地址 154540fe15e0SLoGin pub const DEFAULT_USER_STACK_BOTTOM: VirtAddr = MMArch::USER_STACK_START; 154640fe15e0SLoGin /// 默认的用户栈大小为8MB 154740fe15e0SLoGin pub const DEFAULT_USER_STACK_SIZE: usize = 8 * 1024 * 1024; 154840fe15e0SLoGin /// 用户栈的保护页数量 154940fe15e0SLoGin pub const GUARD_PAGES_NUM: usize = 4; 155040fe15e0SLoGin 155140fe15e0SLoGin /// 创建一个用户栈 155240fe15e0SLoGin pub fn new( 155340fe15e0SLoGin vm: &mut InnerAddressSpace, 155440fe15e0SLoGin stack_bottom: Option<VirtAddr>, 155540fe15e0SLoGin stack_size: usize, 155640fe15e0SLoGin ) -> Result<Self, SystemError> { 155740fe15e0SLoGin let stack_bottom = stack_bottom.unwrap_or(Self::DEFAULT_USER_STACK_BOTTOM); 155840fe15e0SLoGin assert!(stack_bottom.check_aligned(MMArch::PAGE_SIZE)); 155940fe15e0SLoGin 156040fe15e0SLoGin // 分配用户栈的保护页 156140fe15e0SLoGin let guard_size = Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 156240fe15e0SLoGin let actual_stack_bottom = stack_bottom - guard_size; 156340fe15e0SLoGin 156440fe15e0SLoGin let mut prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE; 1565a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE 1566a17651b1SMemoryShore | MapFlags::MAP_ANONYMOUS 1567a17651b1SMemoryShore | MapFlags::MAP_FIXED_NOREPLACE 1568a17651b1SMemoryShore | MapFlags::MAP_GROWSDOWN; 15692eab6dd7S曾俊 // debug!( 157040fe15e0SLoGin // "map anonymous stack: {:?} {}", 157140fe15e0SLoGin // actual_stack_bottom, 157240fe15e0SLoGin // guard_size 157340fe15e0SLoGin // ); 157440fe15e0SLoGin vm.map_anonymous( 157540fe15e0SLoGin actual_stack_bottom, 157640fe15e0SLoGin guard_size, 157740fe15e0SLoGin prot_flags, 157840fe15e0SLoGin map_flags, 157940fe15e0SLoGin false, 1580a17651b1SMemoryShore false, 158140fe15e0SLoGin )?; 158240fe15e0SLoGin // test_buddy(); 158340fe15e0SLoGin // 设置保护页只读 158440fe15e0SLoGin prot_flags.remove(ProtFlags::PROT_WRITE); 15852eab6dd7S曾俊 // debug!( 158640fe15e0SLoGin // "to mprotect stack guard pages: {:?} {}", 158740fe15e0SLoGin // actual_stack_bottom, 158840fe15e0SLoGin // guard_size 158940fe15e0SLoGin // ); 159040fe15e0SLoGin vm.mprotect( 159140fe15e0SLoGin VirtPageFrame::new(actual_stack_bottom), 159240fe15e0SLoGin PageFrameCount::new(Self::GUARD_PAGES_NUM), 159340fe15e0SLoGin prot_flags, 159440fe15e0SLoGin )?; 159540fe15e0SLoGin 15962eab6dd7S曾俊 // debug!( 159740fe15e0SLoGin // "mprotect stack guard pages done: {:?} {}", 159840fe15e0SLoGin // actual_stack_bottom, 159940fe15e0SLoGin // guard_size 160040fe15e0SLoGin // ); 160140fe15e0SLoGin 160240fe15e0SLoGin let mut user_stack = UserStack { 160340fe15e0SLoGin stack_bottom: actual_stack_bottom, 160440fe15e0SLoGin mapped_size: guard_size, 160540fe15e0SLoGin current_sp: actual_stack_bottom - guard_size, 160640fe15e0SLoGin }; 160740fe15e0SLoGin 16082eab6dd7S曾俊 // debug!("extend user stack: {:?} {}", stack_bottom, stack_size); 160940fe15e0SLoGin // 分配用户栈 161040fe15e0SLoGin user_stack.initial_extend(vm, stack_size)?; 16112eab6dd7S曾俊 // debug!("user stack created: {:?} {}", stack_bottom, stack_size); 161240fe15e0SLoGin return Ok(user_stack); 161340fe15e0SLoGin } 161440fe15e0SLoGin 161540fe15e0SLoGin fn initial_extend( 161640fe15e0SLoGin &mut self, 161740fe15e0SLoGin vm: &mut InnerAddressSpace, 161840fe15e0SLoGin mut bytes: usize, 161940fe15e0SLoGin ) -> Result<(), SystemError> { 162040fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 1621a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN; 162240fe15e0SLoGin 162340fe15e0SLoGin bytes = page_align_up(bytes); 162440fe15e0SLoGin self.mapped_size += bytes; 162540fe15e0SLoGin 162640fe15e0SLoGin vm.map_anonymous( 162740fe15e0SLoGin self.stack_bottom - self.mapped_size, 162840fe15e0SLoGin bytes, 162940fe15e0SLoGin prot_flags, 163040fe15e0SLoGin map_flags, 163140fe15e0SLoGin false, 1632a17651b1SMemoryShore false, 163340fe15e0SLoGin )?; 163440fe15e0SLoGin 163540fe15e0SLoGin return Ok(()); 163640fe15e0SLoGin } 163740fe15e0SLoGin 163840fe15e0SLoGin /// 扩展用户栈 163940fe15e0SLoGin /// 164040fe15e0SLoGin /// ## 参数 164140fe15e0SLoGin /// 164240fe15e0SLoGin /// - `vm` 用户地址空间结构体 164340fe15e0SLoGin /// - `bytes` 要扩展的字节数 164440fe15e0SLoGin /// 164540fe15e0SLoGin /// ## 返回值 164640fe15e0SLoGin /// 164740fe15e0SLoGin /// - **Ok(())** 扩展成功 164840fe15e0SLoGin /// - **Err(SystemError)** 扩展失败 164940fe15e0SLoGin #[allow(dead_code)] 165040fe15e0SLoGin pub fn extend( 165140fe15e0SLoGin &mut self, 1652a17651b1SMemoryShore vm: &mut InnerAddressSpace, 165340fe15e0SLoGin mut bytes: usize, 165440fe15e0SLoGin ) -> Result<(), SystemError> { 165540fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 165640fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS; 165740fe15e0SLoGin 165840fe15e0SLoGin bytes = page_align_up(bytes); 165940fe15e0SLoGin self.mapped_size += bytes; 166040fe15e0SLoGin 166140fe15e0SLoGin vm.map_anonymous( 166240fe15e0SLoGin self.stack_bottom - self.mapped_size, 166340fe15e0SLoGin bytes, 166440fe15e0SLoGin prot_flags, 166540fe15e0SLoGin map_flags, 166640fe15e0SLoGin false, 1667a17651b1SMemoryShore false, 166840fe15e0SLoGin )?; 166940fe15e0SLoGin 167040fe15e0SLoGin return Ok(()); 167140fe15e0SLoGin } 167240fe15e0SLoGin 167340fe15e0SLoGin /// 获取栈顶地址 167440fe15e0SLoGin /// 167540fe15e0SLoGin /// 请注意,如果用户栈的栈顶地址发生变化,这个值可能不会实时更新! 167640fe15e0SLoGin pub fn sp(&self) -> VirtAddr { 167740fe15e0SLoGin return self.current_sp; 167840fe15e0SLoGin } 167940fe15e0SLoGin 168040fe15e0SLoGin pub unsafe fn set_sp(&mut self, sp: VirtAddr) { 168140fe15e0SLoGin self.current_sp = sp; 168240fe15e0SLoGin } 168340fe15e0SLoGin 168440fe15e0SLoGin /// 仅仅克隆用户栈的信息,不会克隆用户栈的内容/映射 168540fe15e0SLoGin pub unsafe fn clone_info_only(&self) -> Self { 168640fe15e0SLoGin return Self { 168740fe15e0SLoGin stack_bottom: self.stack_bottom, 168840fe15e0SLoGin mapped_size: self.mapped_size, 168940fe15e0SLoGin current_sp: self.current_sp, 169040fe15e0SLoGin }; 169140fe15e0SLoGin } 169240fe15e0SLoGin 169340fe15e0SLoGin /// 获取当前用户栈的大小(不包括保护页) 169440fe15e0SLoGin pub fn stack_size(&self) -> usize { 169540fe15e0SLoGin return self.mapped_size - Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 169640fe15e0SLoGin } 169740fe15e0SLoGin } 1698