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, 23*cf7f801eSMemoryShore filesystem::vfs::file::File, 2440fe15e0SLoGin libs::{ 2540fe15e0SLoGin align::page_align_up, 26a17651b1SMemoryShore rwlock::RwLock, 2740fe15e0SLoGin spinlock::{SpinLock, SpinLockGuard}, 2840fe15e0SLoGin }, 296fc066acSJomo mm::page::page_manager_lock_irqsave, 301496ba7bSLoGin process::ProcessManager, 314cfa009bSJomo syscall::user_access::{UserBufferReader, UserBufferWriter}, 3240fe15e0SLoGin }; 3340fe15e0SLoGin 3440fe15e0SLoGin use super::{ 3540fe15e0SLoGin allocator::page_frame::{ 3640fe15e0SLoGin deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter, 3740fe15e0SLoGin }, 38*cf7f801eSMemoryShore page::{EntryFlags, Flusher, InactiveFlusher, Page, PageFlushAll}, 39a17651b1SMemoryShore syscall::{MadvFlags, MapFlags, MremapFlags, ProtFlags}, 404cfa009bSJomo MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, VmFlags, 4140fe15e0SLoGin }; 4240fe15e0SLoGin 4340fe15e0SLoGin /// MMAP_MIN_ADDR的默认值 4440fe15e0SLoGin /// 以下内容来自linux-5.19: 4540fe15e0SLoGin /// This is the portion of low virtual memory which should be protected 4640fe15e0SLoGin // from userspace allocation. Keeping a user from writing to low pages 4740fe15e0SLoGin // can help reduce the impact of kernel NULL pointer bugs. 4840fe15e0SLoGin // For most ia64, ppc64 and x86 users with lots of address space 4940fe15e0SLoGin // a value of 65536 is reasonable and should cause no problems. 5040fe15e0SLoGin // On arm and other archs it should not be higher than 32768. 5140fe15e0SLoGin // Programs which use vm86 functionality or have some need to map 5240fe15e0SLoGin // this low address space will need CAP_SYS_RAWIO or disable this 5340fe15e0SLoGin // protection by setting the value to 0. 5440fe15e0SLoGin pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536; 5540fe15e0SLoGin 5656cc4dbeSJomo /// LockedVMA的id分配器 5756cc4dbeSJomo static LOCKEDVMA_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, usize::MAX); 5856cc4dbeSJomo 5940fe15e0SLoGin #[derive(Debug)] 6040fe15e0SLoGin pub struct AddressSpace { 6140fe15e0SLoGin inner: RwLock<InnerAddressSpace>, 6240fe15e0SLoGin } 6340fe15e0SLoGin 6440fe15e0SLoGin impl AddressSpace { 6540fe15e0SLoGin pub fn new(create_stack: bool) -> Result<Arc<Self>, SystemError> { 6640fe15e0SLoGin let inner = InnerAddressSpace::new(create_stack)?; 6740fe15e0SLoGin let result = Self { 6840fe15e0SLoGin inner: RwLock::new(inner), 6940fe15e0SLoGin }; 7040fe15e0SLoGin return Ok(Arc::new(result)); 7140fe15e0SLoGin } 7240fe15e0SLoGin 7340fe15e0SLoGin /// 从pcb中获取当前进程的地址空间结构体的Arc指针 7440fe15e0SLoGin pub fn current() -> Result<Arc<AddressSpace>, SystemError> { 751496ba7bSLoGin let vm = ProcessManager::current_pcb() 761496ba7bSLoGin .basic() 771496ba7bSLoGin .user_vm() 7840fe15e0SLoGin .expect("Current process has no address space"); 791496ba7bSLoGin 801496ba7bSLoGin return Ok(vm); 8140fe15e0SLoGin } 8240fe15e0SLoGin 8340fe15e0SLoGin /// 判断某个地址空间是否为当前进程的地址空间 8440fe15e0SLoGin pub fn is_current(self: &Arc<Self>) -> bool { 8540fe15e0SLoGin let current = Self::current(); 8640fe15e0SLoGin if let Ok(current) = current { 8740fe15e0SLoGin return Arc::ptr_eq(¤t, self); 8840fe15e0SLoGin } 8940fe15e0SLoGin return false; 9040fe15e0SLoGin } 9140fe15e0SLoGin } 9240fe15e0SLoGin 9340fe15e0SLoGin impl core::ops::Deref for AddressSpace { 9440fe15e0SLoGin type Target = RwLock<InnerAddressSpace>; 9540fe15e0SLoGin 9640fe15e0SLoGin fn deref(&self) -> &Self::Target { 9740fe15e0SLoGin &self.inner 9840fe15e0SLoGin } 9940fe15e0SLoGin } 10040fe15e0SLoGin 10140fe15e0SLoGin impl core::ops::DerefMut for AddressSpace { 10240fe15e0SLoGin fn deref_mut(&mut self) -> &mut Self::Target { 10340fe15e0SLoGin &mut self.inner 10440fe15e0SLoGin } 10540fe15e0SLoGin } 10640fe15e0SLoGin 10740fe15e0SLoGin /// @brief 用户地址空间结构体(每个进程都有一个) 10840fe15e0SLoGin #[derive(Debug)] 10940fe15e0SLoGin pub struct InnerAddressSpace { 11040fe15e0SLoGin pub user_mapper: UserMapper, 11140fe15e0SLoGin pub mappings: UserMappings, 11240fe15e0SLoGin pub mmap_min: VirtAddr, 11340fe15e0SLoGin /// 用户栈信息结构体 11440fe15e0SLoGin pub user_stack: Option<UserStack>, 11540fe15e0SLoGin 11640fe15e0SLoGin pub elf_brk_start: VirtAddr, 11740fe15e0SLoGin pub elf_brk: VirtAddr, 11840fe15e0SLoGin 11940fe15e0SLoGin /// 当前进程的堆空间的起始地址 12040fe15e0SLoGin pub brk_start: VirtAddr, 12140fe15e0SLoGin /// 当前进程的堆空间的结束地址(不包含) 12240fe15e0SLoGin pub brk: VirtAddr, 12340fe15e0SLoGin 12440fe15e0SLoGin pub start_code: VirtAddr, 12540fe15e0SLoGin pub end_code: VirtAddr, 12640fe15e0SLoGin pub start_data: VirtAddr, 12740fe15e0SLoGin pub end_data: VirtAddr, 12840fe15e0SLoGin } 12940fe15e0SLoGin 13040fe15e0SLoGin impl InnerAddressSpace { 13140fe15e0SLoGin pub fn new(create_stack: bool) -> Result<Self, SystemError> { 13240fe15e0SLoGin let mut result = Self { 13340fe15e0SLoGin user_mapper: MMArch::setup_new_usermapper()?, 13440fe15e0SLoGin mappings: UserMappings::new(), 13540fe15e0SLoGin mmap_min: VirtAddr(DEFAULT_MMAP_MIN_ADDR), 13640fe15e0SLoGin elf_brk_start: VirtAddr::new(0), 13740fe15e0SLoGin elf_brk: VirtAddr::new(0), 13840fe15e0SLoGin brk_start: MMArch::USER_BRK_START, 13940fe15e0SLoGin brk: MMArch::USER_BRK_START, 14040fe15e0SLoGin user_stack: None, 14140fe15e0SLoGin start_code: VirtAddr(0), 14240fe15e0SLoGin end_code: VirtAddr(0), 14340fe15e0SLoGin start_data: VirtAddr(0), 14440fe15e0SLoGin end_data: VirtAddr(0), 14540fe15e0SLoGin }; 14640fe15e0SLoGin if create_stack { 1472eab6dd7S曾俊 // debug!("to create user stack."); 14840fe15e0SLoGin result.new_user_stack(UserStack::DEFAULT_USER_STACK_SIZE)?; 14940fe15e0SLoGin } 15040fe15e0SLoGin 15140fe15e0SLoGin return Ok(result); 15240fe15e0SLoGin } 15340fe15e0SLoGin 15440fe15e0SLoGin /// 尝试克隆当前进程的地址空间,包括这些映射都会被克隆 15540fe15e0SLoGin /// 15640fe15e0SLoGin /// # Returns 15740fe15e0SLoGin /// 15840fe15e0SLoGin /// 返回克隆后的,新的地址空间的Arc指针 1594fda81ceSLoGin #[inline(never)] 16040fe15e0SLoGin pub fn try_clone(&mut self) -> Result<Arc<AddressSpace>, SystemError> { 16140fe15e0SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 16240fe15e0SLoGin let new_addr_space = AddressSpace::new(false)?; 16340fe15e0SLoGin let mut new_guard = new_addr_space.write(); 164a17651b1SMemoryShore unsafe { 165a17651b1SMemoryShore new_guard 166a17651b1SMemoryShore .user_mapper 167a17651b1SMemoryShore .clone_from(&mut self.user_mapper, MMArch::PAGE_FAULT_ENABLED) 168a17651b1SMemoryShore }; 16940fe15e0SLoGin 17040fe15e0SLoGin // 拷贝用户栈的结构体信息,但是不拷贝用户栈的内容(因为后面VMA的拷贝会拷贝用户栈的内容) 17140fe15e0SLoGin unsafe { 17240fe15e0SLoGin new_guard.user_stack = Some(self.user_stack.as_ref().unwrap().clone_info_only()); 17340fe15e0SLoGin } 17440fe15e0SLoGin let _current_stack_size = self.user_stack.as_ref().unwrap().stack_size(); 17540fe15e0SLoGin 176ea8ad4d4SLoGin // 拷贝空洞 177ea8ad4d4SLoGin new_guard.mappings.vm_holes = self.mappings.vm_holes.clone(); 178ea8ad4d4SLoGin 17940fe15e0SLoGin for vma in self.mappings.vmas.iter() { 18040fe15e0SLoGin // TODO: 增加对VMA是否为文件映射的判断,如果是的话,就跳过 18140fe15e0SLoGin 182*cf7f801eSMemoryShore let vma_guard: SpinLockGuard<'_, VMA> = vma.lock_irqsave(); 18340fe15e0SLoGin 184a17651b1SMemoryShore // 仅拷贝VMA信息并添加反向映射,因为UserMapper克隆时已经分配了新的物理页 185a17651b1SMemoryShore let new_vma = LockedVMA::new(vma_guard.clone_info_only()); 18640fe15e0SLoGin new_guard.mappings.vmas.insert(new_vma.clone()); 1872eab6dd7S曾俊 // debug!("new vma: {:x?}", new_vma); 188*cf7f801eSMemoryShore let new_vma_guard = new_vma.lock_irqsave(); 189a17651b1SMemoryShore let new_mapper = &new_guard.user_mapper.utable; 190*cf7f801eSMemoryShore let mut page_manager_guard = page_manager_lock_irqsave(); 19140fe15e0SLoGin for page in new_vma_guard.pages().map(|p| p.virt_address()) { 192a17651b1SMemoryShore if let Some((paddr, _)) = new_mapper.translate(page) { 193*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 194*cf7f801eSMemoryShore page.write_irqsave().insert_vma(new_vma.clone()); 19540fe15e0SLoGin } 196a17651b1SMemoryShore } 19740fe15e0SLoGin 198*cf7f801eSMemoryShore drop(page_manager_guard); 19940fe15e0SLoGin drop(vma_guard); 20040fe15e0SLoGin drop(new_vma_guard); 20140fe15e0SLoGin } 20240fe15e0SLoGin drop(new_guard); 20340fe15e0SLoGin drop(irq_guard); 20440fe15e0SLoGin return Ok(new_addr_space); 20540fe15e0SLoGin } 20640fe15e0SLoGin 207a17651b1SMemoryShore /// 拓展用户栈 208a17651b1SMemoryShore /// ## 参数 209a17651b1SMemoryShore /// 210a17651b1SMemoryShore /// - `bytes`: 拓展大小 211a17651b1SMemoryShore #[allow(dead_code)] 212a17651b1SMemoryShore pub fn extend_stack(&mut self, mut bytes: usize) -> Result<(), SystemError> { 2132eab6dd7S曾俊 // debug!("extend user stack"); 214a17651b1SMemoryShore let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 215a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN; 216a17651b1SMemoryShore let stack = self.user_stack.as_mut().unwrap(); 217a17651b1SMemoryShore 218a17651b1SMemoryShore bytes = page_align_up(bytes); 219a17651b1SMemoryShore stack.mapped_size += bytes; 220a17651b1SMemoryShore let len = stack.stack_bottom - stack.mapped_size; 221a17651b1SMemoryShore self.map_anonymous(len, bytes, prot_flags, map_flags, false, false)?; 222a17651b1SMemoryShore return Ok(()); 223a17651b1SMemoryShore } 224a17651b1SMemoryShore 22540fe15e0SLoGin /// 判断当前的地址空间是否是当前进程的地址空间 22640fe15e0SLoGin #[inline] 22740fe15e0SLoGin pub fn is_current(&self) -> bool { 22840fe15e0SLoGin return self.user_mapper.utable.is_current(); 22940fe15e0SLoGin } 23040fe15e0SLoGin 23140fe15e0SLoGin /// 进行匿名页映射 23240fe15e0SLoGin /// 23340fe15e0SLoGin /// ## 参数 23440fe15e0SLoGin /// 23540fe15e0SLoGin /// - `start_vaddr`:映射的起始地址 23640fe15e0SLoGin /// - `len`:映射的长度 23740fe15e0SLoGin /// - `prot_flags`:保护标志 23840fe15e0SLoGin /// - `map_flags`:映射标志 23940fe15e0SLoGin /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界 240a17651b1SMemoryShore /// - `allocate_at_once`:是否立即分配物理空间 2411496ba7bSLoGin /// 2421496ba7bSLoGin /// ## 返回 2431496ba7bSLoGin /// 2441496ba7bSLoGin /// 返回映射的起始虚拟页帧 24540fe15e0SLoGin pub fn map_anonymous( 24640fe15e0SLoGin &mut self, 24740fe15e0SLoGin start_vaddr: VirtAddr, 24840fe15e0SLoGin len: usize, 24940fe15e0SLoGin prot_flags: ProtFlags, 25040fe15e0SLoGin map_flags: MapFlags, 25140fe15e0SLoGin round_to_min: bool, 252a17651b1SMemoryShore allocate_at_once: bool, 25340fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 254a17651b1SMemoryShore let allocate_at_once = if MMArch::PAGE_FAULT_ENABLED { 255a17651b1SMemoryShore allocate_at_once 256a17651b1SMemoryShore } else { 257a17651b1SMemoryShore true 258a17651b1SMemoryShore }; 25940fe15e0SLoGin // 用于对齐hint的函数 26040fe15e0SLoGin let round_hint_to_min = |hint: VirtAddr| { 26140fe15e0SLoGin // 先把hint向下对齐到页边界 26240fe15e0SLoGin let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK); 2632eab6dd7S曾俊 // debug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint); 26440fe15e0SLoGin // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR 26540fe15e0SLoGin if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) { 26640fe15e0SLoGin Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR))) 26740fe15e0SLoGin } else if addr == 0 { 26840fe15e0SLoGin None 26940fe15e0SLoGin } else { 27040fe15e0SLoGin Some(VirtAddr::new(addr)) 27140fe15e0SLoGin } 27240fe15e0SLoGin }; 2732eab6dd7S曾俊 // debug!("map_anonymous: start_vaddr = {:?}", start_vaddr); 2742eab6dd7S曾俊 // debug!("map_anonymous: len(no align) = {}", len); 27540fe15e0SLoGin 27640fe15e0SLoGin let len = page_align_up(len); 27740fe15e0SLoGin 2784cfa009bSJomo let vm_flags = VmFlags::from(prot_flags) 2794cfa009bSJomo | VmFlags::from(map_flags) 2804cfa009bSJomo | VmFlags::VM_MAYREAD 2814cfa009bSJomo | VmFlags::VM_MAYWRITE 2824cfa009bSJomo | VmFlags::VM_MAYEXEC; 2834cfa009bSJomo 2842eab6dd7S曾俊 // debug!("map_anonymous: len = {}", len); 28540fe15e0SLoGin 286*cf7f801eSMemoryShore let start_page: VirtPageFrame = 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| { 292*cf7f801eSMemoryShore if allocate_at_once { 293*cf7f801eSMemoryShore VMA::zeroed(page, count, vm_flags, flags, mapper, flusher, None, None) 294a17651b1SMemoryShore } else { 29517dc5589SMemoryShore Ok(LockedVMA::new(VMA::new( 29617dc5589SMemoryShore VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE), 297a17651b1SMemoryShore vm_flags, 298a17651b1SMemoryShore flags, 299*cf7f801eSMemoryShore None, 300*cf7f801eSMemoryShore None, 30117dc5589SMemoryShore false, 30217dc5589SMemoryShore ))) 303*cf7f801eSMemoryShore } 304a17651b1SMemoryShore }, 305*cf7f801eSMemoryShore )?; 30640fe15e0SLoGin 30740fe15e0SLoGin return Ok(start_page); 30840fe15e0SLoGin } 30940fe15e0SLoGin 310*cf7f801eSMemoryShore /// 进行文件页映射 311*cf7f801eSMemoryShore /// 312*cf7f801eSMemoryShore /// ## 参数 313*cf7f801eSMemoryShore /// 314*cf7f801eSMemoryShore /// - `start_vaddr`:映射的起始地址 315*cf7f801eSMemoryShore /// - `len`:映射的长度 316*cf7f801eSMemoryShore /// - `prot_flags`:保护标志 317*cf7f801eSMemoryShore /// - `map_flags`:映射标志 318*cf7f801eSMemoryShore /// - `fd`:文件描述符 319*cf7f801eSMemoryShore /// - `offset`:映射偏移量 320*cf7f801eSMemoryShore /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界 321*cf7f801eSMemoryShore /// - `allocate_at_once`:是否立即分配物理空间 322*cf7f801eSMemoryShore /// 323*cf7f801eSMemoryShore /// ## 返回 324*cf7f801eSMemoryShore /// 325*cf7f801eSMemoryShore /// 返回映射的起始虚拟页帧 326*cf7f801eSMemoryShore #[allow(clippy::too_many_arguments)] 327*cf7f801eSMemoryShore pub fn file_mapping( 328*cf7f801eSMemoryShore &mut self, 329*cf7f801eSMemoryShore start_vaddr: VirtAddr, 330*cf7f801eSMemoryShore len: usize, 331*cf7f801eSMemoryShore prot_flags: ProtFlags, 332*cf7f801eSMemoryShore map_flags: MapFlags, 333*cf7f801eSMemoryShore fd: i32, 334*cf7f801eSMemoryShore offset: usize, 335*cf7f801eSMemoryShore round_to_min: bool, 336*cf7f801eSMemoryShore allocate_at_once: bool, 337*cf7f801eSMemoryShore ) -> Result<VirtPageFrame, SystemError> { 338*cf7f801eSMemoryShore let allocate_at_once = if MMArch::PAGE_FAULT_ENABLED { 339*cf7f801eSMemoryShore allocate_at_once 340*cf7f801eSMemoryShore } else { 341*cf7f801eSMemoryShore true 342*cf7f801eSMemoryShore }; 343*cf7f801eSMemoryShore // 用于对齐hint的函数 344*cf7f801eSMemoryShore let round_hint_to_min = |hint: VirtAddr| { 345*cf7f801eSMemoryShore // 先把hint向下对齐到页边界 346*cf7f801eSMemoryShore let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK); 347*cf7f801eSMemoryShore // debug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint); 348*cf7f801eSMemoryShore // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR 349*cf7f801eSMemoryShore if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) { 350*cf7f801eSMemoryShore Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR))) 351*cf7f801eSMemoryShore } else if addr == 0 { 352*cf7f801eSMemoryShore None 353*cf7f801eSMemoryShore } else { 354*cf7f801eSMemoryShore Some(VirtAddr::new(addr)) 355*cf7f801eSMemoryShore } 356*cf7f801eSMemoryShore }; 357*cf7f801eSMemoryShore // debug!("map_anonymous: start_vaddr = {:?}", start_vaddr); 358*cf7f801eSMemoryShore // debug!("map_anonymous: len(no align) = {}", len); 359*cf7f801eSMemoryShore 360*cf7f801eSMemoryShore let len = page_align_up(len); 361*cf7f801eSMemoryShore 362*cf7f801eSMemoryShore let vm_flags = VmFlags::from(prot_flags) 363*cf7f801eSMemoryShore | VmFlags::from(map_flags) 364*cf7f801eSMemoryShore | VmFlags::VM_MAYREAD 365*cf7f801eSMemoryShore | VmFlags::VM_MAYWRITE 366*cf7f801eSMemoryShore | VmFlags::VM_MAYEXEC; 367*cf7f801eSMemoryShore 368*cf7f801eSMemoryShore // debug!("map_anonymous: len = {}", len); 369*cf7f801eSMemoryShore 370*cf7f801eSMemoryShore let binding = ProcessManager::current_pcb().fd_table(); 371*cf7f801eSMemoryShore let fd_table_guard = binding.read(); 372*cf7f801eSMemoryShore 373*cf7f801eSMemoryShore let file = fd_table_guard.get_file_by_fd(fd); 374*cf7f801eSMemoryShore if file.is_none() { 375*cf7f801eSMemoryShore return Err(SystemError::EBADF); 376*cf7f801eSMemoryShore } 377*cf7f801eSMemoryShore // drop guard 以避免无法调度的问题 378*cf7f801eSMemoryShore drop(fd_table_guard); 379*cf7f801eSMemoryShore 380*cf7f801eSMemoryShore // offset需要4K对齐 381*cf7f801eSMemoryShore if !offset & (MMArch::PAGE_SIZE - 1) == 0 { 382*cf7f801eSMemoryShore return Err(SystemError::EINVAL); 383*cf7f801eSMemoryShore } 384*cf7f801eSMemoryShore let pgoff = offset >> MMArch::PAGE_SHIFT; 385*cf7f801eSMemoryShore 386*cf7f801eSMemoryShore let start_page: VirtPageFrame = self.mmap( 387*cf7f801eSMemoryShore round_hint_to_min(start_vaddr), 388*cf7f801eSMemoryShore PageFrameCount::from_bytes(len).unwrap(), 389*cf7f801eSMemoryShore prot_flags, 390*cf7f801eSMemoryShore map_flags, 391*cf7f801eSMemoryShore move |page, count, flags, mapper, flusher| { 392*cf7f801eSMemoryShore if allocate_at_once { 393*cf7f801eSMemoryShore VMA::zeroed( 394*cf7f801eSMemoryShore page, 395*cf7f801eSMemoryShore count, 396*cf7f801eSMemoryShore vm_flags, 397*cf7f801eSMemoryShore flags, 398*cf7f801eSMemoryShore mapper, 399*cf7f801eSMemoryShore flusher, 400*cf7f801eSMemoryShore file, 401*cf7f801eSMemoryShore Some(pgoff), 402*cf7f801eSMemoryShore ) 403*cf7f801eSMemoryShore } else { 404*cf7f801eSMemoryShore Ok(LockedVMA::new(VMA::new( 405*cf7f801eSMemoryShore VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE), 406*cf7f801eSMemoryShore vm_flags, 407*cf7f801eSMemoryShore flags, 408*cf7f801eSMemoryShore file, 409*cf7f801eSMemoryShore Some(pgoff), 410*cf7f801eSMemoryShore false, 411*cf7f801eSMemoryShore ))) 412*cf7f801eSMemoryShore } 413*cf7f801eSMemoryShore }, 414*cf7f801eSMemoryShore )?; 415*cf7f801eSMemoryShore return Ok(start_page); 416*cf7f801eSMemoryShore } 417*cf7f801eSMemoryShore 41840fe15e0SLoGin /// 向进程的地址空间映射页面 41940fe15e0SLoGin /// 42040fe15e0SLoGin /// # 参数 42140fe15e0SLoGin /// 42240fe15e0SLoGin /// - `addr`:映射的起始地址,如果为`None`,则由内核自动分配 42340fe15e0SLoGin /// - `page_count`:映射的页面数量 42440fe15e0SLoGin /// - `prot_flags`:保护标志 42540fe15e0SLoGin /// - `map_flags`:映射标志 42640fe15e0SLoGin /// - `map_func`:映射函数,用于创建VMA 42740fe15e0SLoGin /// 42840fe15e0SLoGin /// # Returns 42940fe15e0SLoGin /// 43040fe15e0SLoGin /// 返回映射的起始虚拟页帧 43140fe15e0SLoGin /// 43240fe15e0SLoGin /// # Errors 43340fe15e0SLoGin /// 43440fe15e0SLoGin /// - `EINVAL`:参数错误 43540fe15e0SLoGin pub fn mmap< 43640fe15e0SLoGin F: FnOnce( 43740fe15e0SLoGin VirtPageFrame, 43840fe15e0SLoGin PageFrameCount, 439*cf7f801eSMemoryShore EntryFlags<MMArch>, 44040fe15e0SLoGin &mut PageMapper, 44140fe15e0SLoGin &mut dyn Flusher<MMArch>, 44240fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError>, 44340fe15e0SLoGin >( 44440fe15e0SLoGin &mut self, 44540fe15e0SLoGin addr: Option<VirtAddr>, 44640fe15e0SLoGin page_count: PageFrameCount, 44740fe15e0SLoGin prot_flags: ProtFlags, 44840fe15e0SLoGin map_flags: MapFlags, 44940fe15e0SLoGin map_func: F, 45040fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 45140fe15e0SLoGin if page_count == PageFrameCount::new(0) { 45240fe15e0SLoGin return Err(SystemError::EINVAL); 45340fe15e0SLoGin } 4542eab6dd7S曾俊 // debug!("mmap: addr: {addr:?}, page_count: {page_count:?}, prot_flags: {prot_flags:?}, map_flags: {map_flags:?}"); 45540fe15e0SLoGin 45640fe15e0SLoGin // 找到未使用的区域 45740fe15e0SLoGin let region = match addr { 45840fe15e0SLoGin Some(vaddr) => { 45940fe15e0SLoGin self.mappings 46040fe15e0SLoGin .find_free_at(self.mmap_min, vaddr, page_count.bytes(), map_flags)? 46140fe15e0SLoGin } 46240fe15e0SLoGin None => self 46340fe15e0SLoGin .mappings 46440fe15e0SLoGin .find_free(self.mmap_min, page_count.bytes()) 46540fe15e0SLoGin .ok_or(SystemError::ENOMEM)?, 46640fe15e0SLoGin }; 46740fe15e0SLoGin 46840fe15e0SLoGin let page = VirtPageFrame::new(region.start()); 46940fe15e0SLoGin 4702eab6dd7S曾俊 // debug!("mmap: page: {:?}, region={region:?}", page.virt_address()); 47140fe15e0SLoGin 47240fe15e0SLoGin compiler_fence(Ordering::SeqCst); 47340fe15e0SLoGin let (mut active, mut inactive); 47440fe15e0SLoGin let flusher = if self.is_current() { 47540fe15e0SLoGin active = PageFlushAll::new(); 47640fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 47740fe15e0SLoGin } else { 47840fe15e0SLoGin inactive = InactiveFlusher::new(); 47940fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 48040fe15e0SLoGin }; 48140fe15e0SLoGin compiler_fence(Ordering::SeqCst); 48240fe15e0SLoGin // 映射页面,并将VMA插入到地址空间的VMA列表中 48340fe15e0SLoGin self.mappings.insert_vma(map_func( 48440fe15e0SLoGin page, 48540fe15e0SLoGin page_count, 486*cf7f801eSMemoryShore EntryFlags::from_prot_flags(prot_flags, true), 48740fe15e0SLoGin &mut self.user_mapper.utable, 48840fe15e0SLoGin flusher, 48940fe15e0SLoGin )?); 49040fe15e0SLoGin 49140fe15e0SLoGin return Ok(page); 49240fe15e0SLoGin } 49340fe15e0SLoGin 4944cfa009bSJomo /// 重映射内存区域 4954cfa009bSJomo /// 4964cfa009bSJomo /// # 参数 4974cfa009bSJomo /// 4984cfa009bSJomo /// - `old_vaddr`:原映射的起始地址 4994cfa009bSJomo /// - `old_len`:原映射的长度 5004cfa009bSJomo /// - `new_len`:重新映射的长度 5014cfa009bSJomo /// - `mremap_flags`:重映射标志 5024cfa009bSJomo /// - `new_vaddr`:重新映射的起始地址 5034cfa009bSJomo /// - `vm_flags`:旧内存区域标志 5044cfa009bSJomo /// 5054cfa009bSJomo /// # Returns 5064cfa009bSJomo /// 5074cfa009bSJomo /// 返回重映射的起始虚拟页帧地址 5084cfa009bSJomo /// 5094cfa009bSJomo /// # Errors 5104cfa009bSJomo /// 5114cfa009bSJomo /// - `EINVAL`:参数错误 5124cfa009bSJomo pub fn mremap( 5134cfa009bSJomo &mut self, 5144cfa009bSJomo old_vaddr: VirtAddr, 5154cfa009bSJomo old_len: usize, 5164cfa009bSJomo new_len: usize, 5174cfa009bSJomo mremap_flags: MremapFlags, 5184cfa009bSJomo new_vaddr: VirtAddr, 5194cfa009bSJomo vm_flags: VmFlags, 5204cfa009bSJomo ) -> Result<VirtAddr, SystemError> { 5214cfa009bSJomo // 检查新内存地址是否对齐 5224cfa009bSJomo if !new_vaddr.check_aligned(MMArch::PAGE_SIZE) { 5234cfa009bSJomo return Err(SystemError::EINVAL); 5244cfa009bSJomo } 5254cfa009bSJomo 5264cfa009bSJomo // 检查新、旧内存区域是否冲突 5274cfa009bSJomo let old_region = VirtRegion::new(old_vaddr, old_len); 5284cfa009bSJomo let new_region = VirtRegion::new(new_vaddr, new_len); 5294cfa009bSJomo if old_region.collide(&new_region) { 5304cfa009bSJomo return Err(SystemError::EINVAL); 5314cfa009bSJomo } 5324cfa009bSJomo 5333055390cSJomo // 初始化映射标志 5343055390cSJomo let mut map_flags: MapFlags = vm_flags.into(); 5353055390cSJomo // 初始化内存区域保护标志 5363055390cSJomo let prot_flags: ProtFlags = vm_flags.into(); 5373055390cSJomo 5384cfa009bSJomo // 取消新内存区域的原映射 5394cfa009bSJomo if mremap_flags.contains(MremapFlags::MREMAP_FIXED) { 5403055390cSJomo map_flags |= MapFlags::MAP_FIXED; 5414cfa009bSJomo let start_page = VirtPageFrame::new(new_vaddr); 5424cfa009bSJomo let page_count = PageFrameCount::from_bytes(new_len).unwrap(); 5434cfa009bSJomo self.munmap(start_page, page_count)?; 5444cfa009bSJomo } 5454cfa009bSJomo 5464cfa009bSJomo // 获取映射后的新内存页面 547a17651b1SMemoryShore let new_page = self.map_anonymous(new_vaddr, new_len, prot_flags, map_flags, true, true)?; 5484cfa009bSJomo let new_page_vaddr = new_page.virt_address(); 5494cfa009bSJomo 5504cfa009bSJomo // 拷贝旧内存区域内容到新内存区域 5514cfa009bSJomo let old_buffer_reader = 5524cfa009bSJomo UserBufferReader::new(old_vaddr.data() as *const u8, old_len, true)?; 5534cfa009bSJomo let old_buf: &[u8] = old_buffer_reader.read_from_user(0)?; 5544cfa009bSJomo let mut new_buffer_writer = 5554cfa009bSJomo UserBufferWriter::new(new_page_vaddr.data() as *mut u8, new_len, true)?; 5564cfa009bSJomo let new_buf: &mut [u8] = new_buffer_writer.buffer(0)?; 5574cfa009bSJomo let len = old_buf.len().min(new_buf.len()); 558b5b571e0SLoGin new_buf[..len].copy_from_slice(&old_buf[..len]); 5594cfa009bSJomo 5604cfa009bSJomo return Ok(new_page_vaddr); 5614cfa009bSJomo } 5624cfa009bSJomo 56340fe15e0SLoGin /// 取消进程的地址空间中的映射 56440fe15e0SLoGin /// 56540fe15e0SLoGin /// # 参数 56640fe15e0SLoGin /// 56740fe15e0SLoGin /// - `start_page`:起始页帧 56840fe15e0SLoGin /// - `page_count`:取消映射的页帧数量 56940fe15e0SLoGin /// 57040fe15e0SLoGin /// # Errors 57140fe15e0SLoGin /// 57240fe15e0SLoGin /// - `EINVAL`:参数错误 57340fe15e0SLoGin /// - `ENOMEM`:内存不足 57440fe15e0SLoGin pub fn munmap( 57540fe15e0SLoGin &mut self, 57640fe15e0SLoGin start_page: VirtPageFrame, 57740fe15e0SLoGin page_count: PageFrameCount, 57840fe15e0SLoGin ) -> Result<(), SystemError> { 57940fe15e0SLoGin let to_unmap = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 58040fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 58140fe15e0SLoGin 58240fe15e0SLoGin let regions: Vec<Arc<LockedVMA>> = self.mappings.conflicts(to_unmap).collect::<Vec<_>>(); 58340fe15e0SLoGin 58440fe15e0SLoGin for r in regions { 585*cf7f801eSMemoryShore let r = r.lock_irqsave().region; 58640fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 587*cf7f801eSMemoryShore let intersection = r.lock_irqsave().region().intersect(&to_unmap).unwrap(); 58856cc4dbeSJomo let split_result = r.extract(intersection, &self.user_mapper.utable).unwrap(); 58940fe15e0SLoGin 59040fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 59140fe15e0SLoGin 592b5b571e0SLoGin if let Some(before) = split_result.prev { 59340fe15e0SLoGin // 如果前面有VMA,则需要将前面的VMA重新插入到地址空间的VMA列表中 59440fe15e0SLoGin self.mappings.insert_vma(before); 59540fe15e0SLoGin } 59640fe15e0SLoGin 597b5b571e0SLoGin if let Some(after) = split_result.after { 59840fe15e0SLoGin // 如果后面有VMA,则需要将后面的VMA重新插入到地址空间的VMA列表中 59940fe15e0SLoGin self.mappings.insert_vma(after); 60040fe15e0SLoGin } 60140fe15e0SLoGin 60240fe15e0SLoGin r.unmap(&mut self.user_mapper.utable, &mut flusher); 60340fe15e0SLoGin } 60440fe15e0SLoGin 60540fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 60640fe15e0SLoGin 60740fe15e0SLoGin return Ok(()); 60840fe15e0SLoGin } 60940fe15e0SLoGin 61040fe15e0SLoGin pub fn mprotect( 61140fe15e0SLoGin &mut self, 61240fe15e0SLoGin start_page: VirtPageFrame, 61340fe15e0SLoGin page_count: PageFrameCount, 61440fe15e0SLoGin prot_flags: ProtFlags, 61540fe15e0SLoGin ) -> Result<(), SystemError> { 6162eab6dd7S曾俊 // debug!( 61740fe15e0SLoGin // "mprotect: start_page: {:?}, page_count: {:?}, prot_flags:{prot_flags:?}", 61840fe15e0SLoGin // start_page, 61940fe15e0SLoGin // page_count 62040fe15e0SLoGin // ); 62140fe15e0SLoGin let (mut active, mut inactive); 622bd70d2d1SLoGin let flusher = if self.is_current() { 62340fe15e0SLoGin active = PageFlushAll::new(); 62440fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 62540fe15e0SLoGin } else { 62640fe15e0SLoGin inactive = InactiveFlusher::new(); 62740fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 62840fe15e0SLoGin }; 62940fe15e0SLoGin 63040fe15e0SLoGin let mapper = &mut self.user_mapper.utable; 63140fe15e0SLoGin let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 6322eab6dd7S曾俊 // debug!("mprotect: region: {:?}", region); 63340fe15e0SLoGin 63440fe15e0SLoGin let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 6352eab6dd7S曾俊 // debug!("mprotect: regions: {:?}", regions); 63640fe15e0SLoGin 63740fe15e0SLoGin for r in regions { 6382eab6dd7S曾俊 // debug!("mprotect: r: {:?}", r); 639*cf7f801eSMemoryShore let r = *r.lock_irqsave().region(); 64040fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 64140fe15e0SLoGin 642*cf7f801eSMemoryShore let intersection = r.lock_irqsave().region().intersect(®ion).unwrap(); 64356cc4dbeSJomo let split_result = r 64456cc4dbeSJomo .extract(intersection, mapper) 64556cc4dbeSJomo .expect("Failed to extract VMA"); 64640fe15e0SLoGin 647b5b571e0SLoGin if let Some(before) = split_result.prev { 64840fe15e0SLoGin self.mappings.insert_vma(before); 64940fe15e0SLoGin } 650b5b571e0SLoGin if let Some(after) = split_result.after { 65140fe15e0SLoGin self.mappings.insert_vma(after); 65240fe15e0SLoGin } 65340fe15e0SLoGin 654*cf7f801eSMemoryShore let mut r_guard = r.lock_irqsave(); 65540fe15e0SLoGin // 如果VMA的保护标志不允许指定的修改,则返回错误 65640fe15e0SLoGin if !r_guard.can_have_flags(prot_flags) { 65740fe15e0SLoGin drop(r_guard); 65840fe15e0SLoGin self.mappings.insert_vma(r.clone()); 65940fe15e0SLoGin return Err(SystemError::EACCES); 66040fe15e0SLoGin } 66138458c72SMemoryShore r_guard.set_vm_flags(VmFlags::from(prot_flags)); 66238458c72SMemoryShore 663*cf7f801eSMemoryShore let new_flags: EntryFlags<MMArch> = r_guard 66440fe15e0SLoGin .flags() 66540fe15e0SLoGin .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC)) 66640fe15e0SLoGin .set_write(prot_flags.contains(ProtFlags::PROT_WRITE)); 66740fe15e0SLoGin 668bd70d2d1SLoGin r_guard.remap(new_flags, mapper, &mut *flusher)?; 66940fe15e0SLoGin drop(r_guard); 67040fe15e0SLoGin self.mappings.insert_vma(r); 67140fe15e0SLoGin } 67240fe15e0SLoGin 67340fe15e0SLoGin return Ok(()); 67440fe15e0SLoGin } 67540fe15e0SLoGin 676a17651b1SMemoryShore pub fn madvise( 677a17651b1SMemoryShore &mut self, 678a17651b1SMemoryShore start_page: VirtPageFrame, 679a17651b1SMemoryShore page_count: PageFrameCount, 680a17651b1SMemoryShore behavior: MadvFlags, 681a17651b1SMemoryShore ) -> Result<(), SystemError> { 682a17651b1SMemoryShore let (mut active, mut inactive); 683bd70d2d1SLoGin let flusher = if self.is_current() { 684a17651b1SMemoryShore active = PageFlushAll::new(); 685a17651b1SMemoryShore &mut active as &mut dyn Flusher<MMArch> 686a17651b1SMemoryShore } else { 687a17651b1SMemoryShore inactive = InactiveFlusher::new(); 688a17651b1SMemoryShore &mut inactive as &mut dyn Flusher<MMArch> 689a17651b1SMemoryShore }; 690a17651b1SMemoryShore 691a17651b1SMemoryShore let mapper = &mut self.user_mapper.utable; 692a17651b1SMemoryShore 693a17651b1SMemoryShore let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 694a17651b1SMemoryShore let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 695a17651b1SMemoryShore 696a17651b1SMemoryShore for r in regions { 697*cf7f801eSMemoryShore let r = *r.lock_irqsave().region(); 698a17651b1SMemoryShore let r = self.mappings.remove_vma(&r).unwrap(); 699a17651b1SMemoryShore 700*cf7f801eSMemoryShore let intersection = r.lock_irqsave().region().intersect(®ion).unwrap(); 701a17651b1SMemoryShore let split_result = r 702a17651b1SMemoryShore .extract(intersection, mapper) 703a17651b1SMemoryShore .expect("Failed to extract VMA"); 704a17651b1SMemoryShore 705a17651b1SMemoryShore if let Some(before) = split_result.prev { 706a17651b1SMemoryShore self.mappings.insert_vma(before); 707a17651b1SMemoryShore } 708a17651b1SMemoryShore if let Some(after) = split_result.after { 709a17651b1SMemoryShore self.mappings.insert_vma(after); 710a17651b1SMemoryShore } 711bd70d2d1SLoGin r.do_madvise(behavior, mapper, &mut *flusher)?; 712a17651b1SMemoryShore self.mappings.insert_vma(r); 713a17651b1SMemoryShore } 714a17651b1SMemoryShore Ok(()) 715a17651b1SMemoryShore } 716a17651b1SMemoryShore 71740fe15e0SLoGin /// 创建新的用户栈 71840fe15e0SLoGin /// 71940fe15e0SLoGin /// ## 参数 72040fe15e0SLoGin /// 72140fe15e0SLoGin /// - `size`:栈的大小 72240fe15e0SLoGin pub fn new_user_stack(&mut self, size: usize) -> Result<(), SystemError> { 72340fe15e0SLoGin assert!(self.user_stack.is_none(), "User stack already exists"); 72440fe15e0SLoGin let stack = UserStack::new(self, None, size)?; 72540fe15e0SLoGin self.user_stack = Some(stack); 72640fe15e0SLoGin return Ok(()); 72740fe15e0SLoGin } 72840fe15e0SLoGin 72940fe15e0SLoGin #[inline(always)] 73040fe15e0SLoGin pub fn user_stack_mut(&mut self) -> Option<&mut UserStack> { 73140fe15e0SLoGin return self.user_stack.as_mut(); 73240fe15e0SLoGin } 73340fe15e0SLoGin 73440fe15e0SLoGin /// 取消用户空间内的所有映射 73540fe15e0SLoGin pub unsafe fn unmap_all(&mut self) { 73640fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 73740fe15e0SLoGin for vma in self.mappings.iter_vmas() { 7386fc066acSJomo if vma.mapped() { 73940fe15e0SLoGin vma.unmap(&mut self.user_mapper.utable, &mut flusher); 74040fe15e0SLoGin } 74140fe15e0SLoGin } 7426fc066acSJomo } 74340fe15e0SLoGin 74440fe15e0SLoGin /// 设置进程的堆的内存空间 74540fe15e0SLoGin /// 74640fe15e0SLoGin /// ## 参数 74740fe15e0SLoGin /// 74840fe15e0SLoGin /// - `new_brk`:新的堆的结束地址。需要满足页对齐要求,并且是用户空间地址,且大于等于当前的堆的起始地址 74940fe15e0SLoGin /// 75040fe15e0SLoGin /// ## 返回值 75140fe15e0SLoGin /// 75240fe15e0SLoGin /// 返回旧的堆的结束地址 75340fe15e0SLoGin pub unsafe fn set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError> { 75440fe15e0SLoGin assert!(new_brk.check_aligned(MMArch::PAGE_SIZE)); 75540fe15e0SLoGin 75640fe15e0SLoGin if !new_brk.check_user() || new_brk < self.brk_start { 75740fe15e0SLoGin return Err(SystemError::EFAULT); 75840fe15e0SLoGin } 75940fe15e0SLoGin 76040fe15e0SLoGin let old_brk = self.brk; 7611496ba7bSLoGin 76240fe15e0SLoGin if new_brk > self.brk { 76340fe15e0SLoGin let len = new_brk - self.brk; 76440fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 76540fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED; 766a17651b1SMemoryShore self.map_anonymous(old_brk, len, prot_flags, map_flags, true, false)?; 7671496ba7bSLoGin 76840fe15e0SLoGin self.brk = new_brk; 76940fe15e0SLoGin return Ok(old_brk); 77040fe15e0SLoGin } else { 77140fe15e0SLoGin let unmap_len = self.brk - new_brk; 77240fe15e0SLoGin let unmap_start = new_brk; 77340fe15e0SLoGin if unmap_len == 0 { 77440fe15e0SLoGin return Ok(old_brk); 77540fe15e0SLoGin } 77640fe15e0SLoGin self.munmap( 77740fe15e0SLoGin VirtPageFrame::new(unmap_start), 77840fe15e0SLoGin PageFrameCount::from_bytes(unmap_len).unwrap(), 77940fe15e0SLoGin )?; 78040fe15e0SLoGin self.brk = new_brk; 78140fe15e0SLoGin return Ok(old_brk); 78240fe15e0SLoGin } 78340fe15e0SLoGin } 78440fe15e0SLoGin 78540fe15e0SLoGin pub unsafe fn sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError> { 78640fe15e0SLoGin if incr == 0 { 78740fe15e0SLoGin return Ok(self.brk); 78840fe15e0SLoGin } 78940fe15e0SLoGin 79040fe15e0SLoGin let new_brk = if incr > 0 { 79140fe15e0SLoGin self.brk + incr as usize 79240fe15e0SLoGin } else { 793b5b571e0SLoGin self.brk - incr.unsigned_abs() 79440fe15e0SLoGin }; 79540fe15e0SLoGin 79640fe15e0SLoGin let new_brk = VirtAddr::new(page_align_up(new_brk.data())); 79740fe15e0SLoGin 79840fe15e0SLoGin return self.set_brk(new_brk); 79940fe15e0SLoGin } 80040fe15e0SLoGin } 80140fe15e0SLoGin 80240fe15e0SLoGin impl Drop for InnerAddressSpace { 80340fe15e0SLoGin fn drop(&mut self) { 80440fe15e0SLoGin unsafe { 80540fe15e0SLoGin self.unmap_all(); 80640fe15e0SLoGin } 80740fe15e0SLoGin } 80840fe15e0SLoGin } 80940fe15e0SLoGin 81040fe15e0SLoGin #[derive(Debug, Hash)] 81140fe15e0SLoGin pub struct UserMapper { 81240fe15e0SLoGin pub utable: PageMapper, 81340fe15e0SLoGin } 81440fe15e0SLoGin 81540fe15e0SLoGin impl UserMapper { 81640fe15e0SLoGin pub fn new(utable: PageMapper) -> Self { 81740fe15e0SLoGin return Self { utable }; 81840fe15e0SLoGin } 819a17651b1SMemoryShore 820a17651b1SMemoryShore /// 拷贝用户空间映射 821a17651b1SMemoryShore /// ## 参数 822a17651b1SMemoryShore /// 823a17651b1SMemoryShore /// - `umapper`: 要拷贝的用户空间 824a17651b1SMemoryShore /// - `copy_on_write`: 是否写时复制 825a17651b1SMemoryShore pub unsafe fn clone_from(&mut self, umapper: &mut Self, copy_on_write: bool) { 826a17651b1SMemoryShore self.utable 827a17651b1SMemoryShore .clone_user_mapping(&mut umapper.utable, copy_on_write); 828a17651b1SMemoryShore } 82940fe15e0SLoGin } 83040fe15e0SLoGin 83140fe15e0SLoGin impl Drop for UserMapper { 83240fe15e0SLoGin fn drop(&mut self) { 83340fe15e0SLoGin if self.utable.is_current() { 83440fe15e0SLoGin // 如果当前要被销毁的用户空间的页表是当前进程的页表,那么就切换回初始内核页表 83540fe15e0SLoGin unsafe { MMArch::set_table(PageTableKind::User, MMArch::initial_page_table()) } 83640fe15e0SLoGin } 83740fe15e0SLoGin // 释放用户空间顶层页表占用的页帧 83840fe15e0SLoGin // 请注意,在释放这个页帧之前,用户页表应该已经被完全释放,否则会产生内存泄露 83940fe15e0SLoGin unsafe { 84040fe15e0SLoGin deallocate_page_frames( 84140fe15e0SLoGin PhysPageFrame::new(self.utable.table().phys()), 84240fe15e0SLoGin PageFrameCount::new(1), 8436fc066acSJomo &mut page_manager_lock_irqsave(), 84440fe15e0SLoGin ) 84540fe15e0SLoGin }; 84640fe15e0SLoGin } 84740fe15e0SLoGin } 84840fe15e0SLoGin 84940fe15e0SLoGin /// 用户空间映射信息 85040fe15e0SLoGin #[derive(Debug)] 85140fe15e0SLoGin pub struct UserMappings { 85240fe15e0SLoGin /// 当前用户空间的虚拟内存区域 85340fe15e0SLoGin vmas: HashSet<Arc<LockedVMA>>, 85440fe15e0SLoGin /// 当前用户空间的VMA空洞 85540fe15e0SLoGin vm_holes: BTreeMap<VirtAddr, usize>, 85640fe15e0SLoGin } 85740fe15e0SLoGin 85840fe15e0SLoGin impl UserMappings { 85940fe15e0SLoGin pub fn new() -> Self { 86040fe15e0SLoGin return Self { 86140fe15e0SLoGin vmas: HashSet::new(), 86240fe15e0SLoGin vm_holes: core::iter::once((VirtAddr::new(0), MMArch::USER_END_VADDR.data())) 86340fe15e0SLoGin .collect::<BTreeMap<_, _>>(), 86440fe15e0SLoGin }; 86540fe15e0SLoGin } 86640fe15e0SLoGin 86740fe15e0SLoGin /// 判断当前进程的VMA内,是否有包含指定的虚拟地址的VMA。 86840fe15e0SLoGin /// 86940fe15e0SLoGin /// 如果有,返回包含指定虚拟地址的VMA的Arc指针,否则返回None。 87040fe15e0SLoGin #[allow(dead_code)] 87140fe15e0SLoGin pub fn contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 87240fe15e0SLoGin for v in self.vmas.iter() { 873*cf7f801eSMemoryShore let guard = v.lock_irqsave(); 87440fe15e0SLoGin if guard.region.contains(vaddr) { 87540fe15e0SLoGin return Some(v.clone()); 87640fe15e0SLoGin } 87740fe15e0SLoGin } 87840fe15e0SLoGin return None; 87940fe15e0SLoGin } 88040fe15e0SLoGin 881a17651b1SMemoryShore /// 向下寻找距离虚拟地址最近的VMA 882a17651b1SMemoryShore /// ## 参数 883a17651b1SMemoryShore /// 884a17651b1SMemoryShore /// - `vaddr`: 虚拟地址 885a17651b1SMemoryShore /// 886a17651b1SMemoryShore /// ## 返回值 887a17651b1SMemoryShore /// - Some(Arc<LockedVMA>): 虚拟地址所在的或最近的下一个VMA 888a17651b1SMemoryShore /// - None: 未找到VMA 889a17651b1SMemoryShore #[allow(dead_code)] 890a17651b1SMemoryShore pub fn find_nearest(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 891a17651b1SMemoryShore let mut nearest: Option<Arc<LockedVMA>> = None; 892a17651b1SMemoryShore for v in self.vmas.iter() { 893*cf7f801eSMemoryShore let guard = v.lock_irqsave(); 894a17651b1SMemoryShore if guard.region.contains(vaddr) { 895a17651b1SMemoryShore return Some(v.clone()); 896a17651b1SMemoryShore } 897*cf7f801eSMemoryShore if guard.region.start >= vaddr 898a17651b1SMemoryShore && if let Some(ref nearest) = nearest { 899*cf7f801eSMemoryShore guard.region.start < nearest.lock_irqsave().region.start 900a17651b1SMemoryShore } else { 901a17651b1SMemoryShore true 902a17651b1SMemoryShore } 903a17651b1SMemoryShore { 904a17651b1SMemoryShore nearest = Some(v.clone()); 905a17651b1SMemoryShore } 906a17651b1SMemoryShore } 907a17651b1SMemoryShore return nearest; 908a17651b1SMemoryShore } 909a17651b1SMemoryShore 91040fe15e0SLoGin /// 获取当前进程的地址空间中,与给定虚拟地址范围有重叠的VMA的迭代器。 91140fe15e0SLoGin pub fn conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_ { 91240fe15e0SLoGin let r = self 91340fe15e0SLoGin .vmas 91440fe15e0SLoGin .iter() 915*cf7f801eSMemoryShore .filter(move |v| v.lock_irqsave().region.intersect(&request).is_some()) 91640fe15e0SLoGin .cloned(); 91740fe15e0SLoGin return r; 91840fe15e0SLoGin } 91940fe15e0SLoGin 92040fe15e0SLoGin /// 在当前进程的地址空间中,寻找第一个符合条件的空闲的虚拟内存范围。 92140fe15e0SLoGin /// 92240fe15e0SLoGin /// @param min_vaddr 最小的起始地址 92340fe15e0SLoGin /// @param size 请求的大小 92440fe15e0SLoGin /// 92540fe15e0SLoGin /// @return 如果找到了,返回虚拟内存范围,否则返回None 92640fe15e0SLoGin pub fn find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion> { 92740fe15e0SLoGin let _vaddr = min_vaddr; 92840fe15e0SLoGin let mut iter = self 92940fe15e0SLoGin .vm_holes 93040fe15e0SLoGin .iter() 93140fe15e0SLoGin .skip_while(|(hole_vaddr, hole_size)| hole_vaddr.add(**hole_size) <= min_vaddr); 93240fe15e0SLoGin 93340fe15e0SLoGin let (hole_vaddr, size) = iter.find(|(hole_vaddr, hole_size)| { 93440fe15e0SLoGin // 计算当前空洞的可用大小 93540fe15e0SLoGin let available_size: usize = 93640fe15e0SLoGin if hole_vaddr <= &&min_vaddr && min_vaddr <= hole_vaddr.add(**hole_size) { 93740fe15e0SLoGin **hole_size - (min_vaddr - **hole_vaddr) 93840fe15e0SLoGin } else { 93940fe15e0SLoGin **hole_size 94040fe15e0SLoGin }; 94140fe15e0SLoGin 94240fe15e0SLoGin size <= available_size 94340fe15e0SLoGin })?; 94440fe15e0SLoGin 94540fe15e0SLoGin // 创建一个新的虚拟内存范围。 94640fe15e0SLoGin let region = VirtRegion::new(cmp::max(*hole_vaddr, min_vaddr), *size); 9474cfa009bSJomo 94840fe15e0SLoGin return Some(region); 94940fe15e0SLoGin } 95040fe15e0SLoGin 95140fe15e0SLoGin pub fn find_free_at( 95240fe15e0SLoGin &self, 95340fe15e0SLoGin min_vaddr: VirtAddr, 95440fe15e0SLoGin vaddr: VirtAddr, 95540fe15e0SLoGin size: usize, 95640fe15e0SLoGin flags: MapFlags, 95740fe15e0SLoGin ) -> Result<VirtRegion, SystemError> { 95840fe15e0SLoGin // 如果没有指定地址,那么就在当前进程的地址空间中寻找一个空闲的虚拟内存范围。 95940fe15e0SLoGin if vaddr == VirtAddr::new(0) { 96040fe15e0SLoGin return self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM); 96140fe15e0SLoGin } 96240fe15e0SLoGin 96340fe15e0SLoGin // 如果指定了地址,那么就检查指定的地址是否可用。 96440fe15e0SLoGin 96540fe15e0SLoGin let requested = VirtRegion::new(vaddr, size); 96640fe15e0SLoGin 96740fe15e0SLoGin if requested.end() >= MMArch::USER_END_VADDR || !vaddr.check_aligned(MMArch::PAGE_SIZE) { 96840fe15e0SLoGin return Err(SystemError::EINVAL); 96940fe15e0SLoGin } 97040fe15e0SLoGin 97140fe15e0SLoGin if let Some(_x) = self.conflicts(requested).next() { 97240fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED_NOREPLACE) { 97340fe15e0SLoGin // 如果指定了 MAP_FIXED_NOREPLACE 标志,由于所指定的地址无法成功建立映射,则放弃映射,不对地址做修正 97440fe15e0SLoGin return Err(SystemError::EEXIST); 97540fe15e0SLoGin } 97640fe15e0SLoGin 97740fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED) { 97840fe15e0SLoGin // todo: 支持MAP_FIXED标志对已有的VMA进行覆盖 9791074eb34SSamuel Dai return Err(SystemError::ENOSYS); 98040fe15e0SLoGin } 98140fe15e0SLoGin 98240fe15e0SLoGin // 如果没有指定MAP_FIXED标志,那么就对地址做修正 98340fe15e0SLoGin let requested = self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM)?; 98440fe15e0SLoGin return Ok(requested); 98540fe15e0SLoGin } 98640fe15e0SLoGin 98740fe15e0SLoGin return Ok(requested); 98840fe15e0SLoGin } 98940fe15e0SLoGin 99040fe15e0SLoGin /// 在当前进程的地址空间中,保留一个指定大小的区域,使得该区域不在空洞中。 99140fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 99240fe15e0SLoGin /// 99340fe15e0SLoGin /// @param region 要保留的区域 99440fe15e0SLoGin /// 99540fe15e0SLoGin /// 请注意,在调用本函数之前,必须先确定region所在范围内没有VMA。 99640fe15e0SLoGin fn reserve_hole(&mut self, region: &VirtRegion) { 99740fe15e0SLoGin let prev_hole: Option<(&VirtAddr, &mut usize)> = 998971462beSGnoCiYeH self.vm_holes.range_mut(..=region.start()).next_back(); 99940fe15e0SLoGin 100040fe15e0SLoGin if let Some((prev_hole_vaddr, prev_hole_size)) = prev_hole { 100140fe15e0SLoGin let prev_hole_end = prev_hole_vaddr.add(*prev_hole_size); 100240fe15e0SLoGin 100340fe15e0SLoGin if prev_hole_end > region.start() { 100440fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的起始地址,那么就需要调整前一个空洞的大小。 100540fe15e0SLoGin *prev_hole_size = region.start().data() - prev_hole_vaddr.data(); 100640fe15e0SLoGin } 100740fe15e0SLoGin 100840fe15e0SLoGin if prev_hole_end > region.end() { 100940fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的结束地址,那么就需要增加一个新的空洞。 101040fe15e0SLoGin self.vm_holes 101140fe15e0SLoGin .insert(region.end(), prev_hole_end - region.end()); 101240fe15e0SLoGin } 101340fe15e0SLoGin } 101440fe15e0SLoGin } 101540fe15e0SLoGin 101640fe15e0SLoGin /// 在当前进程的地址空间中,释放一个指定大小的区域,使得该区域成为一个空洞。 101740fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 101840fe15e0SLoGin fn unreserve_hole(&mut self, region: &VirtRegion) { 101940fe15e0SLoGin // 如果将要插入的空洞与后一个空洞相邻,那么就需要合并。 102040fe15e0SLoGin let next_hole_size: Option<usize> = self.vm_holes.remove(®ion.end()); 102140fe15e0SLoGin 102240fe15e0SLoGin if let Some((_prev_hole_vaddr, prev_hole_size)) = self 102340fe15e0SLoGin .vm_holes 102440fe15e0SLoGin .range_mut(..region.start()) 102540fe15e0SLoGin .next_back() 102640fe15e0SLoGin .filter(|(offset, size)| offset.data() + **size == region.start().data()) 102740fe15e0SLoGin { 102840fe15e0SLoGin *prev_hole_size += region.size() + next_hole_size.unwrap_or(0); 102940fe15e0SLoGin } else { 103040fe15e0SLoGin self.vm_holes 103140fe15e0SLoGin .insert(region.start(), region.size() + next_hole_size.unwrap_or(0)); 103240fe15e0SLoGin } 103340fe15e0SLoGin } 103440fe15e0SLoGin 103540fe15e0SLoGin /// 在当前进程的映射关系中,插入一个新的VMA。 103640fe15e0SLoGin pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) { 1037*cf7f801eSMemoryShore let region = vma.lock_irqsave().region; 103840fe15e0SLoGin // 要求插入的地址范围必须是空闲的,也就是说,当前进程的地址空间中,不能有任何与之重叠的VMA。 103940fe15e0SLoGin assert!(self.conflicts(region).next().is_none()); 104040fe15e0SLoGin self.reserve_hole(®ion); 104140fe15e0SLoGin 104240fe15e0SLoGin self.vmas.insert(vma); 104340fe15e0SLoGin } 104440fe15e0SLoGin 104540fe15e0SLoGin /// @brief 删除一个VMA,并把对应的地址空间加入空洞中。 104640fe15e0SLoGin /// 104740fe15e0SLoGin /// 这里不会取消VMA对应的地址的映射 104840fe15e0SLoGin /// 104940fe15e0SLoGin /// @param region 要删除的VMA所在的地址范围 105040fe15e0SLoGin /// 105140fe15e0SLoGin /// @return 如果成功删除了VMA,则返回被删除的VMA,否则返回None 105240fe15e0SLoGin /// 如果没有可以删除的VMA,则不会执行删除操作,并报告失败。 105340fe15e0SLoGin pub fn remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>> { 105440fe15e0SLoGin // 请注意,由于这里会对每个VMA加锁,因此性能很低 105540fe15e0SLoGin let vma: Arc<LockedVMA> = self 105640fe15e0SLoGin .vmas 1057*cf7f801eSMemoryShore .drain_filter(|vma| vma.lock_irqsave().region == *region) 105840fe15e0SLoGin .next()?; 105940fe15e0SLoGin self.unreserve_hole(region); 106040fe15e0SLoGin 106140fe15e0SLoGin return Some(vma); 106240fe15e0SLoGin } 106340fe15e0SLoGin 106440fe15e0SLoGin /// @brief Get the iterator of all VMAs in this process. 106540fe15e0SLoGin pub fn iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>> { 106640fe15e0SLoGin return self.vmas.iter(); 106740fe15e0SLoGin } 106840fe15e0SLoGin } 106940fe15e0SLoGin 107040fe15e0SLoGin impl Default for UserMappings { 107140fe15e0SLoGin fn default() -> Self { 107240fe15e0SLoGin return Self::new(); 107340fe15e0SLoGin } 107440fe15e0SLoGin } 107540fe15e0SLoGin 107640fe15e0SLoGin /// 加了锁的VMA 107740fe15e0SLoGin /// 107840fe15e0SLoGin /// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。 107940fe15e0SLoGin #[derive(Debug)] 108056cc4dbeSJomo pub struct LockedVMA { 108156cc4dbeSJomo /// 用于计算哈希值,避免总是获取vma锁来计算哈希值 108256cc4dbeSJomo id: usize, 108356cc4dbeSJomo vma: SpinLock<VMA>, 108456cc4dbeSJomo } 108540fe15e0SLoGin 108640fe15e0SLoGin impl core::hash::Hash for LockedVMA { 108740fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 108856cc4dbeSJomo self.id.hash(state); 108940fe15e0SLoGin } 109040fe15e0SLoGin } 109140fe15e0SLoGin 109240fe15e0SLoGin impl PartialEq for LockedVMA { 109340fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 109456cc4dbeSJomo self.id.eq(&other.id) 109540fe15e0SLoGin } 109640fe15e0SLoGin } 109740fe15e0SLoGin 109840fe15e0SLoGin impl Eq for LockedVMA {} 109940fe15e0SLoGin 110040fe15e0SLoGin #[allow(dead_code)] 110140fe15e0SLoGin impl LockedVMA { 110240fe15e0SLoGin pub fn new(vma: VMA) -> Arc<Self> { 110356cc4dbeSJomo let r = Arc::new(Self { 110456cc4dbeSJomo id: LOCKEDVMA_ID_ALLOCATOR.alloc().unwrap(), 110556cc4dbeSJomo vma: SpinLock::new(vma), 110656cc4dbeSJomo }); 1107*cf7f801eSMemoryShore r.vma.lock_irqsave().self_ref = Arc::downgrade(&r); 110840fe15e0SLoGin return r; 110940fe15e0SLoGin } 111040fe15e0SLoGin 11116fc066acSJomo pub fn id(&self) -> usize { 11126fc066acSJomo self.id 11136fc066acSJomo } 11146fc066acSJomo 111540fe15e0SLoGin pub fn lock(&self) -> SpinLockGuard<VMA> { 111656cc4dbeSJomo return self.vma.lock(); 111740fe15e0SLoGin } 111840fe15e0SLoGin 1119*cf7f801eSMemoryShore pub fn lock_irqsave(&self) -> SpinLockGuard<VMA> { 1120*cf7f801eSMemoryShore return self.vma.lock_irqsave(); 1121*cf7f801eSMemoryShore } 1122*cf7f801eSMemoryShore 112340fe15e0SLoGin /// 调整当前VMA的页面的标志位 112440fe15e0SLoGin /// 112540fe15e0SLoGin /// TODO:增加调整虚拟页映射的物理地址的功能 112640fe15e0SLoGin /// 112740fe15e0SLoGin /// @param flags 新的标志位 112840fe15e0SLoGin /// @param mapper 页表映射器 112940fe15e0SLoGin /// @param flusher 页表项刷新器 113040fe15e0SLoGin /// 113140fe15e0SLoGin pub fn remap( 113240fe15e0SLoGin &self, 1133*cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 113440fe15e0SLoGin mapper: &mut PageMapper, 113540fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 113640fe15e0SLoGin ) -> Result<(), SystemError> { 1137*cf7f801eSMemoryShore let mut guard = self.lock_irqsave(); 113840fe15e0SLoGin for page in guard.region.pages() { 113940fe15e0SLoGin // 暂时要求所有的页帧都已经映射到页表 114040fe15e0SLoGin // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了 114140fe15e0SLoGin let r = unsafe { 114240fe15e0SLoGin mapper 114340fe15e0SLoGin .remap(page.virt_address(), flags) 114440fe15e0SLoGin .expect("Failed to remap, beacuse of some page is not mapped") 114540fe15e0SLoGin }; 114640fe15e0SLoGin flusher.consume(r); 114740fe15e0SLoGin } 114840fe15e0SLoGin guard.flags = flags; 114940fe15e0SLoGin return Ok(()); 115040fe15e0SLoGin } 115140fe15e0SLoGin 115240fe15e0SLoGin pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>) { 11531a62e776SLoGin // todo: 如果当前vma与文件相关,完善文件相关的逻辑 11541a62e776SLoGin 1155*cf7f801eSMemoryShore let mut guard = self.lock_irqsave(); 115656cc4dbeSJomo 115756cc4dbeSJomo // 获取物理页的anon_vma的守卫 11586fc066acSJomo let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> = 11596fc066acSJomo page_manager_lock_irqsave(); 116040fe15e0SLoGin for page in guard.region.pages() { 1161a17651b1SMemoryShore if mapper.translate(page.virt_address()).is_none() { 1162a17651b1SMemoryShore continue; 1163a17651b1SMemoryShore } 116440fe15e0SLoGin let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) } 116540fe15e0SLoGin .expect("Failed to unmap, beacuse of some page is not mapped"); 116640fe15e0SLoGin 116756cc4dbeSJomo // 从anon_vma中删除当前VMA 1168*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1169*cf7f801eSMemoryShore page.write_irqsave().remove_vma(self); 117040fe15e0SLoGin 117156cc4dbeSJomo // 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页. 1172*cf7f801eSMemoryShore if page.read_irqsave().can_deallocate() { 117356cc4dbeSJomo unsafe { 1174*cf7f801eSMemoryShore drop(page); 117556cc4dbeSJomo deallocate_page_frames( 117656cc4dbeSJomo PhysPageFrame::new(paddr), 117756cc4dbeSJomo PageFrameCount::new(1), 11786fc066acSJomo &mut page_manager_guard, 117956cc4dbeSJomo ) 118056cc4dbeSJomo }; 118156cc4dbeSJomo } 118240fe15e0SLoGin 118340fe15e0SLoGin flusher.consume(flush); 118440fe15e0SLoGin } 118540fe15e0SLoGin guard.mapped = false; 1186*cf7f801eSMemoryShore 1187*cf7f801eSMemoryShore // 当vma对应共享文件的写映射时,唤醒脏页回写线程 1188*cf7f801eSMemoryShore if guard.vm_file().is_some() 1189*cf7f801eSMemoryShore && guard 1190*cf7f801eSMemoryShore .vm_flags() 1191*cf7f801eSMemoryShore .contains(VmFlags::VM_SHARED | VmFlags::VM_WRITE) 1192*cf7f801eSMemoryShore { 1193*cf7f801eSMemoryShore crate::mm::page::PageReclaimer::wakeup_claim_thread(); 1194*cf7f801eSMemoryShore } 119540fe15e0SLoGin } 119640fe15e0SLoGin 119740fe15e0SLoGin pub fn mapped(&self) -> bool { 1198*cf7f801eSMemoryShore return self.vma.lock_irqsave().mapped; 119940fe15e0SLoGin } 120040fe15e0SLoGin 120140fe15e0SLoGin /// 将当前VMA进行切分,切分成3个VMA,分别是: 120240fe15e0SLoGin /// 120340fe15e0SLoGin /// 1. 前面的VMA,如果没有则为None 120440fe15e0SLoGin /// 2. 中间的VMA,也就是传入的Region 120540fe15e0SLoGin /// 3. 后面的VMA,如果没有则为None 120656cc4dbeSJomo pub fn extract(&self, region: VirtRegion, utable: &PageMapper) -> Option<VMASplitResult> { 120740fe15e0SLoGin assert!(region.start().check_aligned(MMArch::PAGE_SIZE)); 120840fe15e0SLoGin assert!(region.end().check_aligned(MMArch::PAGE_SIZE)); 120940fe15e0SLoGin 1210*cf7f801eSMemoryShore let mut guard = self.lock_irqsave(); 121140fe15e0SLoGin { 121240fe15e0SLoGin // 如果传入的region不在当前VMA的范围内,则直接返回None 121340fe15e0SLoGin if unlikely(region.start() < guard.region.start() || region.end() > guard.region.end()) 121440fe15e0SLoGin { 121540fe15e0SLoGin return None; 121640fe15e0SLoGin } 121740fe15e0SLoGin 121840fe15e0SLoGin let intersect: Option<VirtRegion> = guard.region.intersect(®ion); 121940fe15e0SLoGin // 如果当前VMA不包含region,则直接返回None 122040fe15e0SLoGin if unlikely(intersect.is_none()) { 122140fe15e0SLoGin return None; 122240fe15e0SLoGin } 122340fe15e0SLoGin let intersect: VirtRegion = intersect.unwrap(); 122440fe15e0SLoGin if unlikely(intersect == guard.region) { 122540fe15e0SLoGin // 如果当前VMA完全包含region,则直接返回当前VMA 1226b5b571e0SLoGin return Some(VMASplitResult::new( 1227b5b571e0SLoGin None, 1228b5b571e0SLoGin guard.self_ref.upgrade().unwrap(), 1229b5b571e0SLoGin None, 1230b5b571e0SLoGin )); 123140fe15e0SLoGin } 123240fe15e0SLoGin } 123340fe15e0SLoGin 123440fe15e0SLoGin let before: Option<Arc<LockedVMA>> = guard.region.before(®ion).map(|virt_region| { 123540fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 123640fe15e0SLoGin vma.region = virt_region; 1237de199e3cSMemoryShore vma.mapped = false; 123840fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 123940fe15e0SLoGin vma 124040fe15e0SLoGin }); 124140fe15e0SLoGin 124240fe15e0SLoGin let after: Option<Arc<LockedVMA>> = guard.region.after(®ion).map(|virt_region| { 124340fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 124440fe15e0SLoGin vma.region = virt_region; 1245de199e3cSMemoryShore vma.mapped = false; 124640fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 124740fe15e0SLoGin vma 124840fe15e0SLoGin }); 124940fe15e0SLoGin 125056cc4dbeSJomo // 重新设置before、after这两个VMA里面的物理页的anon_vma 12516fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 125256cc4dbeSJomo if let Some(before) = before.clone() { 1253*cf7f801eSMemoryShore let virt_iter = before.lock_irqsave().region.iter_pages(); 125456cc4dbeSJomo for frame in virt_iter { 1255de199e3cSMemoryShore if let Some((paddr, _)) = utable.translate(frame.virt_address()) { 1256*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1257*cf7f801eSMemoryShore let mut page_guard = page.write_irqsave(); 1258*cf7f801eSMemoryShore page_guard.insert_vma(before.clone()); 1259*cf7f801eSMemoryShore page_guard.remove_vma(self); 1260*cf7f801eSMemoryShore before.lock_irqsave().mapped = true; 1261de199e3cSMemoryShore } 126256cc4dbeSJomo } 126356cc4dbeSJomo } 126440fe15e0SLoGin 126556cc4dbeSJomo if let Some(after) = after.clone() { 1266*cf7f801eSMemoryShore let virt_iter = after.lock_irqsave().region.iter_pages(); 126756cc4dbeSJomo for frame in virt_iter { 1268de199e3cSMemoryShore if let Some((paddr, _)) = utable.translate(frame.virt_address()) { 1269*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1270*cf7f801eSMemoryShore let mut page_guard = page.write_irqsave(); 1271*cf7f801eSMemoryShore page_guard.insert_vma(after.clone()); 1272*cf7f801eSMemoryShore page_guard.remove_vma(self); 1273*cf7f801eSMemoryShore after.lock_irqsave().mapped = true; 1274de199e3cSMemoryShore } 127556cc4dbeSJomo } 127656cc4dbeSJomo } 127756cc4dbeSJomo 127856cc4dbeSJomo guard.region = region; 127940fe15e0SLoGin 1280b5b571e0SLoGin return Some(VMASplitResult::new( 1281b5b571e0SLoGin before, 1282b5b571e0SLoGin guard.self_ref.upgrade().unwrap(), 1283b5b571e0SLoGin after, 1284b5b571e0SLoGin )); 1285b5b571e0SLoGin } 1286a17651b1SMemoryShore 1287a17651b1SMemoryShore /// 判断VMA是否为外部(非当前进程空间)的VMA 1288a17651b1SMemoryShore pub fn is_foreign(&self) -> bool { 1289*cf7f801eSMemoryShore let guard = self.lock_irqsave(); 1290a17651b1SMemoryShore if let Some(space) = guard.user_address_space.clone() { 1291a17651b1SMemoryShore if let Some(space) = space.upgrade() { 1292a17651b1SMemoryShore return AddressSpace::is_current(&space); 1293a17651b1SMemoryShore } else { 1294a17651b1SMemoryShore return true; 1295a17651b1SMemoryShore } 1296a17651b1SMemoryShore } else { 1297a17651b1SMemoryShore return true; 1298a17651b1SMemoryShore } 1299a17651b1SMemoryShore } 1300a17651b1SMemoryShore 1301a17651b1SMemoryShore /// 判断VMA是否可访问 1302a17651b1SMemoryShore pub fn is_accessible(&self) -> bool { 1303*cf7f801eSMemoryShore let guard = self.lock_irqsave(); 1304a17651b1SMemoryShore let vm_access_flags: VmFlags = VmFlags::VM_READ | VmFlags::VM_WRITE | VmFlags::VM_EXEC; 1305a17651b1SMemoryShore guard.vm_flags().intersects(vm_access_flags) 1306a17651b1SMemoryShore } 1307a17651b1SMemoryShore 1308a17651b1SMemoryShore /// 判断VMA是否为匿名映射 1309a17651b1SMemoryShore pub fn is_anonymous(&self) -> bool { 1310*cf7f801eSMemoryShore let guard = self.lock_irqsave(); 1311*cf7f801eSMemoryShore guard.vm_file.is_none() 1312a17651b1SMemoryShore } 1313a17651b1SMemoryShore 1314a17651b1SMemoryShore /// 判断VMA是否为大页映射 1315a17651b1SMemoryShore pub fn is_hugepage(&self) -> bool { 1316a17651b1SMemoryShore //TODO: 实现巨页映射判断逻辑,目前不支持巨页映射 1317a17651b1SMemoryShore false 1318a17651b1SMemoryShore } 1319b5b571e0SLoGin } 1320b5b571e0SLoGin 132156cc4dbeSJomo impl Drop for LockedVMA { 132256cc4dbeSJomo fn drop(&mut self) { 132356cc4dbeSJomo LOCKEDVMA_ID_ALLOCATOR.free(self.id); 132456cc4dbeSJomo } 132556cc4dbeSJomo } 132656cc4dbeSJomo 1327b5b571e0SLoGin /// VMA切分结果 1328bd70d2d1SLoGin #[allow(dead_code)] 1329b5b571e0SLoGin pub struct VMASplitResult { 1330b5b571e0SLoGin pub prev: Option<Arc<LockedVMA>>, 1331b5b571e0SLoGin pub middle: Arc<LockedVMA>, 1332b5b571e0SLoGin pub after: Option<Arc<LockedVMA>>, 1333b5b571e0SLoGin } 1334b5b571e0SLoGin 1335b5b571e0SLoGin impl VMASplitResult { 1336b5b571e0SLoGin pub fn new( 1337b5b571e0SLoGin prev: Option<Arc<LockedVMA>>, 1338b5b571e0SLoGin middle: Arc<LockedVMA>, 1339b5b571e0SLoGin post: Option<Arc<LockedVMA>>, 1340b5b571e0SLoGin ) -> Self { 1341b5b571e0SLoGin Self { 1342b5b571e0SLoGin prev, 1343b5b571e0SLoGin middle, 1344b5b571e0SLoGin after: post, 1345b5b571e0SLoGin } 134640fe15e0SLoGin } 134740fe15e0SLoGin } 134840fe15e0SLoGin 134940fe15e0SLoGin /// @brief 虚拟内存区域 135040fe15e0SLoGin #[derive(Debug)] 135140fe15e0SLoGin pub struct VMA { 135240fe15e0SLoGin /// 虚拟内存区域对应的虚拟地址范围 135340fe15e0SLoGin region: VirtRegion, 13544cfa009bSJomo /// 虚拟内存区域标志 13554cfa009bSJomo vm_flags: VmFlags, 135640fe15e0SLoGin /// VMA内的页帧的标志 1357*cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 135840fe15e0SLoGin /// VMA内的页帧是否已经映射到页表 135940fe15e0SLoGin mapped: bool, 136040fe15e0SLoGin /// VMA所属的用户地址空间 136140fe15e0SLoGin user_address_space: Option<Weak<AddressSpace>>, 136240fe15e0SLoGin self_ref: Weak<LockedVMA>, 1363971462beSGnoCiYeH 1364*cf7f801eSMemoryShore vm_file: Option<Arc<File>>, 1365*cf7f801eSMemoryShore /// VMA映射的文件部分相对于整个文件的偏移页数 1366*cf7f801eSMemoryShore file_pgoff: Option<usize>, 1367*cf7f801eSMemoryShore 1368971462beSGnoCiYeH provider: Provider, 136940fe15e0SLoGin } 137040fe15e0SLoGin 137140fe15e0SLoGin impl core::hash::Hash for VMA { 137240fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 137340fe15e0SLoGin self.region.hash(state); 137440fe15e0SLoGin self.flags.hash(state); 137540fe15e0SLoGin self.mapped.hash(state); 137640fe15e0SLoGin } 137740fe15e0SLoGin } 137840fe15e0SLoGin 1379971462beSGnoCiYeH /// 描述不同类型的内存提供者或资源 1380971462beSGnoCiYeH #[derive(Debug)] 1381971462beSGnoCiYeH pub enum Provider { 1382971462beSGnoCiYeH Allocated, // TODO:其他 1383971462beSGnoCiYeH } 1384971462beSGnoCiYeH 138540fe15e0SLoGin #[allow(dead_code)] 138640fe15e0SLoGin impl VMA { 13874cfa009bSJomo pub fn new( 13884cfa009bSJomo region: VirtRegion, 13894cfa009bSJomo vm_flags: VmFlags, 1390*cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 1391*cf7f801eSMemoryShore file: Option<Arc<File>>, 1392*cf7f801eSMemoryShore pgoff: Option<usize>, 13934cfa009bSJomo mapped: bool, 13944cfa009bSJomo ) -> Self { 13954cfa009bSJomo VMA { 13964cfa009bSJomo region, 13974cfa009bSJomo vm_flags, 13984cfa009bSJomo flags, 13994cfa009bSJomo mapped, 14004cfa009bSJomo user_address_space: None, 14014cfa009bSJomo self_ref: Weak::default(), 14024cfa009bSJomo provider: Provider::Allocated, 1403*cf7f801eSMemoryShore vm_file: file, 1404*cf7f801eSMemoryShore file_pgoff: pgoff, 14054cfa009bSJomo } 14064cfa009bSJomo } 14074cfa009bSJomo 140840fe15e0SLoGin pub fn region(&self) -> &VirtRegion { 140940fe15e0SLoGin return &self.region; 141040fe15e0SLoGin } 141140fe15e0SLoGin 14124cfa009bSJomo pub fn vm_flags(&self) -> &VmFlags { 14134cfa009bSJomo return &self.vm_flags; 14144cfa009bSJomo } 14154cfa009bSJomo 1416*cf7f801eSMemoryShore pub fn vm_file(&self) -> Option<Arc<File>> { 1417*cf7f801eSMemoryShore return self.vm_file.clone(); 1418*cf7f801eSMemoryShore } 1419*cf7f801eSMemoryShore 1420*cf7f801eSMemoryShore pub fn address_space(&self) -> Option<Weak<AddressSpace>> { 1421*cf7f801eSMemoryShore return self.user_address_space.clone(); 1422*cf7f801eSMemoryShore } 1423*cf7f801eSMemoryShore 14244cfa009bSJomo pub fn set_vm_flags(&mut self, vm_flags: VmFlags) { 14254cfa009bSJomo self.vm_flags = vm_flags; 14264cfa009bSJomo } 14274cfa009bSJomo 14284cfa009bSJomo pub fn set_region_size(&mut self, new_region_size: usize) { 14294cfa009bSJomo self.region.set_size(new_region_size); 14304cfa009bSJomo } 14314cfa009bSJomo 14326fc066acSJomo pub fn set_mapped(&mut self, mapped: bool) { 14336fc066acSJomo self.mapped = mapped; 14346fc066acSJomo } 14356fc066acSJomo 1436*cf7f801eSMemoryShore pub fn set_flags(&mut self) { 1437*cf7f801eSMemoryShore self.flags = MMArch::vm_get_page_prot(self.vm_flags); 1438*cf7f801eSMemoryShore } 1439*cf7f801eSMemoryShore 144040fe15e0SLoGin /// # 拷贝当前VMA的内容 144140fe15e0SLoGin /// 144240fe15e0SLoGin /// ### 安全性 144340fe15e0SLoGin /// 144440fe15e0SLoGin /// 由于这样操作可能由于错误的拷贝,导致内存泄露、内存重复释放等问题,所以需要小心使用。 144540fe15e0SLoGin pub unsafe fn clone(&self) -> Self { 144640fe15e0SLoGin return Self { 144740fe15e0SLoGin region: self.region, 14484cfa009bSJomo vm_flags: self.vm_flags, 144940fe15e0SLoGin flags: self.flags, 145040fe15e0SLoGin mapped: self.mapped, 145140fe15e0SLoGin user_address_space: self.user_address_space.clone(), 145240fe15e0SLoGin self_ref: self.self_ref.clone(), 1453971462beSGnoCiYeH provider: Provider::Allocated, 1454*cf7f801eSMemoryShore file_pgoff: self.file_pgoff, 1455*cf7f801eSMemoryShore vm_file: self.vm_file.clone(), 145640fe15e0SLoGin }; 145740fe15e0SLoGin } 145840fe15e0SLoGin 1459a17651b1SMemoryShore pub fn clone_info_only(&self) -> Self { 1460a17651b1SMemoryShore return Self { 1461a17651b1SMemoryShore region: self.region, 1462a17651b1SMemoryShore vm_flags: self.vm_flags, 1463a17651b1SMemoryShore flags: self.flags, 1464a17651b1SMemoryShore mapped: self.mapped, 1465a17651b1SMemoryShore user_address_space: None, 1466a17651b1SMemoryShore self_ref: Weak::default(), 1467a17651b1SMemoryShore provider: Provider::Allocated, 1468*cf7f801eSMemoryShore file_pgoff: self.file_pgoff, 1469*cf7f801eSMemoryShore vm_file: self.vm_file.clone(), 1470a17651b1SMemoryShore }; 1471a17651b1SMemoryShore } 1472a17651b1SMemoryShore 147340fe15e0SLoGin #[inline(always)] 1474*cf7f801eSMemoryShore pub fn flags(&self) -> EntryFlags<MMArch> { 147540fe15e0SLoGin return self.flags; 147640fe15e0SLoGin } 147740fe15e0SLoGin 1478*cf7f801eSMemoryShore #[inline(always)] 1479*cf7f801eSMemoryShore pub fn file_page_offset(&self) -> Option<usize> { 1480*cf7f801eSMemoryShore return self.file_pgoff; 1481*cf7f801eSMemoryShore } 1482*cf7f801eSMemoryShore 148340fe15e0SLoGin pub fn pages(&self) -> VirtPageFrameIter { 148440fe15e0SLoGin return VirtPageFrameIter::new( 148540fe15e0SLoGin VirtPageFrame::new(self.region.start()), 148640fe15e0SLoGin VirtPageFrame::new(self.region.end()), 148740fe15e0SLoGin ); 148840fe15e0SLoGin } 148940fe15e0SLoGin 149040fe15e0SLoGin pub fn remap( 149140fe15e0SLoGin &mut self, 1492*cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 149340fe15e0SLoGin mapper: &mut PageMapper, 149440fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 149540fe15e0SLoGin ) -> Result<(), SystemError> { 149640fe15e0SLoGin for page in self.region.pages() { 14972eab6dd7S曾俊 // debug!("remap page {:?}", page.virt_address()); 1498a17651b1SMemoryShore if mapper.translate(page.virt_address()).is_some() { 149940fe15e0SLoGin let r = unsafe { 150040fe15e0SLoGin mapper 150140fe15e0SLoGin .remap(page.virt_address(), flags) 1502a17651b1SMemoryShore .expect("Failed to remap") 150340fe15e0SLoGin }; 150440fe15e0SLoGin flusher.consume(r); 1505a17651b1SMemoryShore } 15062eab6dd7S曾俊 // debug!("consume page {:?}", page.virt_address()); 15072eab6dd7S曾俊 // debug!("remap page {:?} done", page.virt_address()); 150840fe15e0SLoGin } 150940fe15e0SLoGin self.flags = flags; 151040fe15e0SLoGin return Ok(()); 151140fe15e0SLoGin } 151240fe15e0SLoGin 151340fe15e0SLoGin /// 检查当前VMA是否可以拥有指定的标志位 151440fe15e0SLoGin /// 151540fe15e0SLoGin /// ## 参数 151640fe15e0SLoGin /// 151740fe15e0SLoGin /// - `prot_flags` 要检查的标志位 151840fe15e0SLoGin pub fn can_have_flags(&self, prot_flags: ProtFlags) -> bool { 1519971462beSGnoCiYeH let is_downgrade = (self.flags.has_write() || !prot_flags.contains(ProtFlags::PROT_WRITE)) 152040fe15e0SLoGin && (self.flags.has_execute() || !prot_flags.contains(ProtFlags::PROT_EXEC)); 1521971462beSGnoCiYeH 1522971462beSGnoCiYeH match self.provider { 1523971462beSGnoCiYeH Provider::Allocated { .. } => true, 1524971462beSGnoCiYeH 1525971462beSGnoCiYeH #[allow(unreachable_patterns)] 1526971462beSGnoCiYeH _ => is_downgrade, 1527971462beSGnoCiYeH } 152840fe15e0SLoGin } 152940fe15e0SLoGin 153040fe15e0SLoGin /// 把物理地址映射到虚拟地址 153140fe15e0SLoGin /// 153240fe15e0SLoGin /// @param phys 要映射的物理地址 153340fe15e0SLoGin /// @param destination 要映射到的虚拟地址 153440fe15e0SLoGin /// @param count 要映射的页帧数量 153540fe15e0SLoGin /// @param flags 页面标志位 153640fe15e0SLoGin /// @param mapper 页表映射器 153740fe15e0SLoGin /// @param flusher 页表项刷新器 153840fe15e0SLoGin /// 153940fe15e0SLoGin /// @return 返回映射后的虚拟内存区域 154040fe15e0SLoGin pub fn physmap( 154140fe15e0SLoGin phys: PhysPageFrame, 154240fe15e0SLoGin destination: VirtPageFrame, 154340fe15e0SLoGin count: PageFrameCount, 15444cfa009bSJomo vm_flags: VmFlags, 1545*cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 154640fe15e0SLoGin mapper: &mut PageMapper, 154740fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 154840fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 154940fe15e0SLoGin let mut cur_phy = phys; 155040fe15e0SLoGin let mut cur_dest = destination; 155140fe15e0SLoGin 155240fe15e0SLoGin for _ in 0..count.data() { 155340fe15e0SLoGin // 将物理页帧映射到虚拟页帧 155456cc4dbeSJomo let r = 155556cc4dbeSJomo unsafe { mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags) } 155640fe15e0SLoGin .expect("Failed to map phys, may be OOM error"); 155740fe15e0SLoGin 155840fe15e0SLoGin // todo: 增加OOM处理 155940fe15e0SLoGin 156040fe15e0SLoGin // 刷新TLB 156140fe15e0SLoGin flusher.consume(r); 156240fe15e0SLoGin 156340fe15e0SLoGin cur_phy = cur_phy.next(); 156440fe15e0SLoGin cur_dest = cur_dest.next(); 156540fe15e0SLoGin } 156640fe15e0SLoGin 1567*cf7f801eSMemoryShore let r: Arc<LockedVMA> = LockedVMA::new(VMA::new( 1568*cf7f801eSMemoryShore VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE), 15694cfa009bSJomo vm_flags, 157040fe15e0SLoGin flags, 1571*cf7f801eSMemoryShore None, 1572*cf7f801eSMemoryShore None, 1573*cf7f801eSMemoryShore true, 1574*cf7f801eSMemoryShore )); 157556cc4dbeSJomo 157656cc4dbeSJomo // 将VMA加入到anon_vma中 15776fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 157856cc4dbeSJomo cur_phy = phys; 157956cc4dbeSJomo for _ in 0..count.data() { 158056cc4dbeSJomo let paddr = cur_phy.phys_address(); 1581*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1582*cf7f801eSMemoryShore page.write_irqsave().insert_vma(r.clone()); 158356cc4dbeSJomo cur_phy = cur_phy.next(); 158456cc4dbeSJomo } 158556cc4dbeSJomo 158640fe15e0SLoGin return Ok(r); 158740fe15e0SLoGin } 158840fe15e0SLoGin 158940fe15e0SLoGin /// 从页分配器中分配一些物理页,并把它们映射到指定的虚拟地址,然后创建VMA 1590*cf7f801eSMemoryShore /// ## 参数 159140fe15e0SLoGin /// 1592*cf7f801eSMemoryShore /// - `destination`: 要映射到的虚拟地址 1593*cf7f801eSMemoryShore /// - `page_count`: 要映射的页帧数量 1594*cf7f801eSMemoryShore /// - `vm_flags`: VMA标志位 1595*cf7f801eSMemoryShore /// - `flags`: 页面标志位 1596*cf7f801eSMemoryShore /// - `mapper`: 页表映射器 1597*cf7f801eSMemoryShore /// - `flusher`: 页表项刷新器 1598*cf7f801eSMemoryShore /// - `file`: 映射文件 1599*cf7f801eSMemoryShore /// - `pgoff`: 返回映射后的虚拟内存区域 160040fe15e0SLoGin /// 1601*cf7f801eSMemoryShore /// ## 返回值 1602*cf7f801eSMemoryShore /// - 页面错误处理信息标志 1603*cf7f801eSMemoryShore #[allow(clippy::too_many_arguments)] 160440fe15e0SLoGin pub fn zeroed( 160540fe15e0SLoGin destination: VirtPageFrame, 160640fe15e0SLoGin page_count: PageFrameCount, 16074cfa009bSJomo vm_flags: VmFlags, 1608*cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 160940fe15e0SLoGin mapper: &mut PageMapper, 161040fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 1611*cf7f801eSMemoryShore file: Option<Arc<File>>, 1612*cf7f801eSMemoryShore pgoff: Option<usize>, 161340fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 161440fe15e0SLoGin let mut cur_dest: VirtPageFrame = destination; 16152eab6dd7S曾俊 // debug!( 161640fe15e0SLoGin // "VMA::zeroed: page_count = {:?}, destination={destination:?}", 161740fe15e0SLoGin // page_count 161840fe15e0SLoGin // ); 161940fe15e0SLoGin for _ in 0..page_count.data() { 16202eab6dd7S曾俊 // debug!( 162140fe15e0SLoGin // "VMA::zeroed: cur_dest={cur_dest:?}, vaddr = {:?}", 162240fe15e0SLoGin // cur_dest.virt_address() 162340fe15e0SLoGin // ); 162440fe15e0SLoGin let r = unsafe { mapper.map(cur_dest.virt_address(), flags) } 162540fe15e0SLoGin .expect("Failed to map zero, may be OOM error"); 162640fe15e0SLoGin // todo: 增加OOM处理 162740fe15e0SLoGin 162840fe15e0SLoGin // 稍后再刷新TLB,这里取消刷新 162940fe15e0SLoGin flusher.consume(r); 163040fe15e0SLoGin cur_dest = cur_dest.next(); 163140fe15e0SLoGin } 163217dc5589SMemoryShore let r = LockedVMA::new(VMA::new( 163317dc5589SMemoryShore VirtRegion::new( 163440fe15e0SLoGin destination.virt_address(), 163540fe15e0SLoGin page_count.data() * MMArch::PAGE_SIZE, 163640fe15e0SLoGin ), 16374cfa009bSJomo vm_flags, 163840fe15e0SLoGin flags, 1639*cf7f801eSMemoryShore file, 1640*cf7f801eSMemoryShore pgoff, 164117dc5589SMemoryShore true, 164217dc5589SMemoryShore )); 164340fe15e0SLoGin drop(flusher); 16442eab6dd7S曾俊 // debug!("VMA::zeroed: flusher dropped"); 164540fe15e0SLoGin 164656cc4dbeSJomo // 清空这些内存并将VMA加入到anon_vma中 16476fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 16489550910aSChiichen let virt_iter: VirtPageFrameIter = 16499550910aSChiichen VirtPageFrameIter::new(destination, destination.add(page_count)); 165040fe15e0SLoGin for frame in virt_iter { 165140fe15e0SLoGin let paddr = mapper.translate(frame.virt_address()).unwrap().0; 165240fe15e0SLoGin 165356cc4dbeSJomo // 将VMA加入到anon_vma 1654*cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1655*cf7f801eSMemoryShore page.write_irqsave().insert_vma(r.clone()); 165640fe15e0SLoGin } 16572eab6dd7S曾俊 // debug!("VMA::zeroed: done"); 165840fe15e0SLoGin return Ok(r); 165940fe15e0SLoGin } 1660*cf7f801eSMemoryShore 1661*cf7f801eSMemoryShore pub fn page_address(&self, page: &Arc<Page>) -> Result<VirtAddr, SystemError> { 1662*cf7f801eSMemoryShore let page_guard = page.read_irqsave(); 1663*cf7f801eSMemoryShore let index = page_guard.index().unwrap(); 1664*cf7f801eSMemoryShore if index >= self.file_pgoff.unwrap() { 1665*cf7f801eSMemoryShore let address = 1666*cf7f801eSMemoryShore self.region.start + ((index - self.file_pgoff.unwrap()) << MMArch::PAGE_SHIFT); 1667*cf7f801eSMemoryShore if address <= self.region.end() { 1668*cf7f801eSMemoryShore return Ok(address); 1669*cf7f801eSMemoryShore } 1670*cf7f801eSMemoryShore } 1671*cf7f801eSMemoryShore return Err(SystemError::EFAULT); 1672*cf7f801eSMemoryShore } 167340fe15e0SLoGin } 167440fe15e0SLoGin 167540fe15e0SLoGin impl Drop for VMA { 167640fe15e0SLoGin fn drop(&mut self) { 167740fe15e0SLoGin // 当VMA被释放时,需要确保它已经被从页表中解除映射 167840fe15e0SLoGin assert!(!self.mapped, "VMA is still mapped"); 167940fe15e0SLoGin } 168040fe15e0SLoGin } 168140fe15e0SLoGin 168240fe15e0SLoGin impl PartialEq for VMA { 168340fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 168440fe15e0SLoGin return self.region == other.region; 168540fe15e0SLoGin } 168640fe15e0SLoGin } 168740fe15e0SLoGin 168840fe15e0SLoGin impl Eq for VMA {} 168940fe15e0SLoGin 169040fe15e0SLoGin impl PartialOrd for VMA { 169140fe15e0SLoGin fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 1692b5b571e0SLoGin Some(self.cmp(other)) 169340fe15e0SLoGin } 169440fe15e0SLoGin } 169540fe15e0SLoGin 169640fe15e0SLoGin impl Ord for VMA { 169740fe15e0SLoGin fn cmp(&self, other: &Self) -> cmp::Ordering { 169840fe15e0SLoGin return self.region.cmp(&other.region); 169940fe15e0SLoGin } 170040fe15e0SLoGin } 170140fe15e0SLoGin 170240fe15e0SLoGin #[derive(Debug)] 170340fe15e0SLoGin pub struct UserStack { 170440fe15e0SLoGin // 栈底地址 170540fe15e0SLoGin stack_bottom: VirtAddr, 170640fe15e0SLoGin // 当前已映射的大小 170740fe15e0SLoGin mapped_size: usize, 170840fe15e0SLoGin /// 栈顶地址(这个值需要仔细确定!因为它可能不会实时与用户栈的真实栈顶保持一致!要小心!) 170940fe15e0SLoGin current_sp: VirtAddr, 171040fe15e0SLoGin } 171140fe15e0SLoGin 171240fe15e0SLoGin impl UserStack { 171340fe15e0SLoGin /// 默认的用户栈底地址 171440fe15e0SLoGin pub const DEFAULT_USER_STACK_BOTTOM: VirtAddr = MMArch::USER_STACK_START; 171540fe15e0SLoGin /// 默认的用户栈大小为8MB 171640fe15e0SLoGin pub const DEFAULT_USER_STACK_SIZE: usize = 8 * 1024 * 1024; 171740fe15e0SLoGin /// 用户栈的保护页数量 171840fe15e0SLoGin pub const GUARD_PAGES_NUM: usize = 4; 171940fe15e0SLoGin 172040fe15e0SLoGin /// 创建一个用户栈 172140fe15e0SLoGin pub fn new( 172240fe15e0SLoGin vm: &mut InnerAddressSpace, 172340fe15e0SLoGin stack_bottom: Option<VirtAddr>, 172440fe15e0SLoGin stack_size: usize, 172540fe15e0SLoGin ) -> Result<Self, SystemError> { 172640fe15e0SLoGin let stack_bottom = stack_bottom.unwrap_or(Self::DEFAULT_USER_STACK_BOTTOM); 172740fe15e0SLoGin assert!(stack_bottom.check_aligned(MMArch::PAGE_SIZE)); 172840fe15e0SLoGin 172940fe15e0SLoGin // 分配用户栈的保护页 173040fe15e0SLoGin let guard_size = Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 173140fe15e0SLoGin let actual_stack_bottom = stack_bottom - guard_size; 173240fe15e0SLoGin 173340fe15e0SLoGin let mut prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE; 1734a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE 1735a17651b1SMemoryShore | MapFlags::MAP_ANONYMOUS 1736a17651b1SMemoryShore | MapFlags::MAP_FIXED_NOREPLACE 1737a17651b1SMemoryShore | MapFlags::MAP_GROWSDOWN; 17382eab6dd7S曾俊 // debug!( 173940fe15e0SLoGin // "map anonymous stack: {:?} {}", 174040fe15e0SLoGin // actual_stack_bottom, 174140fe15e0SLoGin // guard_size 174240fe15e0SLoGin // ); 174340fe15e0SLoGin vm.map_anonymous( 174440fe15e0SLoGin actual_stack_bottom, 174540fe15e0SLoGin guard_size, 174640fe15e0SLoGin prot_flags, 174740fe15e0SLoGin map_flags, 174840fe15e0SLoGin false, 1749a17651b1SMemoryShore false, 175040fe15e0SLoGin )?; 175140fe15e0SLoGin // test_buddy(); 175240fe15e0SLoGin // 设置保护页只读 175340fe15e0SLoGin prot_flags.remove(ProtFlags::PROT_WRITE); 17542eab6dd7S曾俊 // debug!( 175540fe15e0SLoGin // "to mprotect stack guard pages: {:?} {}", 175640fe15e0SLoGin // actual_stack_bottom, 175740fe15e0SLoGin // guard_size 175840fe15e0SLoGin // ); 175940fe15e0SLoGin vm.mprotect( 176040fe15e0SLoGin VirtPageFrame::new(actual_stack_bottom), 176140fe15e0SLoGin PageFrameCount::new(Self::GUARD_PAGES_NUM), 176240fe15e0SLoGin prot_flags, 176340fe15e0SLoGin )?; 176440fe15e0SLoGin 17652eab6dd7S曾俊 // debug!( 176640fe15e0SLoGin // "mprotect stack guard pages done: {:?} {}", 176740fe15e0SLoGin // actual_stack_bottom, 176840fe15e0SLoGin // guard_size 176940fe15e0SLoGin // ); 177040fe15e0SLoGin 177140fe15e0SLoGin let mut user_stack = UserStack { 177240fe15e0SLoGin stack_bottom: actual_stack_bottom, 177340fe15e0SLoGin mapped_size: guard_size, 177440fe15e0SLoGin current_sp: actual_stack_bottom - guard_size, 177540fe15e0SLoGin }; 177640fe15e0SLoGin 17772eab6dd7S曾俊 // debug!("extend user stack: {:?} {}", stack_bottom, stack_size); 177840fe15e0SLoGin // 分配用户栈 177940fe15e0SLoGin user_stack.initial_extend(vm, stack_size)?; 17802eab6dd7S曾俊 // debug!("user stack created: {:?} {}", stack_bottom, stack_size); 178140fe15e0SLoGin return Ok(user_stack); 178240fe15e0SLoGin } 178340fe15e0SLoGin 178440fe15e0SLoGin fn initial_extend( 178540fe15e0SLoGin &mut self, 178640fe15e0SLoGin vm: &mut InnerAddressSpace, 178740fe15e0SLoGin mut bytes: usize, 178840fe15e0SLoGin ) -> Result<(), SystemError> { 178940fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 1790a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN; 179140fe15e0SLoGin 179240fe15e0SLoGin bytes = page_align_up(bytes); 179340fe15e0SLoGin self.mapped_size += bytes; 179440fe15e0SLoGin 179540fe15e0SLoGin vm.map_anonymous( 179640fe15e0SLoGin self.stack_bottom - self.mapped_size, 179740fe15e0SLoGin bytes, 179840fe15e0SLoGin prot_flags, 179940fe15e0SLoGin map_flags, 180040fe15e0SLoGin false, 1801a17651b1SMemoryShore false, 180240fe15e0SLoGin )?; 180340fe15e0SLoGin 180440fe15e0SLoGin return Ok(()); 180540fe15e0SLoGin } 180640fe15e0SLoGin 180740fe15e0SLoGin /// 扩展用户栈 180840fe15e0SLoGin /// 180940fe15e0SLoGin /// ## 参数 181040fe15e0SLoGin /// 181140fe15e0SLoGin /// - `vm` 用户地址空间结构体 181240fe15e0SLoGin /// - `bytes` 要扩展的字节数 181340fe15e0SLoGin /// 181440fe15e0SLoGin /// ## 返回值 181540fe15e0SLoGin /// 181640fe15e0SLoGin /// - **Ok(())** 扩展成功 181740fe15e0SLoGin /// - **Err(SystemError)** 扩展失败 181840fe15e0SLoGin #[allow(dead_code)] 181940fe15e0SLoGin pub fn extend( 182040fe15e0SLoGin &mut self, 1821a17651b1SMemoryShore vm: &mut InnerAddressSpace, 182240fe15e0SLoGin mut bytes: usize, 182340fe15e0SLoGin ) -> Result<(), SystemError> { 182440fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 182540fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS; 182640fe15e0SLoGin 182740fe15e0SLoGin bytes = page_align_up(bytes); 182840fe15e0SLoGin self.mapped_size += bytes; 182940fe15e0SLoGin 183040fe15e0SLoGin vm.map_anonymous( 183140fe15e0SLoGin self.stack_bottom - self.mapped_size, 183240fe15e0SLoGin bytes, 183340fe15e0SLoGin prot_flags, 183440fe15e0SLoGin map_flags, 183540fe15e0SLoGin false, 1836a17651b1SMemoryShore false, 183740fe15e0SLoGin )?; 183840fe15e0SLoGin 183940fe15e0SLoGin return Ok(()); 184040fe15e0SLoGin } 184140fe15e0SLoGin 184240fe15e0SLoGin /// 获取栈顶地址 184340fe15e0SLoGin /// 184440fe15e0SLoGin /// 请注意,如果用户栈的栈顶地址发生变化,这个值可能不会实时更新! 184540fe15e0SLoGin pub fn sp(&self) -> VirtAddr { 184640fe15e0SLoGin return self.current_sp; 184740fe15e0SLoGin } 184840fe15e0SLoGin 184940fe15e0SLoGin pub unsafe fn set_sp(&mut self, sp: VirtAddr) { 185040fe15e0SLoGin self.current_sp = sp; 185140fe15e0SLoGin } 185240fe15e0SLoGin 185340fe15e0SLoGin /// 仅仅克隆用户栈的信息,不会克隆用户栈的内容/映射 185440fe15e0SLoGin pub unsafe fn clone_info_only(&self) -> Self { 185540fe15e0SLoGin return Self { 185640fe15e0SLoGin stack_bottom: self.stack_bottom, 185740fe15e0SLoGin mapped_size: self.mapped_size, 185840fe15e0SLoGin current_sp: self.current_sp, 185940fe15e0SLoGin }; 186040fe15e0SLoGin } 186140fe15e0SLoGin 186240fe15e0SLoGin /// 获取当前用户栈的大小(不包括保护页) 186340fe15e0SLoGin pub fn stack_size(&self) -> usize { 186440fe15e0SLoGin return self.mapped_size - Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 186540fe15e0SLoGin } 186640fe15e0SLoGin } 1867