xref: /DragonOS/kernel/src/mm/ucontext.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
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;
17*91e9d4abSLoGin use system_error::SystemError;
1840fe15e0SLoGin 
1940fe15e0SLoGin use crate::{
201496ba7bSLoGin     arch::{mm::PageMapper, CurrentIrqArch, MMArch},
2140fe15e0SLoGin     exception::InterruptArch,
2240fe15e0SLoGin     libs::{
2340fe15e0SLoGin         align::page_align_up,
2440fe15e0SLoGin         rwlock::{RwLock, RwLockWriteGuard},
2540fe15e0SLoGin         spinlock::{SpinLock, SpinLockGuard},
2640fe15e0SLoGin     },
271496ba7bSLoGin     process::ProcessManager,
2840fe15e0SLoGin };
2940fe15e0SLoGin 
3040fe15e0SLoGin use super::{
3140fe15e0SLoGin     allocator::page_frame::{
3240fe15e0SLoGin         deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter,
3340fe15e0SLoGin     },
3440fe15e0SLoGin     page::{Flusher, InactiveFlusher, PageFlags, PageFlushAll},
3540fe15e0SLoGin     syscall::{MapFlags, ProtFlags},
3640fe15e0SLoGin     MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion,
3740fe15e0SLoGin };
3840fe15e0SLoGin 
3940fe15e0SLoGin /// MMAP_MIN_ADDR的默认值
4040fe15e0SLoGin /// 以下内容来自linux-5.19:
4140fe15e0SLoGin ///  This is the portion of low virtual memory which should be protected
4240fe15e0SLoGin //   from userspace allocation.  Keeping a user from writing to low pages
4340fe15e0SLoGin //   can help reduce the impact of kernel NULL pointer bugs.
4440fe15e0SLoGin //   For most ia64, ppc64 and x86 users with lots of address space
4540fe15e0SLoGin //   a value of 65536 is reasonable and should cause no problems.
4640fe15e0SLoGin //   On arm and other archs it should not be higher than 32768.
4740fe15e0SLoGin //   Programs which use vm86 functionality or have some need to map
4840fe15e0SLoGin //   this low address space will need CAP_SYS_RAWIO or disable this
4940fe15e0SLoGin //   protection by setting the value to 0.
5040fe15e0SLoGin pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536;
5140fe15e0SLoGin 
5240fe15e0SLoGin #[derive(Debug)]
5340fe15e0SLoGin pub struct AddressSpace {
5440fe15e0SLoGin     inner: RwLock<InnerAddressSpace>,
5540fe15e0SLoGin }
5640fe15e0SLoGin 
5740fe15e0SLoGin impl AddressSpace {
5840fe15e0SLoGin     pub fn new(create_stack: bool) -> Result<Arc<Self>, SystemError> {
5940fe15e0SLoGin         let inner = InnerAddressSpace::new(create_stack)?;
6040fe15e0SLoGin         let result = Self {
6140fe15e0SLoGin             inner: RwLock::new(inner),
6240fe15e0SLoGin         };
6340fe15e0SLoGin         return Ok(Arc::new(result));
6440fe15e0SLoGin     }
6540fe15e0SLoGin 
6640fe15e0SLoGin     /// 从pcb中获取当前进程的地址空间结构体的Arc指针
6740fe15e0SLoGin     pub fn current() -> Result<Arc<AddressSpace>, SystemError> {
681496ba7bSLoGin         let vm = ProcessManager::current_pcb()
691496ba7bSLoGin             .basic()
701496ba7bSLoGin             .user_vm()
7140fe15e0SLoGin             .expect("Current process has no address space");
721496ba7bSLoGin 
731496ba7bSLoGin         return Ok(vm);
7440fe15e0SLoGin     }
7540fe15e0SLoGin 
7640fe15e0SLoGin     /// 判断某个地址空间是否为当前进程的地址空间
7740fe15e0SLoGin     pub fn is_current(self: &Arc<Self>) -> bool {
7840fe15e0SLoGin         let current = Self::current();
7940fe15e0SLoGin         if let Ok(current) = current {
8040fe15e0SLoGin             return Arc::ptr_eq(&current, self);
8140fe15e0SLoGin         }
8240fe15e0SLoGin         return false;
8340fe15e0SLoGin     }
8440fe15e0SLoGin }
8540fe15e0SLoGin 
8640fe15e0SLoGin impl core::ops::Deref for AddressSpace {
8740fe15e0SLoGin     type Target = RwLock<InnerAddressSpace>;
8840fe15e0SLoGin 
8940fe15e0SLoGin     fn deref(&self) -> &Self::Target {
9040fe15e0SLoGin         &self.inner
9140fe15e0SLoGin     }
9240fe15e0SLoGin }
9340fe15e0SLoGin 
9440fe15e0SLoGin impl core::ops::DerefMut for AddressSpace {
9540fe15e0SLoGin     fn deref_mut(&mut self) -> &mut Self::Target {
9640fe15e0SLoGin         &mut self.inner
9740fe15e0SLoGin     }
9840fe15e0SLoGin }
9940fe15e0SLoGin 
10040fe15e0SLoGin /// @brief 用户地址空间结构体(每个进程都有一个)
10140fe15e0SLoGin #[derive(Debug)]
10240fe15e0SLoGin pub struct InnerAddressSpace {
10340fe15e0SLoGin     pub user_mapper: UserMapper,
10440fe15e0SLoGin     pub mappings: UserMappings,
10540fe15e0SLoGin     pub mmap_min: VirtAddr,
10640fe15e0SLoGin     /// 用户栈信息结构体
10740fe15e0SLoGin     pub user_stack: Option<UserStack>,
10840fe15e0SLoGin 
10940fe15e0SLoGin     pub elf_brk_start: VirtAddr,
11040fe15e0SLoGin     pub elf_brk: VirtAddr,
11140fe15e0SLoGin 
11240fe15e0SLoGin     /// 当前进程的堆空间的起始地址
11340fe15e0SLoGin     pub brk_start: VirtAddr,
11440fe15e0SLoGin     /// 当前进程的堆空间的结束地址(不包含)
11540fe15e0SLoGin     pub brk: VirtAddr,
11640fe15e0SLoGin 
11740fe15e0SLoGin     pub start_code: VirtAddr,
11840fe15e0SLoGin     pub end_code: VirtAddr,
11940fe15e0SLoGin     pub start_data: VirtAddr,
12040fe15e0SLoGin     pub end_data: VirtAddr,
12140fe15e0SLoGin }
12240fe15e0SLoGin 
12340fe15e0SLoGin impl InnerAddressSpace {
12440fe15e0SLoGin     pub fn new(create_stack: bool) -> Result<Self, SystemError> {
12540fe15e0SLoGin         let mut result = Self {
12640fe15e0SLoGin             user_mapper: MMArch::setup_new_usermapper()?,
12740fe15e0SLoGin             mappings: UserMappings::new(),
12840fe15e0SLoGin             mmap_min: VirtAddr(DEFAULT_MMAP_MIN_ADDR),
12940fe15e0SLoGin             elf_brk_start: VirtAddr::new(0),
13040fe15e0SLoGin             elf_brk: VirtAddr::new(0),
13140fe15e0SLoGin             brk_start: MMArch::USER_BRK_START,
13240fe15e0SLoGin             brk: MMArch::USER_BRK_START,
13340fe15e0SLoGin             user_stack: None,
13440fe15e0SLoGin             start_code: VirtAddr(0),
13540fe15e0SLoGin             end_code: VirtAddr(0),
13640fe15e0SLoGin             start_data: VirtAddr(0),
13740fe15e0SLoGin             end_data: VirtAddr(0),
13840fe15e0SLoGin         };
13940fe15e0SLoGin         if create_stack {
14040fe15e0SLoGin             // kdebug!("to create user stack.");
14140fe15e0SLoGin             result.new_user_stack(UserStack::DEFAULT_USER_STACK_SIZE)?;
14240fe15e0SLoGin         }
14340fe15e0SLoGin 
14440fe15e0SLoGin         return Ok(result);
14540fe15e0SLoGin     }
14640fe15e0SLoGin 
14740fe15e0SLoGin     /// 尝试克隆当前进程的地址空间,包括这些映射都会被克隆
14840fe15e0SLoGin     ///
14940fe15e0SLoGin     /// # Returns
15040fe15e0SLoGin     ///
15140fe15e0SLoGin     /// 返回克隆后的,新的地址空间的Arc指针
1524fda81ceSLoGin     #[inline(never)]
15340fe15e0SLoGin     pub fn try_clone(&mut self) -> Result<Arc<AddressSpace>, SystemError> {
15440fe15e0SLoGin         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
15540fe15e0SLoGin         let new_addr_space = AddressSpace::new(false)?;
15640fe15e0SLoGin         let mut new_guard = new_addr_space.write();
15740fe15e0SLoGin 
15840fe15e0SLoGin         // 拷贝用户栈的结构体信息,但是不拷贝用户栈的内容(因为后面VMA的拷贝会拷贝用户栈的内容)
15940fe15e0SLoGin         unsafe {
16040fe15e0SLoGin             new_guard.user_stack = Some(self.user_stack.as_ref().unwrap().clone_info_only());
16140fe15e0SLoGin         }
16240fe15e0SLoGin         let _current_stack_size = self.user_stack.as_ref().unwrap().stack_size();
16340fe15e0SLoGin 
16440fe15e0SLoGin         let current_mapper = &mut self.user_mapper.utable;
16540fe15e0SLoGin 
166ea8ad4d4SLoGin         // 拷贝空洞
167ea8ad4d4SLoGin         new_guard.mappings.vm_holes = self.mappings.vm_holes.clone();
168ea8ad4d4SLoGin 
16940fe15e0SLoGin         for vma in self.mappings.vmas.iter() {
17040fe15e0SLoGin             // TODO: 增加对VMA是否为文件映射的判断,如果是的话,就跳过
17140fe15e0SLoGin 
17240fe15e0SLoGin             let vma_guard: SpinLockGuard<'_, VMA> = vma.lock();
17340fe15e0SLoGin             let old_flags = vma_guard.flags();
17440fe15e0SLoGin             let tmp_flags: PageFlags<MMArch> = PageFlags::new().set_write(true);
17540fe15e0SLoGin 
17640fe15e0SLoGin             // 分配内存页并创建新的VMA
17740fe15e0SLoGin             let new_vma = VMA::zeroed(
17840fe15e0SLoGin                 VirtPageFrame::new(vma_guard.region.start()),
17940fe15e0SLoGin                 PageFrameCount::new(vma_guard.region.size() / MMArch::PAGE_SIZE),
18040fe15e0SLoGin                 tmp_flags,
18140fe15e0SLoGin                 &mut new_guard.user_mapper.utable,
18240fe15e0SLoGin                 (),
18340fe15e0SLoGin             )?;
18440fe15e0SLoGin             new_guard.mappings.vmas.insert(new_vma.clone());
18540fe15e0SLoGin             // kdebug!("new vma: {:x?}", new_vma);
18640fe15e0SLoGin             let mut new_vma_guard = new_vma.lock();
18740fe15e0SLoGin             for page in new_vma_guard.pages().map(|p| p.virt_address()) {
18840fe15e0SLoGin                 // kdebug!("page: {:x?}", page);
18940fe15e0SLoGin                 let current_frame = unsafe {
19040fe15e0SLoGin                     MMArch::phys_2_virt(
19140fe15e0SLoGin                         current_mapper
19240fe15e0SLoGin                             .translate(page)
19340fe15e0SLoGin                             .expect("VMA page not mapped")
19440fe15e0SLoGin                             .0,
19540fe15e0SLoGin                     )
19640fe15e0SLoGin                 }
19740fe15e0SLoGin                 .expect("Phys2Virt: vaddr overflow.")
19840fe15e0SLoGin                 .data() as *mut u8;
19940fe15e0SLoGin 
20040fe15e0SLoGin                 let new_frame = unsafe {
20140fe15e0SLoGin                     MMArch::phys_2_virt(
20240fe15e0SLoGin                         new_guard
20340fe15e0SLoGin                             .user_mapper
20440fe15e0SLoGin                             .utable
20540fe15e0SLoGin                             .translate(page)
20640fe15e0SLoGin                             .expect("VMA page not mapped")
20740fe15e0SLoGin                             .0,
20840fe15e0SLoGin                     )
20940fe15e0SLoGin                 }
21040fe15e0SLoGin                 .expect("Phys2Virt: vaddr overflow.")
21140fe15e0SLoGin                 .data() as *mut u8;
21240fe15e0SLoGin 
21340fe15e0SLoGin                 unsafe {
21440fe15e0SLoGin                     // 拷贝数据
21540fe15e0SLoGin                     new_frame.copy_from_nonoverlapping(current_frame, MMArch::PAGE_SIZE);
21640fe15e0SLoGin                 }
21740fe15e0SLoGin             }
21840fe15e0SLoGin             drop(vma_guard);
21940fe15e0SLoGin 
22040fe15e0SLoGin             new_vma_guard.remap(old_flags, &mut new_guard.user_mapper.utable, ())?;
22140fe15e0SLoGin             drop(new_vma_guard);
22240fe15e0SLoGin         }
22340fe15e0SLoGin         drop(new_guard);
22440fe15e0SLoGin         drop(irq_guard);
22540fe15e0SLoGin         return Ok(new_addr_space);
22640fe15e0SLoGin     }
22740fe15e0SLoGin 
22840fe15e0SLoGin     /// 判断当前的地址空间是否是当前进程的地址空间
22940fe15e0SLoGin     #[inline]
23040fe15e0SLoGin     pub fn is_current(&self) -> bool {
23140fe15e0SLoGin         return self.user_mapper.utable.is_current();
23240fe15e0SLoGin     }
23340fe15e0SLoGin 
23440fe15e0SLoGin     /// 进行匿名页映射
23540fe15e0SLoGin     ///
23640fe15e0SLoGin     /// ## 参数
23740fe15e0SLoGin     ///
23840fe15e0SLoGin     /// - `start_vaddr`:映射的起始地址
23940fe15e0SLoGin     /// - `len`:映射的长度
24040fe15e0SLoGin     /// - `prot_flags`:保护标志
24140fe15e0SLoGin     /// - `map_flags`:映射标志
24240fe15e0SLoGin     /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界
2431496ba7bSLoGin     ///
2441496ba7bSLoGin     /// ## 返回
2451496ba7bSLoGin     ///
2461496ba7bSLoGin     /// 返回映射的起始虚拟页帧
24740fe15e0SLoGin     pub fn map_anonymous(
24840fe15e0SLoGin         &mut self,
24940fe15e0SLoGin         start_vaddr: VirtAddr,
25040fe15e0SLoGin         len: usize,
25140fe15e0SLoGin         prot_flags: ProtFlags,
25240fe15e0SLoGin         map_flags: MapFlags,
25340fe15e0SLoGin         round_to_min: bool,
25440fe15e0SLoGin     ) -> Result<VirtPageFrame, SystemError> {
25540fe15e0SLoGin         // 用于对齐hint的函数
25640fe15e0SLoGin         let round_hint_to_min = |hint: VirtAddr| {
25740fe15e0SLoGin             // 先把hint向下对齐到页边界
25840fe15e0SLoGin             let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK);
25940fe15e0SLoGin             // kdebug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint);
26040fe15e0SLoGin             // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR
26140fe15e0SLoGin             if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) {
26240fe15e0SLoGin                 Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR)))
26340fe15e0SLoGin             } else if addr == 0 {
26440fe15e0SLoGin                 None
26540fe15e0SLoGin             } else {
26640fe15e0SLoGin                 Some(VirtAddr::new(addr))
26740fe15e0SLoGin             }
26840fe15e0SLoGin         };
26940fe15e0SLoGin         // kdebug!("map_anonymous: start_vaddr = {:?}", start_vaddr);
27040fe15e0SLoGin         // kdebug!("map_anonymous: len(no align) = {}", len);
27140fe15e0SLoGin 
27240fe15e0SLoGin         let len = page_align_up(len);
27340fe15e0SLoGin 
27440fe15e0SLoGin         // kdebug!("map_anonymous: len = {}", len);
27540fe15e0SLoGin 
27640fe15e0SLoGin         let start_page: VirtPageFrame = self.mmap(
27740fe15e0SLoGin             round_hint_to_min(start_vaddr),
27840fe15e0SLoGin             PageFrameCount::from_bytes(len).unwrap(),
27940fe15e0SLoGin             prot_flags,
28040fe15e0SLoGin             map_flags,
28140fe15e0SLoGin             move |page, count, flags, mapper, flusher| {
28240fe15e0SLoGin                 Ok(VMA::zeroed(page, count, flags, mapper, flusher)?)
28340fe15e0SLoGin             },
28440fe15e0SLoGin         )?;
28540fe15e0SLoGin 
28640fe15e0SLoGin         return Ok(start_page);
28740fe15e0SLoGin     }
28840fe15e0SLoGin 
28940fe15e0SLoGin     /// 向进程的地址空间映射页面
29040fe15e0SLoGin     ///
29140fe15e0SLoGin     /// # 参数
29240fe15e0SLoGin     ///
29340fe15e0SLoGin     /// - `addr`:映射的起始地址,如果为`None`,则由内核自动分配
29440fe15e0SLoGin     /// - `page_count`:映射的页面数量
29540fe15e0SLoGin     /// - `prot_flags`:保护标志
29640fe15e0SLoGin     /// - `map_flags`:映射标志
29740fe15e0SLoGin     /// - `map_func`:映射函数,用于创建VMA
29840fe15e0SLoGin     ///
29940fe15e0SLoGin     /// # Returns
30040fe15e0SLoGin     ///
30140fe15e0SLoGin     /// 返回映射的起始虚拟页帧
30240fe15e0SLoGin     ///
30340fe15e0SLoGin     /// # Errors
30440fe15e0SLoGin     ///
30540fe15e0SLoGin     /// - `EINVAL`:参数错误
30640fe15e0SLoGin     pub fn mmap<
30740fe15e0SLoGin         F: FnOnce(
30840fe15e0SLoGin             VirtPageFrame,
30940fe15e0SLoGin             PageFrameCount,
31040fe15e0SLoGin             PageFlags<MMArch>,
31140fe15e0SLoGin             &mut PageMapper,
31240fe15e0SLoGin             &mut dyn Flusher<MMArch>,
31340fe15e0SLoGin         ) -> Result<Arc<LockedVMA>, SystemError>,
31440fe15e0SLoGin     >(
31540fe15e0SLoGin         &mut self,
31640fe15e0SLoGin         addr: Option<VirtAddr>,
31740fe15e0SLoGin         page_count: PageFrameCount,
31840fe15e0SLoGin         prot_flags: ProtFlags,
31940fe15e0SLoGin         map_flags: MapFlags,
32040fe15e0SLoGin         map_func: F,
32140fe15e0SLoGin     ) -> Result<VirtPageFrame, SystemError> {
32240fe15e0SLoGin         if page_count == PageFrameCount::new(0) {
32340fe15e0SLoGin             return Err(SystemError::EINVAL);
32440fe15e0SLoGin         }
32540fe15e0SLoGin         // kdebug!("mmap: addr: {addr:?}, page_count: {page_count:?}, prot_flags: {prot_flags:?}, map_flags: {map_flags:?}");
32640fe15e0SLoGin 
32740fe15e0SLoGin         // 找到未使用的区域
32840fe15e0SLoGin         let region = match addr {
32940fe15e0SLoGin             Some(vaddr) => {
33040fe15e0SLoGin                 self.mappings
33140fe15e0SLoGin                     .find_free_at(self.mmap_min, vaddr, page_count.bytes(), map_flags)?
33240fe15e0SLoGin             }
33340fe15e0SLoGin             None => self
33440fe15e0SLoGin                 .mappings
33540fe15e0SLoGin                 .find_free(self.mmap_min, page_count.bytes())
33640fe15e0SLoGin                 .ok_or(SystemError::ENOMEM)?,
33740fe15e0SLoGin         };
33840fe15e0SLoGin 
33940fe15e0SLoGin         let page = VirtPageFrame::new(region.start());
34040fe15e0SLoGin 
34140fe15e0SLoGin         // kdebug!("mmap: page: {:?}, region={region:?}", page.virt_address());
34240fe15e0SLoGin 
34340fe15e0SLoGin         compiler_fence(Ordering::SeqCst);
34440fe15e0SLoGin         let (mut active, mut inactive);
34540fe15e0SLoGin         let flusher = if self.is_current() {
34640fe15e0SLoGin             active = PageFlushAll::new();
34740fe15e0SLoGin             &mut active as &mut dyn Flusher<MMArch>
34840fe15e0SLoGin         } else {
34940fe15e0SLoGin             inactive = InactiveFlusher::new();
35040fe15e0SLoGin             &mut inactive as &mut dyn Flusher<MMArch>
35140fe15e0SLoGin         };
35240fe15e0SLoGin         compiler_fence(Ordering::SeqCst);
35340fe15e0SLoGin         // 映射页面,并将VMA插入到地址空间的VMA列表中
35440fe15e0SLoGin         self.mappings.insert_vma(map_func(
35540fe15e0SLoGin             page,
35640fe15e0SLoGin             page_count,
35740fe15e0SLoGin             PageFlags::from_prot_flags(prot_flags, true),
35840fe15e0SLoGin             &mut self.user_mapper.utable,
35940fe15e0SLoGin             flusher,
36040fe15e0SLoGin         )?);
36140fe15e0SLoGin 
36240fe15e0SLoGin         return Ok(page);
36340fe15e0SLoGin     }
36440fe15e0SLoGin 
36540fe15e0SLoGin     /// 取消进程的地址空间中的映射
36640fe15e0SLoGin     ///
36740fe15e0SLoGin     /// # 参数
36840fe15e0SLoGin     ///
36940fe15e0SLoGin     /// - `start_page`:起始页帧
37040fe15e0SLoGin     /// - `page_count`:取消映射的页帧数量
37140fe15e0SLoGin     ///
37240fe15e0SLoGin     /// # Errors
37340fe15e0SLoGin     ///
37440fe15e0SLoGin     /// - `EINVAL`:参数错误
37540fe15e0SLoGin     /// - `ENOMEM`:内存不足
37640fe15e0SLoGin     pub fn munmap(
37740fe15e0SLoGin         &mut self,
37840fe15e0SLoGin         start_page: VirtPageFrame,
37940fe15e0SLoGin         page_count: PageFrameCount,
38040fe15e0SLoGin     ) -> Result<(), SystemError> {
38140fe15e0SLoGin         let to_unmap = VirtRegion::new(start_page.virt_address(), page_count.bytes());
38240fe15e0SLoGin         let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new();
38340fe15e0SLoGin 
38440fe15e0SLoGin         let regions: Vec<Arc<LockedVMA>> = self.mappings.conflicts(to_unmap).collect::<Vec<_>>();
38540fe15e0SLoGin 
38640fe15e0SLoGin         for r in regions {
38740fe15e0SLoGin             let r = r.lock().region;
38840fe15e0SLoGin             let r = self.mappings.remove_vma(&r).unwrap();
38940fe15e0SLoGin             let intersection = r.lock().region().intersect(&to_unmap).unwrap();
39040fe15e0SLoGin             let (before, r, after) = r.extract(intersection).unwrap();
39140fe15e0SLoGin 
39240fe15e0SLoGin             // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑
39340fe15e0SLoGin 
39440fe15e0SLoGin             if let Some(before) = before {
39540fe15e0SLoGin                 // 如果前面有VMA,则需要将前面的VMA重新插入到地址空间的VMA列表中
39640fe15e0SLoGin                 self.mappings.insert_vma(before);
39740fe15e0SLoGin             }
39840fe15e0SLoGin 
39940fe15e0SLoGin             if let Some(after) = after {
40040fe15e0SLoGin                 // 如果后面有VMA,则需要将后面的VMA重新插入到地址空间的VMA列表中
40140fe15e0SLoGin                 self.mappings.insert_vma(after);
40240fe15e0SLoGin             }
40340fe15e0SLoGin 
40440fe15e0SLoGin             r.unmap(&mut self.user_mapper.utable, &mut flusher);
40540fe15e0SLoGin         }
40640fe15e0SLoGin 
40740fe15e0SLoGin         // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑
40840fe15e0SLoGin 
40940fe15e0SLoGin         return Ok(());
41040fe15e0SLoGin     }
41140fe15e0SLoGin 
41240fe15e0SLoGin     pub fn mprotect(
41340fe15e0SLoGin         &mut self,
41440fe15e0SLoGin         start_page: VirtPageFrame,
41540fe15e0SLoGin         page_count: PageFrameCount,
41640fe15e0SLoGin         prot_flags: ProtFlags,
41740fe15e0SLoGin     ) -> Result<(), SystemError> {
41840fe15e0SLoGin         // kdebug!(
41940fe15e0SLoGin         //     "mprotect: start_page: {:?}, page_count: {:?}, prot_flags:{prot_flags:?}",
42040fe15e0SLoGin         //     start_page,
42140fe15e0SLoGin         //     page_count
42240fe15e0SLoGin         // );
42340fe15e0SLoGin         let (mut active, mut inactive);
42440fe15e0SLoGin         let mut flusher = if self.is_current() {
42540fe15e0SLoGin             active = PageFlushAll::new();
42640fe15e0SLoGin             &mut active as &mut dyn Flusher<MMArch>
42740fe15e0SLoGin         } else {
42840fe15e0SLoGin             inactive = InactiveFlusher::new();
42940fe15e0SLoGin             &mut inactive as &mut dyn Flusher<MMArch>
43040fe15e0SLoGin         };
43140fe15e0SLoGin 
43240fe15e0SLoGin         let mapper = &mut self.user_mapper.utable;
43340fe15e0SLoGin         let region = VirtRegion::new(start_page.virt_address(), page_count.bytes());
43440fe15e0SLoGin         // kdebug!("mprotect: region: {:?}", region);
43540fe15e0SLoGin 
43640fe15e0SLoGin         let regions = self.mappings.conflicts(region).collect::<Vec<_>>();
43740fe15e0SLoGin         // kdebug!("mprotect: regions: {:?}", regions);
43840fe15e0SLoGin 
43940fe15e0SLoGin         for r in regions {
44040fe15e0SLoGin             // kdebug!("mprotect: r: {:?}", r);
44140fe15e0SLoGin             let r = r.lock().region().clone();
44240fe15e0SLoGin             let r = self.mappings.remove_vma(&r).unwrap();
44340fe15e0SLoGin 
44440fe15e0SLoGin             let intersection = r.lock().region().intersect(&region).unwrap();
44540fe15e0SLoGin             let (before, r, after) = r.extract(intersection).expect("Failed to extract VMA");
44640fe15e0SLoGin 
44740fe15e0SLoGin             if let Some(before) = before {
44840fe15e0SLoGin                 self.mappings.insert_vma(before);
44940fe15e0SLoGin             }
45040fe15e0SLoGin             if let Some(after) = after {
45140fe15e0SLoGin                 self.mappings.insert_vma(after);
45240fe15e0SLoGin             }
45340fe15e0SLoGin 
45440fe15e0SLoGin             let mut r_guard = r.lock();
45540fe15e0SLoGin             // 如果VMA的保护标志不允许指定的修改,则返回错误
45640fe15e0SLoGin             if !r_guard.can_have_flags(prot_flags) {
45740fe15e0SLoGin                 drop(r_guard);
45840fe15e0SLoGin                 self.mappings.insert_vma(r.clone());
45940fe15e0SLoGin                 return Err(SystemError::EACCES);
46040fe15e0SLoGin             }
46140fe15e0SLoGin 
46240fe15e0SLoGin             let new_flags: PageFlags<MMArch> = r_guard
46340fe15e0SLoGin                 .flags()
46440fe15e0SLoGin                 .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC))
46540fe15e0SLoGin                 .set_write(prot_flags.contains(ProtFlags::PROT_WRITE));
46640fe15e0SLoGin 
46740fe15e0SLoGin             r_guard.remap(new_flags, mapper, &mut flusher)?;
46840fe15e0SLoGin             drop(r_guard);
46940fe15e0SLoGin             self.mappings.insert_vma(r);
47040fe15e0SLoGin         }
47140fe15e0SLoGin 
47240fe15e0SLoGin         return Ok(());
47340fe15e0SLoGin     }
47440fe15e0SLoGin 
47540fe15e0SLoGin     /// 创建新的用户栈
47640fe15e0SLoGin     ///
47740fe15e0SLoGin     /// ## 参数
47840fe15e0SLoGin     ///
47940fe15e0SLoGin     /// - `size`:栈的大小
48040fe15e0SLoGin     pub fn new_user_stack(&mut self, size: usize) -> Result<(), SystemError> {
48140fe15e0SLoGin         assert!(self.user_stack.is_none(), "User stack already exists");
48240fe15e0SLoGin         let stack = UserStack::new(self, None, size)?;
48340fe15e0SLoGin         self.user_stack = Some(stack);
48440fe15e0SLoGin         return Ok(());
48540fe15e0SLoGin     }
48640fe15e0SLoGin 
48740fe15e0SLoGin     #[inline(always)]
48840fe15e0SLoGin     pub fn user_stack_mut(&mut self) -> Option<&mut UserStack> {
48940fe15e0SLoGin         return self.user_stack.as_mut();
49040fe15e0SLoGin     }
49140fe15e0SLoGin 
49240fe15e0SLoGin     /// 取消用户空间内的所有映射
49340fe15e0SLoGin     pub unsafe fn unmap_all(&mut self) {
49440fe15e0SLoGin         let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new();
49540fe15e0SLoGin         for vma in self.mappings.iter_vmas() {
49640fe15e0SLoGin             vma.unmap(&mut self.user_mapper.utable, &mut flusher);
49740fe15e0SLoGin         }
49840fe15e0SLoGin     }
49940fe15e0SLoGin 
50040fe15e0SLoGin     /// 设置进程的堆的内存空间
50140fe15e0SLoGin     ///
50240fe15e0SLoGin     /// ## 参数
50340fe15e0SLoGin     ///
50440fe15e0SLoGin     /// - `new_brk`:新的堆的结束地址。需要满足页对齐要求,并且是用户空间地址,且大于等于当前的堆的起始地址
50540fe15e0SLoGin     ///
50640fe15e0SLoGin     /// ## 返回值
50740fe15e0SLoGin     ///
50840fe15e0SLoGin     /// 返回旧的堆的结束地址
50940fe15e0SLoGin     pub unsafe fn set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError> {
51040fe15e0SLoGin         assert!(new_brk.check_aligned(MMArch::PAGE_SIZE));
51140fe15e0SLoGin 
51240fe15e0SLoGin         if !new_brk.check_user() || new_brk < self.brk_start {
51340fe15e0SLoGin             return Err(SystemError::EFAULT);
51440fe15e0SLoGin         }
51540fe15e0SLoGin 
51640fe15e0SLoGin         let old_brk = self.brk;
5171496ba7bSLoGin 
51840fe15e0SLoGin         if new_brk > self.brk {
51940fe15e0SLoGin             let len = new_brk - self.brk;
52040fe15e0SLoGin             let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
52140fe15e0SLoGin             let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED;
5221496ba7bSLoGin             self.map_anonymous(old_brk, len, prot_flags, map_flags, true)?;
5231496ba7bSLoGin 
52440fe15e0SLoGin             self.brk = new_brk;
52540fe15e0SLoGin             return Ok(old_brk);
52640fe15e0SLoGin         } else {
52740fe15e0SLoGin             let unmap_len = self.brk - new_brk;
52840fe15e0SLoGin             let unmap_start = new_brk;
52940fe15e0SLoGin             if unmap_len == 0 {
53040fe15e0SLoGin                 return Ok(old_brk);
53140fe15e0SLoGin             }
53240fe15e0SLoGin             self.munmap(
53340fe15e0SLoGin                 VirtPageFrame::new(unmap_start),
53440fe15e0SLoGin                 PageFrameCount::from_bytes(unmap_len).unwrap(),
53540fe15e0SLoGin             )?;
53640fe15e0SLoGin             self.brk = new_brk;
53740fe15e0SLoGin             return Ok(old_brk);
53840fe15e0SLoGin         }
53940fe15e0SLoGin     }
54040fe15e0SLoGin 
54140fe15e0SLoGin     pub unsafe fn sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError> {
54240fe15e0SLoGin         if incr == 0 {
54340fe15e0SLoGin             return Ok(self.brk);
54440fe15e0SLoGin         }
54540fe15e0SLoGin 
54640fe15e0SLoGin         let new_brk = if incr > 0 {
54740fe15e0SLoGin             self.brk + incr as usize
54840fe15e0SLoGin         } else {
54940fe15e0SLoGin             self.brk - (incr.abs() as usize)
55040fe15e0SLoGin         };
55140fe15e0SLoGin 
55240fe15e0SLoGin         let new_brk = VirtAddr::new(page_align_up(new_brk.data()));
55340fe15e0SLoGin 
55440fe15e0SLoGin         return self.set_brk(new_brk);
55540fe15e0SLoGin     }
55640fe15e0SLoGin }
55740fe15e0SLoGin 
55840fe15e0SLoGin impl Drop for InnerAddressSpace {
55940fe15e0SLoGin     fn drop(&mut self) {
56040fe15e0SLoGin         unsafe {
56140fe15e0SLoGin             self.unmap_all();
56240fe15e0SLoGin         }
56340fe15e0SLoGin     }
56440fe15e0SLoGin }
56540fe15e0SLoGin 
56640fe15e0SLoGin #[derive(Debug, Hash)]
56740fe15e0SLoGin pub struct UserMapper {
56840fe15e0SLoGin     pub utable: PageMapper,
56940fe15e0SLoGin }
57040fe15e0SLoGin 
57140fe15e0SLoGin impl UserMapper {
57240fe15e0SLoGin     pub fn new(utable: PageMapper) -> Self {
57340fe15e0SLoGin         return Self { utable };
57440fe15e0SLoGin     }
57540fe15e0SLoGin }
57640fe15e0SLoGin 
57740fe15e0SLoGin impl Drop for UserMapper {
57840fe15e0SLoGin     fn drop(&mut self) {
57940fe15e0SLoGin         if self.utable.is_current() {
58040fe15e0SLoGin             // 如果当前要被销毁的用户空间的页表是当前进程的页表,那么就切换回初始内核页表
58140fe15e0SLoGin             unsafe { MMArch::set_table(PageTableKind::User, MMArch::initial_page_table()) }
58240fe15e0SLoGin         }
58340fe15e0SLoGin         // 释放用户空间顶层页表占用的页帧
58440fe15e0SLoGin         // 请注意,在释放这个页帧之前,用户页表应该已经被完全释放,否则会产生内存泄露
58540fe15e0SLoGin         unsafe {
58640fe15e0SLoGin             deallocate_page_frames(
58740fe15e0SLoGin                 PhysPageFrame::new(self.utable.table().phys()),
58840fe15e0SLoGin                 PageFrameCount::new(1),
58940fe15e0SLoGin             )
59040fe15e0SLoGin         };
59140fe15e0SLoGin     }
59240fe15e0SLoGin }
59340fe15e0SLoGin 
59440fe15e0SLoGin /// 用户空间映射信息
59540fe15e0SLoGin #[derive(Debug)]
59640fe15e0SLoGin pub struct UserMappings {
59740fe15e0SLoGin     /// 当前用户空间的虚拟内存区域
59840fe15e0SLoGin     vmas: HashSet<Arc<LockedVMA>>,
59940fe15e0SLoGin     /// 当前用户空间的VMA空洞
60040fe15e0SLoGin     vm_holes: BTreeMap<VirtAddr, usize>,
60140fe15e0SLoGin }
60240fe15e0SLoGin 
60340fe15e0SLoGin impl UserMappings {
60440fe15e0SLoGin     pub fn new() -> Self {
60540fe15e0SLoGin         return Self {
60640fe15e0SLoGin             vmas: HashSet::new(),
60740fe15e0SLoGin             vm_holes: core::iter::once((VirtAddr::new(0), MMArch::USER_END_VADDR.data()))
60840fe15e0SLoGin                 .collect::<BTreeMap<_, _>>(),
60940fe15e0SLoGin         };
61040fe15e0SLoGin     }
61140fe15e0SLoGin 
61240fe15e0SLoGin     /// 判断当前进程的VMA内,是否有包含指定的虚拟地址的VMA。
61340fe15e0SLoGin     ///
61440fe15e0SLoGin     /// 如果有,返回包含指定虚拟地址的VMA的Arc指针,否则返回None。
61540fe15e0SLoGin     #[allow(dead_code)]
61640fe15e0SLoGin     pub fn contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> {
61740fe15e0SLoGin         for v in self.vmas.iter() {
61840fe15e0SLoGin             let guard = v.lock();
61940fe15e0SLoGin             if guard.region.contains(vaddr) {
62040fe15e0SLoGin                 return Some(v.clone());
62140fe15e0SLoGin             }
62240fe15e0SLoGin         }
62340fe15e0SLoGin         return None;
62440fe15e0SLoGin     }
62540fe15e0SLoGin 
62640fe15e0SLoGin     /// 获取当前进程的地址空间中,与给定虚拟地址范围有重叠的VMA的迭代器。
62740fe15e0SLoGin     pub fn conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_ {
62840fe15e0SLoGin         let r = self
62940fe15e0SLoGin             .vmas
63040fe15e0SLoGin             .iter()
63140fe15e0SLoGin             .filter(move |v| !v.lock().region.intersect(&request).is_none())
63240fe15e0SLoGin             .cloned();
63340fe15e0SLoGin         return r;
63440fe15e0SLoGin     }
63540fe15e0SLoGin 
63640fe15e0SLoGin     /// 在当前进程的地址空间中,寻找第一个符合条件的空闲的虚拟内存范围。
63740fe15e0SLoGin     ///
63840fe15e0SLoGin     /// @param min_vaddr 最小的起始地址
63940fe15e0SLoGin     /// @param size 请求的大小
64040fe15e0SLoGin     ///
64140fe15e0SLoGin     /// @return 如果找到了,返回虚拟内存范围,否则返回None
64240fe15e0SLoGin     pub fn find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion> {
64340fe15e0SLoGin         let _vaddr = min_vaddr;
64440fe15e0SLoGin         let mut iter = self
64540fe15e0SLoGin             .vm_holes
64640fe15e0SLoGin             .iter()
64740fe15e0SLoGin             .skip_while(|(hole_vaddr, hole_size)| hole_vaddr.add(**hole_size) <= min_vaddr);
64840fe15e0SLoGin 
64940fe15e0SLoGin         let (hole_vaddr, size) = iter.find(|(hole_vaddr, hole_size)| {
65040fe15e0SLoGin             // 计算当前空洞的可用大小
65140fe15e0SLoGin             let available_size: usize =
65240fe15e0SLoGin                 if hole_vaddr <= &&min_vaddr && min_vaddr <= hole_vaddr.add(**hole_size) {
65340fe15e0SLoGin                     **hole_size - (min_vaddr - **hole_vaddr)
65440fe15e0SLoGin                 } else {
65540fe15e0SLoGin                     **hole_size
65640fe15e0SLoGin                 };
65740fe15e0SLoGin 
65840fe15e0SLoGin             size <= available_size
65940fe15e0SLoGin         })?;
66040fe15e0SLoGin 
66140fe15e0SLoGin         // 创建一个新的虚拟内存范围。
66240fe15e0SLoGin         let region = VirtRegion::new(cmp::max(*hole_vaddr, min_vaddr), *size);
66340fe15e0SLoGin         return Some(region);
66440fe15e0SLoGin     }
66540fe15e0SLoGin 
66640fe15e0SLoGin     pub fn find_free_at(
66740fe15e0SLoGin         &self,
66840fe15e0SLoGin         min_vaddr: VirtAddr,
66940fe15e0SLoGin         vaddr: VirtAddr,
67040fe15e0SLoGin         size: usize,
67140fe15e0SLoGin         flags: MapFlags,
67240fe15e0SLoGin     ) -> Result<VirtRegion, SystemError> {
67340fe15e0SLoGin         // 如果没有指定地址,那么就在当前进程的地址空间中寻找一个空闲的虚拟内存范围。
67440fe15e0SLoGin         if vaddr == VirtAddr::new(0) {
67540fe15e0SLoGin             return self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM);
67640fe15e0SLoGin         }
67740fe15e0SLoGin 
67840fe15e0SLoGin         // 如果指定了地址,那么就检查指定的地址是否可用。
67940fe15e0SLoGin 
68040fe15e0SLoGin         let requested = VirtRegion::new(vaddr, size);
68140fe15e0SLoGin 
68240fe15e0SLoGin         if requested.end() >= MMArch::USER_END_VADDR || !vaddr.check_aligned(MMArch::PAGE_SIZE) {
68340fe15e0SLoGin             return Err(SystemError::EINVAL);
68440fe15e0SLoGin         }
68540fe15e0SLoGin 
68640fe15e0SLoGin         if let Some(_x) = self.conflicts(requested).next() {
68740fe15e0SLoGin             if flags.contains(MapFlags::MAP_FIXED_NOREPLACE) {
68840fe15e0SLoGin                 // 如果指定了 MAP_FIXED_NOREPLACE 标志,由于所指定的地址无法成功建立映射,则放弃映射,不对地址做修正
68940fe15e0SLoGin                 return Err(SystemError::EEXIST);
69040fe15e0SLoGin             }
69140fe15e0SLoGin 
69240fe15e0SLoGin             if flags.contains(MapFlags::MAP_FIXED) {
69340fe15e0SLoGin                 // todo: 支持MAP_FIXED标志对已有的VMA进行覆盖
69440fe15e0SLoGin                 return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
69540fe15e0SLoGin             }
69640fe15e0SLoGin 
69740fe15e0SLoGin             // 如果没有指定MAP_FIXED标志,那么就对地址做修正
69840fe15e0SLoGin             let requested = self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM)?;
69940fe15e0SLoGin             return Ok(requested);
70040fe15e0SLoGin         }
70140fe15e0SLoGin 
70240fe15e0SLoGin         return Ok(requested);
70340fe15e0SLoGin     }
70440fe15e0SLoGin 
70540fe15e0SLoGin     /// 在当前进程的地址空间中,保留一个指定大小的区域,使得该区域不在空洞中。
70640fe15e0SLoGin     /// 该函数会修改vm_holes中的空洞信息。
70740fe15e0SLoGin     ///
70840fe15e0SLoGin     /// @param region 要保留的区域
70940fe15e0SLoGin     ///
71040fe15e0SLoGin     /// 请注意,在调用本函数之前,必须先确定region所在范围内没有VMA。
71140fe15e0SLoGin     fn reserve_hole(&mut self, region: &VirtRegion) {
71240fe15e0SLoGin         let prev_hole: Option<(&VirtAddr, &mut usize)> =
713971462beSGnoCiYeH             self.vm_holes.range_mut(..=region.start()).next_back();
71440fe15e0SLoGin 
71540fe15e0SLoGin         if let Some((prev_hole_vaddr, prev_hole_size)) = prev_hole {
71640fe15e0SLoGin             let prev_hole_end = prev_hole_vaddr.add(*prev_hole_size);
71740fe15e0SLoGin 
71840fe15e0SLoGin             if prev_hole_end > region.start() {
71940fe15e0SLoGin                 // 如果前一个空洞的结束地址大于当前空洞的起始地址,那么就需要调整前一个空洞的大小。
72040fe15e0SLoGin                 *prev_hole_size = region.start().data() - prev_hole_vaddr.data();
72140fe15e0SLoGin             }
72240fe15e0SLoGin 
72340fe15e0SLoGin             if prev_hole_end > region.end() {
72440fe15e0SLoGin                 // 如果前一个空洞的结束地址大于当前空洞的结束地址,那么就需要增加一个新的空洞。
72540fe15e0SLoGin                 self.vm_holes
72640fe15e0SLoGin                     .insert(region.end(), prev_hole_end - region.end());
72740fe15e0SLoGin             }
72840fe15e0SLoGin         }
72940fe15e0SLoGin     }
73040fe15e0SLoGin 
73140fe15e0SLoGin     /// 在当前进程的地址空间中,释放一个指定大小的区域,使得该区域成为一个空洞。
73240fe15e0SLoGin     /// 该函数会修改vm_holes中的空洞信息。
73340fe15e0SLoGin     fn unreserve_hole(&mut self, region: &VirtRegion) {
73440fe15e0SLoGin         // 如果将要插入的空洞与后一个空洞相邻,那么就需要合并。
73540fe15e0SLoGin         let next_hole_size: Option<usize> = self.vm_holes.remove(&region.end());
73640fe15e0SLoGin 
73740fe15e0SLoGin         if let Some((_prev_hole_vaddr, prev_hole_size)) = self
73840fe15e0SLoGin             .vm_holes
73940fe15e0SLoGin             .range_mut(..region.start())
74040fe15e0SLoGin             .next_back()
74140fe15e0SLoGin             .filter(|(offset, size)| offset.data() + **size == region.start().data())
74240fe15e0SLoGin         {
74340fe15e0SLoGin             *prev_hole_size += region.size() + next_hole_size.unwrap_or(0);
74440fe15e0SLoGin         } else {
74540fe15e0SLoGin             self.vm_holes
74640fe15e0SLoGin                 .insert(region.start(), region.size() + next_hole_size.unwrap_or(0));
74740fe15e0SLoGin         }
74840fe15e0SLoGin     }
74940fe15e0SLoGin 
75040fe15e0SLoGin     /// 在当前进程的映射关系中,插入一个新的VMA。
75140fe15e0SLoGin     pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) {
75240fe15e0SLoGin         let region = vma.lock().region.clone();
75340fe15e0SLoGin         // 要求插入的地址范围必须是空闲的,也就是说,当前进程的地址空间中,不能有任何与之重叠的VMA。
75440fe15e0SLoGin         assert!(self.conflicts(region).next().is_none());
75540fe15e0SLoGin         self.reserve_hole(&region);
75640fe15e0SLoGin 
75740fe15e0SLoGin         self.vmas.insert(vma);
75840fe15e0SLoGin     }
75940fe15e0SLoGin 
76040fe15e0SLoGin     /// @brief 删除一个VMA,并把对应的地址空间加入空洞中。
76140fe15e0SLoGin     ///
76240fe15e0SLoGin     /// 这里不会取消VMA对应的地址的映射
76340fe15e0SLoGin     ///
76440fe15e0SLoGin     /// @param region 要删除的VMA所在的地址范围
76540fe15e0SLoGin     ///
76640fe15e0SLoGin     /// @return 如果成功删除了VMA,则返回被删除的VMA,否则返回None
76740fe15e0SLoGin     /// 如果没有可以删除的VMA,则不会执行删除操作,并报告失败。
76840fe15e0SLoGin     pub fn remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>> {
76940fe15e0SLoGin         // 请注意,由于这里会对每个VMA加锁,因此性能很低
77040fe15e0SLoGin         let vma: Arc<LockedVMA> = self
77140fe15e0SLoGin             .vmas
77240fe15e0SLoGin             .drain_filter(|vma| vma.lock().region == *region)
77340fe15e0SLoGin             .next()?;
77440fe15e0SLoGin         self.unreserve_hole(region);
77540fe15e0SLoGin 
77640fe15e0SLoGin         return Some(vma);
77740fe15e0SLoGin     }
77840fe15e0SLoGin 
77940fe15e0SLoGin     /// @brief Get the iterator of all VMAs in this process.
78040fe15e0SLoGin     pub fn iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>> {
78140fe15e0SLoGin         return self.vmas.iter();
78240fe15e0SLoGin     }
78340fe15e0SLoGin }
78440fe15e0SLoGin 
78540fe15e0SLoGin impl Default for UserMappings {
78640fe15e0SLoGin     fn default() -> Self {
78740fe15e0SLoGin         return Self::new();
78840fe15e0SLoGin     }
78940fe15e0SLoGin }
79040fe15e0SLoGin 
79140fe15e0SLoGin /// 加了锁的VMA
79240fe15e0SLoGin ///
79340fe15e0SLoGin /// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。
79440fe15e0SLoGin #[derive(Debug)]
79540fe15e0SLoGin pub struct LockedVMA(SpinLock<VMA>);
79640fe15e0SLoGin 
79740fe15e0SLoGin impl core::hash::Hash for LockedVMA {
79840fe15e0SLoGin     fn hash<H: Hasher>(&self, state: &mut H) {
79940fe15e0SLoGin         self.0.lock().hash(state);
80040fe15e0SLoGin     }
80140fe15e0SLoGin }
80240fe15e0SLoGin 
80340fe15e0SLoGin impl PartialEq for LockedVMA {
80440fe15e0SLoGin     fn eq(&self, other: &Self) -> bool {
80540fe15e0SLoGin         self.0.lock().eq(&other.0.lock())
80640fe15e0SLoGin     }
80740fe15e0SLoGin }
80840fe15e0SLoGin 
80940fe15e0SLoGin impl Eq for LockedVMA {}
81040fe15e0SLoGin 
81140fe15e0SLoGin #[allow(dead_code)]
81240fe15e0SLoGin impl LockedVMA {
81340fe15e0SLoGin     pub fn new(vma: VMA) -> Arc<Self> {
81440fe15e0SLoGin         let r = Arc::new(Self(SpinLock::new(vma)));
81540fe15e0SLoGin         r.0.lock().self_ref = Arc::downgrade(&r);
81640fe15e0SLoGin         return r;
81740fe15e0SLoGin     }
81840fe15e0SLoGin 
81940fe15e0SLoGin     pub fn lock(&self) -> SpinLockGuard<VMA> {
82040fe15e0SLoGin         return self.0.lock();
82140fe15e0SLoGin     }
82240fe15e0SLoGin 
82340fe15e0SLoGin     /// 调整当前VMA的页面的标志位
82440fe15e0SLoGin     ///
82540fe15e0SLoGin     /// TODO:增加调整虚拟页映射的物理地址的功能
82640fe15e0SLoGin     ///
82740fe15e0SLoGin     /// @param flags 新的标志位
82840fe15e0SLoGin     /// @param mapper 页表映射器
82940fe15e0SLoGin     /// @param flusher 页表项刷新器
83040fe15e0SLoGin     ///
83140fe15e0SLoGin     pub fn remap(
83240fe15e0SLoGin         &self,
83340fe15e0SLoGin         flags: PageFlags<MMArch>,
83440fe15e0SLoGin         mapper: &mut PageMapper,
83540fe15e0SLoGin         mut flusher: impl Flusher<MMArch>,
83640fe15e0SLoGin     ) -> Result<(), SystemError> {
83740fe15e0SLoGin         let mut guard = self.lock();
83840fe15e0SLoGin         assert!(guard.mapped);
83940fe15e0SLoGin         for page in guard.region.pages() {
84040fe15e0SLoGin             // 暂时要求所有的页帧都已经映射到页表
84140fe15e0SLoGin             // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了
84240fe15e0SLoGin             let r = unsafe {
84340fe15e0SLoGin                 mapper
84440fe15e0SLoGin                     .remap(page.virt_address(), flags)
84540fe15e0SLoGin                     .expect("Failed to remap, beacuse of some page is not mapped")
84640fe15e0SLoGin             };
84740fe15e0SLoGin             flusher.consume(r);
84840fe15e0SLoGin         }
84940fe15e0SLoGin         guard.flags = flags;
85040fe15e0SLoGin         return Ok(());
85140fe15e0SLoGin     }
85240fe15e0SLoGin 
85340fe15e0SLoGin     pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>) {
8541a62e776SLoGin         // todo: 如果当前vma与文件相关,完善文件相关的逻辑
8551a62e776SLoGin 
85640fe15e0SLoGin         let mut guard = self.lock();
85740fe15e0SLoGin         assert!(guard.mapped);
85840fe15e0SLoGin         for page in guard.region.pages() {
85940fe15e0SLoGin             let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) }
86040fe15e0SLoGin                 .expect("Failed to unmap, beacuse of some page is not mapped");
86140fe15e0SLoGin 
86240fe15e0SLoGin             // todo: 获取物理页的anon_vma的守卫
86340fe15e0SLoGin 
86440fe15e0SLoGin             // todo: 从anon_vma中删除当前VMA
86540fe15e0SLoGin 
86640fe15e0SLoGin             // todo: 如果物理页的anon_vma链表长度为0,则释放物理页.
86740fe15e0SLoGin 
86840fe15e0SLoGin             // 目前由于还没有实现共享页,所以直接释放物理页也没问题。
86940fe15e0SLoGin             // 但是在实现共享页之后,就不能直接释放物理页了,需要在anon_vma链表长度为0的时候才能释放物理页
87040fe15e0SLoGin             unsafe { deallocate_page_frames(PhysPageFrame::new(paddr), PageFrameCount::new(1)) };
87140fe15e0SLoGin 
87240fe15e0SLoGin             flusher.consume(flush);
87340fe15e0SLoGin         }
87440fe15e0SLoGin         guard.mapped = false;
87540fe15e0SLoGin     }
87640fe15e0SLoGin 
87740fe15e0SLoGin     pub fn mapped(&self) -> bool {
87840fe15e0SLoGin         return self.0.lock().mapped;
87940fe15e0SLoGin     }
88040fe15e0SLoGin 
88140fe15e0SLoGin     /// 将当前VMA进行切分,切分成3个VMA,分别是:
88240fe15e0SLoGin     ///
88340fe15e0SLoGin     /// 1. 前面的VMA,如果没有则为None
88440fe15e0SLoGin     /// 2. 中间的VMA,也就是传入的Region
88540fe15e0SLoGin     /// 3. 后面的VMA,如果没有则为None
88640fe15e0SLoGin     pub fn extract(
88740fe15e0SLoGin         &self,
88840fe15e0SLoGin         region: VirtRegion,
88940fe15e0SLoGin     ) -> Option<(
89040fe15e0SLoGin         Option<Arc<LockedVMA>>,
89140fe15e0SLoGin         Arc<LockedVMA>,
89240fe15e0SLoGin         Option<Arc<LockedVMA>>,
89340fe15e0SLoGin     )> {
89440fe15e0SLoGin         assert!(region.start().check_aligned(MMArch::PAGE_SIZE));
89540fe15e0SLoGin         assert!(region.end().check_aligned(MMArch::PAGE_SIZE));
89640fe15e0SLoGin 
89740fe15e0SLoGin         let mut guard = self.lock();
89840fe15e0SLoGin         {
89940fe15e0SLoGin             // 如果传入的region不在当前VMA的范围内,则直接返回None
90040fe15e0SLoGin             if unlikely(region.start() < guard.region.start() || region.end() > guard.region.end())
90140fe15e0SLoGin             {
90240fe15e0SLoGin                 return None;
90340fe15e0SLoGin             }
90440fe15e0SLoGin 
90540fe15e0SLoGin             let intersect: Option<VirtRegion> = guard.region.intersect(&region);
90640fe15e0SLoGin             // 如果当前VMA不包含region,则直接返回None
90740fe15e0SLoGin             if unlikely(intersect.is_none()) {
90840fe15e0SLoGin                 return None;
90940fe15e0SLoGin             }
91040fe15e0SLoGin             let intersect: VirtRegion = intersect.unwrap();
91140fe15e0SLoGin             if unlikely(intersect == guard.region) {
91240fe15e0SLoGin                 // 如果当前VMA完全包含region,则直接返回当前VMA
91340fe15e0SLoGin                 return Some((None, guard.self_ref.upgrade().unwrap(), None));
91440fe15e0SLoGin             }
91540fe15e0SLoGin         }
91640fe15e0SLoGin 
91740fe15e0SLoGin         let before: Option<Arc<LockedVMA>> = guard.region.before(&region).map(|virt_region| {
91840fe15e0SLoGin             let mut vma: VMA = unsafe { guard.clone() };
91940fe15e0SLoGin             vma.region = virt_region;
92040fe15e0SLoGin 
92140fe15e0SLoGin             let vma: Arc<LockedVMA> = LockedVMA::new(vma);
92240fe15e0SLoGin             vma
92340fe15e0SLoGin         });
92440fe15e0SLoGin 
92540fe15e0SLoGin         let after: Option<Arc<LockedVMA>> = guard.region.after(&region).map(|virt_region| {
92640fe15e0SLoGin             let mut vma: VMA = unsafe { guard.clone() };
92740fe15e0SLoGin             vma.region = virt_region;
92840fe15e0SLoGin 
92940fe15e0SLoGin             let vma: Arc<LockedVMA> = LockedVMA::new(vma);
93040fe15e0SLoGin             vma
93140fe15e0SLoGin         });
93240fe15e0SLoGin 
93340fe15e0SLoGin         guard.region = region;
93440fe15e0SLoGin 
93540fe15e0SLoGin         // TODO: 重新设置before、after这两个VMA里面的物理页的anon_vma
93640fe15e0SLoGin 
93740fe15e0SLoGin         return Some((before, guard.self_ref.upgrade().unwrap(), after));
93840fe15e0SLoGin     }
93940fe15e0SLoGin }
94040fe15e0SLoGin 
94140fe15e0SLoGin /// @brief 虚拟内存区域
94240fe15e0SLoGin #[derive(Debug)]
94340fe15e0SLoGin pub struct VMA {
94440fe15e0SLoGin     /// 虚拟内存区域对应的虚拟地址范围
94540fe15e0SLoGin     region: VirtRegion,
94640fe15e0SLoGin     /// VMA内的页帧的标志
94740fe15e0SLoGin     flags: PageFlags<MMArch>,
94840fe15e0SLoGin     /// VMA内的页帧是否已经映射到页表
94940fe15e0SLoGin     mapped: bool,
95040fe15e0SLoGin     /// VMA所属的用户地址空间
95140fe15e0SLoGin     user_address_space: Option<Weak<AddressSpace>>,
95240fe15e0SLoGin     self_ref: Weak<LockedVMA>,
953971462beSGnoCiYeH 
954971462beSGnoCiYeH     provider: Provider,
95540fe15e0SLoGin }
95640fe15e0SLoGin 
95740fe15e0SLoGin impl core::hash::Hash for VMA {
95840fe15e0SLoGin     fn hash<H: Hasher>(&self, state: &mut H) {
95940fe15e0SLoGin         self.region.hash(state);
96040fe15e0SLoGin         self.flags.hash(state);
96140fe15e0SLoGin         self.mapped.hash(state);
96240fe15e0SLoGin     }
96340fe15e0SLoGin }
96440fe15e0SLoGin 
965971462beSGnoCiYeH /// 描述不同类型的内存提供者或资源
966971462beSGnoCiYeH #[derive(Debug)]
967971462beSGnoCiYeH pub enum Provider {
968971462beSGnoCiYeH     Allocated, // TODO:其他
969971462beSGnoCiYeH }
970971462beSGnoCiYeH 
97140fe15e0SLoGin #[allow(dead_code)]
97240fe15e0SLoGin impl VMA {
97340fe15e0SLoGin     pub fn region(&self) -> &VirtRegion {
97440fe15e0SLoGin         return &self.region;
97540fe15e0SLoGin     }
97640fe15e0SLoGin 
97740fe15e0SLoGin     /// # 拷贝当前VMA的内容
97840fe15e0SLoGin     ///
97940fe15e0SLoGin     /// ### 安全性
98040fe15e0SLoGin     ///
98140fe15e0SLoGin     /// 由于这样操作可能由于错误的拷贝,导致内存泄露、内存重复释放等问题,所以需要小心使用。
98240fe15e0SLoGin     pub unsafe fn clone(&self) -> Self {
98340fe15e0SLoGin         return Self {
98440fe15e0SLoGin             region: self.region,
98540fe15e0SLoGin             flags: self.flags,
98640fe15e0SLoGin             mapped: self.mapped,
98740fe15e0SLoGin             user_address_space: self.user_address_space.clone(),
98840fe15e0SLoGin             self_ref: self.self_ref.clone(),
989971462beSGnoCiYeH             provider: Provider::Allocated,
99040fe15e0SLoGin         };
99140fe15e0SLoGin     }
99240fe15e0SLoGin 
99340fe15e0SLoGin     #[inline(always)]
99440fe15e0SLoGin     pub fn flags(&self) -> PageFlags<MMArch> {
99540fe15e0SLoGin         return self.flags;
99640fe15e0SLoGin     }
99740fe15e0SLoGin 
99840fe15e0SLoGin     pub fn pages(&self) -> VirtPageFrameIter {
99940fe15e0SLoGin         return VirtPageFrameIter::new(
100040fe15e0SLoGin             VirtPageFrame::new(self.region.start()),
100140fe15e0SLoGin             VirtPageFrame::new(self.region.end()),
100240fe15e0SLoGin         );
100340fe15e0SLoGin     }
100440fe15e0SLoGin 
100540fe15e0SLoGin     pub fn remap(
100640fe15e0SLoGin         &mut self,
100740fe15e0SLoGin         flags: PageFlags<MMArch>,
100840fe15e0SLoGin         mapper: &mut PageMapper,
100940fe15e0SLoGin         mut flusher: impl Flusher<MMArch>,
101040fe15e0SLoGin     ) -> Result<(), SystemError> {
101140fe15e0SLoGin         assert!(self.mapped);
101240fe15e0SLoGin         for page in self.region.pages() {
101340fe15e0SLoGin             // kdebug!("remap page {:?}", page.virt_address());
101440fe15e0SLoGin             // 暂时要求所有的页帧都已经映射到页表
101540fe15e0SLoGin             // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了
101640fe15e0SLoGin             let r = unsafe {
101740fe15e0SLoGin                 mapper
101840fe15e0SLoGin                     .remap(page.virt_address(), flags)
101940fe15e0SLoGin                     .expect("Failed to remap, beacuse of some page is not mapped")
102040fe15e0SLoGin             };
102140fe15e0SLoGin             // kdebug!("consume page {:?}", page.virt_address());
102240fe15e0SLoGin             flusher.consume(r);
102340fe15e0SLoGin             // kdebug!("remap page {:?} done", page.virt_address());
102440fe15e0SLoGin         }
102540fe15e0SLoGin         self.flags = flags;
102640fe15e0SLoGin         return Ok(());
102740fe15e0SLoGin     }
102840fe15e0SLoGin 
102940fe15e0SLoGin     /// 检查当前VMA是否可以拥有指定的标志位
103040fe15e0SLoGin     ///
103140fe15e0SLoGin     /// ## 参数
103240fe15e0SLoGin     ///
103340fe15e0SLoGin     /// - `prot_flags` 要检查的标志位
103440fe15e0SLoGin     pub fn can_have_flags(&self, prot_flags: ProtFlags) -> bool {
1035971462beSGnoCiYeH         let is_downgrade = (self.flags.has_write() || !prot_flags.contains(ProtFlags::PROT_WRITE))
103640fe15e0SLoGin             && (self.flags.has_execute() || !prot_flags.contains(ProtFlags::PROT_EXEC));
1037971462beSGnoCiYeH 
1038971462beSGnoCiYeH         match self.provider {
1039971462beSGnoCiYeH             Provider::Allocated { .. } => true,
1040971462beSGnoCiYeH 
1041971462beSGnoCiYeH             #[allow(unreachable_patterns)]
1042971462beSGnoCiYeH             _ => is_downgrade,
1043971462beSGnoCiYeH         }
104440fe15e0SLoGin     }
104540fe15e0SLoGin 
104640fe15e0SLoGin     /// 把物理地址映射到虚拟地址
104740fe15e0SLoGin     ///
104840fe15e0SLoGin     /// @param phys 要映射的物理地址
104940fe15e0SLoGin     /// @param destination 要映射到的虚拟地址
105040fe15e0SLoGin     /// @param count 要映射的页帧数量
105140fe15e0SLoGin     /// @param flags 页面标志位
105240fe15e0SLoGin     /// @param mapper 页表映射器
105340fe15e0SLoGin     /// @param flusher 页表项刷新器
105440fe15e0SLoGin     ///
105540fe15e0SLoGin     /// @return 返回映射后的虚拟内存区域
105640fe15e0SLoGin     pub fn physmap(
105740fe15e0SLoGin         phys: PhysPageFrame,
105840fe15e0SLoGin         destination: VirtPageFrame,
105940fe15e0SLoGin         count: PageFrameCount,
106040fe15e0SLoGin         flags: PageFlags<MMArch>,
106140fe15e0SLoGin         mapper: &mut PageMapper,
106240fe15e0SLoGin         mut flusher: impl Flusher<MMArch>,
106340fe15e0SLoGin     ) -> Result<Arc<LockedVMA>, SystemError> {
106440fe15e0SLoGin         {
106540fe15e0SLoGin             let mut cur_phy = phys;
106640fe15e0SLoGin             let mut cur_dest = destination;
106740fe15e0SLoGin 
106840fe15e0SLoGin             for _ in 0..count.data() {
106940fe15e0SLoGin                 // 将物理页帧映射到虚拟页帧
107040fe15e0SLoGin                 let r = unsafe {
107140fe15e0SLoGin                     mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags)
107240fe15e0SLoGin                 }
107340fe15e0SLoGin                 .expect("Failed to map phys, may be OOM error");
107440fe15e0SLoGin 
107540fe15e0SLoGin                 // todo: 增加OOM处理
107640fe15e0SLoGin 
107740fe15e0SLoGin                 // todo: 将VMA加入到anon_vma中
107840fe15e0SLoGin 
107940fe15e0SLoGin                 // 刷新TLB
108040fe15e0SLoGin                 flusher.consume(r);
108140fe15e0SLoGin 
108240fe15e0SLoGin                 cur_phy = cur_phy.next();
108340fe15e0SLoGin                 cur_dest = cur_dest.next();
108440fe15e0SLoGin             }
108540fe15e0SLoGin         }
108640fe15e0SLoGin 
108740fe15e0SLoGin         let r: Arc<LockedVMA> = LockedVMA::new(VMA {
108840fe15e0SLoGin             region: VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE),
108940fe15e0SLoGin             flags,
109040fe15e0SLoGin             mapped: true,
109140fe15e0SLoGin             user_address_space: None,
109240fe15e0SLoGin             self_ref: Weak::default(),
1093971462beSGnoCiYeH             provider: Provider::Allocated,
109440fe15e0SLoGin         });
109540fe15e0SLoGin         return Ok(r);
109640fe15e0SLoGin     }
109740fe15e0SLoGin 
109840fe15e0SLoGin     /// 从页分配器中分配一些物理页,并把它们映射到指定的虚拟地址,然后创建VMA
109940fe15e0SLoGin     ///
110040fe15e0SLoGin     /// @param destination 要映射到的虚拟地址
110140fe15e0SLoGin     /// @param count 要映射的页帧数量
110240fe15e0SLoGin     /// @param flags 页面标志位
110340fe15e0SLoGin     /// @param mapper 页表映射器
110440fe15e0SLoGin     /// @param flusher 页表项刷新器
110540fe15e0SLoGin     ///
110640fe15e0SLoGin     /// @return 返回映射后的虚拟内存区域
110740fe15e0SLoGin     pub fn zeroed(
110840fe15e0SLoGin         destination: VirtPageFrame,
110940fe15e0SLoGin         page_count: PageFrameCount,
111040fe15e0SLoGin         flags: PageFlags<MMArch>,
111140fe15e0SLoGin         mapper: &mut PageMapper,
111240fe15e0SLoGin         mut flusher: impl Flusher<MMArch>,
111340fe15e0SLoGin     ) -> Result<Arc<LockedVMA>, SystemError> {
111440fe15e0SLoGin         let mut cur_dest: VirtPageFrame = destination;
111540fe15e0SLoGin         // kdebug!(
111640fe15e0SLoGin         //     "VMA::zeroed: page_count = {:?}, destination={destination:?}",
111740fe15e0SLoGin         //     page_count
111840fe15e0SLoGin         // );
111940fe15e0SLoGin         for _ in 0..page_count.data() {
112040fe15e0SLoGin             // kdebug!(
112140fe15e0SLoGin             //     "VMA::zeroed: cur_dest={cur_dest:?}, vaddr = {:?}",
112240fe15e0SLoGin             //     cur_dest.virt_address()
112340fe15e0SLoGin             // );
112440fe15e0SLoGin             let r = unsafe { mapper.map(cur_dest.virt_address(), flags) }
112540fe15e0SLoGin                 .expect("Failed to map zero, may be OOM error");
112640fe15e0SLoGin             // todo: 将VMA加入到anon_vma中
112740fe15e0SLoGin             // todo: 增加OOM处理
112840fe15e0SLoGin 
112940fe15e0SLoGin             // 稍后再刷新TLB,这里取消刷新
113040fe15e0SLoGin             flusher.consume(r);
113140fe15e0SLoGin             cur_dest = cur_dest.next();
113240fe15e0SLoGin         }
113340fe15e0SLoGin         let r = LockedVMA::new(VMA {
113440fe15e0SLoGin             region: VirtRegion::new(
113540fe15e0SLoGin                 destination.virt_address(),
113640fe15e0SLoGin                 page_count.data() * MMArch::PAGE_SIZE,
113740fe15e0SLoGin             ),
113840fe15e0SLoGin             flags,
113940fe15e0SLoGin             mapped: true,
114040fe15e0SLoGin             user_address_space: None,
114140fe15e0SLoGin             self_ref: Weak::default(),
1142971462beSGnoCiYeH             provider: Provider::Allocated,
114340fe15e0SLoGin         });
114440fe15e0SLoGin         drop(flusher);
114540fe15e0SLoGin         // kdebug!("VMA::zeroed: flusher dropped");
114640fe15e0SLoGin 
114740fe15e0SLoGin         // 清空这些内存
11489550910aSChiichen         let virt_iter: VirtPageFrameIter =
11499550910aSChiichen             VirtPageFrameIter::new(destination, destination.add(page_count));
115040fe15e0SLoGin         for frame in virt_iter {
115140fe15e0SLoGin             let paddr = mapper.translate(frame.virt_address()).unwrap().0;
115240fe15e0SLoGin 
115340fe15e0SLoGin             unsafe {
115440fe15e0SLoGin                 let vaddr = MMArch::phys_2_virt(paddr).unwrap();
115540fe15e0SLoGin                 MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE);
115640fe15e0SLoGin             }
115740fe15e0SLoGin         }
115840fe15e0SLoGin         // kdebug!("VMA::zeroed: done");
115940fe15e0SLoGin         return Ok(r);
116040fe15e0SLoGin     }
116140fe15e0SLoGin }
116240fe15e0SLoGin 
116340fe15e0SLoGin impl Drop for VMA {
116440fe15e0SLoGin     fn drop(&mut self) {
116540fe15e0SLoGin         // 当VMA被释放时,需要确保它已经被从页表中解除映射
116640fe15e0SLoGin         assert!(!self.mapped, "VMA is still mapped");
116740fe15e0SLoGin     }
116840fe15e0SLoGin }
116940fe15e0SLoGin 
117040fe15e0SLoGin impl PartialEq for VMA {
117140fe15e0SLoGin     fn eq(&self, other: &Self) -> bool {
117240fe15e0SLoGin         return self.region == other.region;
117340fe15e0SLoGin     }
117440fe15e0SLoGin }
117540fe15e0SLoGin 
117640fe15e0SLoGin impl Eq for VMA {}
117740fe15e0SLoGin 
117840fe15e0SLoGin impl PartialOrd for VMA {
117940fe15e0SLoGin     fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
118040fe15e0SLoGin         return self.region.partial_cmp(&other.region);
118140fe15e0SLoGin     }
118240fe15e0SLoGin }
118340fe15e0SLoGin 
118440fe15e0SLoGin impl Ord for VMA {
118540fe15e0SLoGin     fn cmp(&self, other: &Self) -> cmp::Ordering {
118640fe15e0SLoGin         return self.region.cmp(&other.region);
118740fe15e0SLoGin     }
118840fe15e0SLoGin }
118940fe15e0SLoGin 
119040fe15e0SLoGin #[derive(Debug)]
119140fe15e0SLoGin pub struct UserStack {
119240fe15e0SLoGin     // 栈底地址
119340fe15e0SLoGin     stack_bottom: VirtAddr,
119440fe15e0SLoGin     // 当前已映射的大小
119540fe15e0SLoGin     mapped_size: usize,
119640fe15e0SLoGin     /// 栈顶地址(这个值需要仔细确定!因为它可能不会实时与用户栈的真实栈顶保持一致!要小心!)
119740fe15e0SLoGin     current_sp: VirtAddr,
119840fe15e0SLoGin }
119940fe15e0SLoGin 
120040fe15e0SLoGin impl UserStack {
120140fe15e0SLoGin     /// 默认的用户栈底地址
120240fe15e0SLoGin     pub const DEFAULT_USER_STACK_BOTTOM: VirtAddr = MMArch::USER_STACK_START;
120340fe15e0SLoGin     /// 默认的用户栈大小为8MB
120440fe15e0SLoGin     pub const DEFAULT_USER_STACK_SIZE: usize = 8 * 1024 * 1024;
120540fe15e0SLoGin     /// 用户栈的保护页数量
120640fe15e0SLoGin     pub const GUARD_PAGES_NUM: usize = 4;
120740fe15e0SLoGin 
120840fe15e0SLoGin     /// 创建一个用户栈
120940fe15e0SLoGin     pub fn new(
121040fe15e0SLoGin         vm: &mut InnerAddressSpace,
121140fe15e0SLoGin         stack_bottom: Option<VirtAddr>,
121240fe15e0SLoGin         stack_size: usize,
121340fe15e0SLoGin     ) -> Result<Self, SystemError> {
121440fe15e0SLoGin         let stack_bottom = stack_bottom.unwrap_or(Self::DEFAULT_USER_STACK_BOTTOM);
121540fe15e0SLoGin         assert!(stack_bottom.check_aligned(MMArch::PAGE_SIZE));
121640fe15e0SLoGin 
121740fe15e0SLoGin         // 分配用户栈的保护页
121840fe15e0SLoGin         let guard_size = Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE;
121940fe15e0SLoGin         let actual_stack_bottom = stack_bottom - guard_size;
122040fe15e0SLoGin 
122140fe15e0SLoGin         let mut prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE;
122240fe15e0SLoGin         let map_flags =
122340fe15e0SLoGin             MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED_NOREPLACE;
122440fe15e0SLoGin         // kdebug!(
122540fe15e0SLoGin         //     "map anonymous stack: {:?} {}",
122640fe15e0SLoGin         //     actual_stack_bottom,
122740fe15e0SLoGin         //     guard_size
122840fe15e0SLoGin         // );
122940fe15e0SLoGin         vm.map_anonymous(
123040fe15e0SLoGin             actual_stack_bottom,
123140fe15e0SLoGin             guard_size,
123240fe15e0SLoGin             prot_flags,
123340fe15e0SLoGin             map_flags,
123440fe15e0SLoGin             false,
123540fe15e0SLoGin         )?;
123640fe15e0SLoGin         // test_buddy();
123740fe15e0SLoGin         // 设置保护页只读
123840fe15e0SLoGin         prot_flags.remove(ProtFlags::PROT_WRITE);
123940fe15e0SLoGin         // kdebug!(
124040fe15e0SLoGin         //     "to mprotect stack guard pages: {:?} {}",
124140fe15e0SLoGin         //     actual_stack_bottom,
124240fe15e0SLoGin         //     guard_size
124340fe15e0SLoGin         // );
124440fe15e0SLoGin         vm.mprotect(
124540fe15e0SLoGin             VirtPageFrame::new(actual_stack_bottom),
124640fe15e0SLoGin             PageFrameCount::new(Self::GUARD_PAGES_NUM),
124740fe15e0SLoGin             prot_flags,
124840fe15e0SLoGin         )?;
124940fe15e0SLoGin 
125040fe15e0SLoGin         // kdebug!(
125140fe15e0SLoGin         //     "mprotect stack guard pages done: {:?} {}",
125240fe15e0SLoGin         //     actual_stack_bottom,
125340fe15e0SLoGin         //     guard_size
125440fe15e0SLoGin         // );
125540fe15e0SLoGin 
125640fe15e0SLoGin         let mut user_stack = UserStack {
125740fe15e0SLoGin             stack_bottom: actual_stack_bottom,
125840fe15e0SLoGin             mapped_size: guard_size,
125940fe15e0SLoGin             current_sp: actual_stack_bottom - guard_size,
126040fe15e0SLoGin         };
126140fe15e0SLoGin 
126240fe15e0SLoGin         // kdebug!("extend user stack: {:?} {}", stack_bottom, stack_size);
126340fe15e0SLoGin         // 分配用户栈
126440fe15e0SLoGin         user_stack.initial_extend(vm, stack_size)?;
126540fe15e0SLoGin         // kdebug!("user stack created: {:?} {}", stack_bottom, stack_size);
126640fe15e0SLoGin         return Ok(user_stack);
126740fe15e0SLoGin     }
126840fe15e0SLoGin 
126940fe15e0SLoGin     fn initial_extend(
127040fe15e0SLoGin         &mut self,
127140fe15e0SLoGin         vm: &mut InnerAddressSpace,
127240fe15e0SLoGin         mut bytes: usize,
127340fe15e0SLoGin     ) -> Result<(), SystemError> {
127440fe15e0SLoGin         let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
127540fe15e0SLoGin         let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS;
127640fe15e0SLoGin 
127740fe15e0SLoGin         bytes = page_align_up(bytes);
127840fe15e0SLoGin         self.mapped_size += bytes;
127940fe15e0SLoGin 
128040fe15e0SLoGin         vm.map_anonymous(
128140fe15e0SLoGin             self.stack_bottom - self.mapped_size,
128240fe15e0SLoGin             bytes,
128340fe15e0SLoGin             prot_flags,
128440fe15e0SLoGin             map_flags,
128540fe15e0SLoGin             false,
128640fe15e0SLoGin         )?;
128740fe15e0SLoGin 
128840fe15e0SLoGin         return Ok(());
128940fe15e0SLoGin     }
129040fe15e0SLoGin 
129140fe15e0SLoGin     /// 扩展用户栈
129240fe15e0SLoGin     ///
129340fe15e0SLoGin     /// ## 参数
129440fe15e0SLoGin     ///
129540fe15e0SLoGin     /// - `vm` 用户地址空间结构体
129640fe15e0SLoGin     /// - `bytes` 要扩展的字节数
129740fe15e0SLoGin     ///
129840fe15e0SLoGin     /// ## 返回值
129940fe15e0SLoGin     ///
130040fe15e0SLoGin     /// - **Ok(())** 扩展成功
130140fe15e0SLoGin     /// - **Err(SystemError)** 扩展失败
130240fe15e0SLoGin     #[allow(dead_code)]
130340fe15e0SLoGin     pub fn extend(
130440fe15e0SLoGin         &mut self,
130540fe15e0SLoGin         vm: &mut RwLockWriteGuard<InnerAddressSpace>,
130640fe15e0SLoGin         mut bytes: usize,
130740fe15e0SLoGin     ) -> Result<(), SystemError> {
130840fe15e0SLoGin         let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
130940fe15e0SLoGin         let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS;
131040fe15e0SLoGin 
131140fe15e0SLoGin         bytes = page_align_up(bytes);
131240fe15e0SLoGin         self.mapped_size += bytes;
131340fe15e0SLoGin 
131440fe15e0SLoGin         vm.map_anonymous(
131540fe15e0SLoGin             self.stack_bottom - self.mapped_size,
131640fe15e0SLoGin             bytes,
131740fe15e0SLoGin             prot_flags,
131840fe15e0SLoGin             map_flags,
131940fe15e0SLoGin             false,
132040fe15e0SLoGin         )?;
132140fe15e0SLoGin 
132240fe15e0SLoGin         return Ok(());
132340fe15e0SLoGin     }
132440fe15e0SLoGin 
132540fe15e0SLoGin     /// 获取栈顶地址
132640fe15e0SLoGin     ///
132740fe15e0SLoGin     /// 请注意,如果用户栈的栈顶地址发生变化,这个值可能不会实时更新!
132840fe15e0SLoGin     pub fn sp(&self) -> VirtAddr {
132940fe15e0SLoGin         return self.current_sp;
133040fe15e0SLoGin     }
133140fe15e0SLoGin 
133240fe15e0SLoGin     pub unsafe fn set_sp(&mut self, sp: VirtAddr) {
133340fe15e0SLoGin         self.current_sp = sp;
133440fe15e0SLoGin     }
133540fe15e0SLoGin 
133640fe15e0SLoGin     /// 仅仅克隆用户栈的信息,不会克隆用户栈的内容/映射
133740fe15e0SLoGin     pub unsafe fn clone_info_only(&self) -> Self {
133840fe15e0SLoGin         return Self {
133940fe15e0SLoGin             stack_bottom: self.stack_bottom,
134040fe15e0SLoGin             mapped_size: self.mapped_size,
134140fe15e0SLoGin             current_sp: self.current_sp,
134240fe15e0SLoGin         };
134340fe15e0SLoGin     }
134440fe15e0SLoGin 
134540fe15e0SLoGin     /// 获取当前用户栈的大小(不包括保护页)
134640fe15e0SLoGin     pub fn stack_size(&self) -> usize {
134740fe15e0SLoGin         return self.mapped_size - Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE;
134840fe15e0SLoGin     }
134940fe15e0SLoGin }
1350