1*40fe15e0SLoGin // 进程的用户空间内存管理 2*40fe15e0SLoGin 3*40fe15e0SLoGin use core::{ 4*40fe15e0SLoGin cmp, 5*40fe15e0SLoGin hash::Hasher, 6*40fe15e0SLoGin intrinsics::unlikely, 7*40fe15e0SLoGin ops::Add, 8*40fe15e0SLoGin sync::atomic::{compiler_fence, Ordering}, 9*40fe15e0SLoGin }; 10*40fe15e0SLoGin 11*40fe15e0SLoGin use alloc::{ 12*40fe15e0SLoGin collections::BTreeMap, 13*40fe15e0SLoGin sync::{Arc, Weak}, 14*40fe15e0SLoGin vec::Vec, 15*40fe15e0SLoGin }; 16*40fe15e0SLoGin use hashbrown::HashSet; 17*40fe15e0SLoGin 18*40fe15e0SLoGin use crate::{ 19*40fe15e0SLoGin arch::{asm::current::current_pcb, mm::PageMapper, CurrentIrqArch, MMArch}, 20*40fe15e0SLoGin exception::InterruptArch, 21*40fe15e0SLoGin libs::{ 22*40fe15e0SLoGin align::page_align_up, 23*40fe15e0SLoGin rwlock::{RwLock, RwLockWriteGuard}, 24*40fe15e0SLoGin spinlock::{SpinLock, SpinLockGuard}, 25*40fe15e0SLoGin }, 26*40fe15e0SLoGin syscall::SystemError, 27*40fe15e0SLoGin }; 28*40fe15e0SLoGin 29*40fe15e0SLoGin use super::{ 30*40fe15e0SLoGin allocator::page_frame::{ 31*40fe15e0SLoGin deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter, 32*40fe15e0SLoGin }, 33*40fe15e0SLoGin page::{Flusher, InactiveFlusher, PageFlags, PageFlushAll}, 34*40fe15e0SLoGin syscall::{MapFlags, ProtFlags}, 35*40fe15e0SLoGin MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, 36*40fe15e0SLoGin }; 37*40fe15e0SLoGin 38*40fe15e0SLoGin /// MMAP_MIN_ADDR的默认值 39*40fe15e0SLoGin /// 以下内容来自linux-5.19: 40*40fe15e0SLoGin /// This is the portion of low virtual memory which should be protected 41*40fe15e0SLoGin // from userspace allocation. Keeping a user from writing to low pages 42*40fe15e0SLoGin // can help reduce the impact of kernel NULL pointer bugs. 43*40fe15e0SLoGin // For most ia64, ppc64 and x86 users with lots of address space 44*40fe15e0SLoGin // a value of 65536 is reasonable and should cause no problems. 45*40fe15e0SLoGin // On arm and other archs it should not be higher than 32768. 46*40fe15e0SLoGin // Programs which use vm86 functionality or have some need to map 47*40fe15e0SLoGin // this low address space will need CAP_SYS_RAWIO or disable this 48*40fe15e0SLoGin // protection by setting the value to 0. 49*40fe15e0SLoGin pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536; 50*40fe15e0SLoGin 51*40fe15e0SLoGin #[derive(Debug)] 52*40fe15e0SLoGin pub struct AddressSpace { 53*40fe15e0SLoGin inner: RwLock<InnerAddressSpace>, 54*40fe15e0SLoGin } 55*40fe15e0SLoGin 56*40fe15e0SLoGin impl AddressSpace { 57*40fe15e0SLoGin pub fn new(create_stack: bool) -> Result<Arc<Self>, SystemError> { 58*40fe15e0SLoGin let inner = InnerAddressSpace::new(create_stack)?; 59*40fe15e0SLoGin let result = Self { 60*40fe15e0SLoGin inner: RwLock::new(inner), 61*40fe15e0SLoGin }; 62*40fe15e0SLoGin return Ok(Arc::new(result)); 63*40fe15e0SLoGin } 64*40fe15e0SLoGin 65*40fe15e0SLoGin /// 从pcb中获取当前进程的地址空间结构体的Arc指针 66*40fe15e0SLoGin pub fn current() -> Result<Arc<AddressSpace>, SystemError> { 67*40fe15e0SLoGin let result = current_pcb() 68*40fe15e0SLoGin .address_space() 69*40fe15e0SLoGin .expect("Current process has no address space"); 70*40fe15e0SLoGin return Ok(result); 71*40fe15e0SLoGin } 72*40fe15e0SLoGin 73*40fe15e0SLoGin /// 判断某个地址空间是否为当前进程的地址空间 74*40fe15e0SLoGin pub fn is_current(self: &Arc<Self>) -> bool { 75*40fe15e0SLoGin let current = Self::current(); 76*40fe15e0SLoGin if let Ok(current) = current { 77*40fe15e0SLoGin return Arc::ptr_eq(¤t, self); 78*40fe15e0SLoGin } 79*40fe15e0SLoGin return false; 80*40fe15e0SLoGin } 81*40fe15e0SLoGin } 82*40fe15e0SLoGin 83*40fe15e0SLoGin impl core::ops::Deref for AddressSpace { 84*40fe15e0SLoGin type Target = RwLock<InnerAddressSpace>; 85*40fe15e0SLoGin 86*40fe15e0SLoGin fn deref(&self) -> &Self::Target { 87*40fe15e0SLoGin &self.inner 88*40fe15e0SLoGin } 89*40fe15e0SLoGin } 90*40fe15e0SLoGin 91*40fe15e0SLoGin impl core::ops::DerefMut for AddressSpace { 92*40fe15e0SLoGin fn deref_mut(&mut self) -> &mut Self::Target { 93*40fe15e0SLoGin &mut self.inner 94*40fe15e0SLoGin } 95*40fe15e0SLoGin } 96*40fe15e0SLoGin 97*40fe15e0SLoGin /// @brief 用户地址空间结构体(每个进程都有一个) 98*40fe15e0SLoGin #[derive(Debug)] 99*40fe15e0SLoGin pub struct InnerAddressSpace { 100*40fe15e0SLoGin pub user_mapper: UserMapper, 101*40fe15e0SLoGin pub mappings: UserMappings, 102*40fe15e0SLoGin pub mmap_min: VirtAddr, 103*40fe15e0SLoGin /// 用户栈信息结构体 104*40fe15e0SLoGin pub user_stack: Option<UserStack>, 105*40fe15e0SLoGin 106*40fe15e0SLoGin pub elf_brk_start: VirtAddr, 107*40fe15e0SLoGin pub elf_brk: VirtAddr, 108*40fe15e0SLoGin 109*40fe15e0SLoGin /// 当前进程的堆空间的起始地址 110*40fe15e0SLoGin pub brk_start: VirtAddr, 111*40fe15e0SLoGin /// 当前进程的堆空间的结束地址(不包含) 112*40fe15e0SLoGin pub brk: VirtAddr, 113*40fe15e0SLoGin 114*40fe15e0SLoGin pub start_code: VirtAddr, 115*40fe15e0SLoGin pub end_code: VirtAddr, 116*40fe15e0SLoGin pub start_data: VirtAddr, 117*40fe15e0SLoGin pub end_data: VirtAddr, 118*40fe15e0SLoGin } 119*40fe15e0SLoGin 120*40fe15e0SLoGin impl InnerAddressSpace { 121*40fe15e0SLoGin pub fn new(create_stack: bool) -> Result<Self, SystemError> { 122*40fe15e0SLoGin let mut result = Self { 123*40fe15e0SLoGin user_mapper: MMArch::setup_new_usermapper()?, 124*40fe15e0SLoGin mappings: UserMappings::new(), 125*40fe15e0SLoGin mmap_min: VirtAddr(DEFAULT_MMAP_MIN_ADDR), 126*40fe15e0SLoGin elf_brk_start: VirtAddr::new(0), 127*40fe15e0SLoGin elf_brk: VirtAddr::new(0), 128*40fe15e0SLoGin brk_start: MMArch::USER_BRK_START, 129*40fe15e0SLoGin brk: MMArch::USER_BRK_START, 130*40fe15e0SLoGin user_stack: None, 131*40fe15e0SLoGin start_code: VirtAddr(0), 132*40fe15e0SLoGin end_code: VirtAddr(0), 133*40fe15e0SLoGin start_data: VirtAddr(0), 134*40fe15e0SLoGin end_data: VirtAddr(0), 135*40fe15e0SLoGin }; 136*40fe15e0SLoGin if create_stack { 137*40fe15e0SLoGin // kdebug!("to create user stack."); 138*40fe15e0SLoGin result.new_user_stack(UserStack::DEFAULT_USER_STACK_SIZE)?; 139*40fe15e0SLoGin } 140*40fe15e0SLoGin 141*40fe15e0SLoGin return Ok(result); 142*40fe15e0SLoGin } 143*40fe15e0SLoGin 144*40fe15e0SLoGin /// 尝试克隆当前进程的地址空间,包括这些映射都会被克隆 145*40fe15e0SLoGin /// 146*40fe15e0SLoGin /// # Returns 147*40fe15e0SLoGin /// 148*40fe15e0SLoGin /// 返回克隆后的,新的地址空间的Arc指针 149*40fe15e0SLoGin pub fn try_clone(&mut self) -> Result<Arc<AddressSpace>, SystemError> { 150*40fe15e0SLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 151*40fe15e0SLoGin let new_addr_space = AddressSpace::new(false)?; 152*40fe15e0SLoGin let mut new_guard = new_addr_space.write(); 153*40fe15e0SLoGin 154*40fe15e0SLoGin // 拷贝用户栈的结构体信息,但是不拷贝用户栈的内容(因为后面VMA的拷贝会拷贝用户栈的内容) 155*40fe15e0SLoGin unsafe { 156*40fe15e0SLoGin new_guard.user_stack = Some(self.user_stack.as_ref().unwrap().clone_info_only()); 157*40fe15e0SLoGin } 158*40fe15e0SLoGin let _current_stack_size = self.user_stack.as_ref().unwrap().stack_size(); 159*40fe15e0SLoGin 160*40fe15e0SLoGin let current_mapper = &mut self.user_mapper.utable; 161*40fe15e0SLoGin 162*40fe15e0SLoGin for vma in self.mappings.vmas.iter() { 163*40fe15e0SLoGin // TODO: 增加对VMA是否为文件映射的判断,如果是的话,就跳过 164*40fe15e0SLoGin 165*40fe15e0SLoGin let vma_guard: SpinLockGuard<'_, VMA> = vma.lock(); 166*40fe15e0SLoGin let old_flags = vma_guard.flags(); 167*40fe15e0SLoGin let tmp_flags: PageFlags<MMArch> = PageFlags::new().set_write(true); 168*40fe15e0SLoGin 169*40fe15e0SLoGin // 分配内存页并创建新的VMA 170*40fe15e0SLoGin let new_vma = VMA::zeroed( 171*40fe15e0SLoGin VirtPageFrame::new(vma_guard.region.start()), 172*40fe15e0SLoGin PageFrameCount::new(vma_guard.region.size() / MMArch::PAGE_SIZE), 173*40fe15e0SLoGin tmp_flags, 174*40fe15e0SLoGin &mut new_guard.user_mapper.utable, 175*40fe15e0SLoGin (), 176*40fe15e0SLoGin )?; 177*40fe15e0SLoGin new_guard.mappings.vmas.insert(new_vma.clone()); 178*40fe15e0SLoGin // kdebug!("new vma: {:x?}", new_vma); 179*40fe15e0SLoGin let mut new_vma_guard = new_vma.lock(); 180*40fe15e0SLoGin for page in new_vma_guard.pages().map(|p| p.virt_address()) { 181*40fe15e0SLoGin // kdebug!("page: {:x?}", page); 182*40fe15e0SLoGin let current_frame = unsafe { 183*40fe15e0SLoGin MMArch::phys_2_virt( 184*40fe15e0SLoGin current_mapper 185*40fe15e0SLoGin .translate(page) 186*40fe15e0SLoGin .expect("VMA page not mapped") 187*40fe15e0SLoGin .0, 188*40fe15e0SLoGin ) 189*40fe15e0SLoGin } 190*40fe15e0SLoGin .expect("Phys2Virt: vaddr overflow.") 191*40fe15e0SLoGin .data() as *mut u8; 192*40fe15e0SLoGin 193*40fe15e0SLoGin let new_frame = unsafe { 194*40fe15e0SLoGin MMArch::phys_2_virt( 195*40fe15e0SLoGin new_guard 196*40fe15e0SLoGin .user_mapper 197*40fe15e0SLoGin .utable 198*40fe15e0SLoGin .translate(page) 199*40fe15e0SLoGin .expect("VMA page not mapped") 200*40fe15e0SLoGin .0, 201*40fe15e0SLoGin ) 202*40fe15e0SLoGin } 203*40fe15e0SLoGin .expect("Phys2Virt: vaddr overflow.") 204*40fe15e0SLoGin .data() as *mut u8; 205*40fe15e0SLoGin 206*40fe15e0SLoGin unsafe { 207*40fe15e0SLoGin // 拷贝数据 208*40fe15e0SLoGin new_frame.copy_from_nonoverlapping(current_frame, MMArch::PAGE_SIZE); 209*40fe15e0SLoGin } 210*40fe15e0SLoGin } 211*40fe15e0SLoGin drop(vma_guard); 212*40fe15e0SLoGin 213*40fe15e0SLoGin new_vma_guard.remap(old_flags, &mut new_guard.user_mapper.utable, ())?; 214*40fe15e0SLoGin drop(new_vma_guard); 215*40fe15e0SLoGin } 216*40fe15e0SLoGin drop(new_guard); 217*40fe15e0SLoGin drop(irq_guard); 218*40fe15e0SLoGin return Ok(new_addr_space); 219*40fe15e0SLoGin } 220*40fe15e0SLoGin 221*40fe15e0SLoGin /// 判断当前的地址空间是否是当前进程的地址空间 222*40fe15e0SLoGin #[inline] 223*40fe15e0SLoGin pub fn is_current(&self) -> bool { 224*40fe15e0SLoGin return self.user_mapper.utable.is_current(); 225*40fe15e0SLoGin } 226*40fe15e0SLoGin 227*40fe15e0SLoGin /// 进行匿名页映射 228*40fe15e0SLoGin /// 229*40fe15e0SLoGin /// ## 参数 230*40fe15e0SLoGin /// 231*40fe15e0SLoGin /// - `start_vaddr`:映射的起始地址 232*40fe15e0SLoGin /// - `len`:映射的长度 233*40fe15e0SLoGin /// - `prot_flags`:保护标志 234*40fe15e0SLoGin /// - `map_flags`:映射标志 235*40fe15e0SLoGin /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界 236*40fe15e0SLoGin pub fn map_anonymous( 237*40fe15e0SLoGin &mut self, 238*40fe15e0SLoGin start_vaddr: VirtAddr, 239*40fe15e0SLoGin len: usize, 240*40fe15e0SLoGin prot_flags: ProtFlags, 241*40fe15e0SLoGin map_flags: MapFlags, 242*40fe15e0SLoGin round_to_min: bool, 243*40fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 244*40fe15e0SLoGin // 用于对齐hint的函数 245*40fe15e0SLoGin let round_hint_to_min = |hint: VirtAddr| { 246*40fe15e0SLoGin // 先把hint向下对齐到页边界 247*40fe15e0SLoGin let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK); 248*40fe15e0SLoGin // kdebug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint); 249*40fe15e0SLoGin // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR 250*40fe15e0SLoGin if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) { 251*40fe15e0SLoGin Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR))) 252*40fe15e0SLoGin } else if addr == 0 { 253*40fe15e0SLoGin None 254*40fe15e0SLoGin } else { 255*40fe15e0SLoGin Some(VirtAddr::new(addr)) 256*40fe15e0SLoGin } 257*40fe15e0SLoGin }; 258*40fe15e0SLoGin // kdebug!("map_anonymous: start_vaddr = {:?}", start_vaddr); 259*40fe15e0SLoGin // kdebug!("map_anonymous: len(no align) = {}", len); 260*40fe15e0SLoGin 261*40fe15e0SLoGin let len = page_align_up(len); 262*40fe15e0SLoGin 263*40fe15e0SLoGin // kdebug!("map_anonymous: len = {}", len); 264*40fe15e0SLoGin 265*40fe15e0SLoGin let start_page: VirtPageFrame = self.mmap( 266*40fe15e0SLoGin round_hint_to_min(start_vaddr), 267*40fe15e0SLoGin PageFrameCount::from_bytes(len).unwrap(), 268*40fe15e0SLoGin prot_flags, 269*40fe15e0SLoGin map_flags, 270*40fe15e0SLoGin move |page, count, flags, mapper, flusher| { 271*40fe15e0SLoGin Ok(VMA::zeroed(page, count, flags, mapper, flusher)?) 272*40fe15e0SLoGin }, 273*40fe15e0SLoGin )?; 274*40fe15e0SLoGin 275*40fe15e0SLoGin return Ok(start_page); 276*40fe15e0SLoGin } 277*40fe15e0SLoGin 278*40fe15e0SLoGin /// 向进程的地址空间映射页面 279*40fe15e0SLoGin /// 280*40fe15e0SLoGin /// # 参数 281*40fe15e0SLoGin /// 282*40fe15e0SLoGin /// - `addr`:映射的起始地址,如果为`None`,则由内核自动分配 283*40fe15e0SLoGin /// - `page_count`:映射的页面数量 284*40fe15e0SLoGin /// - `prot_flags`:保护标志 285*40fe15e0SLoGin /// - `map_flags`:映射标志 286*40fe15e0SLoGin /// - `map_func`:映射函数,用于创建VMA 287*40fe15e0SLoGin /// 288*40fe15e0SLoGin /// # Returns 289*40fe15e0SLoGin /// 290*40fe15e0SLoGin /// 返回映射的起始虚拟页帧 291*40fe15e0SLoGin /// 292*40fe15e0SLoGin /// # Errors 293*40fe15e0SLoGin /// 294*40fe15e0SLoGin /// - `EINVAL`:参数错误 295*40fe15e0SLoGin pub fn mmap< 296*40fe15e0SLoGin F: FnOnce( 297*40fe15e0SLoGin VirtPageFrame, 298*40fe15e0SLoGin PageFrameCount, 299*40fe15e0SLoGin PageFlags<MMArch>, 300*40fe15e0SLoGin &mut PageMapper, 301*40fe15e0SLoGin &mut dyn Flusher<MMArch>, 302*40fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError>, 303*40fe15e0SLoGin >( 304*40fe15e0SLoGin &mut self, 305*40fe15e0SLoGin addr: Option<VirtAddr>, 306*40fe15e0SLoGin page_count: PageFrameCount, 307*40fe15e0SLoGin prot_flags: ProtFlags, 308*40fe15e0SLoGin map_flags: MapFlags, 309*40fe15e0SLoGin map_func: F, 310*40fe15e0SLoGin ) -> Result<VirtPageFrame, SystemError> { 311*40fe15e0SLoGin if page_count == PageFrameCount::new(0) { 312*40fe15e0SLoGin return Err(SystemError::EINVAL); 313*40fe15e0SLoGin } 314*40fe15e0SLoGin // kdebug!("mmap: addr: {addr:?}, page_count: {page_count:?}, prot_flags: {prot_flags:?}, map_flags: {map_flags:?}"); 315*40fe15e0SLoGin 316*40fe15e0SLoGin // 找到未使用的区域 317*40fe15e0SLoGin let region = match addr { 318*40fe15e0SLoGin Some(vaddr) => { 319*40fe15e0SLoGin self.mappings 320*40fe15e0SLoGin .find_free_at(self.mmap_min, vaddr, page_count.bytes(), map_flags)? 321*40fe15e0SLoGin } 322*40fe15e0SLoGin None => self 323*40fe15e0SLoGin .mappings 324*40fe15e0SLoGin .find_free(self.mmap_min, page_count.bytes()) 325*40fe15e0SLoGin .ok_or(SystemError::ENOMEM)?, 326*40fe15e0SLoGin }; 327*40fe15e0SLoGin 328*40fe15e0SLoGin let page = VirtPageFrame::new(region.start()); 329*40fe15e0SLoGin 330*40fe15e0SLoGin // kdebug!("mmap: page: {:?}, region={region:?}", page.virt_address()); 331*40fe15e0SLoGin 332*40fe15e0SLoGin compiler_fence(Ordering::SeqCst); 333*40fe15e0SLoGin let (mut active, mut inactive); 334*40fe15e0SLoGin let flusher = if self.is_current() { 335*40fe15e0SLoGin // kdebug!("mmap: current ucontext"); 336*40fe15e0SLoGin active = PageFlushAll::new(); 337*40fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 338*40fe15e0SLoGin } else { 339*40fe15e0SLoGin // kdebug!("mmap: not current ucontext"); 340*40fe15e0SLoGin inactive = InactiveFlusher::new(); 341*40fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 342*40fe15e0SLoGin }; 343*40fe15e0SLoGin compiler_fence(Ordering::SeqCst); 344*40fe15e0SLoGin // 映射页面,并将VMA插入到地址空间的VMA列表中 345*40fe15e0SLoGin self.mappings.insert_vma(map_func( 346*40fe15e0SLoGin page, 347*40fe15e0SLoGin page_count, 348*40fe15e0SLoGin PageFlags::from_prot_flags(prot_flags, true), 349*40fe15e0SLoGin &mut self.user_mapper.utable, 350*40fe15e0SLoGin flusher, 351*40fe15e0SLoGin )?); 352*40fe15e0SLoGin 353*40fe15e0SLoGin return Ok(page); 354*40fe15e0SLoGin } 355*40fe15e0SLoGin 356*40fe15e0SLoGin /// 取消进程的地址空间中的映射 357*40fe15e0SLoGin /// 358*40fe15e0SLoGin /// # 参数 359*40fe15e0SLoGin /// 360*40fe15e0SLoGin /// - `start_page`:起始页帧 361*40fe15e0SLoGin /// - `page_count`:取消映射的页帧数量 362*40fe15e0SLoGin /// 363*40fe15e0SLoGin /// # Errors 364*40fe15e0SLoGin /// 365*40fe15e0SLoGin /// - `EINVAL`:参数错误 366*40fe15e0SLoGin /// - `ENOMEM`:内存不足 367*40fe15e0SLoGin pub fn munmap( 368*40fe15e0SLoGin &mut self, 369*40fe15e0SLoGin start_page: VirtPageFrame, 370*40fe15e0SLoGin page_count: PageFrameCount, 371*40fe15e0SLoGin ) -> Result<(), SystemError> { 372*40fe15e0SLoGin let to_unmap = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 373*40fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 374*40fe15e0SLoGin 375*40fe15e0SLoGin let regions: Vec<Arc<LockedVMA>> = self.mappings.conflicts(to_unmap).collect::<Vec<_>>(); 376*40fe15e0SLoGin 377*40fe15e0SLoGin for r in regions { 378*40fe15e0SLoGin let r = r.lock().region; 379*40fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 380*40fe15e0SLoGin let intersection = r.lock().region().intersect(&to_unmap).unwrap(); 381*40fe15e0SLoGin let (before, r, after) = r.extract(intersection).unwrap(); 382*40fe15e0SLoGin 383*40fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 384*40fe15e0SLoGin 385*40fe15e0SLoGin if let Some(before) = before { 386*40fe15e0SLoGin // 如果前面有VMA,则需要将前面的VMA重新插入到地址空间的VMA列表中 387*40fe15e0SLoGin self.mappings.insert_vma(before); 388*40fe15e0SLoGin } 389*40fe15e0SLoGin 390*40fe15e0SLoGin if let Some(after) = after { 391*40fe15e0SLoGin // 如果后面有VMA,则需要将后面的VMA重新插入到地址空间的VMA列表中 392*40fe15e0SLoGin self.mappings.insert_vma(after); 393*40fe15e0SLoGin } 394*40fe15e0SLoGin 395*40fe15e0SLoGin r.unmap(&mut self.user_mapper.utable, &mut flusher); 396*40fe15e0SLoGin } 397*40fe15e0SLoGin 398*40fe15e0SLoGin // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑 399*40fe15e0SLoGin 400*40fe15e0SLoGin return Ok(()); 401*40fe15e0SLoGin } 402*40fe15e0SLoGin 403*40fe15e0SLoGin pub fn mprotect( 404*40fe15e0SLoGin &mut self, 405*40fe15e0SLoGin start_page: VirtPageFrame, 406*40fe15e0SLoGin page_count: PageFrameCount, 407*40fe15e0SLoGin prot_flags: ProtFlags, 408*40fe15e0SLoGin ) -> Result<(), SystemError> { 409*40fe15e0SLoGin // kdebug!( 410*40fe15e0SLoGin // "mprotect: start_page: {:?}, page_count: {:?}, prot_flags:{prot_flags:?}", 411*40fe15e0SLoGin // start_page, 412*40fe15e0SLoGin // page_count 413*40fe15e0SLoGin // ); 414*40fe15e0SLoGin let (mut active, mut inactive); 415*40fe15e0SLoGin let mut flusher = if self.is_current() { 416*40fe15e0SLoGin active = PageFlushAll::new(); 417*40fe15e0SLoGin &mut active as &mut dyn Flusher<MMArch> 418*40fe15e0SLoGin } else { 419*40fe15e0SLoGin inactive = InactiveFlusher::new(); 420*40fe15e0SLoGin &mut inactive as &mut dyn Flusher<MMArch> 421*40fe15e0SLoGin }; 422*40fe15e0SLoGin 423*40fe15e0SLoGin let mapper = &mut self.user_mapper.utable; 424*40fe15e0SLoGin let region = VirtRegion::new(start_page.virt_address(), page_count.bytes()); 425*40fe15e0SLoGin // kdebug!("mprotect: region: {:?}", region); 426*40fe15e0SLoGin 427*40fe15e0SLoGin let regions = self.mappings.conflicts(region).collect::<Vec<_>>(); 428*40fe15e0SLoGin // kdebug!("mprotect: regions: {:?}", regions); 429*40fe15e0SLoGin 430*40fe15e0SLoGin for r in regions { 431*40fe15e0SLoGin // kdebug!("mprotect: r: {:?}", r); 432*40fe15e0SLoGin let r = r.lock().region().clone(); 433*40fe15e0SLoGin let r = self.mappings.remove_vma(&r).unwrap(); 434*40fe15e0SLoGin 435*40fe15e0SLoGin let intersection = r.lock().region().intersect(®ion).unwrap(); 436*40fe15e0SLoGin let (before, r, after) = r.extract(intersection).expect("Failed to extract VMA"); 437*40fe15e0SLoGin 438*40fe15e0SLoGin if let Some(before) = before { 439*40fe15e0SLoGin self.mappings.insert_vma(before); 440*40fe15e0SLoGin } 441*40fe15e0SLoGin if let Some(after) = after { 442*40fe15e0SLoGin self.mappings.insert_vma(after); 443*40fe15e0SLoGin } 444*40fe15e0SLoGin 445*40fe15e0SLoGin let mut r_guard = r.lock(); 446*40fe15e0SLoGin // 如果VMA的保护标志不允许指定的修改,则返回错误 447*40fe15e0SLoGin if !r_guard.can_have_flags(prot_flags) { 448*40fe15e0SLoGin drop(r_guard); 449*40fe15e0SLoGin self.mappings.insert_vma(r.clone()); 450*40fe15e0SLoGin return Err(SystemError::EACCES); 451*40fe15e0SLoGin } 452*40fe15e0SLoGin 453*40fe15e0SLoGin let new_flags: PageFlags<MMArch> = r_guard 454*40fe15e0SLoGin .flags() 455*40fe15e0SLoGin .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC)) 456*40fe15e0SLoGin .set_write(prot_flags.contains(ProtFlags::PROT_WRITE)); 457*40fe15e0SLoGin 458*40fe15e0SLoGin r_guard.remap(new_flags, mapper, &mut flusher)?; 459*40fe15e0SLoGin drop(r_guard); 460*40fe15e0SLoGin self.mappings.insert_vma(r); 461*40fe15e0SLoGin } 462*40fe15e0SLoGin 463*40fe15e0SLoGin return Ok(()); 464*40fe15e0SLoGin } 465*40fe15e0SLoGin 466*40fe15e0SLoGin /// 创建新的用户栈 467*40fe15e0SLoGin /// 468*40fe15e0SLoGin /// ## 参数 469*40fe15e0SLoGin /// 470*40fe15e0SLoGin /// - `size`:栈的大小 471*40fe15e0SLoGin pub fn new_user_stack(&mut self, size: usize) -> Result<(), SystemError> { 472*40fe15e0SLoGin assert!(self.user_stack.is_none(), "User stack already exists"); 473*40fe15e0SLoGin let stack = UserStack::new(self, None, size)?; 474*40fe15e0SLoGin self.user_stack = Some(stack); 475*40fe15e0SLoGin return Ok(()); 476*40fe15e0SLoGin } 477*40fe15e0SLoGin 478*40fe15e0SLoGin #[inline(always)] 479*40fe15e0SLoGin pub fn user_stack_mut(&mut self) -> Option<&mut UserStack> { 480*40fe15e0SLoGin return self.user_stack.as_mut(); 481*40fe15e0SLoGin } 482*40fe15e0SLoGin 483*40fe15e0SLoGin /// 取消用户空间内的所有映射 484*40fe15e0SLoGin pub unsafe fn unmap_all(&mut self) { 485*40fe15e0SLoGin let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new(); 486*40fe15e0SLoGin for vma in self.mappings.iter_vmas() { 487*40fe15e0SLoGin vma.unmap(&mut self.user_mapper.utable, &mut flusher); 488*40fe15e0SLoGin } 489*40fe15e0SLoGin } 490*40fe15e0SLoGin 491*40fe15e0SLoGin /// 设置进程的堆的内存空间 492*40fe15e0SLoGin /// 493*40fe15e0SLoGin /// ## 参数 494*40fe15e0SLoGin /// 495*40fe15e0SLoGin /// - `new_brk`:新的堆的结束地址。需要满足页对齐要求,并且是用户空间地址,且大于等于当前的堆的起始地址 496*40fe15e0SLoGin /// 497*40fe15e0SLoGin /// ## 返回值 498*40fe15e0SLoGin /// 499*40fe15e0SLoGin /// 返回旧的堆的结束地址 500*40fe15e0SLoGin pub unsafe fn set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError> { 501*40fe15e0SLoGin assert!(new_brk.check_aligned(MMArch::PAGE_SIZE)); 502*40fe15e0SLoGin 503*40fe15e0SLoGin if !new_brk.check_user() || new_brk < self.brk_start { 504*40fe15e0SLoGin return Err(SystemError::EFAULT); 505*40fe15e0SLoGin } 506*40fe15e0SLoGin 507*40fe15e0SLoGin let old_brk = self.brk; 508*40fe15e0SLoGin // kdebug!("set_brk: old_brk: {:?}, new_brk: {:?}", old_brk, new_brk); 509*40fe15e0SLoGin if new_brk > self.brk { 510*40fe15e0SLoGin let len = new_brk - self.brk; 511*40fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 512*40fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED; 513*40fe15e0SLoGin self.map_anonymous(old_brk, len, prot_flags, map_flags, true)? 514*40fe15e0SLoGin .virt_address(); 515*40fe15e0SLoGin self.brk = new_brk; 516*40fe15e0SLoGin return Ok(old_brk); 517*40fe15e0SLoGin } else { 518*40fe15e0SLoGin let unmap_len = self.brk - new_brk; 519*40fe15e0SLoGin let unmap_start = new_brk; 520*40fe15e0SLoGin if unmap_len == 0 { 521*40fe15e0SLoGin return Ok(old_brk); 522*40fe15e0SLoGin } 523*40fe15e0SLoGin self.munmap( 524*40fe15e0SLoGin VirtPageFrame::new(unmap_start), 525*40fe15e0SLoGin PageFrameCount::from_bytes(unmap_len).unwrap(), 526*40fe15e0SLoGin )?; 527*40fe15e0SLoGin self.brk = new_brk; 528*40fe15e0SLoGin return Ok(old_brk); 529*40fe15e0SLoGin } 530*40fe15e0SLoGin } 531*40fe15e0SLoGin 532*40fe15e0SLoGin pub unsafe fn sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError> { 533*40fe15e0SLoGin if incr == 0 { 534*40fe15e0SLoGin return Ok(self.brk); 535*40fe15e0SLoGin } 536*40fe15e0SLoGin 537*40fe15e0SLoGin let new_brk = if incr > 0 { 538*40fe15e0SLoGin self.brk + incr as usize 539*40fe15e0SLoGin } else { 540*40fe15e0SLoGin self.brk - (incr.abs() as usize) 541*40fe15e0SLoGin }; 542*40fe15e0SLoGin 543*40fe15e0SLoGin let new_brk = VirtAddr::new(page_align_up(new_brk.data())); 544*40fe15e0SLoGin 545*40fe15e0SLoGin return self.set_brk(new_brk); 546*40fe15e0SLoGin } 547*40fe15e0SLoGin } 548*40fe15e0SLoGin 549*40fe15e0SLoGin impl Drop for InnerAddressSpace { 550*40fe15e0SLoGin fn drop(&mut self) { 551*40fe15e0SLoGin unsafe { 552*40fe15e0SLoGin self.unmap_all(); 553*40fe15e0SLoGin } 554*40fe15e0SLoGin } 555*40fe15e0SLoGin } 556*40fe15e0SLoGin 557*40fe15e0SLoGin #[derive(Debug, Hash)] 558*40fe15e0SLoGin pub struct UserMapper { 559*40fe15e0SLoGin pub utable: PageMapper, 560*40fe15e0SLoGin } 561*40fe15e0SLoGin 562*40fe15e0SLoGin impl UserMapper { 563*40fe15e0SLoGin pub fn new(utable: PageMapper) -> Self { 564*40fe15e0SLoGin return Self { utable }; 565*40fe15e0SLoGin } 566*40fe15e0SLoGin } 567*40fe15e0SLoGin 568*40fe15e0SLoGin impl Drop for UserMapper { 569*40fe15e0SLoGin fn drop(&mut self) { 570*40fe15e0SLoGin if self.utable.is_current() { 571*40fe15e0SLoGin // 如果当前要被销毁的用户空间的页表是当前进程的页表,那么就切换回初始内核页表 572*40fe15e0SLoGin unsafe { MMArch::set_table(PageTableKind::User, MMArch::initial_page_table()) } 573*40fe15e0SLoGin } 574*40fe15e0SLoGin // 释放用户空间顶层页表占用的页帧 575*40fe15e0SLoGin // 请注意,在释放这个页帧之前,用户页表应该已经被完全释放,否则会产生内存泄露 576*40fe15e0SLoGin unsafe { 577*40fe15e0SLoGin deallocate_page_frames( 578*40fe15e0SLoGin PhysPageFrame::new(self.utable.table().phys()), 579*40fe15e0SLoGin PageFrameCount::new(1), 580*40fe15e0SLoGin ) 581*40fe15e0SLoGin }; 582*40fe15e0SLoGin } 583*40fe15e0SLoGin } 584*40fe15e0SLoGin 585*40fe15e0SLoGin /// 用户空间映射信息 586*40fe15e0SLoGin #[derive(Debug)] 587*40fe15e0SLoGin pub struct UserMappings { 588*40fe15e0SLoGin /// 当前用户空间的虚拟内存区域 589*40fe15e0SLoGin vmas: HashSet<Arc<LockedVMA>>, 590*40fe15e0SLoGin /// 当前用户空间的VMA空洞 591*40fe15e0SLoGin vm_holes: BTreeMap<VirtAddr, usize>, 592*40fe15e0SLoGin } 593*40fe15e0SLoGin 594*40fe15e0SLoGin impl UserMappings { 595*40fe15e0SLoGin pub fn new() -> Self { 596*40fe15e0SLoGin return Self { 597*40fe15e0SLoGin vmas: HashSet::new(), 598*40fe15e0SLoGin vm_holes: core::iter::once((VirtAddr::new(0), MMArch::USER_END_VADDR.data())) 599*40fe15e0SLoGin .collect::<BTreeMap<_, _>>(), 600*40fe15e0SLoGin }; 601*40fe15e0SLoGin } 602*40fe15e0SLoGin 603*40fe15e0SLoGin /// 判断当前进程的VMA内,是否有包含指定的虚拟地址的VMA。 604*40fe15e0SLoGin /// 605*40fe15e0SLoGin /// 如果有,返回包含指定虚拟地址的VMA的Arc指针,否则返回None。 606*40fe15e0SLoGin #[allow(dead_code)] 607*40fe15e0SLoGin pub fn contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> { 608*40fe15e0SLoGin for v in self.vmas.iter() { 609*40fe15e0SLoGin let guard = v.lock(); 610*40fe15e0SLoGin if guard.region.contains(vaddr) { 611*40fe15e0SLoGin return Some(v.clone()); 612*40fe15e0SLoGin } 613*40fe15e0SLoGin } 614*40fe15e0SLoGin return None; 615*40fe15e0SLoGin } 616*40fe15e0SLoGin 617*40fe15e0SLoGin /// 获取当前进程的地址空间中,与给定虚拟地址范围有重叠的VMA的迭代器。 618*40fe15e0SLoGin pub fn conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_ { 619*40fe15e0SLoGin let r = self 620*40fe15e0SLoGin .vmas 621*40fe15e0SLoGin .iter() 622*40fe15e0SLoGin .filter(move |v| !v.lock().region.intersect(&request).is_none()) 623*40fe15e0SLoGin .cloned(); 624*40fe15e0SLoGin return r; 625*40fe15e0SLoGin } 626*40fe15e0SLoGin 627*40fe15e0SLoGin /// 在当前进程的地址空间中,寻找第一个符合条件的空闲的虚拟内存范围。 628*40fe15e0SLoGin /// 629*40fe15e0SLoGin /// @param min_vaddr 最小的起始地址 630*40fe15e0SLoGin /// @param size 请求的大小 631*40fe15e0SLoGin /// 632*40fe15e0SLoGin /// @return 如果找到了,返回虚拟内存范围,否则返回None 633*40fe15e0SLoGin pub fn find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion> { 634*40fe15e0SLoGin let _vaddr = min_vaddr; 635*40fe15e0SLoGin let mut iter = self 636*40fe15e0SLoGin .vm_holes 637*40fe15e0SLoGin .iter() 638*40fe15e0SLoGin .skip_while(|(hole_vaddr, hole_size)| hole_vaddr.add(**hole_size) <= min_vaddr); 639*40fe15e0SLoGin 640*40fe15e0SLoGin let (hole_vaddr, size) = iter.find(|(hole_vaddr, hole_size)| { 641*40fe15e0SLoGin // 计算当前空洞的可用大小 642*40fe15e0SLoGin let available_size: usize = 643*40fe15e0SLoGin if hole_vaddr <= &&min_vaddr && min_vaddr <= hole_vaddr.add(**hole_size) { 644*40fe15e0SLoGin **hole_size - (min_vaddr - **hole_vaddr) 645*40fe15e0SLoGin } else { 646*40fe15e0SLoGin **hole_size 647*40fe15e0SLoGin }; 648*40fe15e0SLoGin 649*40fe15e0SLoGin size <= available_size 650*40fe15e0SLoGin })?; 651*40fe15e0SLoGin 652*40fe15e0SLoGin // 创建一个新的虚拟内存范围。 653*40fe15e0SLoGin let region = VirtRegion::new(cmp::max(*hole_vaddr, min_vaddr), *size); 654*40fe15e0SLoGin return Some(region); 655*40fe15e0SLoGin } 656*40fe15e0SLoGin 657*40fe15e0SLoGin pub fn find_free_at( 658*40fe15e0SLoGin &self, 659*40fe15e0SLoGin min_vaddr: VirtAddr, 660*40fe15e0SLoGin vaddr: VirtAddr, 661*40fe15e0SLoGin size: usize, 662*40fe15e0SLoGin flags: MapFlags, 663*40fe15e0SLoGin ) -> Result<VirtRegion, SystemError> { 664*40fe15e0SLoGin // 如果没有指定地址,那么就在当前进程的地址空间中寻找一个空闲的虚拟内存范围。 665*40fe15e0SLoGin if vaddr == VirtAddr::new(0) { 666*40fe15e0SLoGin return self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM); 667*40fe15e0SLoGin } 668*40fe15e0SLoGin 669*40fe15e0SLoGin // 如果指定了地址,那么就检查指定的地址是否可用。 670*40fe15e0SLoGin 671*40fe15e0SLoGin let requested = VirtRegion::new(vaddr, size); 672*40fe15e0SLoGin 673*40fe15e0SLoGin if requested.end() >= MMArch::USER_END_VADDR || !vaddr.check_aligned(MMArch::PAGE_SIZE) { 674*40fe15e0SLoGin return Err(SystemError::EINVAL); 675*40fe15e0SLoGin } 676*40fe15e0SLoGin 677*40fe15e0SLoGin if let Some(_x) = self.conflicts(requested).next() { 678*40fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED_NOREPLACE) { 679*40fe15e0SLoGin // 如果指定了 MAP_FIXED_NOREPLACE 标志,由于所指定的地址无法成功建立映射,则放弃映射,不对地址做修正 680*40fe15e0SLoGin return Err(SystemError::EEXIST); 681*40fe15e0SLoGin } 682*40fe15e0SLoGin 683*40fe15e0SLoGin if flags.contains(MapFlags::MAP_FIXED) { 684*40fe15e0SLoGin // todo: 支持MAP_FIXED标志对已有的VMA进行覆盖 685*40fe15e0SLoGin return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); 686*40fe15e0SLoGin } 687*40fe15e0SLoGin 688*40fe15e0SLoGin // 如果没有指定MAP_FIXED标志,那么就对地址做修正 689*40fe15e0SLoGin let requested = self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM)?; 690*40fe15e0SLoGin return Ok(requested); 691*40fe15e0SLoGin } 692*40fe15e0SLoGin 693*40fe15e0SLoGin return Ok(requested); 694*40fe15e0SLoGin } 695*40fe15e0SLoGin 696*40fe15e0SLoGin /// 在当前进程的地址空间中,保留一个指定大小的区域,使得该区域不在空洞中。 697*40fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 698*40fe15e0SLoGin /// 699*40fe15e0SLoGin /// @param region 要保留的区域 700*40fe15e0SLoGin /// 701*40fe15e0SLoGin /// 请注意,在调用本函数之前,必须先确定region所在范围内没有VMA。 702*40fe15e0SLoGin fn reserve_hole(&mut self, region: &VirtRegion) { 703*40fe15e0SLoGin let prev_hole: Option<(&VirtAddr, &mut usize)> = 704*40fe15e0SLoGin self.vm_holes.range_mut(..region.start()).next_back(); 705*40fe15e0SLoGin 706*40fe15e0SLoGin if let Some((prev_hole_vaddr, prev_hole_size)) = prev_hole { 707*40fe15e0SLoGin let prev_hole_end = prev_hole_vaddr.add(*prev_hole_size); 708*40fe15e0SLoGin 709*40fe15e0SLoGin if prev_hole_end > region.start() { 710*40fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的起始地址,那么就需要调整前一个空洞的大小。 711*40fe15e0SLoGin *prev_hole_size = region.start().data() - prev_hole_vaddr.data(); 712*40fe15e0SLoGin } 713*40fe15e0SLoGin 714*40fe15e0SLoGin if prev_hole_end > region.end() { 715*40fe15e0SLoGin // 如果前一个空洞的结束地址大于当前空洞的结束地址,那么就需要增加一个新的空洞。 716*40fe15e0SLoGin self.vm_holes 717*40fe15e0SLoGin .insert(region.end(), prev_hole_end - region.end()); 718*40fe15e0SLoGin } 719*40fe15e0SLoGin } 720*40fe15e0SLoGin } 721*40fe15e0SLoGin 722*40fe15e0SLoGin /// 在当前进程的地址空间中,释放一个指定大小的区域,使得该区域成为一个空洞。 723*40fe15e0SLoGin /// 该函数会修改vm_holes中的空洞信息。 724*40fe15e0SLoGin fn unreserve_hole(&mut self, region: &VirtRegion) { 725*40fe15e0SLoGin // 如果将要插入的空洞与后一个空洞相邻,那么就需要合并。 726*40fe15e0SLoGin let next_hole_size: Option<usize> = self.vm_holes.remove(®ion.end()); 727*40fe15e0SLoGin 728*40fe15e0SLoGin if let Some((_prev_hole_vaddr, prev_hole_size)) = self 729*40fe15e0SLoGin .vm_holes 730*40fe15e0SLoGin .range_mut(..region.start()) 731*40fe15e0SLoGin .next_back() 732*40fe15e0SLoGin .filter(|(offset, size)| offset.data() + **size == region.start().data()) 733*40fe15e0SLoGin { 734*40fe15e0SLoGin *prev_hole_size += region.size() + next_hole_size.unwrap_or(0); 735*40fe15e0SLoGin } else { 736*40fe15e0SLoGin self.vm_holes 737*40fe15e0SLoGin .insert(region.start(), region.size() + next_hole_size.unwrap_or(0)); 738*40fe15e0SLoGin } 739*40fe15e0SLoGin } 740*40fe15e0SLoGin 741*40fe15e0SLoGin /// 在当前进程的映射关系中,插入一个新的VMA。 742*40fe15e0SLoGin pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) { 743*40fe15e0SLoGin let region = vma.lock().region.clone(); 744*40fe15e0SLoGin // 要求插入的地址范围必须是空闲的,也就是说,当前进程的地址空间中,不能有任何与之重叠的VMA。 745*40fe15e0SLoGin assert!(self.conflicts(region).next().is_none()); 746*40fe15e0SLoGin self.reserve_hole(®ion); 747*40fe15e0SLoGin 748*40fe15e0SLoGin self.vmas.insert(vma); 749*40fe15e0SLoGin } 750*40fe15e0SLoGin 751*40fe15e0SLoGin /// @brief 删除一个VMA,并把对应的地址空间加入空洞中。 752*40fe15e0SLoGin /// 753*40fe15e0SLoGin /// 这里不会取消VMA对应的地址的映射 754*40fe15e0SLoGin /// 755*40fe15e0SLoGin /// @param region 要删除的VMA所在的地址范围 756*40fe15e0SLoGin /// 757*40fe15e0SLoGin /// @return 如果成功删除了VMA,则返回被删除的VMA,否则返回None 758*40fe15e0SLoGin /// 如果没有可以删除的VMA,则不会执行删除操作,并报告失败。 759*40fe15e0SLoGin pub fn remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>> { 760*40fe15e0SLoGin // 请注意,由于这里会对每个VMA加锁,因此性能很低 761*40fe15e0SLoGin let vma: Arc<LockedVMA> = self 762*40fe15e0SLoGin .vmas 763*40fe15e0SLoGin .drain_filter(|vma| vma.lock().region == *region) 764*40fe15e0SLoGin .next()?; 765*40fe15e0SLoGin self.unreserve_hole(region); 766*40fe15e0SLoGin 767*40fe15e0SLoGin return Some(vma); 768*40fe15e0SLoGin } 769*40fe15e0SLoGin 770*40fe15e0SLoGin /// @brief Get the iterator of all VMAs in this process. 771*40fe15e0SLoGin pub fn iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>> { 772*40fe15e0SLoGin return self.vmas.iter(); 773*40fe15e0SLoGin } 774*40fe15e0SLoGin } 775*40fe15e0SLoGin 776*40fe15e0SLoGin impl Default for UserMappings { 777*40fe15e0SLoGin fn default() -> Self { 778*40fe15e0SLoGin return Self::new(); 779*40fe15e0SLoGin } 780*40fe15e0SLoGin } 781*40fe15e0SLoGin 782*40fe15e0SLoGin /// 加了锁的VMA 783*40fe15e0SLoGin /// 784*40fe15e0SLoGin /// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。 785*40fe15e0SLoGin #[derive(Debug)] 786*40fe15e0SLoGin pub struct LockedVMA(SpinLock<VMA>); 787*40fe15e0SLoGin 788*40fe15e0SLoGin impl core::hash::Hash for LockedVMA { 789*40fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 790*40fe15e0SLoGin self.0.lock().hash(state); 791*40fe15e0SLoGin } 792*40fe15e0SLoGin } 793*40fe15e0SLoGin 794*40fe15e0SLoGin impl PartialEq for LockedVMA { 795*40fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 796*40fe15e0SLoGin self.0.lock().eq(&other.0.lock()) 797*40fe15e0SLoGin } 798*40fe15e0SLoGin } 799*40fe15e0SLoGin 800*40fe15e0SLoGin impl Eq for LockedVMA {} 801*40fe15e0SLoGin 802*40fe15e0SLoGin #[allow(dead_code)] 803*40fe15e0SLoGin impl LockedVMA { 804*40fe15e0SLoGin pub fn new(vma: VMA) -> Arc<Self> { 805*40fe15e0SLoGin let r = Arc::new(Self(SpinLock::new(vma))); 806*40fe15e0SLoGin r.0.lock().self_ref = Arc::downgrade(&r); 807*40fe15e0SLoGin return r; 808*40fe15e0SLoGin } 809*40fe15e0SLoGin 810*40fe15e0SLoGin pub fn lock(&self) -> SpinLockGuard<VMA> { 811*40fe15e0SLoGin return self.0.lock(); 812*40fe15e0SLoGin } 813*40fe15e0SLoGin 814*40fe15e0SLoGin /// 调整当前VMA的页面的标志位 815*40fe15e0SLoGin /// 816*40fe15e0SLoGin /// TODO:增加调整虚拟页映射的物理地址的功能 817*40fe15e0SLoGin /// 818*40fe15e0SLoGin /// @param flags 新的标志位 819*40fe15e0SLoGin /// @param mapper 页表映射器 820*40fe15e0SLoGin /// @param flusher 页表项刷新器 821*40fe15e0SLoGin /// 822*40fe15e0SLoGin pub fn remap( 823*40fe15e0SLoGin &self, 824*40fe15e0SLoGin flags: PageFlags<MMArch>, 825*40fe15e0SLoGin mapper: &mut PageMapper, 826*40fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 827*40fe15e0SLoGin ) -> Result<(), SystemError> { 828*40fe15e0SLoGin let mut guard = self.lock(); 829*40fe15e0SLoGin assert!(guard.mapped); 830*40fe15e0SLoGin for page in guard.region.pages() { 831*40fe15e0SLoGin // 暂时要求所有的页帧都已经映射到页表 832*40fe15e0SLoGin // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了 833*40fe15e0SLoGin let r = unsafe { 834*40fe15e0SLoGin mapper 835*40fe15e0SLoGin .remap(page.virt_address(), flags) 836*40fe15e0SLoGin .expect("Failed to remap, beacuse of some page is not mapped") 837*40fe15e0SLoGin }; 838*40fe15e0SLoGin flusher.consume(r); 839*40fe15e0SLoGin } 840*40fe15e0SLoGin guard.flags = flags; 841*40fe15e0SLoGin return Ok(()); 842*40fe15e0SLoGin } 843*40fe15e0SLoGin 844*40fe15e0SLoGin pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>) { 845*40fe15e0SLoGin let mut guard = self.lock(); 846*40fe15e0SLoGin assert!(guard.mapped); 847*40fe15e0SLoGin for page in guard.region.pages() { 848*40fe15e0SLoGin let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) } 849*40fe15e0SLoGin .expect("Failed to unmap, beacuse of some page is not mapped"); 850*40fe15e0SLoGin 851*40fe15e0SLoGin // todo: 获取物理页的anon_vma的守卫 852*40fe15e0SLoGin 853*40fe15e0SLoGin // todo: 从anon_vma中删除当前VMA 854*40fe15e0SLoGin 855*40fe15e0SLoGin // todo: 如果物理页的anon_vma链表长度为0,则释放物理页. 856*40fe15e0SLoGin 857*40fe15e0SLoGin // 目前由于还没有实现共享页,所以直接释放物理页也没问题。 858*40fe15e0SLoGin // 但是在实现共享页之后,就不能直接释放物理页了,需要在anon_vma链表长度为0的时候才能释放物理页 859*40fe15e0SLoGin unsafe { deallocate_page_frames(PhysPageFrame::new(paddr), PageFrameCount::new(1)) }; 860*40fe15e0SLoGin 861*40fe15e0SLoGin flusher.consume(flush); 862*40fe15e0SLoGin } 863*40fe15e0SLoGin guard.mapped = false; 864*40fe15e0SLoGin } 865*40fe15e0SLoGin 866*40fe15e0SLoGin pub fn mapped(&self) -> bool { 867*40fe15e0SLoGin return self.0.lock().mapped; 868*40fe15e0SLoGin } 869*40fe15e0SLoGin 870*40fe15e0SLoGin /// 将当前VMA进行切分,切分成3个VMA,分别是: 871*40fe15e0SLoGin /// 872*40fe15e0SLoGin /// 1. 前面的VMA,如果没有则为None 873*40fe15e0SLoGin /// 2. 中间的VMA,也就是传入的Region 874*40fe15e0SLoGin /// 3. 后面的VMA,如果没有则为None 875*40fe15e0SLoGin pub fn extract( 876*40fe15e0SLoGin &self, 877*40fe15e0SLoGin region: VirtRegion, 878*40fe15e0SLoGin ) -> Option<( 879*40fe15e0SLoGin Option<Arc<LockedVMA>>, 880*40fe15e0SLoGin Arc<LockedVMA>, 881*40fe15e0SLoGin Option<Arc<LockedVMA>>, 882*40fe15e0SLoGin )> { 883*40fe15e0SLoGin assert!(region.start().check_aligned(MMArch::PAGE_SIZE)); 884*40fe15e0SLoGin assert!(region.end().check_aligned(MMArch::PAGE_SIZE)); 885*40fe15e0SLoGin 886*40fe15e0SLoGin let mut guard = self.lock(); 887*40fe15e0SLoGin { 888*40fe15e0SLoGin // 如果传入的region不在当前VMA的范围内,则直接返回None 889*40fe15e0SLoGin if unlikely(region.start() < guard.region.start() || region.end() > guard.region.end()) 890*40fe15e0SLoGin { 891*40fe15e0SLoGin return None; 892*40fe15e0SLoGin } 893*40fe15e0SLoGin 894*40fe15e0SLoGin let intersect: Option<VirtRegion> = guard.region.intersect(®ion); 895*40fe15e0SLoGin // 如果当前VMA不包含region,则直接返回None 896*40fe15e0SLoGin if unlikely(intersect.is_none()) { 897*40fe15e0SLoGin return None; 898*40fe15e0SLoGin } 899*40fe15e0SLoGin let intersect: VirtRegion = intersect.unwrap(); 900*40fe15e0SLoGin if unlikely(intersect == guard.region) { 901*40fe15e0SLoGin // 如果当前VMA完全包含region,则直接返回当前VMA 902*40fe15e0SLoGin return Some((None, guard.self_ref.upgrade().unwrap(), None)); 903*40fe15e0SLoGin } 904*40fe15e0SLoGin } 905*40fe15e0SLoGin 906*40fe15e0SLoGin let before: Option<Arc<LockedVMA>> = guard.region.before(®ion).map(|virt_region| { 907*40fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 908*40fe15e0SLoGin vma.region = virt_region; 909*40fe15e0SLoGin 910*40fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 911*40fe15e0SLoGin vma 912*40fe15e0SLoGin }); 913*40fe15e0SLoGin 914*40fe15e0SLoGin let after: Option<Arc<LockedVMA>> = guard.region.after(®ion).map(|virt_region| { 915*40fe15e0SLoGin let mut vma: VMA = unsafe { guard.clone() }; 916*40fe15e0SLoGin vma.region = virt_region; 917*40fe15e0SLoGin 918*40fe15e0SLoGin let vma: Arc<LockedVMA> = LockedVMA::new(vma); 919*40fe15e0SLoGin vma 920*40fe15e0SLoGin }); 921*40fe15e0SLoGin 922*40fe15e0SLoGin guard.region = region; 923*40fe15e0SLoGin 924*40fe15e0SLoGin // TODO: 重新设置before、after这两个VMA里面的物理页的anon_vma 925*40fe15e0SLoGin 926*40fe15e0SLoGin return Some((before, guard.self_ref.upgrade().unwrap(), after)); 927*40fe15e0SLoGin } 928*40fe15e0SLoGin } 929*40fe15e0SLoGin 930*40fe15e0SLoGin /// @brief 虚拟内存区域 931*40fe15e0SLoGin #[derive(Debug)] 932*40fe15e0SLoGin pub struct VMA { 933*40fe15e0SLoGin /// 虚拟内存区域对应的虚拟地址范围 934*40fe15e0SLoGin region: VirtRegion, 935*40fe15e0SLoGin /// VMA内的页帧的标志 936*40fe15e0SLoGin flags: PageFlags<MMArch>, 937*40fe15e0SLoGin /// VMA内的页帧是否已经映射到页表 938*40fe15e0SLoGin mapped: bool, 939*40fe15e0SLoGin /// VMA所属的用户地址空间 940*40fe15e0SLoGin user_address_space: Option<Weak<AddressSpace>>, 941*40fe15e0SLoGin self_ref: Weak<LockedVMA>, 942*40fe15e0SLoGin } 943*40fe15e0SLoGin 944*40fe15e0SLoGin impl core::hash::Hash for VMA { 945*40fe15e0SLoGin fn hash<H: Hasher>(&self, state: &mut H) { 946*40fe15e0SLoGin self.region.hash(state); 947*40fe15e0SLoGin self.flags.hash(state); 948*40fe15e0SLoGin self.mapped.hash(state); 949*40fe15e0SLoGin } 950*40fe15e0SLoGin } 951*40fe15e0SLoGin 952*40fe15e0SLoGin #[allow(dead_code)] 953*40fe15e0SLoGin impl VMA { 954*40fe15e0SLoGin pub fn region(&self) -> &VirtRegion { 955*40fe15e0SLoGin return &self.region; 956*40fe15e0SLoGin } 957*40fe15e0SLoGin 958*40fe15e0SLoGin /// # 拷贝当前VMA的内容 959*40fe15e0SLoGin /// 960*40fe15e0SLoGin /// ### 安全性 961*40fe15e0SLoGin /// 962*40fe15e0SLoGin /// 由于这样操作可能由于错误的拷贝,导致内存泄露、内存重复释放等问题,所以需要小心使用。 963*40fe15e0SLoGin pub unsafe fn clone(&self) -> Self { 964*40fe15e0SLoGin return Self { 965*40fe15e0SLoGin region: self.region, 966*40fe15e0SLoGin flags: self.flags, 967*40fe15e0SLoGin mapped: self.mapped, 968*40fe15e0SLoGin user_address_space: self.user_address_space.clone(), 969*40fe15e0SLoGin self_ref: self.self_ref.clone(), 970*40fe15e0SLoGin }; 971*40fe15e0SLoGin } 972*40fe15e0SLoGin 973*40fe15e0SLoGin #[inline(always)] 974*40fe15e0SLoGin pub fn flags(&self) -> PageFlags<MMArch> { 975*40fe15e0SLoGin return self.flags; 976*40fe15e0SLoGin } 977*40fe15e0SLoGin 978*40fe15e0SLoGin pub fn pages(&self) -> VirtPageFrameIter { 979*40fe15e0SLoGin return VirtPageFrameIter::new( 980*40fe15e0SLoGin VirtPageFrame::new(self.region.start()), 981*40fe15e0SLoGin VirtPageFrame::new(self.region.end()), 982*40fe15e0SLoGin ); 983*40fe15e0SLoGin } 984*40fe15e0SLoGin 985*40fe15e0SLoGin pub fn remap( 986*40fe15e0SLoGin &mut self, 987*40fe15e0SLoGin flags: PageFlags<MMArch>, 988*40fe15e0SLoGin mapper: &mut PageMapper, 989*40fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 990*40fe15e0SLoGin ) -> Result<(), SystemError> { 991*40fe15e0SLoGin assert!(self.mapped); 992*40fe15e0SLoGin for page in self.region.pages() { 993*40fe15e0SLoGin // kdebug!("remap page {:?}", page.virt_address()); 994*40fe15e0SLoGin // 暂时要求所有的页帧都已经映射到页表 995*40fe15e0SLoGin // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了 996*40fe15e0SLoGin let r = unsafe { 997*40fe15e0SLoGin mapper 998*40fe15e0SLoGin .remap(page.virt_address(), flags) 999*40fe15e0SLoGin .expect("Failed to remap, beacuse of some page is not mapped") 1000*40fe15e0SLoGin }; 1001*40fe15e0SLoGin // kdebug!("consume page {:?}", page.virt_address()); 1002*40fe15e0SLoGin flusher.consume(r); 1003*40fe15e0SLoGin // kdebug!("remap page {:?} done", page.virt_address()); 1004*40fe15e0SLoGin } 1005*40fe15e0SLoGin self.flags = flags; 1006*40fe15e0SLoGin return Ok(()); 1007*40fe15e0SLoGin } 1008*40fe15e0SLoGin 1009*40fe15e0SLoGin /// 检查当前VMA是否可以拥有指定的标志位 1010*40fe15e0SLoGin /// 1011*40fe15e0SLoGin /// ## 参数 1012*40fe15e0SLoGin /// 1013*40fe15e0SLoGin /// - `prot_flags` 要检查的标志位 1014*40fe15e0SLoGin pub fn can_have_flags(&self, prot_flags: ProtFlags) -> bool { 1015*40fe15e0SLoGin return (self.flags.has_write() || !prot_flags.contains(ProtFlags::PROT_WRITE)) 1016*40fe15e0SLoGin && (self.flags.has_execute() || !prot_flags.contains(ProtFlags::PROT_EXEC)); 1017*40fe15e0SLoGin } 1018*40fe15e0SLoGin 1019*40fe15e0SLoGin /// 把物理地址映射到虚拟地址 1020*40fe15e0SLoGin /// 1021*40fe15e0SLoGin /// @param phys 要映射的物理地址 1022*40fe15e0SLoGin /// @param destination 要映射到的虚拟地址 1023*40fe15e0SLoGin /// @param count 要映射的页帧数量 1024*40fe15e0SLoGin /// @param flags 页面标志位 1025*40fe15e0SLoGin /// @param mapper 页表映射器 1026*40fe15e0SLoGin /// @param flusher 页表项刷新器 1027*40fe15e0SLoGin /// 1028*40fe15e0SLoGin /// @return 返回映射后的虚拟内存区域 1029*40fe15e0SLoGin pub fn physmap( 1030*40fe15e0SLoGin phys: PhysPageFrame, 1031*40fe15e0SLoGin destination: VirtPageFrame, 1032*40fe15e0SLoGin count: PageFrameCount, 1033*40fe15e0SLoGin flags: PageFlags<MMArch>, 1034*40fe15e0SLoGin mapper: &mut PageMapper, 1035*40fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 1036*40fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 1037*40fe15e0SLoGin { 1038*40fe15e0SLoGin let mut cur_phy = phys; 1039*40fe15e0SLoGin let mut cur_dest = destination; 1040*40fe15e0SLoGin 1041*40fe15e0SLoGin for _ in 0..count.data() { 1042*40fe15e0SLoGin // 将物理页帧映射到虚拟页帧 1043*40fe15e0SLoGin let r = unsafe { 1044*40fe15e0SLoGin mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags) 1045*40fe15e0SLoGin } 1046*40fe15e0SLoGin .expect("Failed to map phys, may be OOM error"); 1047*40fe15e0SLoGin 1048*40fe15e0SLoGin // todo: 增加OOM处理 1049*40fe15e0SLoGin 1050*40fe15e0SLoGin // todo: 将VMA加入到anon_vma中 1051*40fe15e0SLoGin 1052*40fe15e0SLoGin // 刷新TLB 1053*40fe15e0SLoGin flusher.consume(r); 1054*40fe15e0SLoGin 1055*40fe15e0SLoGin cur_phy = cur_phy.next(); 1056*40fe15e0SLoGin cur_dest = cur_dest.next(); 1057*40fe15e0SLoGin } 1058*40fe15e0SLoGin } 1059*40fe15e0SLoGin 1060*40fe15e0SLoGin let r: Arc<LockedVMA> = LockedVMA::new(VMA { 1061*40fe15e0SLoGin region: VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE), 1062*40fe15e0SLoGin flags, 1063*40fe15e0SLoGin mapped: true, 1064*40fe15e0SLoGin user_address_space: None, 1065*40fe15e0SLoGin self_ref: Weak::default(), 1066*40fe15e0SLoGin }); 1067*40fe15e0SLoGin return Ok(r); 1068*40fe15e0SLoGin } 1069*40fe15e0SLoGin 1070*40fe15e0SLoGin /// 从页分配器中分配一些物理页,并把它们映射到指定的虚拟地址,然后创建VMA 1071*40fe15e0SLoGin /// 1072*40fe15e0SLoGin /// @param destination 要映射到的虚拟地址 1073*40fe15e0SLoGin /// @param count 要映射的页帧数量 1074*40fe15e0SLoGin /// @param flags 页面标志位 1075*40fe15e0SLoGin /// @param mapper 页表映射器 1076*40fe15e0SLoGin /// @param flusher 页表项刷新器 1077*40fe15e0SLoGin /// 1078*40fe15e0SLoGin /// @return 返回映射后的虚拟内存区域 1079*40fe15e0SLoGin pub fn zeroed( 1080*40fe15e0SLoGin destination: VirtPageFrame, 1081*40fe15e0SLoGin page_count: PageFrameCount, 1082*40fe15e0SLoGin flags: PageFlags<MMArch>, 1083*40fe15e0SLoGin mapper: &mut PageMapper, 1084*40fe15e0SLoGin mut flusher: impl Flusher<MMArch>, 1085*40fe15e0SLoGin ) -> Result<Arc<LockedVMA>, SystemError> { 1086*40fe15e0SLoGin let mut cur_dest: VirtPageFrame = destination; 1087*40fe15e0SLoGin // kdebug!( 1088*40fe15e0SLoGin // "VMA::zeroed: page_count = {:?}, destination={destination:?}", 1089*40fe15e0SLoGin // page_count 1090*40fe15e0SLoGin // ); 1091*40fe15e0SLoGin for _ in 0..page_count.data() { 1092*40fe15e0SLoGin // kdebug!( 1093*40fe15e0SLoGin // "VMA::zeroed: cur_dest={cur_dest:?}, vaddr = {:?}", 1094*40fe15e0SLoGin // cur_dest.virt_address() 1095*40fe15e0SLoGin // ); 1096*40fe15e0SLoGin let r = unsafe { mapper.map(cur_dest.virt_address(), flags) } 1097*40fe15e0SLoGin .expect("Failed to map zero, may be OOM error"); 1098*40fe15e0SLoGin // todo: 将VMA加入到anon_vma中 1099*40fe15e0SLoGin // todo: 增加OOM处理 1100*40fe15e0SLoGin 1101*40fe15e0SLoGin // 稍后再刷新TLB,这里取消刷新 1102*40fe15e0SLoGin flusher.consume(r); 1103*40fe15e0SLoGin cur_dest = cur_dest.next(); 1104*40fe15e0SLoGin } 1105*40fe15e0SLoGin let r = LockedVMA::new(VMA { 1106*40fe15e0SLoGin region: VirtRegion::new( 1107*40fe15e0SLoGin destination.virt_address(), 1108*40fe15e0SLoGin page_count.data() * MMArch::PAGE_SIZE, 1109*40fe15e0SLoGin ), 1110*40fe15e0SLoGin flags, 1111*40fe15e0SLoGin mapped: true, 1112*40fe15e0SLoGin user_address_space: None, 1113*40fe15e0SLoGin self_ref: Weak::default(), 1114*40fe15e0SLoGin }); 1115*40fe15e0SLoGin drop(flusher); 1116*40fe15e0SLoGin // kdebug!("VMA::zeroed: flusher dropped"); 1117*40fe15e0SLoGin 1118*40fe15e0SLoGin // 清空这些内存 1119*40fe15e0SLoGin let virt_iter = VirtPageFrameIter::new(destination, destination.add(page_count)); 1120*40fe15e0SLoGin for frame in virt_iter { 1121*40fe15e0SLoGin let paddr = mapper.translate(frame.virt_address()).unwrap().0; 1122*40fe15e0SLoGin 1123*40fe15e0SLoGin unsafe { 1124*40fe15e0SLoGin let vaddr = MMArch::phys_2_virt(paddr).unwrap(); 1125*40fe15e0SLoGin MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE); 1126*40fe15e0SLoGin } 1127*40fe15e0SLoGin } 1128*40fe15e0SLoGin // kdebug!("VMA::zeroed: done"); 1129*40fe15e0SLoGin return Ok(r); 1130*40fe15e0SLoGin } 1131*40fe15e0SLoGin } 1132*40fe15e0SLoGin 1133*40fe15e0SLoGin impl Drop for VMA { 1134*40fe15e0SLoGin fn drop(&mut self) { 1135*40fe15e0SLoGin // 当VMA被释放时,需要确保它已经被从页表中解除映射 1136*40fe15e0SLoGin assert!(!self.mapped, "VMA is still mapped"); 1137*40fe15e0SLoGin } 1138*40fe15e0SLoGin } 1139*40fe15e0SLoGin 1140*40fe15e0SLoGin impl PartialEq for VMA { 1141*40fe15e0SLoGin fn eq(&self, other: &Self) -> bool { 1142*40fe15e0SLoGin return self.region == other.region; 1143*40fe15e0SLoGin } 1144*40fe15e0SLoGin } 1145*40fe15e0SLoGin 1146*40fe15e0SLoGin impl Eq for VMA {} 1147*40fe15e0SLoGin 1148*40fe15e0SLoGin impl PartialOrd for VMA { 1149*40fe15e0SLoGin fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { 1150*40fe15e0SLoGin return self.region.partial_cmp(&other.region); 1151*40fe15e0SLoGin } 1152*40fe15e0SLoGin } 1153*40fe15e0SLoGin 1154*40fe15e0SLoGin impl Ord for VMA { 1155*40fe15e0SLoGin fn cmp(&self, other: &Self) -> cmp::Ordering { 1156*40fe15e0SLoGin return self.region.cmp(&other.region); 1157*40fe15e0SLoGin } 1158*40fe15e0SLoGin } 1159*40fe15e0SLoGin 1160*40fe15e0SLoGin #[derive(Debug)] 1161*40fe15e0SLoGin pub struct UserStack { 1162*40fe15e0SLoGin // 栈底地址 1163*40fe15e0SLoGin stack_bottom: VirtAddr, 1164*40fe15e0SLoGin // 当前已映射的大小 1165*40fe15e0SLoGin mapped_size: usize, 1166*40fe15e0SLoGin /// 栈顶地址(这个值需要仔细确定!因为它可能不会实时与用户栈的真实栈顶保持一致!要小心!) 1167*40fe15e0SLoGin current_sp: VirtAddr, 1168*40fe15e0SLoGin } 1169*40fe15e0SLoGin 1170*40fe15e0SLoGin impl UserStack { 1171*40fe15e0SLoGin /// 默认的用户栈底地址 1172*40fe15e0SLoGin pub const DEFAULT_USER_STACK_BOTTOM: VirtAddr = MMArch::USER_STACK_START; 1173*40fe15e0SLoGin /// 默认的用户栈大小为8MB 1174*40fe15e0SLoGin pub const DEFAULT_USER_STACK_SIZE: usize = 8 * 1024 * 1024; 1175*40fe15e0SLoGin /// 用户栈的保护页数量 1176*40fe15e0SLoGin pub const GUARD_PAGES_NUM: usize = 4; 1177*40fe15e0SLoGin 1178*40fe15e0SLoGin /// 创建一个用户栈 1179*40fe15e0SLoGin pub fn new( 1180*40fe15e0SLoGin vm: &mut InnerAddressSpace, 1181*40fe15e0SLoGin stack_bottom: Option<VirtAddr>, 1182*40fe15e0SLoGin stack_size: usize, 1183*40fe15e0SLoGin ) -> Result<Self, SystemError> { 1184*40fe15e0SLoGin let stack_bottom = stack_bottom.unwrap_or(Self::DEFAULT_USER_STACK_BOTTOM); 1185*40fe15e0SLoGin assert!(stack_bottom.check_aligned(MMArch::PAGE_SIZE)); 1186*40fe15e0SLoGin 1187*40fe15e0SLoGin // 分配用户栈的保护页 1188*40fe15e0SLoGin let guard_size = Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 1189*40fe15e0SLoGin let actual_stack_bottom = stack_bottom - guard_size; 1190*40fe15e0SLoGin 1191*40fe15e0SLoGin let mut prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE; 1192*40fe15e0SLoGin let map_flags = 1193*40fe15e0SLoGin MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED_NOREPLACE; 1194*40fe15e0SLoGin // kdebug!( 1195*40fe15e0SLoGin // "map anonymous stack: {:?} {}", 1196*40fe15e0SLoGin // actual_stack_bottom, 1197*40fe15e0SLoGin // guard_size 1198*40fe15e0SLoGin // ); 1199*40fe15e0SLoGin vm.map_anonymous( 1200*40fe15e0SLoGin actual_stack_bottom, 1201*40fe15e0SLoGin guard_size, 1202*40fe15e0SLoGin prot_flags, 1203*40fe15e0SLoGin map_flags, 1204*40fe15e0SLoGin false, 1205*40fe15e0SLoGin )?; 1206*40fe15e0SLoGin // test_buddy(); 1207*40fe15e0SLoGin // 设置保护页只读 1208*40fe15e0SLoGin prot_flags.remove(ProtFlags::PROT_WRITE); 1209*40fe15e0SLoGin // kdebug!( 1210*40fe15e0SLoGin // "to mprotect stack guard pages: {:?} {}", 1211*40fe15e0SLoGin // actual_stack_bottom, 1212*40fe15e0SLoGin // guard_size 1213*40fe15e0SLoGin // ); 1214*40fe15e0SLoGin vm.mprotect( 1215*40fe15e0SLoGin VirtPageFrame::new(actual_stack_bottom), 1216*40fe15e0SLoGin PageFrameCount::new(Self::GUARD_PAGES_NUM), 1217*40fe15e0SLoGin prot_flags, 1218*40fe15e0SLoGin )?; 1219*40fe15e0SLoGin 1220*40fe15e0SLoGin // kdebug!( 1221*40fe15e0SLoGin // "mprotect stack guard pages done: {:?} {}", 1222*40fe15e0SLoGin // actual_stack_bottom, 1223*40fe15e0SLoGin // guard_size 1224*40fe15e0SLoGin // ); 1225*40fe15e0SLoGin 1226*40fe15e0SLoGin let mut user_stack = UserStack { 1227*40fe15e0SLoGin stack_bottom: actual_stack_bottom, 1228*40fe15e0SLoGin mapped_size: guard_size, 1229*40fe15e0SLoGin current_sp: actual_stack_bottom - guard_size, 1230*40fe15e0SLoGin }; 1231*40fe15e0SLoGin 1232*40fe15e0SLoGin // kdebug!("extend user stack: {:?} {}", stack_bottom, stack_size); 1233*40fe15e0SLoGin // 分配用户栈 1234*40fe15e0SLoGin user_stack.initial_extend(vm, stack_size)?; 1235*40fe15e0SLoGin // kdebug!("user stack created: {:?} {}", stack_bottom, stack_size); 1236*40fe15e0SLoGin return Ok(user_stack); 1237*40fe15e0SLoGin } 1238*40fe15e0SLoGin 1239*40fe15e0SLoGin fn initial_extend( 1240*40fe15e0SLoGin &mut self, 1241*40fe15e0SLoGin vm: &mut InnerAddressSpace, 1242*40fe15e0SLoGin mut bytes: usize, 1243*40fe15e0SLoGin ) -> Result<(), SystemError> { 1244*40fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 1245*40fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS; 1246*40fe15e0SLoGin 1247*40fe15e0SLoGin bytes = page_align_up(bytes); 1248*40fe15e0SLoGin self.mapped_size += bytes; 1249*40fe15e0SLoGin 1250*40fe15e0SLoGin vm.map_anonymous( 1251*40fe15e0SLoGin self.stack_bottom - self.mapped_size, 1252*40fe15e0SLoGin bytes, 1253*40fe15e0SLoGin prot_flags, 1254*40fe15e0SLoGin map_flags, 1255*40fe15e0SLoGin false, 1256*40fe15e0SLoGin )?; 1257*40fe15e0SLoGin 1258*40fe15e0SLoGin return Ok(()); 1259*40fe15e0SLoGin } 1260*40fe15e0SLoGin 1261*40fe15e0SLoGin /// 扩展用户栈 1262*40fe15e0SLoGin /// 1263*40fe15e0SLoGin /// ## 参数 1264*40fe15e0SLoGin /// 1265*40fe15e0SLoGin /// - `vm` 用户地址空间结构体 1266*40fe15e0SLoGin /// - `bytes` 要扩展的字节数 1267*40fe15e0SLoGin /// 1268*40fe15e0SLoGin /// ## 返回值 1269*40fe15e0SLoGin /// 1270*40fe15e0SLoGin /// - **Ok(())** 扩展成功 1271*40fe15e0SLoGin /// - **Err(SystemError)** 扩展失败 1272*40fe15e0SLoGin #[allow(dead_code)] 1273*40fe15e0SLoGin pub fn extend( 1274*40fe15e0SLoGin &mut self, 1275*40fe15e0SLoGin vm: &mut RwLockWriteGuard<InnerAddressSpace>, 1276*40fe15e0SLoGin mut bytes: usize, 1277*40fe15e0SLoGin ) -> Result<(), SystemError> { 1278*40fe15e0SLoGin let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC; 1279*40fe15e0SLoGin let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS; 1280*40fe15e0SLoGin 1281*40fe15e0SLoGin bytes = page_align_up(bytes); 1282*40fe15e0SLoGin self.mapped_size += bytes; 1283*40fe15e0SLoGin 1284*40fe15e0SLoGin vm.map_anonymous( 1285*40fe15e0SLoGin self.stack_bottom - self.mapped_size, 1286*40fe15e0SLoGin bytes, 1287*40fe15e0SLoGin prot_flags, 1288*40fe15e0SLoGin map_flags, 1289*40fe15e0SLoGin false, 1290*40fe15e0SLoGin )?; 1291*40fe15e0SLoGin 1292*40fe15e0SLoGin return Ok(()); 1293*40fe15e0SLoGin } 1294*40fe15e0SLoGin 1295*40fe15e0SLoGin /// 获取栈顶地址 1296*40fe15e0SLoGin /// 1297*40fe15e0SLoGin /// 请注意,如果用户栈的栈顶地址发生变化,这个值可能不会实时更新! 1298*40fe15e0SLoGin pub fn sp(&self) -> VirtAddr { 1299*40fe15e0SLoGin return self.current_sp; 1300*40fe15e0SLoGin } 1301*40fe15e0SLoGin 1302*40fe15e0SLoGin pub unsafe fn set_sp(&mut self, sp: VirtAddr) { 1303*40fe15e0SLoGin self.current_sp = sp; 1304*40fe15e0SLoGin } 1305*40fe15e0SLoGin 1306*40fe15e0SLoGin /// 仅仅克隆用户栈的信息,不会克隆用户栈的内容/映射 1307*40fe15e0SLoGin pub unsafe fn clone_info_only(&self) -> Self { 1308*40fe15e0SLoGin return Self { 1309*40fe15e0SLoGin stack_bottom: self.stack_bottom, 1310*40fe15e0SLoGin mapped_size: self.mapped_size, 1311*40fe15e0SLoGin current_sp: self.current_sp, 1312*40fe15e0SLoGin }; 1313*40fe15e0SLoGin } 1314*40fe15e0SLoGin 1315*40fe15e0SLoGin /// 获取当前用户栈的大小(不包括保护页) 1316*40fe15e0SLoGin pub fn stack_size(&self) -> usize { 1317*40fe15e0SLoGin return self.mapped_size - Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE; 1318*40fe15e0SLoGin } 1319*40fe15e0SLoGin } 1320