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, 23cf7f801eSMemoryShore 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 }, 38cf7f801eSMemoryShore 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 { new(create_stack: bool) -> Result<Arc<Self>, SystemError>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指针 current() -> Result<Arc<AddressSpace>, SystemError>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 /// 判断某个地址空间是否为当前进程的地址空间 is_current(self: &Arc<Self>) -> bool8440fe15e0SLoGin 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 deref(&self) -> &Self::Target9640fe15e0SLoGin fn deref(&self) -> &Self::Target { 9740fe15e0SLoGin &self.inner 9840fe15e0SLoGin } 9940fe15e0SLoGin } 10040fe15e0SLoGin 10140fe15e0SLoGin impl core::ops::DerefMut for AddressSpace { deref_mut(&mut self) -> &mut Self::Target10240fe15e0SLoGin 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 { new(create_stack: bool) -> Result<Self, SystemError>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)] try_clone(&mut self) -> Result<Arc<AddressSpace>, SystemError>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 182cf7f801eSMemoryShore 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); 188cf7f801eSMemoryShore let new_vma_guard = new_vma.lock_irqsave(); 189a17651b1SMemoryShore let new_mapper = &new_guard.user_mapper.utable; 190cf7f801eSMemoryShore 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) { 193cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 194cf7f801eSMemoryShore page.write_irqsave().insert_vma(new_vma.clone()); 19540fe15e0SLoGin } 196a17651b1SMemoryShore } 19740fe15e0SLoGin 198cf7f801eSMemoryShore 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)] extend_stack(&mut self, mut bytes: usize) -> Result<(), SystemError>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] is_current(&self) -> bool22740fe15e0SLoGin 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 /// 返回映射的起始虚拟页帧 map_anonymous( &mut self, start_vaddr: VirtAddr, len: usize, prot_flags: ProtFlags, map_flags: MapFlags, round_to_min: bool, allocate_at_once: bool, ) -> Result<VirtPageFrame, SystemError>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 2782eab6dd7S曾俊 // debug!("map_anonymous: len = {}", len); 27940fe15e0SLoGin 280cf7f801eSMemoryShore let start_page: VirtPageFrame = self.mmap( 28140fe15e0SLoGin round_hint_to_min(start_vaddr), 28240fe15e0SLoGin PageFrameCount::from_bytes(len).unwrap(), 28340fe15e0SLoGin prot_flags, 28440fe15e0SLoGin map_flags, 285*a3571c8bSMemoryShore move |page, count, vm_flags, flags, mapper, flusher| { 286cf7f801eSMemoryShore if allocate_at_once { 287cf7f801eSMemoryShore VMA::zeroed(page, count, vm_flags, flags, mapper, flusher, None, None) 288a17651b1SMemoryShore } else { 28917dc5589SMemoryShore Ok(LockedVMA::new(VMA::new( 29017dc5589SMemoryShore VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE), 291a17651b1SMemoryShore vm_flags, 292a17651b1SMemoryShore flags, 293cf7f801eSMemoryShore None, 294cf7f801eSMemoryShore None, 29517dc5589SMemoryShore false, 29617dc5589SMemoryShore ))) 297cf7f801eSMemoryShore } 298a17651b1SMemoryShore }, 299cf7f801eSMemoryShore )?; 30040fe15e0SLoGin 30140fe15e0SLoGin return Ok(start_page); 30240fe15e0SLoGin } 30340fe15e0SLoGin 304cf7f801eSMemoryShore /// 进行文件页映射 305cf7f801eSMemoryShore /// 306cf7f801eSMemoryShore /// ## 参数 307cf7f801eSMemoryShore /// 308cf7f801eSMemoryShore /// - `start_vaddr`:映射的起始地址 309cf7f801eSMemoryShore /// - `len`:映射的长度 310cf7f801eSMemoryShore /// - `prot_flags`:保护标志 311cf7f801eSMemoryShore /// - `map_flags`:映射标志 312cf7f801eSMemoryShore /// - `fd`:文件描述符 313cf7f801eSMemoryShore /// - `offset`:映射偏移量 314cf7f801eSMemoryShore /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界 315cf7f801eSMemoryShore /// - `allocate_at_once`:是否立即分配物理空间 316cf7f801eSMemoryShore /// 317cf7f801eSMemoryShore /// ## 返回 318cf7f801eSMemoryShore /// 319cf7f801eSMemoryShore /// 返回映射的起始虚拟页帧 320cf7f801eSMemoryShore #[allow(clippy::too_many_arguments)] file_mapping( &mut self, start_vaddr: VirtAddr, len: usize, prot_flags: ProtFlags, map_flags: MapFlags, fd: i32, offset: usize, round_to_min: bool, allocate_at_once: bool, ) -> Result<VirtPageFrame, SystemError>321cf7f801eSMemoryShore pub fn file_mapping( 322cf7f801eSMemoryShore &mut self, 323cf7f801eSMemoryShore start_vaddr: VirtAddr, 324cf7f801eSMemoryShore len: usize, 325cf7f801eSMemoryShore prot_flags: ProtFlags, 326cf7f801eSMemoryShore map_flags: MapFlags, 327cf7f801eSMemoryShore fd: i32, 328cf7f801eSMemoryShore offset: usize, 329cf7f801eSMemoryShore round_to_min: bool, 330cf7f801eSMemoryShore allocate_at_once: bool, 331cf7f801eSMemoryShore ) -> Result<VirtPageFrame, SystemError> { 332cf7f801eSMemoryShore let allocate_at_once = if MMArch::PAGE_FAULT_ENABLED { 333cf7f801eSMemoryShore allocate_at_once 334cf7f801eSMemoryShore } else { 335cf7f801eSMemoryShore true 336cf7f801eSMemoryShore }; 337cf7f801eSMemoryShore // 用于对齐hint的函数 338cf7f801eSMemoryShore let round_hint_to_min = |hint: VirtAddr| { 339cf7f801eSMemoryShore // 先把hint向下对齐到页边界 340cf7f801eSMemoryShore let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK); 341cf7f801eSMemoryShore // debug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint); 342cf7f801eSMemoryShore // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR 343cf7f801eSMemoryShore if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) { 344cf7f801eSMemoryShore Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR))) 345cf7f801eSMemoryShore } else if addr == 0 { 346cf7f801eSMemoryShore None 347cf7f801eSMemoryShore } else { 348cf7f801eSMemoryShore Some(VirtAddr::new(addr)) 349cf7f801eSMemoryShore } 350cf7f801eSMemoryShore }; 351cf7f801eSMemoryShore // debug!("map_anonymous: start_vaddr = {:?}", start_vaddr); 352cf7f801eSMemoryShore // debug!("map_anonymous: len(no align) = {}", len); 353cf7f801eSMemoryShore 354cf7f801eSMemoryShore let len = page_align_up(len); 355cf7f801eSMemoryShore 356cf7f801eSMemoryShore // debug!("map_anonymous: len = {}", len); 357cf7f801eSMemoryShore 358cf7f801eSMemoryShore let binding = ProcessManager::current_pcb().fd_table(); 359cf7f801eSMemoryShore let fd_table_guard = binding.read(); 360cf7f801eSMemoryShore 361cf7f801eSMemoryShore let file = fd_table_guard.get_file_by_fd(fd); 362cf7f801eSMemoryShore if file.is_none() { 363cf7f801eSMemoryShore return Err(SystemError::EBADF); 364cf7f801eSMemoryShore } 365cf7f801eSMemoryShore // drop guard 以避免无法调度的问题 366cf7f801eSMemoryShore drop(fd_table_guard); 367cf7f801eSMemoryShore 368cf7f801eSMemoryShore // offset需要4K对齐 369cf7f801eSMemoryShore if !offset & (MMArch::PAGE_SIZE - 1) == 0 { 370cf7f801eSMemoryShore return Err(SystemError::EINVAL); 371cf7f801eSMemoryShore } 372cf7f801eSMemoryShore let pgoff = offset >> MMArch::PAGE_SHIFT; 373cf7f801eSMemoryShore 374cf7f801eSMemoryShore let start_page: VirtPageFrame = self.mmap( 375cf7f801eSMemoryShore round_hint_to_min(start_vaddr), 376cf7f801eSMemoryShore PageFrameCount::from_bytes(len).unwrap(), 377cf7f801eSMemoryShore prot_flags, 378cf7f801eSMemoryShore map_flags, 379*a3571c8bSMemoryShore move |page, count, vm_flags, flags, mapper, flusher| { 380cf7f801eSMemoryShore if allocate_at_once { 381cf7f801eSMemoryShore VMA::zeroed( 382cf7f801eSMemoryShore page, 383cf7f801eSMemoryShore count, 384cf7f801eSMemoryShore vm_flags, 385cf7f801eSMemoryShore flags, 386cf7f801eSMemoryShore mapper, 387cf7f801eSMemoryShore flusher, 388cf7f801eSMemoryShore file, 389cf7f801eSMemoryShore Some(pgoff), 390cf7f801eSMemoryShore ) 391cf7f801eSMemoryShore } else { 392cf7f801eSMemoryShore Ok(LockedVMA::new(VMA::new( 393cf7f801eSMemoryShore VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE), 394cf7f801eSMemoryShore vm_flags, 395cf7f801eSMemoryShore flags, 396cf7f801eSMemoryShore file, 397cf7f801eSMemoryShore Some(pgoff), 398cf7f801eSMemoryShore false, 399cf7f801eSMemoryShore ))) 400cf7f801eSMemoryShore } 401cf7f801eSMemoryShore }, 402cf7f801eSMemoryShore )?; 403cf7f801eSMemoryShore return Ok(start_page); 404cf7f801eSMemoryShore } 405cf7f801eSMemoryShore 40640fe15e0SLoGin /// 向进程的地址空间映射页面 40740fe15e0SLoGin /// 40840fe15e0SLoGin /// # 参数 40940fe15e0SLoGin /// 41040fe15e0SLoGin /// - `addr`:映射的起始地址,如果为`None`,则由内核自动分配 41140fe15e0SLoGin /// - `page_count`:映射的页面数量 41240fe15e0SLoGin /// - `prot_flags`:保护标志 41340fe15e0SLoGin /// - `map_flags`:映射标志 41440fe15e0SLoGin /// - `map_func`:映射函数,用于创建VMA 41540fe15e0SLoGin /// 41640fe15e0SLoGin /// # Returns 41740fe15e0SLoGin /// 41840fe15e0SLoGin /// 返回映射的起始虚拟页帧 41940fe15e0SLoGin /// 42040fe15e0SLoGin /// # Errors 42140fe15e0SLoGin /// 42240fe15e0SLoGin /// - `EINVAL`:参数错误 mmap< F: FnOnce( VirtPageFrame, PageFrameCount, VmFlags, EntryFlags<MMArch>, &mut PageMapper, &mut dyn Flusher<MMArch>, ) -> Result<Arc<LockedVMA>, SystemError>, >( &mut self, addr: Option<VirtAddr>, page_count: PageFrameCount, prot_flags: ProtFlags, map_flags: MapFlags, map_func: F, ) -> Result<VirtPageFrame, SystemError>42340fe15e0SLoGin pub fn mmap< 42440fe15e0SLoGin F: FnOnce( 42540fe15e0SLoGin VirtPageFrame, 42640fe15e0SLoGin PageFrameCount, 427*a3571c8bSMemoryShore VmFlags, 428cf7f801eSMemoryShore EntryFlags<MMArch>, 42940fe15e0SLoGin &mut PageMapper, 43040fe15e0SLoGin &mut dyn Flusher<MMArch>, 43140fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError>, 43240fe15e0SLoGin >( 43340fe15e0SLoGin &mut self, 43440fe15e0SLoGin addr: Option<VirtAddr>, 43540fe15e0SLoGin page_count: PageFrameCount, 43640fe15e0SLoGin prot_flags: ProtFlags, 43740fe15e0SLoGin map_flags: MapFlags, 43840fe15e0SLoGin map_func: F, 43940fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 44040fe15e0SLoGin if page_count == PageFrameCount::new(0) { 44140fe15e0SLoGin return Err(SystemError::EINVAL); 44240fe15e0SLoGin } 4432eab6dd7S曾俊 // debug!("mmap: addr: {addr:?}, page_count: {page_count:?}, prot_flags: {prot_flags:?}, map_flags: {map_flags:?}"); 44440fe15e0SLoGin 44540fe15e0SLoGin // 找到未使用的区域 44640fe15e0SLoGin let region = match addr { 44740fe15e0SLoGin Some(vaddr) => { 44840fe15e0SLoGin self.mappings 44940fe15e0SLoGin .find_free_at(self.mmap_min, vaddr, page_count.bytes(), map_flags)? 45040fe15e0SLoGin } 45140fe15e0SLoGin None => self 45240fe15e0SLoGin .mappings 45340fe15e0SLoGin .find_free(self.mmap_min, page_count.bytes()) 45440fe15e0SLoGin .ok_or(SystemError::ENOMEM)?, 45540fe15e0SLoGin }; 45640fe15e0SLoGin 45740fe15e0SLoGin let page = VirtPageFrame::new(region.start()); 45840fe15e0SLoGin 459*a3571c8bSMemoryShore let vm_flags = VmFlags::from(prot_flags) 460*a3571c8bSMemoryShore | VmFlags::from(map_flags) 461*a3571c8bSMemoryShore | VmFlags::VM_MAYREAD 462*a3571c8bSMemoryShore | VmFlags::VM_MAYWRITE 463*a3571c8bSMemoryShore | VmFlags::VM_MAYEXEC; 464*a3571c8bSMemoryShore 4652eab6dd7S曾俊 // debug!("mmap: page: {:?}, region={region:?}", page.virt_address()); 46640fe15e0SLoGin 46740fe15e0SLoGin compiler_fence(Ordering::SeqCst); 46840fe15e0SLoGin let (mut active, mut inactive); 46940fe15e0SLoGin let flusher = if self.is_current() { 47040fe15e0SLoGin active = PageFlushAll::new(); 47140fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 47240fe15e0SLoGin } else { 47340fe15e0SLoGin inactive = InactiveFlusher::new(); 47440fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 47540fe15e0SLoGin }; 47640fe15e0SLoGin compiler_fence(Ordering::SeqCst); 47740fe15e0SLoGin // 映射页面,并将VMA插入到地址空间的VMA列表中 47840fe15e0SLoGin self.mappings.insert_vma(map_func( 47940fe15e0SLoGin page, 48040fe15e0SLoGin page_count, 481*a3571c8bSMemoryShore vm_flags, 482cf7f801eSMemoryShore EntryFlags::from_prot_flags(prot_flags, true), 48340fe15e0SLoGin &mut self.user_mapper.utable, 48440fe15e0SLoGin flusher, 48540fe15e0SLoGin )?); 48640fe15e0SLoGin 48740fe15e0SLoGin return Ok(page); 48840fe15e0SLoGin } 48940fe15e0SLoGin 4904cfa009bSJomo /// 重映射内存区域 4914cfa009bSJomo /// 4924cfa009bSJomo /// # 参数 4934cfa009bSJomo /// 4944cfa009bSJomo /// - `old_vaddr`:原映射的起始地址 4954cfa009bSJomo /// - `old_len`:原映射的长度 4964cfa009bSJomo /// - `new_len`:重新映射的长度 4974cfa009bSJomo /// - `mremap_flags`:重映射标志 4984cfa009bSJomo /// - `new_vaddr`:重新映射的起始地址 4994cfa009bSJomo /// - `vm_flags`:旧内存区域标志 5004cfa009bSJomo /// 5014cfa009bSJomo /// # Returns 5024cfa009bSJomo /// 5034cfa009bSJomo /// 返回重映射的起始虚拟页帧地址 5044cfa009bSJomo /// 5054cfa009bSJomo /// # Errors 5064cfa009bSJomo /// 5074cfa009bSJomo /// - `EINVAL`:参数错误 mremap( &mut self, old_vaddr: VirtAddr, old_len: usize, new_len: usize, mremap_flags: MremapFlags, new_vaddr: VirtAddr, vm_flags: VmFlags, ) -> Result<VirtAddr, SystemError>5084cfa009bSJomo pub fn mremap( 5094cfa009bSJomo &mut self, 5104cfa009bSJomo old_vaddr: VirtAddr, 5114cfa009bSJomo old_len: usize, 5124cfa009bSJomo new_len: usize, 5134cfa009bSJomo mremap_flags: MremapFlags, 5144cfa009bSJomo new_vaddr: VirtAddr, 5154cfa009bSJomo vm_flags: VmFlags, 5164cfa009bSJomo ) -> Result<VirtAddr, SystemError> { 5174cfa009bSJomo // 检查新内存地址是否对齐 5184cfa009bSJomo if !new_vaddr.check_aligned(MMArch::PAGE_SIZE) { 5194cfa009bSJomo return Err(SystemError::EINVAL); 5204cfa009bSJomo } 5214cfa009bSJomo 5224cfa009bSJomo // 检查新、旧内存区域是否冲突 5234cfa009bSJomo let old_region = VirtRegion::new(old_vaddr, old_len); 5244cfa009bSJomo let new_region = VirtRegion::new(new_vaddr, new_len); 5254cfa009bSJomo if old_region.collide(&new_region) { 5264cfa009bSJomo return Err(SystemError::EINVAL); 5274cfa009bSJomo } 5284cfa009bSJomo 5293055390cSJomo // 初始化映射标志 5303055390cSJomo let mut map_flags: MapFlags = vm_flags.into(); 5313055390cSJomo // 初始化内存区域保护标志 5323055390cSJomo let prot_flags: ProtFlags = vm_flags.into(); 5333055390cSJomo 5344cfa009bSJomo // 取消新内存区域的原映射 5354cfa009bSJomo if mremap_flags.contains(MremapFlags::MREMAP_FIXED) { 5363055390cSJomo map_flags |= MapFlags::MAP_FIXED; 5374cfa009bSJomo let start_page = VirtPageFrame::new(new_vaddr); 5384cfa009bSJomo let page_count = PageFrameCount::from_bytes(new_len).unwrap(); 5394cfa009bSJomo self.munmap(start_page, page_count)?; 5404cfa009bSJomo } 5414cfa009bSJomo 5424cfa009bSJomo // 获取映射后的新内存页面 543a17651b1SMemoryShore let new_page = self.map_anonymous(new_vaddr, new_len, prot_flags, map_flags, true, true)?; 5444cfa009bSJomo let new_page_vaddr = new_page.virt_address(); 5454cfa009bSJomo 5464cfa009bSJomo // 拷贝旧内存区域内容到新内存区域 5474cfa009bSJomo let old_buffer_reader = 5484cfa009bSJomo UserBufferReader::new(old_vaddr.data() as *const u8, old_len, true)?; 5494cfa009bSJomo let old_buf: &[u8] = old_buffer_reader.read_from_user(0)?; 5504cfa009bSJomo let mut new_buffer_writer = 5514cfa009bSJomo UserBufferWriter::new(new_page_vaddr.data() as *mut u8, new_len, true)?; 5524cfa009bSJomo let new_buf: &mut [u8] = new_buffer_writer.buffer(0)?; 5534cfa009bSJomo let len = old_buf.len().min(new_buf.len()); 554b5b571e0SLoGin new_buf[..len].copy_from_slice(&old_buf[..len]); 5554cfa009bSJomo 5564cfa009bSJomo return Ok(new_page_vaddr); 5574cfa009bSJomo } 5584cfa009bSJomo 55940fe15e0SLoGin /// 取消进程的地址空间中的映射 56040fe15e0SLoGin /// 56140fe15e0SLoGin /// # 参数 56240fe15e0SLoGin /// 56340fe15e0SLoGin /// - `start_page`:起始页帧 56440fe15e0SLoGin /// - `page_count`:取消映射的页帧数量 56540fe15e0SLoGin /// 56640fe15e0SLoGin /// # Errors 56740fe15e0SLoGin /// 56840fe15e0SLoGin /// - `EINVAL`:参数错误 56940fe15e0SLoGin /// - `ENOMEM`:内存不足 munmap( &mut self, start_page: VirtPageFrame, page_count: PageFrameCount, ) -> Result<(), SystemError>57040fe15e0SLoGin pub fn munmap( 57140fe15e0SLoGin &mut self, 57240fe15e0SLoGin start_page: VirtPageFrame, 57340fe15e0SLoGin page_count: PageFrameCount, 57440fe15e0SLoGin ) -> Result<(), SystemError> { 57540fe15e0SLoGin let to_unmap = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 57640fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 57740fe15e0SLoGin 57840fe15e0SLoGin let regions: Vec<Arc<LockedVMA>> = self.mappings.conflicts(to_unmap).collect::<Vec<_>>(); 57940fe15e0SLoGin 58040fe15e0SLoGin for r in regions { 581cf7f801eSMemoryShore let r = r.lock_irqsave().region; 58240fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 583cf7f801eSMemoryShore let intersection = r.lock_irqsave().region().intersect(&to_unmap).unwrap(); 58456cc4dbeSJomo let split_result = r.extract(intersection, &self.user_mapper.utable).unwrap(); 58540fe15e0SLoGin 58640fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 58740fe15e0SLoGin 588b5b571e0SLoGin if let Some(before) = split_result.prev { 58940fe15e0SLoGin // 如果前面有VMA,则需要将前面的VMA重新插入到地址空间的VMA列表中 59040fe15e0SLoGin self.mappings.insert_vma(before); 59140fe15e0SLoGin } 59240fe15e0SLoGin 593b5b571e0SLoGin if let Some(after) = split_result.after { 59440fe15e0SLoGin // 如果后面有VMA,则需要将后面的VMA重新插入到地址空间的VMA列表中 59540fe15e0SLoGin self.mappings.insert_vma(after); 59640fe15e0SLoGin } 59740fe15e0SLoGin 59840fe15e0SLoGin r.unmap(&mut self.user_mapper.utable, &mut flusher); 59940fe15e0SLoGin } 60040fe15e0SLoGin 60140fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 60240fe15e0SLoGin 60340fe15e0SLoGin return Ok(()); 60440fe15e0SLoGin } 60540fe15e0SLoGin mprotect( &mut self, start_page: VirtPageFrame, page_count: PageFrameCount, prot_flags: ProtFlags, ) -> Result<(), SystemError>60640fe15e0SLoGin pub fn mprotect( 60740fe15e0SLoGin &mut self, 60840fe15e0SLoGin start_page: VirtPageFrame, 60940fe15e0SLoGin page_count: PageFrameCount, 61040fe15e0SLoGin prot_flags: ProtFlags, 61140fe15e0SLoGin ) -> Result<(), SystemError> { 6122eab6dd7S曾俊 // debug!( 61340fe15e0SLoGin // "mprotect: start_page: {:?}, page_count: {:?}, prot_flags:{prot_flags:?}", 61440fe15e0SLoGin // start_page, 61540fe15e0SLoGin // page_count 61640fe15e0SLoGin // ); 61740fe15e0SLoGin let (mut active, mut inactive); 618bd70d2d1SLoGin let flusher = if self.is_current() { 61940fe15e0SLoGin active = PageFlushAll::new(); 62040fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 62140fe15e0SLoGin } else { 62240fe15e0SLoGin inactive = InactiveFlusher::new(); 62340fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 62440fe15e0SLoGin }; 62540fe15e0SLoGin 62640fe15e0SLoGin let mapper = &mut self.user_mapper.utable; 62740fe15e0SLoGin let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 6282eab6dd7S曾俊 // debug!("mprotect: region: {:?}", region); 62940fe15e0SLoGin 63040fe15e0SLoGin let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 6312eab6dd7S曾俊 // debug!("mprotect: regions: {:?}", regions); 63240fe15e0SLoGin 63340fe15e0SLoGin for r in regions { 6342eab6dd7S曾俊 // debug!("mprotect: r: {:?}", r); 635cf7f801eSMemoryShore let r = *r.lock_irqsave().region(); 63640fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 63740fe15e0SLoGin 638cf7f801eSMemoryShore let intersection = r.lock_irqsave().region().intersect(®ion).unwrap(); 63956cc4dbeSJomo let split_result = r 64056cc4dbeSJomo .extract(intersection, mapper) 64156cc4dbeSJomo .expect("Failed to extract VMA"); 64240fe15e0SLoGin 643b5b571e0SLoGin if let Some(before) = split_result.prev { 64440fe15e0SLoGin self.mappings.insert_vma(before); 64540fe15e0SLoGin } 646b5b571e0SLoGin if let Some(after) = split_result.after { 64740fe15e0SLoGin self.mappings.insert_vma(after); 64840fe15e0SLoGin } 64940fe15e0SLoGin 650cf7f801eSMemoryShore let mut r_guard = r.lock_irqsave(); 65140fe15e0SLoGin // 如果VMA的保护标志不允许指定的修改,则返回错误 65240fe15e0SLoGin if !r_guard.can_have_flags(prot_flags) { 65340fe15e0SLoGin drop(r_guard); 65440fe15e0SLoGin self.mappings.insert_vma(r.clone()); 65540fe15e0SLoGin return Err(SystemError::EACCES); 65640fe15e0SLoGin } 65738458c72SMemoryShore r_guard.set_vm_flags(VmFlags::from(prot_flags)); 65838458c72SMemoryShore 659cf7f801eSMemoryShore let new_flags: EntryFlags<MMArch> = r_guard 66040fe15e0SLoGin .flags() 66140fe15e0SLoGin .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC)) 66240fe15e0SLoGin .set_write(prot_flags.contains(ProtFlags::PROT_WRITE)); 66340fe15e0SLoGin 664bd70d2d1SLoGin r_guard.remap(new_flags, mapper, &mut *flusher)?; 66540fe15e0SLoGin drop(r_guard); 66640fe15e0SLoGin self.mappings.insert_vma(r); 66740fe15e0SLoGin } 66840fe15e0SLoGin 66940fe15e0SLoGin return Ok(()); 67040fe15e0SLoGin } 67140fe15e0SLoGin madvise( &mut self, start_page: VirtPageFrame, page_count: PageFrameCount, behavior: MadvFlags, ) -> Result<(), SystemError>672a17651b1SMemoryShore pub fn madvise( 673a17651b1SMemoryShore &mut self, 674a17651b1SMemoryShore start_page: VirtPageFrame, 675a17651b1SMemoryShore page_count: PageFrameCount, 676a17651b1SMemoryShore behavior: MadvFlags, 677a17651b1SMemoryShore ) -> Result<(), SystemError> { 678a17651b1SMemoryShore let (mut active, mut inactive); 679bd70d2d1SLoGin let flusher = if self.is_current() { 680a17651b1SMemoryShore active = PageFlushAll::new(); 681a17651b1SMemoryShore &mut active as &mut dyn Flusher<MMArch> 682a17651b1SMemoryShore } else { 683a17651b1SMemoryShore inactive = InactiveFlusher::new(); 684a17651b1SMemoryShore &mut inactive as &mut dyn Flusher<MMArch> 685a17651b1SMemoryShore }; 686a17651b1SMemoryShore 687a17651b1SMemoryShore let mapper = &mut self.user_mapper.utable; 688a17651b1SMemoryShore 689a17651b1SMemoryShore let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 690a17651b1SMemoryShore let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 691a17651b1SMemoryShore 692a17651b1SMemoryShore for r in regions { 693cf7f801eSMemoryShore let r = *r.lock_irqsave().region(); 694a17651b1SMemoryShore let r = self.mappings.remove_vma(&r).unwrap(); 695a17651b1SMemoryShore 696cf7f801eSMemoryShore let intersection = r.lock_irqsave().region().intersect(®ion).unwrap(); 697a17651b1SMemoryShore let split_result = r 698a17651b1SMemoryShore .extract(intersection, mapper) 699a17651b1SMemoryShore .expect("Failed to extract VMA"); 700a17651b1SMemoryShore 701a17651b1SMemoryShore if let Some(before) = split_result.prev { 702a17651b1SMemoryShore self.mappings.insert_vma(before); 703a17651b1SMemoryShore } 704a17651b1SMemoryShore if let Some(after) = split_result.after { 705a17651b1SMemoryShore self.mappings.insert_vma(after); 706a17651b1SMemoryShore } 707bd70d2d1SLoGin r.do_madvise(behavior, mapper, &mut *flusher)?; 708a17651b1SMemoryShore self.mappings.insert_vma(r); 709a17651b1SMemoryShore } 710a17651b1SMemoryShore Ok(()) 711a17651b1SMemoryShore } 712a17651b1SMemoryShore 71340fe15e0SLoGin /// 创建新的用户栈 71440fe15e0SLoGin /// 71540fe15e0SLoGin /// ## 参数 71640fe15e0SLoGin /// 71740fe15e0SLoGin /// - `size`:栈的大小 new_user_stack(&mut self, size: usize) -> Result<(), SystemError>71840fe15e0SLoGin pub fn new_user_stack(&mut self, size: usize) -> Result<(), SystemError> { 71940fe15e0SLoGin assert!(self.user_stack.is_none(), "User stack already exists"); 72040fe15e0SLoGin let stack = UserStack::new(self, None, size)?; 72140fe15e0SLoGin self.user_stack = Some(stack); 72240fe15e0SLoGin return Ok(()); 72340fe15e0SLoGin } 72440fe15e0SLoGin 72540fe15e0SLoGin #[inline(always)] user_stack_mut(&mut self) -> Option<&mut UserStack>72640fe15e0SLoGin pub fn user_stack_mut(&mut self) -> Option<&mut UserStack> { 72740fe15e0SLoGin return self.user_stack.as_mut(); 72840fe15e0SLoGin } 72940fe15e0SLoGin 73040fe15e0SLoGin /// 取消用户空间内的所有映射 unmap_all(&mut self)73140fe15e0SLoGin pub unsafe fn unmap_all(&mut self) { 73240fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 73340fe15e0SLoGin for vma in self.mappings.iter_vmas() { 7346fc066acSJomo if vma.mapped() { 73540fe15e0SLoGin vma.unmap(&mut self.user_mapper.utable, &mut flusher); 73640fe15e0SLoGin } 73740fe15e0SLoGin } 7386fc066acSJomo } 73940fe15e0SLoGin 74040fe15e0SLoGin /// 设置进程的堆的内存空间 74140fe15e0SLoGin /// 74240fe15e0SLoGin /// ## 参数 74340fe15e0SLoGin /// 74440fe15e0SLoGin /// - `new_brk`:新的堆的结束地址。需要满足页对齐要求,并且是用户空间地址,且大于等于当前的堆的起始地址 74540fe15e0SLoGin /// 74640fe15e0SLoGin /// ## 返回值 74740fe15e0SLoGin /// 74840fe15e0SLoGin /// 返回旧的堆的结束地址 set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError>74940fe15e0SLoGin pub unsafe fn set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError> { 75040fe15e0SLoGin assert!(new_brk.check_aligned(MMArch::PAGE_SIZE)); 75140fe15e0SLoGin 75240fe15e0SLoGin if !new_brk.check_user() || new_brk < self.brk_start { 75340fe15e0SLoGin return Err(SystemError::EFAULT); 75440fe15e0SLoGin } 75540fe15e0SLoGin 75640fe15e0SLoGin let old_brk = self.brk; 7571496ba7bSLoGin 75840fe15e0SLoGin if new_brk > self.brk { 75940fe15e0SLoGin let len = new_brk - self.brk; 76040fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 76140fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED; 762a17651b1SMemoryShore self.map_anonymous(old_brk, len, prot_flags, map_flags, true, false)?; 7631496ba7bSLoGin 76440fe15e0SLoGin self.brk = new_brk; 76540fe15e0SLoGin return Ok(old_brk); 76640fe15e0SLoGin } else { 76740fe15e0SLoGin let unmap_len = self.brk - new_brk; 76840fe15e0SLoGin let unmap_start = new_brk; 76940fe15e0SLoGin if unmap_len == 0 { 77040fe15e0SLoGin return Ok(old_brk); 77140fe15e0SLoGin } 77240fe15e0SLoGin self.munmap( 77340fe15e0SLoGin VirtPageFrame::new(unmap_start), 77440fe15e0SLoGin PageFrameCount::from_bytes(unmap_len).unwrap(), 77540fe15e0SLoGin )?; 77640fe15e0SLoGin self.brk = new_brk; 77740fe15e0SLoGin return Ok(old_brk); 77840fe15e0SLoGin } 77940fe15e0SLoGin } 78040fe15e0SLoGin sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError>78140fe15e0SLoGin pub unsafe fn sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError> { 78240fe15e0SLoGin if incr == 0 { 78340fe15e0SLoGin return Ok(self.brk); 78440fe15e0SLoGin } 78540fe15e0SLoGin 78640fe15e0SLoGin let new_brk = if incr > 0 { 78740fe15e0SLoGin self.brk + incr as usize 78840fe15e0SLoGin } else { 789b5b571e0SLoGin self.brk - incr.unsigned_abs() 79040fe15e0SLoGin }; 79140fe15e0SLoGin 79240fe15e0SLoGin let new_brk = VirtAddr::new(page_align_up(new_brk.data())); 79340fe15e0SLoGin 79440fe15e0SLoGin return self.set_brk(new_brk); 79540fe15e0SLoGin } 79640fe15e0SLoGin } 79740fe15e0SLoGin 79840fe15e0SLoGin impl Drop for InnerAddressSpace { drop(&mut self)79940fe15e0SLoGin fn drop(&mut self) { 80040fe15e0SLoGin unsafe { 80140fe15e0SLoGin self.unmap_all(); 80240fe15e0SLoGin } 80340fe15e0SLoGin } 80440fe15e0SLoGin } 80540fe15e0SLoGin 80640fe15e0SLoGin #[derive(Debug, Hash)] 80740fe15e0SLoGin pub struct UserMapper { 80840fe15e0SLoGin pub utable: PageMapper, 80940fe15e0SLoGin } 81040fe15e0SLoGin 81140fe15e0SLoGin impl UserMapper { new(utable: PageMapper) -> Self81240fe15e0SLoGin pub fn new(utable: PageMapper) -> Self { 81340fe15e0SLoGin return Self { utable }; 81440fe15e0SLoGin } 815a17651b1SMemoryShore 816a17651b1SMemoryShore /// 拷贝用户空间映射 817a17651b1SMemoryShore /// ## 参数 818a17651b1SMemoryShore /// 819a17651b1SMemoryShore /// - `umapper`: 要拷贝的用户空间 820a17651b1SMemoryShore /// - `copy_on_write`: 是否写时复制 clone_from(&mut self, umapper: &mut Self, copy_on_write: bool)821a17651b1SMemoryShore pub unsafe fn clone_from(&mut self, umapper: &mut Self, copy_on_write: bool) { 822a17651b1SMemoryShore self.utable 823a17651b1SMemoryShore .clone_user_mapping(&mut umapper.utable, copy_on_write); 824a17651b1SMemoryShore } 82540fe15e0SLoGin } 82640fe15e0SLoGin 82740fe15e0SLoGin impl Drop for UserMapper { drop(&mut self)82840fe15e0SLoGin fn drop(&mut self) { 82940fe15e0SLoGin if self.utable.is_current() { 83040fe15e0SLoGin // 如果当前要被销毁的用户空间的页表是当前进程的页表,那么就切换回初始内核页表 83140fe15e0SLoGin unsafe { MMArch::set_table(PageTableKind::User, MMArch::initial_page_table()) } 83240fe15e0SLoGin } 83340fe15e0SLoGin // 释放用户空间顶层页表占用的页帧 83440fe15e0SLoGin // 请注意,在释放这个页帧之前,用户页表应该已经被完全释放,否则会产生内存泄露 83540fe15e0SLoGin unsafe { 83640fe15e0SLoGin deallocate_page_frames( 83740fe15e0SLoGin PhysPageFrame::new(self.utable.table().phys()), 83840fe15e0SLoGin PageFrameCount::new(1), 8396fc066acSJomo &mut page_manager_lock_irqsave(), 84040fe15e0SLoGin ) 84140fe15e0SLoGin }; 84240fe15e0SLoGin } 84340fe15e0SLoGin } 84440fe15e0SLoGin 84540fe15e0SLoGin /// 用户空间映射信息 84640fe15e0SLoGin #[derive(Debug)] 84740fe15e0SLoGin pub struct UserMappings { 84840fe15e0SLoGin /// 当前用户空间的虚拟内存区域 84940fe15e0SLoGin vmas: HashSet<Arc<LockedVMA>>, 85040fe15e0SLoGin /// 当前用户空间的VMA空洞 85140fe15e0SLoGin vm_holes: BTreeMap<VirtAddr, usize>, 85240fe15e0SLoGin } 85340fe15e0SLoGin 85440fe15e0SLoGin impl UserMappings { new() -> Self85540fe15e0SLoGin pub fn new() -> Self { 85640fe15e0SLoGin return Self { 85740fe15e0SLoGin vmas: HashSet::new(), 85840fe15e0SLoGin vm_holes: core::iter::once((VirtAddr::new(0), MMArch::USER_END_VADDR.data())) 85940fe15e0SLoGin .collect::<BTreeMap<_, _>>(), 86040fe15e0SLoGin }; 86140fe15e0SLoGin } 86240fe15e0SLoGin 86340fe15e0SLoGin /// 判断当前进程的VMA内,是否有包含指定的虚拟地址的VMA。 86440fe15e0SLoGin /// 86540fe15e0SLoGin /// 如果有,返回包含指定虚拟地址的VMA的Arc指针,否则返回None。 86640fe15e0SLoGin #[allow(dead_code)] contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>>86740fe15e0SLoGin pub fn contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 86840fe15e0SLoGin for v in self.vmas.iter() { 869cf7f801eSMemoryShore let guard = v.lock_irqsave(); 87040fe15e0SLoGin if guard.region.contains(vaddr) { 87140fe15e0SLoGin return Some(v.clone()); 87240fe15e0SLoGin } 87340fe15e0SLoGin } 87440fe15e0SLoGin return None; 87540fe15e0SLoGin } 87640fe15e0SLoGin 877a17651b1SMemoryShore /// 向下寻找距离虚拟地址最近的VMA 878a17651b1SMemoryShore /// ## 参数 879a17651b1SMemoryShore /// 880a17651b1SMemoryShore /// - `vaddr`: 虚拟地址 881a17651b1SMemoryShore /// 882a17651b1SMemoryShore /// ## 返回值 883a17651b1SMemoryShore /// - Some(Arc<LockedVMA>): 虚拟地址所在的或最近的下一个VMA 884a17651b1SMemoryShore /// - None: 未找到VMA 885a17651b1SMemoryShore #[allow(dead_code)] find_nearest(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>>886a17651b1SMemoryShore pub fn find_nearest(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 887a17651b1SMemoryShore let mut nearest: Option<Arc<LockedVMA>> = None; 888a17651b1SMemoryShore for v in self.vmas.iter() { 889cf7f801eSMemoryShore let guard = v.lock_irqsave(); 890a17651b1SMemoryShore if guard.region.contains(vaddr) { 891a17651b1SMemoryShore return Some(v.clone()); 892a17651b1SMemoryShore } 893cf7f801eSMemoryShore if guard.region.start >= vaddr 894a17651b1SMemoryShore && if let Some(ref nearest) = nearest { 895cf7f801eSMemoryShore guard.region.start < nearest.lock_irqsave().region.start 896a17651b1SMemoryShore } else { 897a17651b1SMemoryShore true 898a17651b1SMemoryShore } 899a17651b1SMemoryShore { 900a17651b1SMemoryShore nearest = Some(v.clone()); 901a17651b1SMemoryShore } 902a17651b1SMemoryShore } 903a17651b1SMemoryShore return nearest; 904a17651b1SMemoryShore } 905a17651b1SMemoryShore 90640fe15e0SLoGin /// 获取当前进程的地址空间中,与给定虚拟地址范围有重叠的VMA的迭代器。 conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_90740fe15e0SLoGin pub fn conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_ { 90840fe15e0SLoGin let r = self 90940fe15e0SLoGin .vmas 91040fe15e0SLoGin .iter() 911cf7f801eSMemoryShore .filter(move |v| v.lock_irqsave().region.intersect(&request).is_some()) 91240fe15e0SLoGin .cloned(); 91340fe15e0SLoGin return r; 91440fe15e0SLoGin } 91540fe15e0SLoGin 91640fe15e0SLoGin /// 在当前进程的地址空间中,寻找第一个符合条件的空闲的虚拟内存范围。 91740fe15e0SLoGin /// 91840fe15e0SLoGin /// @param min_vaddr 最小的起始地址 91940fe15e0SLoGin /// @param size 请求的大小 92040fe15e0SLoGin /// 92140fe15e0SLoGin /// @return 如果找到了,返回虚拟内存范围,否则返回None find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion>92240fe15e0SLoGin pub fn find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion> { 92340fe15e0SLoGin let _vaddr = min_vaddr; 92440fe15e0SLoGin let mut iter = self 92540fe15e0SLoGin .vm_holes 92640fe15e0SLoGin .iter() 92740fe15e0SLoGin .skip_while(|(hole_vaddr, hole_size)| hole_vaddr.add(**hole_size) <= min_vaddr); 92840fe15e0SLoGin 92940fe15e0SLoGin let (hole_vaddr, size) = iter.find(|(hole_vaddr, hole_size)| { 93040fe15e0SLoGin // 计算当前空洞的可用大小 93140fe15e0SLoGin let available_size: usize = 93240fe15e0SLoGin if hole_vaddr <= &&min_vaddr && min_vaddr <= hole_vaddr.add(**hole_size) { 93340fe15e0SLoGin **hole_size - (min_vaddr - **hole_vaddr) 93440fe15e0SLoGin } else { 93540fe15e0SLoGin **hole_size 93640fe15e0SLoGin }; 93740fe15e0SLoGin 93840fe15e0SLoGin size <= available_size 93940fe15e0SLoGin })?; 94040fe15e0SLoGin 94140fe15e0SLoGin // 创建一个新的虚拟内存范围。 94240fe15e0SLoGin let region = VirtRegion::new(cmp::max(*hole_vaddr, min_vaddr), *size); 9434cfa009bSJomo 94440fe15e0SLoGin return Some(region); 94540fe15e0SLoGin } 94640fe15e0SLoGin find_free_at( &self, min_vaddr: VirtAddr, vaddr: VirtAddr, size: usize, flags: MapFlags, ) -> Result<VirtRegion, SystemError>94740fe15e0SLoGin pub fn find_free_at( 94840fe15e0SLoGin &self, 94940fe15e0SLoGin min_vaddr: VirtAddr, 95040fe15e0SLoGin vaddr: VirtAddr, 95140fe15e0SLoGin size: usize, 95240fe15e0SLoGin flags: MapFlags, 95340fe15e0SLoGin ) -> Result<VirtRegion, SystemError> { 95440fe15e0SLoGin // 如果没有指定地址,那么就在当前进程的地址空间中寻找一个空闲的虚拟内存范围。 95540fe15e0SLoGin if vaddr == VirtAddr::new(0) { 95640fe15e0SLoGin return self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM); 95740fe15e0SLoGin } 95840fe15e0SLoGin 95940fe15e0SLoGin // 如果指定了地址,那么就检查指定的地址是否可用。 96040fe15e0SLoGin 96140fe15e0SLoGin let requested = VirtRegion::new(vaddr, size); 96240fe15e0SLoGin 96340fe15e0SLoGin if requested.end() >= MMArch::USER_END_VADDR || !vaddr.check_aligned(MMArch::PAGE_SIZE) { 96440fe15e0SLoGin return Err(SystemError::EINVAL); 96540fe15e0SLoGin } 96640fe15e0SLoGin 96740fe15e0SLoGin if let Some(_x) = self.conflicts(requested).next() { 96840fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED_NOREPLACE) { 96940fe15e0SLoGin // 如果指定了 MAP_FIXED_NOREPLACE 标志,由于所指定的地址无法成功建立映射,则放弃映射,不对地址做修正 97040fe15e0SLoGin return Err(SystemError::EEXIST); 97140fe15e0SLoGin } 97240fe15e0SLoGin 97340fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED) { 97440fe15e0SLoGin // todo: 支持MAP_FIXED标志对已有的VMA进行覆盖 9751074eb34SSamuel Dai return Err(SystemError::ENOSYS); 97640fe15e0SLoGin } 97740fe15e0SLoGin 97840fe15e0SLoGin // 如果没有指定MAP_FIXED标志,那么就对地址做修正 97940fe15e0SLoGin let requested = self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM)?; 98040fe15e0SLoGin return Ok(requested); 98140fe15e0SLoGin } 98240fe15e0SLoGin 98340fe15e0SLoGin return Ok(requested); 98440fe15e0SLoGin } 98540fe15e0SLoGin 98640fe15e0SLoGin /// 在当前进程的地址空间中,保留一个指定大小的区域,使得该区域不在空洞中。 98740fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 98840fe15e0SLoGin /// 98940fe15e0SLoGin /// @param region 要保留的区域 99040fe15e0SLoGin /// 99140fe15e0SLoGin /// 请注意,在调用本函数之前,必须先确定region所在范围内没有VMA。 reserve_hole(&mut self, region: &VirtRegion)99240fe15e0SLoGin fn reserve_hole(&mut self, region: &VirtRegion) { 99340fe15e0SLoGin let prev_hole: Option<(&VirtAddr, &mut usize)> = 994971462beSGnoCiYeH self.vm_holes.range_mut(..=region.start()).next_back(); 99540fe15e0SLoGin 99640fe15e0SLoGin if let Some((prev_hole_vaddr, prev_hole_size)) = prev_hole { 99740fe15e0SLoGin let prev_hole_end = prev_hole_vaddr.add(*prev_hole_size); 99840fe15e0SLoGin 99940fe15e0SLoGin if prev_hole_end > region.start() { 100040fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的起始地址,那么就需要调整前一个空洞的大小。 100140fe15e0SLoGin *prev_hole_size = region.start().data() - prev_hole_vaddr.data(); 100240fe15e0SLoGin } 100340fe15e0SLoGin 100440fe15e0SLoGin if prev_hole_end > region.end() { 100540fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的结束地址,那么就需要增加一个新的空洞。 100640fe15e0SLoGin self.vm_holes 100740fe15e0SLoGin .insert(region.end(), prev_hole_end - region.end()); 100840fe15e0SLoGin } 100940fe15e0SLoGin } 101040fe15e0SLoGin } 101140fe15e0SLoGin 101240fe15e0SLoGin /// 在当前进程的地址空间中,释放一个指定大小的区域,使得该区域成为一个空洞。 101340fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 unreserve_hole(&mut self, region: &VirtRegion)101440fe15e0SLoGin fn unreserve_hole(&mut self, region: &VirtRegion) { 101540fe15e0SLoGin // 如果将要插入的空洞与后一个空洞相邻,那么就需要合并。 101640fe15e0SLoGin let next_hole_size: Option<usize> = self.vm_holes.remove(®ion.end()); 101740fe15e0SLoGin 101840fe15e0SLoGin if let Some((_prev_hole_vaddr, prev_hole_size)) = self 101940fe15e0SLoGin .vm_holes 102040fe15e0SLoGin .range_mut(..region.start()) 102140fe15e0SLoGin .next_back() 102240fe15e0SLoGin .filter(|(offset, size)| offset.data() + **size == region.start().data()) 102340fe15e0SLoGin { 102440fe15e0SLoGin *prev_hole_size += region.size() + next_hole_size.unwrap_or(0); 102540fe15e0SLoGin } else { 102640fe15e0SLoGin self.vm_holes 102740fe15e0SLoGin .insert(region.start(), region.size() + next_hole_size.unwrap_or(0)); 102840fe15e0SLoGin } 102940fe15e0SLoGin } 103040fe15e0SLoGin 103140fe15e0SLoGin /// 在当前进程的映射关系中,插入一个新的VMA。 insert_vma(&mut self, vma: Arc<LockedVMA>)103240fe15e0SLoGin pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) { 1033cf7f801eSMemoryShore let region = vma.lock_irqsave().region; 103440fe15e0SLoGin // 要求插入的地址范围必须是空闲的,也就是说,当前进程的地址空间中,不能有任何与之重叠的VMA。 103540fe15e0SLoGin assert!(self.conflicts(region).next().is_none()); 103640fe15e0SLoGin self.reserve_hole(®ion); 103740fe15e0SLoGin 103840fe15e0SLoGin self.vmas.insert(vma); 103940fe15e0SLoGin } 104040fe15e0SLoGin 104140fe15e0SLoGin /// @brief 删除一个VMA,并把对应的地址空间加入空洞中。 104240fe15e0SLoGin /// 104340fe15e0SLoGin /// 这里不会取消VMA对应的地址的映射 104440fe15e0SLoGin /// 104540fe15e0SLoGin /// @param region 要删除的VMA所在的地址范围 104640fe15e0SLoGin /// 104740fe15e0SLoGin /// @return 如果成功删除了VMA,则返回被删除的VMA,否则返回None 104840fe15e0SLoGin /// 如果没有可以删除的VMA,则不会执行删除操作,并报告失败。 remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>>104940fe15e0SLoGin pub fn remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>> { 105040fe15e0SLoGin // 请注意,由于这里会对每个VMA加锁,因此性能很低 105140fe15e0SLoGin let vma: Arc<LockedVMA> = self 105240fe15e0SLoGin .vmas 1053cf7f801eSMemoryShore .drain_filter(|vma| vma.lock_irqsave().region == *region) 105440fe15e0SLoGin .next()?; 105540fe15e0SLoGin self.unreserve_hole(region); 105640fe15e0SLoGin 105740fe15e0SLoGin return Some(vma); 105840fe15e0SLoGin } 105940fe15e0SLoGin 106040fe15e0SLoGin /// @brief Get the iterator of all VMAs in this process. iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>>106140fe15e0SLoGin pub fn iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>> { 106240fe15e0SLoGin return self.vmas.iter(); 106340fe15e0SLoGin } 106440fe15e0SLoGin } 106540fe15e0SLoGin 106640fe15e0SLoGin impl Default for UserMappings { default() -> Self106740fe15e0SLoGin fn default() -> Self { 106840fe15e0SLoGin return Self::new(); 106940fe15e0SLoGin } 107040fe15e0SLoGin } 107140fe15e0SLoGin 107240fe15e0SLoGin /// 加了锁的VMA 107340fe15e0SLoGin /// 107440fe15e0SLoGin /// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。 107540fe15e0SLoGin #[derive(Debug)] 107656cc4dbeSJomo pub struct LockedVMA { 107756cc4dbeSJomo /// 用于计算哈希值,避免总是获取vma锁来计算哈希值 107856cc4dbeSJomo id: usize, 107956cc4dbeSJomo vma: SpinLock<VMA>, 108056cc4dbeSJomo } 108140fe15e0SLoGin 108240fe15e0SLoGin impl core::hash::Hash for LockedVMA { hash<H: Hasher>(&self, state: &mut H)108340fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 108456cc4dbeSJomo self.id.hash(state); 108540fe15e0SLoGin } 108640fe15e0SLoGin } 108740fe15e0SLoGin 108840fe15e0SLoGin impl PartialEq for LockedVMA { eq(&self, other: &Self) -> bool108940fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 109056cc4dbeSJomo self.id.eq(&other.id) 109140fe15e0SLoGin } 109240fe15e0SLoGin } 109340fe15e0SLoGin 109440fe15e0SLoGin impl Eq for LockedVMA {} 109540fe15e0SLoGin 109640fe15e0SLoGin #[allow(dead_code)] 109740fe15e0SLoGin impl LockedVMA { new(vma: VMA) -> Arc<Self>109840fe15e0SLoGin pub fn new(vma: VMA) -> Arc<Self> { 109956cc4dbeSJomo let r = Arc::new(Self { 110056cc4dbeSJomo id: LOCKEDVMA_ID_ALLOCATOR.alloc().unwrap(), 110156cc4dbeSJomo vma: SpinLock::new(vma), 110256cc4dbeSJomo }); 1103cf7f801eSMemoryShore r.vma.lock_irqsave().self_ref = Arc::downgrade(&r); 110440fe15e0SLoGin return r; 110540fe15e0SLoGin } 110640fe15e0SLoGin id(&self) -> usize11076fc066acSJomo pub fn id(&self) -> usize { 11086fc066acSJomo self.id 11096fc066acSJomo } 11106fc066acSJomo lock(&self) -> SpinLockGuard<VMA>111140fe15e0SLoGin pub fn lock(&self) -> SpinLockGuard<VMA> { 111256cc4dbeSJomo return self.vma.lock(); 111340fe15e0SLoGin } 111440fe15e0SLoGin lock_irqsave(&self) -> SpinLockGuard<VMA>1115cf7f801eSMemoryShore pub fn lock_irqsave(&self) -> SpinLockGuard<VMA> { 1116cf7f801eSMemoryShore return self.vma.lock_irqsave(); 1117cf7f801eSMemoryShore } 1118cf7f801eSMemoryShore 111940fe15e0SLoGin /// 调整当前VMA的页面的标志位 112040fe15e0SLoGin /// 112140fe15e0SLoGin /// TODO:增加调整虚拟页映射的物理地址的功能 112240fe15e0SLoGin /// 112340fe15e0SLoGin /// @param flags 新的标志位 112440fe15e0SLoGin /// @param mapper 页表映射器 112540fe15e0SLoGin /// @param flusher 页表项刷新器 112640fe15e0SLoGin /// remap( &self, flags: EntryFlags<MMArch>, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>, ) -> Result<(), SystemError>112740fe15e0SLoGin pub fn remap( 112840fe15e0SLoGin &self, 1129cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 113040fe15e0SLoGin mapper: &mut PageMapper, 113140fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 113240fe15e0SLoGin ) -> Result<(), SystemError> { 1133cf7f801eSMemoryShore let mut guard = self.lock_irqsave(); 113440fe15e0SLoGin for page in guard.region.pages() { 113540fe15e0SLoGin // 暂时要求所有的页帧都已经映射到页表 113640fe15e0SLoGin // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了 113740fe15e0SLoGin let r = unsafe { 113840fe15e0SLoGin mapper 113940fe15e0SLoGin .remap(page.virt_address(), flags) 114040fe15e0SLoGin .expect("Failed to remap, beacuse of some page is not mapped") 114140fe15e0SLoGin }; 114240fe15e0SLoGin flusher.consume(r); 114340fe15e0SLoGin } 114440fe15e0SLoGin guard.flags = flags; 114540fe15e0SLoGin return Ok(()); 114640fe15e0SLoGin } 114740fe15e0SLoGin unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>)114840fe15e0SLoGin pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>) { 11491a62e776SLoGin // todo: 如果当前vma与文件相关,完善文件相关的逻辑 11501a62e776SLoGin 1151cf7f801eSMemoryShore let mut guard = self.lock_irqsave(); 115256cc4dbeSJomo 115356cc4dbeSJomo // 获取物理页的anon_vma的守卫 11546fc066acSJomo let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> = 11556fc066acSJomo page_manager_lock_irqsave(); 115640fe15e0SLoGin for page in guard.region.pages() { 1157a17651b1SMemoryShore if mapper.translate(page.virt_address()).is_none() { 1158a17651b1SMemoryShore continue; 1159a17651b1SMemoryShore } 116040fe15e0SLoGin let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) } 116140fe15e0SLoGin .expect("Failed to unmap, beacuse of some page is not mapped"); 116240fe15e0SLoGin 116356cc4dbeSJomo // 从anon_vma中删除当前VMA 1164cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1165cf7f801eSMemoryShore page.write_irqsave().remove_vma(self); 116640fe15e0SLoGin 116756cc4dbeSJomo // 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页. 1168cf7f801eSMemoryShore if page.read_irqsave().can_deallocate() { 116956cc4dbeSJomo unsafe { 1170cf7f801eSMemoryShore drop(page); 117156cc4dbeSJomo deallocate_page_frames( 117256cc4dbeSJomo PhysPageFrame::new(paddr), 117356cc4dbeSJomo PageFrameCount::new(1), 11746fc066acSJomo &mut page_manager_guard, 117556cc4dbeSJomo ) 117656cc4dbeSJomo }; 117756cc4dbeSJomo } 117840fe15e0SLoGin 117940fe15e0SLoGin flusher.consume(flush); 118040fe15e0SLoGin } 118140fe15e0SLoGin guard.mapped = false; 1182cf7f801eSMemoryShore 1183cf7f801eSMemoryShore // 当vma对应共享文件的写映射时,唤醒脏页回写线程 1184cf7f801eSMemoryShore if guard.vm_file().is_some() 1185cf7f801eSMemoryShore && guard 1186cf7f801eSMemoryShore .vm_flags() 1187cf7f801eSMemoryShore .contains(VmFlags::VM_SHARED | VmFlags::VM_WRITE) 1188cf7f801eSMemoryShore { 1189cf7f801eSMemoryShore crate::mm::page::PageReclaimer::wakeup_claim_thread(); 1190cf7f801eSMemoryShore } 119140fe15e0SLoGin } 119240fe15e0SLoGin mapped(&self) -> bool119340fe15e0SLoGin pub fn mapped(&self) -> bool { 1194cf7f801eSMemoryShore return self.vma.lock_irqsave().mapped; 119540fe15e0SLoGin } 119640fe15e0SLoGin 119740fe15e0SLoGin /// 将当前VMA进行切分,切分成3个VMA,分别是: 119840fe15e0SLoGin /// 119940fe15e0SLoGin /// 1. 前面的VMA,如果没有则为None 120040fe15e0SLoGin /// 2. 中间的VMA,也就是传入的Region 120140fe15e0SLoGin /// 3. 后面的VMA,如果没有则为None extract(&self, region: VirtRegion, utable: &PageMapper) -> Option<VMASplitResult>120256cc4dbeSJomo pub fn extract(&self, region: VirtRegion, utable: &PageMapper) -> Option<VMASplitResult> { 120340fe15e0SLoGin assert!(region.start().check_aligned(MMArch::PAGE_SIZE)); 120440fe15e0SLoGin assert!(region.end().check_aligned(MMArch::PAGE_SIZE)); 120540fe15e0SLoGin 1206cf7f801eSMemoryShore let mut guard = self.lock_irqsave(); 120740fe15e0SLoGin { 120840fe15e0SLoGin // 如果传入的region不在当前VMA的范围内,则直接返回None 120940fe15e0SLoGin if unlikely(region.start() < guard.region.start() || region.end() > guard.region.end()) 121040fe15e0SLoGin { 121140fe15e0SLoGin return None; 121240fe15e0SLoGin } 121340fe15e0SLoGin 121440fe15e0SLoGin let intersect: Option<VirtRegion> = guard.region.intersect(®ion); 121540fe15e0SLoGin // 如果当前VMA不包含region,则直接返回None 121640fe15e0SLoGin if unlikely(intersect.is_none()) { 121740fe15e0SLoGin return None; 121840fe15e0SLoGin } 121940fe15e0SLoGin let intersect: VirtRegion = intersect.unwrap(); 122040fe15e0SLoGin if unlikely(intersect == guard.region) { 122140fe15e0SLoGin // 如果当前VMA完全包含region,则直接返回当前VMA 1222b5b571e0SLoGin return Some(VMASplitResult::new( 1223b5b571e0SLoGin None, 1224b5b571e0SLoGin guard.self_ref.upgrade().unwrap(), 1225b5b571e0SLoGin None, 1226b5b571e0SLoGin )); 122740fe15e0SLoGin } 122840fe15e0SLoGin } 122940fe15e0SLoGin 123040fe15e0SLoGin let before: Option<Arc<LockedVMA>> = guard.region.before(®ion).map(|virt_region| { 123140fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 123240fe15e0SLoGin vma.region = virt_region; 1233de199e3cSMemoryShore vma.mapped = false; 123440fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 123540fe15e0SLoGin vma 123640fe15e0SLoGin }); 123740fe15e0SLoGin 123840fe15e0SLoGin let after: Option<Arc<LockedVMA>> = guard.region.after(®ion).map(|virt_region| { 123940fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 124040fe15e0SLoGin vma.region = virt_region; 1241de199e3cSMemoryShore vma.mapped = false; 124240fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 124340fe15e0SLoGin vma 124440fe15e0SLoGin }); 124540fe15e0SLoGin 124656cc4dbeSJomo // 重新设置before、after这两个VMA里面的物理页的anon_vma 12476fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 124856cc4dbeSJomo if let Some(before) = before.clone() { 1249cf7f801eSMemoryShore let virt_iter = before.lock_irqsave().region.iter_pages(); 125056cc4dbeSJomo for frame in virt_iter { 1251de199e3cSMemoryShore if let Some((paddr, _)) = utable.translate(frame.virt_address()) { 1252cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1253cf7f801eSMemoryShore let mut page_guard = page.write_irqsave(); 1254cf7f801eSMemoryShore page_guard.insert_vma(before.clone()); 1255cf7f801eSMemoryShore page_guard.remove_vma(self); 1256cf7f801eSMemoryShore before.lock_irqsave().mapped = true; 1257de199e3cSMemoryShore } 125856cc4dbeSJomo } 125956cc4dbeSJomo } 126040fe15e0SLoGin 126156cc4dbeSJomo if let Some(after) = after.clone() { 1262cf7f801eSMemoryShore let virt_iter = after.lock_irqsave().region.iter_pages(); 126356cc4dbeSJomo for frame in virt_iter { 1264de199e3cSMemoryShore if let Some((paddr, _)) = utable.translate(frame.virt_address()) { 1265cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1266cf7f801eSMemoryShore let mut page_guard = page.write_irqsave(); 1267cf7f801eSMemoryShore page_guard.insert_vma(after.clone()); 1268cf7f801eSMemoryShore page_guard.remove_vma(self); 1269cf7f801eSMemoryShore after.lock_irqsave().mapped = true; 1270de199e3cSMemoryShore } 127156cc4dbeSJomo } 127256cc4dbeSJomo } 127356cc4dbeSJomo 127456cc4dbeSJomo guard.region = region; 127540fe15e0SLoGin 1276b5b571e0SLoGin return Some(VMASplitResult::new( 1277b5b571e0SLoGin before, 1278b5b571e0SLoGin guard.self_ref.upgrade().unwrap(), 1279b5b571e0SLoGin after, 1280b5b571e0SLoGin )); 1281b5b571e0SLoGin } 1282a17651b1SMemoryShore 1283a17651b1SMemoryShore /// 判断VMA是否为外部(非当前进程空间)的VMA is_foreign(&self) -> bool1284a17651b1SMemoryShore pub fn is_foreign(&self) -> bool { 1285cf7f801eSMemoryShore let guard = self.lock_irqsave(); 1286a17651b1SMemoryShore if let Some(space) = guard.user_address_space.clone() { 1287a17651b1SMemoryShore if let Some(space) = space.upgrade() { 1288a17651b1SMemoryShore return AddressSpace::is_current(&space); 1289a17651b1SMemoryShore } else { 1290a17651b1SMemoryShore return true; 1291a17651b1SMemoryShore } 1292a17651b1SMemoryShore } else { 1293a17651b1SMemoryShore return true; 1294a17651b1SMemoryShore } 1295a17651b1SMemoryShore } 1296a17651b1SMemoryShore 1297a17651b1SMemoryShore /// 判断VMA是否可访问 is_accessible(&self) -> bool1298a17651b1SMemoryShore pub fn is_accessible(&self) -> bool { 1299cf7f801eSMemoryShore let guard = self.lock_irqsave(); 1300a17651b1SMemoryShore let vm_access_flags: VmFlags = VmFlags::VM_READ | VmFlags::VM_WRITE | VmFlags::VM_EXEC; 1301a17651b1SMemoryShore guard.vm_flags().intersects(vm_access_flags) 1302a17651b1SMemoryShore } 1303a17651b1SMemoryShore 1304a17651b1SMemoryShore /// 判断VMA是否为匿名映射 is_anonymous(&self) -> bool1305a17651b1SMemoryShore pub fn is_anonymous(&self) -> bool { 1306cf7f801eSMemoryShore let guard = self.lock_irqsave(); 1307cf7f801eSMemoryShore guard.vm_file.is_none() 1308a17651b1SMemoryShore } 1309a17651b1SMemoryShore 1310a17651b1SMemoryShore /// 判断VMA是否为大页映射 is_hugepage(&self) -> bool1311a17651b1SMemoryShore pub fn is_hugepage(&self) -> bool { 1312a17651b1SMemoryShore //TODO: 实现巨页映射判断逻辑,目前不支持巨页映射 1313a17651b1SMemoryShore false 1314a17651b1SMemoryShore } 1315b5b571e0SLoGin } 1316b5b571e0SLoGin 131756cc4dbeSJomo impl Drop for LockedVMA { drop(&mut self)131856cc4dbeSJomo fn drop(&mut self) { 131956cc4dbeSJomo LOCKEDVMA_ID_ALLOCATOR.free(self.id); 132056cc4dbeSJomo } 132156cc4dbeSJomo } 132256cc4dbeSJomo 1323b5b571e0SLoGin /// VMA切分结果 1324bd70d2d1SLoGin #[allow(dead_code)] 1325b5b571e0SLoGin pub struct VMASplitResult { 1326b5b571e0SLoGin pub prev: Option<Arc<LockedVMA>>, 1327b5b571e0SLoGin pub middle: Arc<LockedVMA>, 1328b5b571e0SLoGin pub after: Option<Arc<LockedVMA>>, 1329b5b571e0SLoGin } 1330b5b571e0SLoGin 1331b5b571e0SLoGin impl VMASplitResult { new( prev: Option<Arc<LockedVMA>>, middle: Arc<LockedVMA>, post: Option<Arc<LockedVMA>>, ) -> Self1332b5b571e0SLoGin pub fn new( 1333b5b571e0SLoGin prev: Option<Arc<LockedVMA>>, 1334b5b571e0SLoGin middle: Arc<LockedVMA>, 1335b5b571e0SLoGin post: Option<Arc<LockedVMA>>, 1336b5b571e0SLoGin ) -> Self { 1337b5b571e0SLoGin Self { 1338b5b571e0SLoGin prev, 1339b5b571e0SLoGin middle, 1340b5b571e0SLoGin after: post, 1341b5b571e0SLoGin } 134240fe15e0SLoGin } 134340fe15e0SLoGin } 134440fe15e0SLoGin 134540fe15e0SLoGin /// @brief 虚拟内存区域 134640fe15e0SLoGin #[derive(Debug)] 134740fe15e0SLoGin pub struct VMA { 134840fe15e0SLoGin /// 虚拟内存区域对应的虚拟地址范围 134940fe15e0SLoGin region: VirtRegion, 13504cfa009bSJomo /// 虚拟内存区域标志 13514cfa009bSJomo vm_flags: VmFlags, 135240fe15e0SLoGin /// VMA内的页帧的标志 1353cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 135440fe15e0SLoGin /// VMA内的页帧是否已经映射到页表 135540fe15e0SLoGin mapped: bool, 135640fe15e0SLoGin /// VMA所属的用户地址空间 135740fe15e0SLoGin user_address_space: Option<Weak<AddressSpace>>, 135840fe15e0SLoGin self_ref: Weak<LockedVMA>, 1359971462beSGnoCiYeH 1360cf7f801eSMemoryShore vm_file: Option<Arc<File>>, 1361cf7f801eSMemoryShore /// VMA映射的文件部分相对于整个文件的偏移页数 1362cf7f801eSMemoryShore file_pgoff: Option<usize>, 1363cf7f801eSMemoryShore 1364971462beSGnoCiYeH provider: Provider, 136540fe15e0SLoGin } 136640fe15e0SLoGin 136740fe15e0SLoGin impl core::hash::Hash for VMA { hash<H: Hasher>(&self, state: &mut H)136840fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 136940fe15e0SLoGin self.region.hash(state); 137040fe15e0SLoGin self.flags.hash(state); 137140fe15e0SLoGin self.mapped.hash(state); 137240fe15e0SLoGin } 137340fe15e0SLoGin } 137440fe15e0SLoGin 1375971462beSGnoCiYeH /// 描述不同类型的内存提供者或资源 1376971462beSGnoCiYeH #[derive(Debug)] 1377971462beSGnoCiYeH pub enum Provider { 1378971462beSGnoCiYeH Allocated, // TODO:其他 1379971462beSGnoCiYeH } 1380971462beSGnoCiYeH 138140fe15e0SLoGin #[allow(dead_code)] 138240fe15e0SLoGin impl VMA { new( region: VirtRegion, vm_flags: VmFlags, flags: EntryFlags<MMArch>, file: Option<Arc<File>>, pgoff: Option<usize>, mapped: bool, ) -> Self13834cfa009bSJomo pub fn new( 13844cfa009bSJomo region: VirtRegion, 13854cfa009bSJomo vm_flags: VmFlags, 1386cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 1387cf7f801eSMemoryShore file: Option<Arc<File>>, 1388cf7f801eSMemoryShore pgoff: Option<usize>, 13894cfa009bSJomo mapped: bool, 13904cfa009bSJomo ) -> Self { 13914cfa009bSJomo VMA { 13924cfa009bSJomo region, 13934cfa009bSJomo vm_flags, 13944cfa009bSJomo flags, 13954cfa009bSJomo mapped, 13964cfa009bSJomo user_address_space: None, 13974cfa009bSJomo self_ref: Weak::default(), 13984cfa009bSJomo provider: Provider::Allocated, 1399cf7f801eSMemoryShore vm_file: file, 1400cf7f801eSMemoryShore file_pgoff: pgoff, 14014cfa009bSJomo } 14024cfa009bSJomo } 14034cfa009bSJomo region(&self) -> &VirtRegion140440fe15e0SLoGin pub fn region(&self) -> &VirtRegion { 140540fe15e0SLoGin return &self.region; 140640fe15e0SLoGin } 140740fe15e0SLoGin vm_flags(&self) -> &VmFlags14084cfa009bSJomo pub fn vm_flags(&self) -> &VmFlags { 14094cfa009bSJomo return &self.vm_flags; 14104cfa009bSJomo } 14114cfa009bSJomo vm_file(&self) -> Option<Arc<File>>1412cf7f801eSMemoryShore pub fn vm_file(&self) -> Option<Arc<File>> { 1413cf7f801eSMemoryShore return self.vm_file.clone(); 1414cf7f801eSMemoryShore } 1415cf7f801eSMemoryShore address_space(&self) -> Option<Weak<AddressSpace>>1416cf7f801eSMemoryShore pub fn address_space(&self) -> Option<Weak<AddressSpace>> { 1417cf7f801eSMemoryShore return self.user_address_space.clone(); 1418cf7f801eSMemoryShore } 1419cf7f801eSMemoryShore set_vm_flags(&mut self, vm_flags: VmFlags)14204cfa009bSJomo pub fn set_vm_flags(&mut self, vm_flags: VmFlags) { 14214cfa009bSJomo self.vm_flags = vm_flags; 14224cfa009bSJomo } 14234cfa009bSJomo set_region_size(&mut self, new_region_size: usize)14244cfa009bSJomo pub fn set_region_size(&mut self, new_region_size: usize) { 14254cfa009bSJomo self.region.set_size(new_region_size); 14264cfa009bSJomo } 14274cfa009bSJomo set_mapped(&mut self, mapped: bool)14286fc066acSJomo pub fn set_mapped(&mut self, mapped: bool) { 14296fc066acSJomo self.mapped = mapped; 14306fc066acSJomo } 14316fc066acSJomo set_flags(&mut self)1432cf7f801eSMemoryShore pub fn set_flags(&mut self) { 1433cf7f801eSMemoryShore self.flags = MMArch::vm_get_page_prot(self.vm_flags); 1434cf7f801eSMemoryShore } 1435cf7f801eSMemoryShore 143640fe15e0SLoGin /// # 拷贝当前VMA的内容 143740fe15e0SLoGin /// 143840fe15e0SLoGin /// ### 安全性 143940fe15e0SLoGin /// 144040fe15e0SLoGin /// 由于这样操作可能由于错误的拷贝,导致内存泄露、内存重复释放等问题,所以需要小心使用。 clone(&self) -> Self144140fe15e0SLoGin pub unsafe fn clone(&self) -> Self { 144240fe15e0SLoGin return Self { 144340fe15e0SLoGin region: self.region, 14444cfa009bSJomo vm_flags: self.vm_flags, 144540fe15e0SLoGin flags: self.flags, 144640fe15e0SLoGin mapped: self.mapped, 144740fe15e0SLoGin user_address_space: self.user_address_space.clone(), 144840fe15e0SLoGin self_ref: self.self_ref.clone(), 1449971462beSGnoCiYeH provider: Provider::Allocated, 1450cf7f801eSMemoryShore file_pgoff: self.file_pgoff, 1451cf7f801eSMemoryShore vm_file: self.vm_file.clone(), 145240fe15e0SLoGin }; 145340fe15e0SLoGin } 145440fe15e0SLoGin clone_info_only(&self) -> Self1455a17651b1SMemoryShore pub fn clone_info_only(&self) -> Self { 1456a17651b1SMemoryShore return Self { 1457a17651b1SMemoryShore region: self.region, 1458a17651b1SMemoryShore vm_flags: self.vm_flags, 1459a17651b1SMemoryShore flags: self.flags, 1460a17651b1SMemoryShore mapped: self.mapped, 1461a17651b1SMemoryShore user_address_space: None, 1462a17651b1SMemoryShore self_ref: Weak::default(), 1463a17651b1SMemoryShore provider: Provider::Allocated, 1464cf7f801eSMemoryShore file_pgoff: self.file_pgoff, 1465cf7f801eSMemoryShore vm_file: self.vm_file.clone(), 1466a17651b1SMemoryShore }; 1467a17651b1SMemoryShore } 1468a17651b1SMemoryShore 146940fe15e0SLoGin #[inline(always)] flags(&self) -> EntryFlags<MMArch>1470cf7f801eSMemoryShore pub fn flags(&self) -> EntryFlags<MMArch> { 147140fe15e0SLoGin return self.flags; 147240fe15e0SLoGin } 147340fe15e0SLoGin 1474cf7f801eSMemoryShore #[inline(always)] file_page_offset(&self) -> Option<usize>1475cf7f801eSMemoryShore pub fn file_page_offset(&self) -> Option<usize> { 1476cf7f801eSMemoryShore return self.file_pgoff; 1477cf7f801eSMemoryShore } 1478cf7f801eSMemoryShore pages(&self) -> VirtPageFrameIter147940fe15e0SLoGin pub fn pages(&self) -> VirtPageFrameIter { 148040fe15e0SLoGin return VirtPageFrameIter::new( 148140fe15e0SLoGin VirtPageFrame::new(self.region.start()), 148240fe15e0SLoGin VirtPageFrame::new(self.region.end()), 148340fe15e0SLoGin ); 148440fe15e0SLoGin } 148540fe15e0SLoGin remap( &mut self, flags: EntryFlags<MMArch>, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>, ) -> Result<(), SystemError>148640fe15e0SLoGin pub fn remap( 148740fe15e0SLoGin &mut self, 1488cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 148940fe15e0SLoGin mapper: &mut PageMapper, 149040fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 149140fe15e0SLoGin ) -> Result<(), SystemError> { 149240fe15e0SLoGin for page in self.region.pages() { 14932eab6dd7S曾俊 // debug!("remap page {:?}", page.virt_address()); 1494a17651b1SMemoryShore if mapper.translate(page.virt_address()).is_some() { 149540fe15e0SLoGin let r = unsafe { 149640fe15e0SLoGin mapper 149740fe15e0SLoGin .remap(page.virt_address(), flags) 1498a17651b1SMemoryShore .expect("Failed to remap") 149940fe15e0SLoGin }; 150040fe15e0SLoGin flusher.consume(r); 1501a17651b1SMemoryShore } 15022eab6dd7S曾俊 // debug!("consume page {:?}", page.virt_address()); 15032eab6dd7S曾俊 // debug!("remap page {:?} done", page.virt_address()); 150440fe15e0SLoGin } 150540fe15e0SLoGin self.flags = flags; 150640fe15e0SLoGin return Ok(()); 150740fe15e0SLoGin } 150840fe15e0SLoGin 150940fe15e0SLoGin /// 检查当前VMA是否可以拥有指定的标志位 151040fe15e0SLoGin /// 151140fe15e0SLoGin /// ## 参数 151240fe15e0SLoGin /// 151340fe15e0SLoGin /// - `prot_flags` 要检查的标志位 can_have_flags(&self, prot_flags: ProtFlags) -> bool151440fe15e0SLoGin pub fn can_have_flags(&self, prot_flags: ProtFlags) -> bool { 1515971462beSGnoCiYeH let is_downgrade = (self.flags.has_write() || !prot_flags.contains(ProtFlags::PROT_WRITE)) 151640fe15e0SLoGin && (self.flags.has_execute() || !prot_flags.contains(ProtFlags::PROT_EXEC)); 1517971462beSGnoCiYeH 1518971462beSGnoCiYeH match self.provider { 1519971462beSGnoCiYeH Provider::Allocated { .. } => true, 1520971462beSGnoCiYeH 1521971462beSGnoCiYeH #[allow(unreachable_patterns)] 1522971462beSGnoCiYeH _ => is_downgrade, 1523971462beSGnoCiYeH } 152440fe15e0SLoGin } 152540fe15e0SLoGin 152640fe15e0SLoGin /// 把物理地址映射到虚拟地址 152740fe15e0SLoGin /// 152840fe15e0SLoGin /// @param phys 要映射的物理地址 152940fe15e0SLoGin /// @param destination 要映射到的虚拟地址 153040fe15e0SLoGin /// @param count 要映射的页帧数量 153140fe15e0SLoGin /// @param flags 页面标志位 153240fe15e0SLoGin /// @param mapper 页表映射器 153340fe15e0SLoGin /// @param flusher 页表项刷新器 153440fe15e0SLoGin /// 153540fe15e0SLoGin /// @return 返回映射后的虚拟内存区域 physmap( phys: PhysPageFrame, destination: VirtPageFrame, count: PageFrameCount, vm_flags: VmFlags, flags: EntryFlags<MMArch>, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>, ) -> Result<Arc<LockedVMA>, SystemError>153640fe15e0SLoGin pub fn physmap( 153740fe15e0SLoGin phys: PhysPageFrame, 153840fe15e0SLoGin destination: VirtPageFrame, 153940fe15e0SLoGin count: PageFrameCount, 15404cfa009bSJomo vm_flags: VmFlags, 1541cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 154240fe15e0SLoGin mapper: &mut PageMapper, 154340fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 154440fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 154540fe15e0SLoGin let mut cur_phy = phys; 154640fe15e0SLoGin let mut cur_dest = destination; 154740fe15e0SLoGin 154840fe15e0SLoGin for _ in 0..count.data() { 154940fe15e0SLoGin // 将物理页帧映射到虚拟页帧 155056cc4dbeSJomo let r = 155156cc4dbeSJomo unsafe { mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags) } 155240fe15e0SLoGin .expect("Failed to map phys, may be OOM error"); 155340fe15e0SLoGin 155440fe15e0SLoGin // todo: 增加OOM处理 155540fe15e0SLoGin 155640fe15e0SLoGin // 刷新TLB 155740fe15e0SLoGin flusher.consume(r); 155840fe15e0SLoGin 155940fe15e0SLoGin cur_phy = cur_phy.next(); 156040fe15e0SLoGin cur_dest = cur_dest.next(); 156140fe15e0SLoGin } 156240fe15e0SLoGin 1563cf7f801eSMemoryShore let r: Arc<LockedVMA> = LockedVMA::new(VMA::new( 1564cf7f801eSMemoryShore VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE), 15654cfa009bSJomo vm_flags, 156640fe15e0SLoGin flags, 1567cf7f801eSMemoryShore None, 1568cf7f801eSMemoryShore None, 1569cf7f801eSMemoryShore true, 1570cf7f801eSMemoryShore )); 157156cc4dbeSJomo 157256cc4dbeSJomo // 将VMA加入到anon_vma中 15736fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 157456cc4dbeSJomo cur_phy = phys; 157556cc4dbeSJomo for _ in 0..count.data() { 157656cc4dbeSJomo let paddr = cur_phy.phys_address(); 1577cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1578cf7f801eSMemoryShore page.write_irqsave().insert_vma(r.clone()); 157956cc4dbeSJomo cur_phy = cur_phy.next(); 158056cc4dbeSJomo } 158156cc4dbeSJomo 158240fe15e0SLoGin return Ok(r); 158340fe15e0SLoGin } 158440fe15e0SLoGin 158540fe15e0SLoGin /// 从页分配器中分配一些物理页,并把它们映射到指定的虚拟地址,然后创建VMA 1586cf7f801eSMemoryShore /// ## 参数 158740fe15e0SLoGin /// 1588cf7f801eSMemoryShore /// - `destination`: 要映射到的虚拟地址 1589cf7f801eSMemoryShore /// - `page_count`: 要映射的页帧数量 1590cf7f801eSMemoryShore /// - `vm_flags`: VMA标志位 1591cf7f801eSMemoryShore /// - `flags`: 页面标志位 1592cf7f801eSMemoryShore /// - `mapper`: 页表映射器 1593cf7f801eSMemoryShore /// - `flusher`: 页表项刷新器 1594cf7f801eSMemoryShore /// - `file`: 映射文件 1595cf7f801eSMemoryShore /// - `pgoff`: 返回映射后的虚拟内存区域 159640fe15e0SLoGin /// 1597cf7f801eSMemoryShore /// ## 返回值 1598cf7f801eSMemoryShore /// - 页面错误处理信息标志 1599cf7f801eSMemoryShore #[allow(clippy::too_many_arguments)] zeroed( destination: VirtPageFrame, page_count: PageFrameCount, vm_flags: VmFlags, flags: EntryFlags<MMArch>, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>, file: Option<Arc<File>>, pgoff: Option<usize>, ) -> Result<Arc<LockedVMA>, SystemError>160040fe15e0SLoGin pub fn zeroed( 160140fe15e0SLoGin destination: VirtPageFrame, 160240fe15e0SLoGin page_count: PageFrameCount, 16034cfa009bSJomo vm_flags: VmFlags, 1604cf7f801eSMemoryShore flags: EntryFlags<MMArch>, 160540fe15e0SLoGin mapper: &mut PageMapper, 160640fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 1607cf7f801eSMemoryShore file: Option<Arc<File>>, 1608cf7f801eSMemoryShore pgoff: Option<usize>, 160940fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 161040fe15e0SLoGin let mut cur_dest: VirtPageFrame = destination; 16112eab6dd7S曾俊 // debug!( 161240fe15e0SLoGin // "VMA::zeroed: page_count = {:?}, destination={destination:?}", 161340fe15e0SLoGin // page_count 161440fe15e0SLoGin // ); 161540fe15e0SLoGin for _ in 0..page_count.data() { 16162eab6dd7S曾俊 // debug!( 161740fe15e0SLoGin // "VMA::zeroed: cur_dest={cur_dest:?}, vaddr = {:?}", 161840fe15e0SLoGin // cur_dest.virt_address() 161940fe15e0SLoGin // ); 162040fe15e0SLoGin let r = unsafe { mapper.map(cur_dest.virt_address(), flags) } 162140fe15e0SLoGin .expect("Failed to map zero, may be OOM error"); 162240fe15e0SLoGin // todo: 增加OOM处理 162340fe15e0SLoGin 162440fe15e0SLoGin // 稍后再刷新TLB,这里取消刷新 162540fe15e0SLoGin flusher.consume(r); 162640fe15e0SLoGin cur_dest = cur_dest.next(); 162740fe15e0SLoGin } 162817dc5589SMemoryShore let r = LockedVMA::new(VMA::new( 162917dc5589SMemoryShore VirtRegion::new( 163040fe15e0SLoGin destination.virt_address(), 163140fe15e0SLoGin page_count.data() * MMArch::PAGE_SIZE, 163240fe15e0SLoGin ), 16334cfa009bSJomo vm_flags, 163440fe15e0SLoGin flags, 1635cf7f801eSMemoryShore file, 1636cf7f801eSMemoryShore pgoff, 163717dc5589SMemoryShore true, 163817dc5589SMemoryShore )); 163940fe15e0SLoGin drop(flusher); 16402eab6dd7S曾俊 // debug!("VMA::zeroed: flusher dropped"); 164140fe15e0SLoGin 164256cc4dbeSJomo // 清空这些内存并将VMA加入到anon_vma中 16436fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 16449550910aSChiichen let virt_iter: VirtPageFrameIter = 16459550910aSChiichen VirtPageFrameIter::new(destination, destination.add(page_count)); 164640fe15e0SLoGin for frame in virt_iter { 164740fe15e0SLoGin let paddr = mapper.translate(frame.virt_address()).unwrap().0; 164840fe15e0SLoGin 164956cc4dbeSJomo // 将VMA加入到anon_vma 1650cf7f801eSMemoryShore let page = page_manager_guard.get_unwrap(&paddr); 1651cf7f801eSMemoryShore page.write_irqsave().insert_vma(r.clone()); 165240fe15e0SLoGin } 16532eab6dd7S曾俊 // debug!("VMA::zeroed: done"); 165440fe15e0SLoGin return Ok(r); 165540fe15e0SLoGin } 1656cf7f801eSMemoryShore page_address(&self, page: &Arc<Page>) -> Result<VirtAddr, SystemError>1657cf7f801eSMemoryShore pub fn page_address(&self, page: &Arc<Page>) -> Result<VirtAddr, SystemError> { 1658cf7f801eSMemoryShore let page_guard = page.read_irqsave(); 1659cf7f801eSMemoryShore let index = page_guard.index().unwrap(); 1660cf7f801eSMemoryShore if index >= self.file_pgoff.unwrap() { 1661cf7f801eSMemoryShore let address = 1662cf7f801eSMemoryShore self.region.start + ((index - self.file_pgoff.unwrap()) << MMArch::PAGE_SHIFT); 1663cf7f801eSMemoryShore if address <= self.region.end() { 1664cf7f801eSMemoryShore return Ok(address); 1665cf7f801eSMemoryShore } 1666cf7f801eSMemoryShore } 1667cf7f801eSMemoryShore return Err(SystemError::EFAULT); 1668cf7f801eSMemoryShore } 166940fe15e0SLoGin } 167040fe15e0SLoGin 167140fe15e0SLoGin impl Drop for VMA { drop(&mut self)167240fe15e0SLoGin fn drop(&mut self) { 167340fe15e0SLoGin // 当VMA被释放时,需要确保它已经被从页表中解除映射 167440fe15e0SLoGin assert!(!self.mapped, "VMA is still mapped"); 167540fe15e0SLoGin } 167640fe15e0SLoGin } 167740fe15e0SLoGin 167840fe15e0SLoGin impl PartialEq for VMA { eq(&self, other: &Self) -> bool167940fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 168040fe15e0SLoGin return self.region == other.region; 168140fe15e0SLoGin } 168240fe15e0SLoGin } 168340fe15e0SLoGin 168440fe15e0SLoGin impl Eq for VMA {} 168540fe15e0SLoGin 168640fe15e0SLoGin impl PartialOrd for VMA { partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>168740fe15e0SLoGin fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 1688b5b571e0SLoGin Some(self.cmp(other)) 168940fe15e0SLoGin } 169040fe15e0SLoGin } 169140fe15e0SLoGin 169240fe15e0SLoGin impl Ord for VMA { cmp(&self, other: &Self) -> cmp::Ordering169340fe15e0SLoGin fn cmp(&self, other: &Self) -> cmp::Ordering { 169440fe15e0SLoGin return self.region.cmp(&other.region); 169540fe15e0SLoGin } 169640fe15e0SLoGin } 169740fe15e0SLoGin 169840fe15e0SLoGin #[derive(Debug)] 169940fe15e0SLoGin pub struct UserStack { 170040fe15e0SLoGin // 栈底地址 170140fe15e0SLoGin stack_bottom: VirtAddr, 170240fe15e0SLoGin // 当前已映射的大小 170340fe15e0SLoGin mapped_size: usize, 170440fe15e0SLoGin /// 栈顶地址(这个值需要仔细确定!因为它可能不会实时与用户栈的真实栈顶保持一致!要小心!) 170540fe15e0SLoGin current_sp: VirtAddr, 170640fe15e0SLoGin } 170740fe15e0SLoGin 170840fe15e0SLoGin impl UserStack { 170940fe15e0SLoGin /// 默认的用户栈底地址 171040fe15e0SLoGin pub const DEFAULT_USER_STACK_BOTTOM: VirtAddr = MMArch::USER_STACK_START; 171140fe15e0SLoGin /// 默认的用户栈大小为8MB 171240fe15e0SLoGin pub const DEFAULT_USER_STACK_SIZE: usize = 8 * 1024 * 1024; 171340fe15e0SLoGin /// 用户栈的保护页数量 171440fe15e0SLoGin pub const GUARD_PAGES_NUM: usize = 4; 171540fe15e0SLoGin 171640fe15e0SLoGin /// 创建一个用户栈 new( vm: &mut InnerAddressSpace, stack_bottom: Option<VirtAddr>, stack_size: usize, ) -> Result<Self, SystemError>171740fe15e0SLoGin pub fn new( 171840fe15e0SLoGin vm: &mut InnerAddressSpace, 171940fe15e0SLoGin stack_bottom: Option<VirtAddr>, 172040fe15e0SLoGin stack_size: usize, 172140fe15e0SLoGin ) -> Result<Self, SystemError> { 172240fe15e0SLoGin let stack_bottom = stack_bottom.unwrap_or(Self::DEFAULT_USER_STACK_BOTTOM); 172340fe15e0SLoGin assert!(stack_bottom.check_aligned(MMArch::PAGE_SIZE)); 172440fe15e0SLoGin 172540fe15e0SLoGin // 分配用户栈的保护页 172640fe15e0SLoGin let guard_size = Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 172740fe15e0SLoGin let actual_stack_bottom = stack_bottom - guard_size; 172840fe15e0SLoGin 172940fe15e0SLoGin let mut prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE; 1730a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE 1731a17651b1SMemoryShore | MapFlags::MAP_ANONYMOUS 1732a17651b1SMemoryShore | MapFlags::MAP_FIXED_NOREPLACE 1733a17651b1SMemoryShore | MapFlags::MAP_GROWSDOWN; 17342eab6dd7S曾俊 // debug!( 173540fe15e0SLoGin // "map anonymous stack: {:?} {}", 173640fe15e0SLoGin // actual_stack_bottom, 173740fe15e0SLoGin // guard_size 173840fe15e0SLoGin // ); 173940fe15e0SLoGin vm.map_anonymous( 174040fe15e0SLoGin actual_stack_bottom, 174140fe15e0SLoGin guard_size, 174240fe15e0SLoGin prot_flags, 174340fe15e0SLoGin map_flags, 174440fe15e0SLoGin false, 1745a17651b1SMemoryShore false, 174640fe15e0SLoGin )?; 174740fe15e0SLoGin // test_buddy(); 174840fe15e0SLoGin // 设置保护页只读 174940fe15e0SLoGin prot_flags.remove(ProtFlags::PROT_WRITE); 17502eab6dd7S曾俊 // debug!( 175140fe15e0SLoGin // "to mprotect stack guard pages: {:?} {}", 175240fe15e0SLoGin // actual_stack_bottom, 175340fe15e0SLoGin // guard_size 175440fe15e0SLoGin // ); 175540fe15e0SLoGin vm.mprotect( 175640fe15e0SLoGin VirtPageFrame::new(actual_stack_bottom), 175740fe15e0SLoGin PageFrameCount::new(Self::GUARD_PAGES_NUM), 175840fe15e0SLoGin prot_flags, 175940fe15e0SLoGin )?; 176040fe15e0SLoGin 17612eab6dd7S曾俊 // debug!( 176240fe15e0SLoGin // "mprotect stack guard pages done: {:?} {}", 176340fe15e0SLoGin // actual_stack_bottom, 176440fe15e0SLoGin // guard_size 176540fe15e0SLoGin // ); 176640fe15e0SLoGin 176740fe15e0SLoGin let mut user_stack = UserStack { 176840fe15e0SLoGin stack_bottom: actual_stack_bottom, 176940fe15e0SLoGin mapped_size: guard_size, 177040fe15e0SLoGin current_sp: actual_stack_bottom - guard_size, 177140fe15e0SLoGin }; 177240fe15e0SLoGin 17732eab6dd7S曾俊 // debug!("extend user stack: {:?} {}", stack_bottom, stack_size); 177440fe15e0SLoGin // 分配用户栈 177540fe15e0SLoGin user_stack.initial_extend(vm, stack_size)?; 17762eab6dd7S曾俊 // debug!("user stack created: {:?} {}", stack_bottom, stack_size); 177740fe15e0SLoGin return Ok(user_stack); 177840fe15e0SLoGin } 177940fe15e0SLoGin initial_extend( &mut self, vm: &mut InnerAddressSpace, mut bytes: usize, ) -> Result<(), SystemError>178040fe15e0SLoGin fn initial_extend( 178140fe15e0SLoGin &mut self, 178240fe15e0SLoGin vm: &mut InnerAddressSpace, 178340fe15e0SLoGin mut bytes: usize, 178440fe15e0SLoGin ) -> Result<(), SystemError> { 178540fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 1786a17651b1SMemoryShore let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN; 178740fe15e0SLoGin 178840fe15e0SLoGin bytes = page_align_up(bytes); 178940fe15e0SLoGin self.mapped_size += bytes; 179040fe15e0SLoGin 179140fe15e0SLoGin vm.map_anonymous( 179240fe15e0SLoGin self.stack_bottom - self.mapped_size, 179340fe15e0SLoGin bytes, 179440fe15e0SLoGin prot_flags, 179540fe15e0SLoGin map_flags, 179640fe15e0SLoGin false, 1797a17651b1SMemoryShore false, 179840fe15e0SLoGin )?; 179940fe15e0SLoGin 180040fe15e0SLoGin return Ok(()); 180140fe15e0SLoGin } 180240fe15e0SLoGin 180340fe15e0SLoGin /// 扩展用户栈 180440fe15e0SLoGin /// 180540fe15e0SLoGin /// ## 参数 180640fe15e0SLoGin /// 180740fe15e0SLoGin /// - `vm` 用户地址空间结构体 180840fe15e0SLoGin /// - `bytes` 要扩展的字节数 180940fe15e0SLoGin /// 181040fe15e0SLoGin /// ## 返回值 181140fe15e0SLoGin /// 181240fe15e0SLoGin /// - **Ok(())** 扩展成功 181340fe15e0SLoGin /// - **Err(SystemError)** 扩展失败 181440fe15e0SLoGin #[allow(dead_code)] extend( &mut self, vm: &mut InnerAddressSpace, mut bytes: usize, ) -> Result<(), SystemError>181540fe15e0SLoGin pub fn extend( 181640fe15e0SLoGin &mut self, 1817a17651b1SMemoryShore vm: &mut InnerAddressSpace, 181840fe15e0SLoGin mut bytes: usize, 181940fe15e0SLoGin ) -> Result<(), SystemError> { 182040fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 182140fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS; 182240fe15e0SLoGin 182340fe15e0SLoGin bytes = page_align_up(bytes); 182440fe15e0SLoGin self.mapped_size += bytes; 182540fe15e0SLoGin 182640fe15e0SLoGin vm.map_anonymous( 182740fe15e0SLoGin self.stack_bottom - self.mapped_size, 182840fe15e0SLoGin bytes, 182940fe15e0SLoGin prot_flags, 183040fe15e0SLoGin map_flags, 183140fe15e0SLoGin false, 1832a17651b1SMemoryShore false, 183340fe15e0SLoGin )?; 183440fe15e0SLoGin 183540fe15e0SLoGin return Ok(()); 183640fe15e0SLoGin } 183740fe15e0SLoGin 183840fe15e0SLoGin /// 获取栈顶地址 183940fe15e0SLoGin /// 184040fe15e0SLoGin /// 请注意,如果用户栈的栈顶地址发生变化,这个值可能不会实时更新! sp(&self) -> VirtAddr184140fe15e0SLoGin pub fn sp(&self) -> VirtAddr { 184240fe15e0SLoGin return self.current_sp; 184340fe15e0SLoGin } 184440fe15e0SLoGin set_sp(&mut self, sp: VirtAddr)184540fe15e0SLoGin pub unsafe fn set_sp(&mut self, sp: VirtAddr) { 184640fe15e0SLoGin self.current_sp = sp; 184740fe15e0SLoGin } 184840fe15e0SLoGin 184940fe15e0SLoGin /// 仅仅克隆用户栈的信息,不会克隆用户栈的内容/映射 clone_info_only(&self) -> Self185040fe15e0SLoGin pub unsafe fn clone_info_only(&self) -> Self { 185140fe15e0SLoGin return Self { 185240fe15e0SLoGin stack_bottom: self.stack_bottom, 185340fe15e0SLoGin mapped_size: self.mapped_size, 185440fe15e0SLoGin current_sp: self.current_sp, 185540fe15e0SLoGin }; 185640fe15e0SLoGin } 185740fe15e0SLoGin 185840fe15e0SLoGin /// 获取当前用户栈的大小(不包括保护页) stack_size(&self) -> usize185940fe15e0SLoGin pub fn stack_size(&self) -> usize { 186040fe15e0SLoGin return self.mapped_size - Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 186140fe15e0SLoGin } 186240fe15e0SLoGin } 1863