xref: /DragonOS/kernel/src/mm/ucontext.rs (revision 731bc2b32d7b37298883d7a15b6dca659b436ee4)
1 // 进程的用户空间内存管理
2 
3 use core::{
4     cmp,
5     hash::Hasher,
6     intrinsics::unlikely,
7     ops::Add,
8     sync::atomic::{compiler_fence, Ordering},
9 };
10 
11 use alloc::{
12     collections::BTreeMap,
13     sync::{Arc, Weak},
14     vec::Vec,
15 };
16 use hashbrown::HashSet;
17 use ida::IdAllocator;
18 use system_error::SystemError;
19 
20 use crate::{
21     arch::{mm::PageMapper, CurrentIrqArch, MMArch},
22     exception::InterruptArch,
23     libs::{
24         align::page_align_up,
25         rwlock::RwLock,
26         spinlock::{SpinLock, SpinLockGuard},
27     },
28     mm::page::page_manager_lock_irqsave,
29     process::ProcessManager,
30     syscall::user_access::{UserBufferReader, UserBufferWriter},
31 };
32 
33 use super::{
34     allocator::page_frame::{
35         deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter,
36     },
37     page::{Flusher, InactiveFlusher, PageFlags, PageFlushAll},
38     syscall::{MadvFlags, MapFlags, MremapFlags, ProtFlags},
39     MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, VmFlags,
40 };
41 
42 /// MMAP_MIN_ADDR的默认值
43 /// 以下内容来自linux-5.19:
44 ///  This is the portion of low virtual memory which should be protected
45 //   from userspace allocation.  Keeping a user from writing to low pages
46 //   can help reduce the impact of kernel NULL pointer bugs.
47 //   For most ia64, ppc64 and x86 users with lots of address space
48 //   a value of 65536 is reasonable and should cause no problems.
49 //   On arm and other archs it should not be higher than 32768.
50 //   Programs which use vm86 functionality or have some need to map
51 //   this low address space will need CAP_SYS_RAWIO or disable this
52 //   protection by setting the value to 0.
53 pub const DEFAULT_MMAP_MIN_ADDR: usize = 65536;
54 
55 /// LockedVMA的id分配器
56 static LOCKEDVMA_ID_ALLOCATOR: IdAllocator = IdAllocator::new(0, usize::MAX);
57 
58 #[derive(Debug)]
59 pub struct AddressSpace {
60     inner: RwLock<InnerAddressSpace>,
61 }
62 
63 impl AddressSpace {
64     pub fn new(create_stack: bool) -> Result<Arc<Self>, SystemError> {
65         let inner = InnerAddressSpace::new(create_stack)?;
66         let result = Self {
67             inner: RwLock::new(inner),
68         };
69         return Ok(Arc::new(result));
70     }
71 
72     /// 从pcb中获取当前进程的地址空间结构体的Arc指针
73     pub fn current() -> Result<Arc<AddressSpace>, SystemError> {
74         let vm = ProcessManager::current_pcb()
75             .basic()
76             .user_vm()
77             .expect("Current process has no address space");
78 
79         return Ok(vm);
80     }
81 
82     /// 判断某个地址空间是否为当前进程的地址空间
83     pub fn is_current(self: &Arc<Self>) -> bool {
84         let current = Self::current();
85         if let Ok(current) = current {
86             return Arc::ptr_eq(&current, self);
87         }
88         return false;
89     }
90 }
91 
92 impl core::ops::Deref for AddressSpace {
93     type Target = RwLock<InnerAddressSpace>;
94 
95     fn deref(&self) -> &Self::Target {
96         &self.inner
97     }
98 }
99 
100 impl core::ops::DerefMut for AddressSpace {
101     fn deref_mut(&mut self) -> &mut Self::Target {
102         &mut self.inner
103     }
104 }
105 
106 /// @brief 用户地址空间结构体(每个进程都有一个)
107 #[derive(Debug)]
108 pub struct InnerAddressSpace {
109     pub user_mapper: UserMapper,
110     pub mappings: UserMappings,
111     pub mmap_min: VirtAddr,
112     /// 用户栈信息结构体
113     pub user_stack: Option<UserStack>,
114 
115     pub elf_brk_start: VirtAddr,
116     pub elf_brk: VirtAddr,
117 
118     /// 当前进程的堆空间的起始地址
119     pub brk_start: VirtAddr,
120     /// 当前进程的堆空间的结束地址(不包含)
121     pub brk: VirtAddr,
122 
123     pub start_code: VirtAddr,
124     pub end_code: VirtAddr,
125     pub start_data: VirtAddr,
126     pub end_data: VirtAddr,
127 }
128 
129 impl InnerAddressSpace {
130     pub fn new(create_stack: bool) -> Result<Self, SystemError> {
131         let mut result = Self {
132             user_mapper: MMArch::setup_new_usermapper()?,
133             mappings: UserMappings::new(),
134             mmap_min: VirtAddr(DEFAULT_MMAP_MIN_ADDR),
135             elf_brk_start: VirtAddr::new(0),
136             elf_brk: VirtAddr::new(0),
137             brk_start: MMArch::USER_BRK_START,
138             brk: MMArch::USER_BRK_START,
139             user_stack: None,
140             start_code: VirtAddr(0),
141             end_code: VirtAddr(0),
142             start_data: VirtAddr(0),
143             end_data: VirtAddr(0),
144         };
145         if create_stack {
146             // kdebug!("to create user stack.");
147             result.new_user_stack(UserStack::DEFAULT_USER_STACK_SIZE)?;
148         }
149 
150         return Ok(result);
151     }
152 
153     /// 尝试克隆当前进程的地址空间,包括这些映射都会被克隆
154     ///
155     /// # Returns
156     ///
157     /// 返回克隆后的,新的地址空间的Arc指针
158     #[inline(never)]
159     pub fn try_clone(&mut self) -> Result<Arc<AddressSpace>, SystemError> {
160         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
161         let new_addr_space = AddressSpace::new(false)?;
162         let mut new_guard = new_addr_space.write();
163         unsafe {
164             new_guard
165                 .user_mapper
166                 .clone_from(&mut self.user_mapper, MMArch::PAGE_FAULT_ENABLED)
167         };
168 
169         // 拷贝用户栈的结构体信息,但是不拷贝用户栈的内容(因为后面VMA的拷贝会拷贝用户栈的内容)
170         unsafe {
171             new_guard.user_stack = Some(self.user_stack.as_ref().unwrap().clone_info_only());
172         }
173         let _current_stack_size = self.user_stack.as_ref().unwrap().stack_size();
174 
175         // 拷贝空洞
176         new_guard.mappings.vm_holes = self.mappings.vm_holes.clone();
177 
178         for vma in self.mappings.vmas.iter() {
179             // TODO: 增加对VMA是否为文件映射的判断,如果是的话,就跳过
180 
181             let vma_guard: SpinLockGuard<'_, VMA> = vma.lock();
182 
183             // 仅拷贝VMA信息并添加反向映射,因为UserMapper克隆时已经分配了新的物理页
184             let new_vma = LockedVMA::new(vma_guard.clone_info_only());
185             new_guard.mappings.vmas.insert(new_vma.clone());
186             // kdebug!("new vma: {:x?}", new_vma);
187             let new_vma_guard = new_vma.lock();
188             let new_mapper = &new_guard.user_mapper.utable;
189             let mut anon_vma_guard = page_manager_lock_irqsave();
190             for page in new_vma_guard.pages().map(|p| p.virt_address()) {
191                 if let Some((paddr, _)) = new_mapper.translate(page) {
192                     let page = anon_vma_guard.get_mut(&paddr);
193                     page.insert_vma(new_vma.clone());
194                 }
195             }
196 
197             drop(anon_vma_guard);
198             drop(vma_guard);
199             drop(new_vma_guard);
200         }
201         drop(new_guard);
202         drop(irq_guard);
203         return Ok(new_addr_space);
204     }
205 
206     /// 拓展用户栈
207     /// ## 参数
208     ///
209     /// - `bytes`: 拓展大小
210     #[allow(dead_code)]
211     pub fn extend_stack(&mut self, mut bytes: usize) -> Result<(), SystemError> {
212         // kdebug!("extend user stack");
213         let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
214         let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN;
215         let stack = self.user_stack.as_mut().unwrap();
216 
217         bytes = page_align_up(bytes);
218         stack.mapped_size += bytes;
219         let len = stack.stack_bottom - stack.mapped_size;
220         self.map_anonymous(len, bytes, prot_flags, map_flags, false, false)?;
221         return Ok(());
222     }
223 
224     /// 判断当前的地址空间是否是当前进程的地址空间
225     #[inline]
226     pub fn is_current(&self) -> bool {
227         return self.user_mapper.utable.is_current();
228     }
229 
230     /// 进行匿名页映射
231     ///
232     /// ## 参数
233     ///
234     /// - `start_vaddr`:映射的起始地址
235     /// - `len`:映射的长度
236     /// - `prot_flags`:保护标志
237     /// - `map_flags`:映射标志
238     /// - `round_to_min`:是否将`start_vaddr`对齐到`mmap_min`,如果为`true`,则当`start_vaddr`不为0时,会对齐到`mmap_min`,否则仅向下对齐到页边界
239     /// - `allocate_at_once`:是否立即分配物理空间
240     ///
241     /// ## 返回
242     ///
243     /// 返回映射的起始虚拟页帧
244     pub fn map_anonymous(
245         &mut self,
246         start_vaddr: VirtAddr,
247         len: usize,
248         prot_flags: ProtFlags,
249         map_flags: MapFlags,
250         round_to_min: bool,
251         allocate_at_once: bool,
252     ) -> Result<VirtPageFrame, SystemError> {
253         let allocate_at_once = if MMArch::PAGE_FAULT_ENABLED {
254             allocate_at_once
255         } else {
256             true
257         };
258         // 用于对齐hint的函数
259         let round_hint_to_min = |hint: VirtAddr| {
260             // 先把hint向下对齐到页边界
261             let addr = hint.data() & (!MMArch::PAGE_OFFSET_MASK);
262             // kdebug!("map_anonymous: hint = {:?}, addr = {addr:#x}", hint);
263             // 如果hint不是0,且hint小于DEFAULT_MMAP_MIN_ADDR,则对齐到DEFAULT_MMAP_MIN_ADDR
264             if (addr != 0) && round_to_min && (addr < DEFAULT_MMAP_MIN_ADDR) {
265                 Some(VirtAddr::new(page_align_up(DEFAULT_MMAP_MIN_ADDR)))
266             } else if addr == 0 {
267                 None
268             } else {
269                 Some(VirtAddr::new(addr))
270             }
271         };
272         // kdebug!("map_anonymous: start_vaddr = {:?}", start_vaddr);
273         // kdebug!("map_anonymous: len(no align) = {}", len);
274 
275         let len = page_align_up(len);
276 
277         let vm_flags = VmFlags::from(prot_flags)
278             | VmFlags::from(map_flags)
279             | VmFlags::VM_MAYREAD
280             | VmFlags::VM_MAYWRITE
281             | VmFlags::VM_MAYEXEC;
282 
283         // kdebug!("map_anonymous: len = {}", len);
284 
285         let start_page: VirtPageFrame = if allocate_at_once {
286             self.mmap(
287                 round_hint_to_min(start_vaddr),
288                 PageFrameCount::from_bytes(len).unwrap(),
289                 prot_flags,
290                 map_flags,
291                 move |page, count, flags, mapper, flusher| {
292                     VMA::zeroed(page, count, vm_flags, flags, mapper, flusher)
293                 },
294             )?
295         } else {
296             self.mmap(
297                 round_hint_to_min(start_vaddr),
298                 PageFrameCount::from_bytes(len).unwrap(),
299                 prot_flags,
300                 map_flags,
301                 move |page, count, flags, _mapper, _flusher| {
302                     Ok(LockedVMA::new(VMA {
303                         region: VirtRegion::new(
304                             page.virt_address(),
305                             count.data() * MMArch::PAGE_SIZE,
306                         ),
307                         vm_flags,
308                         flags,
309                         mapped: true,
310                         user_address_space: None,
311                         self_ref: Weak::default(),
312                         provider: Provider::Allocated,
313                     }))
314                 },
315             )?
316         };
317 
318         return Ok(start_page);
319     }
320 
321     /// 向进程的地址空间映射页面
322     ///
323     /// # 参数
324     ///
325     /// - `addr`:映射的起始地址,如果为`None`,则由内核自动分配
326     /// - `page_count`:映射的页面数量
327     /// - `prot_flags`:保护标志
328     /// - `map_flags`:映射标志
329     /// - `map_func`:映射函数,用于创建VMA
330     ///
331     /// # Returns
332     ///
333     /// 返回映射的起始虚拟页帧
334     ///
335     /// # Errors
336     ///
337     /// - `EINVAL`:参数错误
338     pub fn mmap<
339         F: FnOnce(
340             VirtPageFrame,
341             PageFrameCount,
342             PageFlags<MMArch>,
343             &mut PageMapper,
344             &mut dyn Flusher<MMArch>,
345         ) -> Result<Arc<LockedVMA>, SystemError>,
346     >(
347         &mut self,
348         addr: Option<VirtAddr>,
349         page_count: PageFrameCount,
350         prot_flags: ProtFlags,
351         map_flags: MapFlags,
352         map_func: F,
353     ) -> Result<VirtPageFrame, SystemError> {
354         if page_count == PageFrameCount::new(0) {
355             return Err(SystemError::EINVAL);
356         }
357         // kdebug!("mmap: addr: {addr:?}, page_count: {page_count:?}, prot_flags: {prot_flags:?}, map_flags: {map_flags:?}");
358 
359         // 找到未使用的区域
360         let region = match addr {
361             Some(vaddr) => {
362                 self.mappings
363                     .find_free_at(self.mmap_min, vaddr, page_count.bytes(), map_flags)?
364             }
365             None => self
366                 .mappings
367                 .find_free(self.mmap_min, page_count.bytes())
368                 .ok_or(SystemError::ENOMEM)?,
369         };
370 
371         let page = VirtPageFrame::new(region.start());
372 
373         // kdebug!("mmap: page: {:?}, region={region:?}", page.virt_address());
374 
375         compiler_fence(Ordering::SeqCst);
376         let (mut active, mut inactive);
377         let flusher = if self.is_current() {
378             active = PageFlushAll::new();
379             &mut active as &mut dyn Flusher<MMArch>
380         } else {
381             inactive = InactiveFlusher::new();
382             &mut inactive as &mut dyn Flusher<MMArch>
383         };
384         compiler_fence(Ordering::SeqCst);
385         // 映射页面,并将VMA插入到地址空间的VMA列表中
386         self.mappings.insert_vma(map_func(
387             page,
388             page_count,
389             PageFlags::from_prot_flags(prot_flags, true),
390             &mut self.user_mapper.utable,
391             flusher,
392         )?);
393 
394         return Ok(page);
395     }
396 
397     /// 重映射内存区域
398     ///
399     /// # 参数
400     ///
401     /// - `old_vaddr`:原映射的起始地址
402     /// - `old_len`:原映射的长度
403     /// - `new_len`:重新映射的长度
404     /// - `mremap_flags`:重映射标志
405     /// - `new_vaddr`:重新映射的起始地址
406     /// - `vm_flags`:旧内存区域标志
407     ///
408     /// # Returns
409     ///
410     /// 返回重映射的起始虚拟页帧地址
411     ///
412     /// # Errors
413     ///
414     /// - `EINVAL`:参数错误
415     pub fn mremap(
416         &mut self,
417         old_vaddr: VirtAddr,
418         old_len: usize,
419         new_len: usize,
420         mremap_flags: MremapFlags,
421         new_vaddr: VirtAddr,
422         vm_flags: VmFlags,
423     ) -> Result<VirtAddr, SystemError> {
424         // 检查新内存地址是否对齐
425         if !new_vaddr.check_aligned(MMArch::PAGE_SIZE) {
426             return Err(SystemError::EINVAL);
427         }
428 
429         // 检查新、旧内存区域是否冲突
430         let old_region = VirtRegion::new(old_vaddr, old_len);
431         let new_region = VirtRegion::new(new_vaddr, new_len);
432         if old_region.collide(&new_region) {
433             return Err(SystemError::EINVAL);
434         }
435 
436         // 初始化映射标志
437         let mut map_flags: MapFlags = vm_flags.into();
438         // 初始化内存区域保护标志
439         let prot_flags: ProtFlags = vm_flags.into();
440 
441         // 取消新内存区域的原映射
442         if mremap_flags.contains(MremapFlags::MREMAP_FIXED) {
443             map_flags |= MapFlags::MAP_FIXED;
444             let start_page = VirtPageFrame::new(new_vaddr);
445             let page_count = PageFrameCount::from_bytes(new_len).unwrap();
446             self.munmap(start_page, page_count)?;
447         }
448 
449         // 获取映射后的新内存页面
450         let new_page = self.map_anonymous(new_vaddr, new_len, prot_flags, map_flags, true, true)?;
451         let new_page_vaddr = new_page.virt_address();
452 
453         // 拷贝旧内存区域内容到新内存区域
454         let old_buffer_reader =
455             UserBufferReader::new(old_vaddr.data() as *const u8, old_len, true)?;
456         let old_buf: &[u8] = old_buffer_reader.read_from_user(0)?;
457         let mut new_buffer_writer =
458             UserBufferWriter::new(new_page_vaddr.data() as *mut u8, new_len, true)?;
459         let new_buf: &mut [u8] = new_buffer_writer.buffer(0)?;
460         let len = old_buf.len().min(new_buf.len());
461         new_buf[..len].copy_from_slice(&old_buf[..len]);
462 
463         return Ok(new_page_vaddr);
464     }
465 
466     /// 取消进程的地址空间中的映射
467     ///
468     /// # 参数
469     ///
470     /// - `start_page`:起始页帧
471     /// - `page_count`:取消映射的页帧数量
472     ///
473     /// # Errors
474     ///
475     /// - `EINVAL`:参数错误
476     /// - `ENOMEM`:内存不足
477     pub fn munmap(
478         &mut self,
479         start_page: VirtPageFrame,
480         page_count: PageFrameCount,
481     ) -> Result<(), SystemError> {
482         let to_unmap = VirtRegion::new(start_page.virt_address(), page_count.bytes());
483         let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new();
484 
485         let regions: Vec<Arc<LockedVMA>> = self.mappings.conflicts(to_unmap).collect::<Vec<_>>();
486 
487         for r in regions {
488             let r = r.lock().region;
489             let r = self.mappings.remove_vma(&r).unwrap();
490             let intersection = r.lock().region().intersect(&to_unmap).unwrap();
491             let split_result = r.extract(intersection, &self.user_mapper.utable).unwrap();
492 
493             // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑
494 
495             if let Some(before) = split_result.prev {
496                 // 如果前面有VMA,则需要将前面的VMA重新插入到地址空间的VMA列表中
497                 self.mappings.insert_vma(before);
498             }
499 
500             if let Some(after) = split_result.after {
501                 // 如果后面有VMA,则需要将后面的VMA重新插入到地址空间的VMA列表中
502                 self.mappings.insert_vma(after);
503             }
504 
505             r.unmap(&mut self.user_mapper.utable, &mut flusher);
506         }
507 
508         // TODO: 当引入后备页映射后,这里需要增加通知文件的逻辑
509 
510         return Ok(());
511     }
512 
513     pub fn mprotect(
514         &mut self,
515         start_page: VirtPageFrame,
516         page_count: PageFrameCount,
517         prot_flags: ProtFlags,
518     ) -> Result<(), SystemError> {
519         // kdebug!(
520         //     "mprotect: start_page: {:?}, page_count: {:?}, prot_flags:{prot_flags:?}",
521         //     start_page,
522         //     page_count
523         // );
524         let (mut active, mut inactive);
525         let mut flusher = if self.is_current() {
526             active = PageFlushAll::new();
527             &mut active as &mut dyn Flusher<MMArch>
528         } else {
529             inactive = InactiveFlusher::new();
530             &mut inactive as &mut dyn Flusher<MMArch>
531         };
532 
533         let mapper = &mut self.user_mapper.utable;
534         let region = VirtRegion::new(start_page.virt_address(), page_count.bytes());
535         // kdebug!("mprotect: region: {:?}", region);
536 
537         let regions = self.mappings.conflicts(region).collect::<Vec<_>>();
538         // kdebug!("mprotect: regions: {:?}", regions);
539 
540         for r in regions {
541             // kdebug!("mprotect: r: {:?}", r);
542             let r = *r.lock().region();
543             let r = self.mappings.remove_vma(&r).unwrap();
544 
545             let intersection = r.lock().region().intersect(&region).unwrap();
546             let split_result = r
547                 .extract(intersection, mapper)
548                 .expect("Failed to extract VMA");
549 
550             if let Some(before) = split_result.prev {
551                 self.mappings.insert_vma(before);
552             }
553             if let Some(after) = split_result.after {
554                 self.mappings.insert_vma(after);
555             }
556 
557             let mut r_guard = r.lock();
558             // 如果VMA的保护标志不允许指定的修改,则返回错误
559             if !r_guard.can_have_flags(prot_flags) {
560                 drop(r_guard);
561                 self.mappings.insert_vma(r.clone());
562                 return Err(SystemError::EACCES);
563             }
564 
565             let new_flags: PageFlags<MMArch> = r_guard
566                 .flags()
567                 .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC))
568                 .set_write(prot_flags.contains(ProtFlags::PROT_WRITE));
569 
570             r_guard.remap(new_flags, mapper, &mut flusher)?;
571             drop(r_guard);
572             self.mappings.insert_vma(r);
573         }
574 
575         return Ok(());
576     }
577 
578     pub fn madvise(
579         &mut self,
580         start_page: VirtPageFrame,
581         page_count: PageFrameCount,
582         behavior: MadvFlags,
583     ) -> Result<(), SystemError> {
584         let (mut active, mut inactive);
585         let mut flusher = if self.is_current() {
586             active = PageFlushAll::new();
587             &mut active as &mut dyn Flusher<MMArch>
588         } else {
589             inactive = InactiveFlusher::new();
590             &mut inactive as &mut dyn Flusher<MMArch>
591         };
592 
593         let mapper = &mut self.user_mapper.utable;
594 
595         let region = VirtRegion::new(start_page.virt_address(), page_count.bytes());
596         let regions = self.mappings.conflicts(region).collect::<Vec<_>>();
597 
598         for r in regions {
599             let r = *r.lock().region();
600             let r = self.mappings.remove_vma(&r).unwrap();
601 
602             let intersection = r.lock().region().intersect(&region).unwrap();
603             let split_result = r
604                 .extract(intersection, mapper)
605                 .expect("Failed to extract VMA");
606 
607             if let Some(before) = split_result.prev {
608                 self.mappings.insert_vma(before);
609             }
610             if let Some(after) = split_result.after {
611                 self.mappings.insert_vma(after);
612             }
613             r.do_madvise(behavior, mapper, &mut flusher)?;
614             self.mappings.insert_vma(r);
615         }
616         Ok(())
617     }
618 
619     /// 创建新的用户栈
620     ///
621     /// ## 参数
622     ///
623     /// - `size`:栈的大小
624     pub fn new_user_stack(&mut self, size: usize) -> Result<(), SystemError> {
625         assert!(self.user_stack.is_none(), "User stack already exists");
626         let stack = UserStack::new(self, None, size)?;
627         self.user_stack = Some(stack);
628         return Ok(());
629     }
630 
631     #[inline(always)]
632     pub fn user_stack_mut(&mut self) -> Option<&mut UserStack> {
633         return self.user_stack.as_mut();
634     }
635 
636     /// 取消用户空间内的所有映射
637     pub unsafe fn unmap_all(&mut self) {
638         let mut flusher: PageFlushAll<MMArch> = PageFlushAll::new();
639         for vma in self.mappings.iter_vmas() {
640             if vma.mapped() {
641                 vma.unmap(&mut self.user_mapper.utable, &mut flusher);
642             }
643         }
644     }
645 
646     /// 设置进程的堆的内存空间
647     ///
648     /// ## 参数
649     ///
650     /// - `new_brk`:新的堆的结束地址。需要满足页对齐要求,并且是用户空间地址,且大于等于当前的堆的起始地址
651     ///
652     /// ## 返回值
653     ///
654     /// 返回旧的堆的结束地址
655     pub unsafe fn set_brk(&mut self, new_brk: VirtAddr) -> Result<VirtAddr, SystemError> {
656         assert!(new_brk.check_aligned(MMArch::PAGE_SIZE));
657 
658         if !new_brk.check_user() || new_brk < self.brk_start {
659             return Err(SystemError::EFAULT);
660         }
661 
662         let old_brk = self.brk;
663 
664         if new_brk > self.brk {
665             let len = new_brk - self.brk;
666             let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
667             let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_FIXED;
668             self.map_anonymous(old_brk, len, prot_flags, map_flags, true, false)?;
669 
670             self.brk = new_brk;
671             return Ok(old_brk);
672         } else {
673             let unmap_len = self.brk - new_brk;
674             let unmap_start = new_brk;
675             if unmap_len == 0 {
676                 return Ok(old_brk);
677             }
678             self.munmap(
679                 VirtPageFrame::new(unmap_start),
680                 PageFrameCount::from_bytes(unmap_len).unwrap(),
681             )?;
682             self.brk = new_brk;
683             return Ok(old_brk);
684         }
685     }
686 
687     pub unsafe fn sbrk(&mut self, incr: isize) -> Result<VirtAddr, SystemError> {
688         if incr == 0 {
689             return Ok(self.brk);
690         }
691 
692         let new_brk = if incr > 0 {
693             self.brk + incr as usize
694         } else {
695             self.brk - incr.unsigned_abs()
696         };
697 
698         let new_brk = VirtAddr::new(page_align_up(new_brk.data()));
699 
700         return self.set_brk(new_brk);
701     }
702 }
703 
704 impl Drop for InnerAddressSpace {
705     fn drop(&mut self) {
706         unsafe {
707             self.unmap_all();
708         }
709     }
710 }
711 
712 #[derive(Debug, Hash)]
713 pub struct UserMapper {
714     pub utable: PageMapper,
715 }
716 
717 impl UserMapper {
718     pub fn new(utable: PageMapper) -> Self {
719         return Self { utable };
720     }
721 
722     /// 拷贝用户空间映射
723     /// ## 参数
724     ///
725     /// - `umapper`: 要拷贝的用户空间
726     /// - `copy_on_write`: 是否写时复制
727     pub unsafe fn clone_from(&mut self, umapper: &mut Self, copy_on_write: bool) {
728         self.utable
729             .clone_user_mapping(&mut umapper.utable, copy_on_write);
730     }
731 }
732 
733 impl Drop for UserMapper {
734     fn drop(&mut self) {
735         if self.utable.is_current() {
736             // 如果当前要被销毁的用户空间的页表是当前进程的页表,那么就切换回初始内核页表
737             unsafe { MMArch::set_table(PageTableKind::User, MMArch::initial_page_table()) }
738         }
739         // 释放用户空间顶层页表占用的页帧
740         // 请注意,在释放这个页帧之前,用户页表应该已经被完全释放,否则会产生内存泄露
741         unsafe {
742             deallocate_page_frames(
743                 PhysPageFrame::new(self.utable.table().phys()),
744                 PageFrameCount::new(1),
745                 &mut page_manager_lock_irqsave(),
746             )
747         };
748     }
749 }
750 
751 /// 用户空间映射信息
752 #[derive(Debug)]
753 pub struct UserMappings {
754     /// 当前用户空间的虚拟内存区域
755     vmas: HashSet<Arc<LockedVMA>>,
756     /// 当前用户空间的VMA空洞
757     vm_holes: BTreeMap<VirtAddr, usize>,
758 }
759 
760 impl UserMappings {
761     pub fn new() -> Self {
762         return Self {
763             vmas: HashSet::new(),
764             vm_holes: core::iter::once((VirtAddr::new(0), MMArch::USER_END_VADDR.data()))
765                 .collect::<BTreeMap<_, _>>(),
766         };
767     }
768 
769     /// 判断当前进程的VMA内,是否有包含指定的虚拟地址的VMA。
770     ///
771     /// 如果有,返回包含指定虚拟地址的VMA的Arc指针,否则返回None。
772     #[allow(dead_code)]
773     pub fn contains(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> {
774         for v in self.vmas.iter() {
775             let guard = v.lock();
776             if guard.region.contains(vaddr) {
777                 return Some(v.clone());
778             }
779         }
780         return None;
781     }
782 
783     /// 向下寻找距离虚拟地址最近的VMA
784     /// ## 参数
785     ///
786     /// - `vaddr`: 虚拟地址
787     ///
788     /// ## 返回值
789     /// - Some(Arc<LockedVMA>): 虚拟地址所在的或最近的下一个VMA
790     /// - None: 未找到VMA
791     #[allow(dead_code)]
792     pub fn find_nearest(&self, vaddr: VirtAddr) -> Option<Arc<LockedVMA>> {
793         let mut nearest: Option<Arc<LockedVMA>> = None;
794         for v in self.vmas.iter() {
795             let guard = v.lock();
796             if guard.region.contains(vaddr) {
797                 return Some(v.clone());
798             }
799             if guard.region.start > vaddr
800                 && if let Some(ref nearest) = nearest {
801                     guard.region.start < nearest.lock().region.start
802                 } else {
803                     true
804                 }
805             {
806                 nearest = Some(v.clone());
807             }
808         }
809         return nearest;
810     }
811 
812     /// 获取当前进程的地址空间中,与给定虚拟地址范围有重叠的VMA的迭代器。
813     pub fn conflicts(&self, request: VirtRegion) -> impl Iterator<Item = Arc<LockedVMA>> + '_ {
814         let r = self
815             .vmas
816             .iter()
817             .filter(move |v| v.lock().region.intersect(&request).is_some())
818             .cloned();
819         return r;
820     }
821 
822     /// 在当前进程的地址空间中,寻找第一个符合条件的空闲的虚拟内存范围。
823     ///
824     /// @param min_vaddr 最小的起始地址
825     /// @param size 请求的大小
826     ///
827     /// @return 如果找到了,返回虚拟内存范围,否则返回None
828     pub fn find_free(&self, min_vaddr: VirtAddr, size: usize) -> Option<VirtRegion> {
829         let _vaddr = min_vaddr;
830         let mut iter = self
831             .vm_holes
832             .iter()
833             .skip_while(|(hole_vaddr, hole_size)| hole_vaddr.add(**hole_size) <= min_vaddr);
834 
835         let (hole_vaddr, size) = iter.find(|(hole_vaddr, hole_size)| {
836             // 计算当前空洞的可用大小
837             let available_size: usize =
838                 if hole_vaddr <= &&min_vaddr && min_vaddr <= hole_vaddr.add(**hole_size) {
839                     **hole_size - (min_vaddr - **hole_vaddr)
840                 } else {
841                     **hole_size
842                 };
843 
844             size <= available_size
845         })?;
846 
847         // 创建一个新的虚拟内存范围。
848         let region = VirtRegion::new(cmp::max(*hole_vaddr, min_vaddr), *size);
849 
850         return Some(region);
851     }
852 
853     pub fn find_free_at(
854         &self,
855         min_vaddr: VirtAddr,
856         vaddr: VirtAddr,
857         size: usize,
858         flags: MapFlags,
859     ) -> Result<VirtRegion, SystemError> {
860         // 如果没有指定地址,那么就在当前进程的地址空间中寻找一个空闲的虚拟内存范围。
861         if vaddr == VirtAddr::new(0) {
862             return self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM);
863         }
864 
865         // 如果指定了地址,那么就检查指定的地址是否可用。
866 
867         let requested = VirtRegion::new(vaddr, size);
868 
869         if requested.end() >= MMArch::USER_END_VADDR || !vaddr.check_aligned(MMArch::PAGE_SIZE) {
870             return Err(SystemError::EINVAL);
871         }
872 
873         if let Some(_x) = self.conflicts(requested).next() {
874             if flags.contains(MapFlags::MAP_FIXED_NOREPLACE) {
875                 // 如果指定了 MAP_FIXED_NOREPLACE 标志,由于所指定的地址无法成功建立映射,则放弃映射,不对地址做修正
876                 return Err(SystemError::EEXIST);
877             }
878 
879             if flags.contains(MapFlags::MAP_FIXED) {
880                 // todo: 支持MAP_FIXED标志对已有的VMA进行覆盖
881                 return Err(SystemError::ENOSYS);
882             }
883 
884             // 如果没有指定MAP_FIXED标志,那么就对地址做修正
885             let requested = self.find_free(min_vaddr, size).ok_or(SystemError::ENOMEM)?;
886             return Ok(requested);
887         }
888 
889         return Ok(requested);
890     }
891 
892     /// 在当前进程的地址空间中,保留一个指定大小的区域,使得该区域不在空洞中。
893     /// 该函数会修改vm_holes中的空洞信息。
894     ///
895     /// @param region 要保留的区域
896     ///
897     /// 请注意,在调用本函数之前,必须先确定region所在范围内没有VMA。
898     fn reserve_hole(&mut self, region: &VirtRegion) {
899         let prev_hole: Option<(&VirtAddr, &mut usize)> =
900             self.vm_holes.range_mut(..=region.start()).next_back();
901 
902         if let Some((prev_hole_vaddr, prev_hole_size)) = prev_hole {
903             let prev_hole_end = prev_hole_vaddr.add(*prev_hole_size);
904 
905             if prev_hole_end > region.start() {
906                 // 如果前一个空洞的结束地址大于当前空洞的起始地址,那么就需要调整前一个空洞的大小。
907                 *prev_hole_size = region.start().data() - prev_hole_vaddr.data();
908             }
909 
910             if prev_hole_end > region.end() {
911                 // 如果前一个空洞的结束地址大于当前空洞的结束地址,那么就需要增加一个新的空洞。
912                 self.vm_holes
913                     .insert(region.end(), prev_hole_end - region.end());
914             }
915         }
916     }
917 
918     /// 在当前进程的地址空间中,释放一个指定大小的区域,使得该区域成为一个空洞。
919     /// 该函数会修改vm_holes中的空洞信息。
920     fn unreserve_hole(&mut self, region: &VirtRegion) {
921         // 如果将要插入的空洞与后一个空洞相邻,那么就需要合并。
922         let next_hole_size: Option<usize> = self.vm_holes.remove(&region.end());
923 
924         if let Some((_prev_hole_vaddr, prev_hole_size)) = self
925             .vm_holes
926             .range_mut(..region.start())
927             .next_back()
928             .filter(|(offset, size)| offset.data() + **size == region.start().data())
929         {
930             *prev_hole_size += region.size() + next_hole_size.unwrap_or(0);
931         } else {
932             self.vm_holes
933                 .insert(region.start(), region.size() + next_hole_size.unwrap_or(0));
934         }
935     }
936 
937     /// 在当前进程的映射关系中,插入一个新的VMA。
938     pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) {
939         let region = vma.lock().region;
940         // 要求插入的地址范围必须是空闲的,也就是说,当前进程的地址空间中,不能有任何与之重叠的VMA。
941         assert!(self.conflicts(region).next().is_none());
942         self.reserve_hole(&region);
943 
944         self.vmas.insert(vma);
945     }
946 
947     /// @brief 删除一个VMA,并把对应的地址空间加入空洞中。
948     ///
949     /// 这里不会取消VMA对应的地址的映射
950     ///
951     /// @param region 要删除的VMA所在的地址范围
952     ///
953     /// @return 如果成功删除了VMA,则返回被删除的VMA,否则返回None
954     /// 如果没有可以删除的VMA,则不会执行删除操作,并报告失败。
955     pub fn remove_vma(&mut self, region: &VirtRegion) -> Option<Arc<LockedVMA>> {
956         // 请注意,由于这里会对每个VMA加锁,因此性能很低
957         let vma: Arc<LockedVMA> = self
958             .vmas
959             .drain_filter(|vma| vma.lock().region == *region)
960             .next()?;
961         self.unreserve_hole(region);
962 
963         return Some(vma);
964     }
965 
966     /// @brief Get the iterator of all VMAs in this process.
967     pub fn iter_vmas(&self) -> hashbrown::hash_set::Iter<Arc<LockedVMA>> {
968         return self.vmas.iter();
969     }
970 }
971 
972 impl Default for UserMappings {
973     fn default() -> Self {
974         return Self::new();
975     }
976 }
977 
978 /// 加了锁的VMA
979 ///
980 /// 备注:进行性能测试,看看SpinLock和RwLock哪个更快。
981 #[derive(Debug)]
982 pub struct LockedVMA {
983     /// 用于计算哈希值,避免总是获取vma锁来计算哈希值
984     id: usize,
985     vma: SpinLock<VMA>,
986 }
987 
988 impl core::hash::Hash for LockedVMA {
989     fn hash<H: Hasher>(&self, state: &mut H) {
990         self.id.hash(state);
991     }
992 }
993 
994 impl PartialEq for LockedVMA {
995     fn eq(&self, other: &Self) -> bool {
996         self.id.eq(&other.id)
997     }
998 }
999 
1000 impl Eq for LockedVMA {}
1001 
1002 #[allow(dead_code)]
1003 impl LockedVMA {
1004     pub fn new(vma: VMA) -> Arc<Self> {
1005         let r = Arc::new(Self {
1006             id: LOCKEDVMA_ID_ALLOCATOR.alloc().unwrap(),
1007             vma: SpinLock::new(vma),
1008         });
1009         r.vma.lock().self_ref = Arc::downgrade(&r);
1010         return r;
1011     }
1012 
1013     pub fn id(&self) -> usize {
1014         self.id
1015     }
1016 
1017     pub fn lock(&self) -> SpinLockGuard<VMA> {
1018         return self.vma.lock();
1019     }
1020 
1021     /// 调整当前VMA的页面的标志位
1022     ///
1023     /// TODO:增加调整虚拟页映射的物理地址的功能
1024     ///
1025     /// @param flags 新的标志位
1026     /// @param mapper 页表映射器
1027     /// @param flusher 页表项刷新器
1028     ///
1029     pub fn remap(
1030         &self,
1031         flags: PageFlags<MMArch>,
1032         mapper: &mut PageMapper,
1033         mut flusher: impl Flusher<MMArch>,
1034     ) -> Result<(), SystemError> {
1035         let mut guard = self.lock();
1036         assert!(guard.mapped);
1037         for page in guard.region.pages() {
1038             // 暂时要求所有的页帧都已经映射到页表
1039             // TODO: 引入Lazy Mapping, 通过缺页中断来映射页帧,这里就不必要求所有的页帧都已经映射到页表了
1040             let r = unsafe {
1041                 mapper
1042                     .remap(page.virt_address(), flags)
1043                     .expect("Failed to remap, beacuse of some page is not mapped")
1044             };
1045             flusher.consume(r);
1046         }
1047         guard.flags = flags;
1048         return Ok(());
1049     }
1050 
1051     pub fn unmap(&self, mapper: &mut PageMapper, mut flusher: impl Flusher<MMArch>) {
1052         // todo: 如果当前vma与文件相关,完善文件相关的逻辑
1053 
1054         let mut guard = self.lock();
1055         assert!(guard.mapped);
1056 
1057         // 获取物理页的anon_vma的守卫
1058         let mut page_manager_guard: SpinLockGuard<'_, crate::mm::page::PageManager> =
1059             page_manager_lock_irqsave();
1060         for page in guard.region.pages() {
1061             if mapper.translate(page.virt_address()).is_none() {
1062                 continue;
1063             }
1064             let (paddr, _, flush) = unsafe { mapper.unmap_phys(page.virt_address(), true) }
1065                 .expect("Failed to unmap, beacuse of some page is not mapped");
1066 
1067             // 从anon_vma中删除当前VMA
1068             let page = page_manager_guard.get_mut(&paddr);
1069             page.remove_vma(self);
1070 
1071             // 如果物理页的anon_vma链表长度为0并且不是共享页,则释放物理页.
1072             if page.can_deallocate() {
1073                 unsafe {
1074                     deallocate_page_frames(
1075                         PhysPageFrame::new(paddr),
1076                         PageFrameCount::new(1),
1077                         &mut page_manager_guard,
1078                     )
1079                 };
1080             }
1081 
1082             flusher.consume(flush);
1083         }
1084         guard.mapped = false;
1085     }
1086 
1087     pub fn mapped(&self) -> bool {
1088         return self.vma.lock().mapped;
1089     }
1090 
1091     /// 将当前VMA进行切分,切分成3个VMA,分别是:
1092     ///
1093     /// 1. 前面的VMA,如果没有则为None
1094     /// 2. 中间的VMA,也就是传入的Region
1095     /// 3. 后面的VMA,如果没有则为None
1096     pub fn extract(&self, region: VirtRegion, utable: &PageMapper) -> Option<VMASplitResult> {
1097         assert!(region.start().check_aligned(MMArch::PAGE_SIZE));
1098         assert!(region.end().check_aligned(MMArch::PAGE_SIZE));
1099 
1100         let mut guard = self.lock();
1101         {
1102             // 如果传入的region不在当前VMA的范围内,则直接返回None
1103             if unlikely(region.start() < guard.region.start() || region.end() > guard.region.end())
1104             {
1105                 return None;
1106             }
1107 
1108             let intersect: Option<VirtRegion> = guard.region.intersect(&region);
1109             // 如果当前VMA不包含region,则直接返回None
1110             if unlikely(intersect.is_none()) {
1111                 return None;
1112             }
1113             let intersect: VirtRegion = intersect.unwrap();
1114             if unlikely(intersect == guard.region) {
1115                 // 如果当前VMA完全包含region,则直接返回当前VMA
1116                 return Some(VMASplitResult::new(
1117                     None,
1118                     guard.self_ref.upgrade().unwrap(),
1119                     None,
1120                 ));
1121             }
1122         }
1123 
1124         let before: Option<Arc<LockedVMA>> = guard.region.before(&region).map(|virt_region| {
1125             let mut vma: VMA = unsafe { guard.clone() };
1126             vma.region = virt_region;
1127 
1128             let vma: Arc<LockedVMA> = LockedVMA::new(vma);
1129             vma
1130         });
1131 
1132         let after: Option<Arc<LockedVMA>> = guard.region.after(&region).map(|virt_region| {
1133             let mut vma: VMA = unsafe { guard.clone() };
1134             vma.region = virt_region;
1135 
1136             let vma: Arc<LockedVMA> = LockedVMA::new(vma);
1137             vma
1138         });
1139 
1140         // 重新设置before、after这两个VMA里面的物理页的anon_vma
1141         let mut page_manager_guard = page_manager_lock_irqsave();
1142         if let Some(before) = before.clone() {
1143             let virt_iter = before.lock().region.iter_pages();
1144             for frame in virt_iter {
1145                 let paddr = utable.translate(frame.virt_address()).unwrap().0;
1146                 let page = page_manager_guard.get_mut(&paddr);
1147                 page.insert_vma(before.clone());
1148                 page.remove_vma(self);
1149             }
1150         }
1151 
1152         if let Some(after) = after.clone() {
1153             let virt_iter = after.lock().region.iter_pages();
1154             for frame in virt_iter {
1155                 let paddr = utable.translate(frame.virt_address()).unwrap().0;
1156                 let page = page_manager_guard.get_mut(&paddr);
1157                 page.insert_vma(after.clone());
1158                 page.remove_vma(self);
1159             }
1160         }
1161 
1162         guard.region = region;
1163 
1164         return Some(VMASplitResult::new(
1165             before,
1166             guard.self_ref.upgrade().unwrap(),
1167             after,
1168         ));
1169     }
1170 
1171     /// 判断VMA是否为外部(非当前进程空间)的VMA
1172     pub fn is_foreign(&self) -> bool {
1173         let guard = self.lock();
1174         if let Some(space) = guard.user_address_space.clone() {
1175             if let Some(space) = space.upgrade() {
1176                 return AddressSpace::is_current(&space);
1177             } else {
1178                 return true;
1179             }
1180         } else {
1181             return true;
1182         }
1183     }
1184 
1185     /// 判断VMA是否可访问
1186     pub fn is_accessible(&self) -> bool {
1187         let guard = self.lock();
1188         let vm_access_flags: VmFlags = VmFlags::VM_READ | VmFlags::VM_WRITE | VmFlags::VM_EXEC;
1189         guard.vm_flags().intersects(vm_access_flags)
1190     }
1191 
1192     /// 判断VMA是否为匿名映射
1193     pub fn is_anonymous(&self) -> bool {
1194         //TODO: 实现匿名映射判断逻辑,目前仅支持匿名映射
1195         true
1196     }
1197 
1198     /// 判断VMA是否为大页映射
1199     pub fn is_hugepage(&self) -> bool {
1200         //TODO: 实现巨页映射判断逻辑,目前不支持巨页映射
1201         false
1202     }
1203 }
1204 
1205 impl Drop for LockedVMA {
1206     fn drop(&mut self) {
1207         LOCKEDVMA_ID_ALLOCATOR.free(self.id);
1208     }
1209 }
1210 
1211 /// VMA切分结果
1212 pub struct VMASplitResult {
1213     pub prev: Option<Arc<LockedVMA>>,
1214     pub middle: Arc<LockedVMA>,
1215     pub after: Option<Arc<LockedVMA>>,
1216 }
1217 
1218 impl VMASplitResult {
1219     pub fn new(
1220         prev: Option<Arc<LockedVMA>>,
1221         middle: Arc<LockedVMA>,
1222         post: Option<Arc<LockedVMA>>,
1223     ) -> Self {
1224         Self {
1225             prev,
1226             middle,
1227             after: post,
1228         }
1229     }
1230 }
1231 
1232 /// @brief 虚拟内存区域
1233 #[derive(Debug)]
1234 pub struct VMA {
1235     /// 虚拟内存区域对应的虚拟地址范围
1236     region: VirtRegion,
1237     /// 虚拟内存区域标志
1238     vm_flags: VmFlags,
1239     /// VMA内的页帧的标志
1240     flags: PageFlags<MMArch>,
1241     /// VMA内的页帧是否已经映射到页表
1242     mapped: bool,
1243     /// VMA所属的用户地址空间
1244     user_address_space: Option<Weak<AddressSpace>>,
1245     self_ref: Weak<LockedVMA>,
1246 
1247     provider: Provider,
1248 }
1249 
1250 impl core::hash::Hash for VMA {
1251     fn hash<H: Hasher>(&self, state: &mut H) {
1252         self.region.hash(state);
1253         self.flags.hash(state);
1254         self.mapped.hash(state);
1255     }
1256 }
1257 
1258 /// 描述不同类型的内存提供者或资源
1259 #[derive(Debug)]
1260 pub enum Provider {
1261     Allocated, // TODO:其他
1262 }
1263 
1264 #[allow(dead_code)]
1265 impl VMA {
1266     pub fn new(
1267         region: VirtRegion,
1268         vm_flags: VmFlags,
1269         flags: PageFlags<MMArch>,
1270         mapped: bool,
1271     ) -> Self {
1272         VMA {
1273             region,
1274             vm_flags,
1275             flags,
1276             mapped,
1277             user_address_space: None,
1278             self_ref: Weak::default(),
1279             provider: Provider::Allocated,
1280         }
1281     }
1282 
1283     pub fn region(&self) -> &VirtRegion {
1284         return &self.region;
1285     }
1286 
1287     pub fn vm_flags(&self) -> &VmFlags {
1288         return &self.vm_flags;
1289     }
1290 
1291     pub fn set_vm_flags(&mut self, vm_flags: VmFlags) {
1292         self.vm_flags = vm_flags;
1293     }
1294 
1295     pub fn set_region_size(&mut self, new_region_size: usize) {
1296         self.region.set_size(new_region_size);
1297     }
1298 
1299     pub fn set_mapped(&mut self, mapped: bool) {
1300         self.mapped = mapped;
1301     }
1302 
1303     /// # 拷贝当前VMA的内容
1304     ///
1305     /// ### 安全性
1306     ///
1307     /// 由于这样操作可能由于错误的拷贝,导致内存泄露、内存重复释放等问题,所以需要小心使用。
1308     pub unsafe fn clone(&self) -> Self {
1309         return Self {
1310             region: self.region,
1311             vm_flags: self.vm_flags,
1312             flags: self.flags,
1313             mapped: self.mapped,
1314             user_address_space: self.user_address_space.clone(),
1315             self_ref: self.self_ref.clone(),
1316             provider: Provider::Allocated,
1317         };
1318     }
1319 
1320     pub fn clone_info_only(&self) -> Self {
1321         return Self {
1322             region: self.region,
1323             vm_flags: self.vm_flags,
1324             flags: self.flags,
1325             mapped: self.mapped,
1326             user_address_space: None,
1327             self_ref: Weak::default(),
1328             provider: Provider::Allocated,
1329         };
1330     }
1331 
1332     #[inline(always)]
1333     pub fn flags(&self) -> PageFlags<MMArch> {
1334         return self.flags;
1335     }
1336 
1337     pub fn pages(&self) -> VirtPageFrameIter {
1338         return VirtPageFrameIter::new(
1339             VirtPageFrame::new(self.region.start()),
1340             VirtPageFrame::new(self.region.end()),
1341         );
1342     }
1343 
1344     pub fn remap(
1345         &mut self,
1346         flags: PageFlags<MMArch>,
1347         mapper: &mut PageMapper,
1348         mut flusher: impl Flusher<MMArch>,
1349     ) -> Result<(), SystemError> {
1350         assert!(self.mapped);
1351         for page in self.region.pages() {
1352             // kdebug!("remap page {:?}", page.virt_address());
1353             if mapper.translate(page.virt_address()).is_some() {
1354                 let r = unsafe {
1355                     mapper
1356                         .remap(page.virt_address(), flags)
1357                         .expect("Failed to remap")
1358                 };
1359                 flusher.consume(r);
1360             }
1361             // kdebug!("consume page {:?}", page.virt_address());
1362             // kdebug!("remap page {:?} done", page.virt_address());
1363         }
1364         self.flags = flags;
1365         return Ok(());
1366     }
1367 
1368     /// 检查当前VMA是否可以拥有指定的标志位
1369     ///
1370     /// ## 参数
1371     ///
1372     /// - `prot_flags` 要检查的标志位
1373     pub fn can_have_flags(&self, prot_flags: ProtFlags) -> bool {
1374         let is_downgrade = (self.flags.has_write() || !prot_flags.contains(ProtFlags::PROT_WRITE))
1375             && (self.flags.has_execute() || !prot_flags.contains(ProtFlags::PROT_EXEC));
1376 
1377         match self.provider {
1378             Provider::Allocated { .. } => true,
1379 
1380             #[allow(unreachable_patterns)]
1381             _ => is_downgrade,
1382         }
1383     }
1384 
1385     /// 把物理地址映射到虚拟地址
1386     ///
1387     /// @param phys 要映射的物理地址
1388     /// @param destination 要映射到的虚拟地址
1389     /// @param count 要映射的页帧数量
1390     /// @param flags 页面标志位
1391     /// @param mapper 页表映射器
1392     /// @param flusher 页表项刷新器
1393     ///
1394     /// @return 返回映射后的虚拟内存区域
1395     pub fn physmap(
1396         phys: PhysPageFrame,
1397         destination: VirtPageFrame,
1398         count: PageFrameCount,
1399         vm_flags: VmFlags,
1400         flags: PageFlags<MMArch>,
1401         mapper: &mut PageMapper,
1402         mut flusher: impl Flusher<MMArch>,
1403     ) -> Result<Arc<LockedVMA>, SystemError> {
1404         let mut cur_phy = phys;
1405         let mut cur_dest = destination;
1406 
1407         for _ in 0..count.data() {
1408             // 将物理页帧映射到虚拟页帧
1409             let r =
1410                 unsafe { mapper.map_phys(cur_dest.virt_address(), cur_phy.phys_address(), flags) }
1411                     .expect("Failed to map phys, may be OOM error");
1412 
1413             // todo: 增加OOM处理
1414 
1415             // 刷新TLB
1416             flusher.consume(r);
1417 
1418             cur_phy = cur_phy.next();
1419             cur_dest = cur_dest.next();
1420         }
1421 
1422         let r: Arc<LockedVMA> = LockedVMA::new(VMA {
1423             region: VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE),
1424             vm_flags,
1425             flags,
1426             mapped: true,
1427             user_address_space: None,
1428             self_ref: Weak::default(),
1429             provider: Provider::Allocated,
1430         });
1431 
1432         // 将VMA加入到anon_vma中
1433         let mut page_manager_guard = page_manager_lock_irqsave();
1434         cur_phy = phys;
1435         for _ in 0..count.data() {
1436             let paddr = cur_phy.phys_address();
1437             let page = page_manager_guard.get_mut(&paddr);
1438             page.insert_vma(r.clone());
1439             cur_phy = cur_phy.next();
1440         }
1441 
1442         return Ok(r);
1443     }
1444 
1445     /// 从页分配器中分配一些物理页,并把它们映射到指定的虚拟地址,然后创建VMA
1446     ///
1447     /// @param destination 要映射到的虚拟地址
1448     /// @param count 要映射的页帧数量
1449     /// @param flags 页面标志位
1450     /// @param mapper 页表映射器
1451     /// @param flusher 页表项刷新器
1452     ///
1453     /// @return 返回映射后的虚拟内存区域
1454     pub fn zeroed(
1455         destination: VirtPageFrame,
1456         page_count: PageFrameCount,
1457         vm_flags: VmFlags,
1458         flags: PageFlags<MMArch>,
1459         mapper: &mut PageMapper,
1460         mut flusher: impl Flusher<MMArch>,
1461     ) -> Result<Arc<LockedVMA>, SystemError> {
1462         let mut cur_dest: VirtPageFrame = destination;
1463         // kdebug!(
1464         //     "VMA::zeroed: page_count = {:?}, destination={destination:?}",
1465         //     page_count
1466         // );
1467         for _ in 0..page_count.data() {
1468             // kdebug!(
1469             //     "VMA::zeroed: cur_dest={cur_dest:?}, vaddr = {:?}",
1470             //     cur_dest.virt_address()
1471             // );
1472             let r = unsafe { mapper.map(cur_dest.virt_address(), flags) }
1473                 .expect("Failed to map zero, may be OOM error");
1474             // todo: 增加OOM处理
1475 
1476             // 稍后再刷新TLB,这里取消刷新
1477             flusher.consume(r);
1478             cur_dest = cur_dest.next();
1479         }
1480         let r = LockedVMA::new(VMA {
1481             region: VirtRegion::new(
1482                 destination.virt_address(),
1483                 page_count.data() * MMArch::PAGE_SIZE,
1484             ),
1485             vm_flags,
1486             flags,
1487             mapped: true,
1488             user_address_space: None,
1489             self_ref: Weak::default(),
1490             provider: Provider::Allocated,
1491         });
1492         drop(flusher);
1493         // kdebug!("VMA::zeroed: flusher dropped");
1494 
1495         // 清空这些内存并将VMA加入到anon_vma中
1496         let mut page_manager_guard = page_manager_lock_irqsave();
1497         let virt_iter: VirtPageFrameIter =
1498             VirtPageFrameIter::new(destination, destination.add(page_count));
1499         for frame in virt_iter {
1500             let paddr = mapper.translate(frame.virt_address()).unwrap().0;
1501 
1502             // 将VMA加入到anon_vma
1503             let page = page_manager_guard.get_mut(&paddr);
1504             page.insert_vma(r.clone());
1505 
1506             // 清空内存
1507             unsafe {
1508                 let vaddr = MMArch::phys_2_virt(paddr).unwrap();
1509                 MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE);
1510             }
1511         }
1512         // kdebug!("VMA::zeroed: done");
1513         return Ok(r);
1514     }
1515 }
1516 
1517 impl Drop for VMA {
1518     fn drop(&mut self) {
1519         // 当VMA被释放时,需要确保它已经被从页表中解除映射
1520         assert!(!self.mapped, "VMA is still mapped");
1521     }
1522 }
1523 
1524 impl PartialEq for VMA {
1525     fn eq(&self, other: &Self) -> bool {
1526         return self.region == other.region;
1527     }
1528 }
1529 
1530 impl Eq for VMA {}
1531 
1532 impl PartialOrd for VMA {
1533     fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1534         Some(self.cmp(other))
1535     }
1536 }
1537 
1538 impl Ord for VMA {
1539     fn cmp(&self, other: &Self) -> cmp::Ordering {
1540         return self.region.cmp(&other.region);
1541     }
1542 }
1543 
1544 #[derive(Debug)]
1545 pub struct UserStack {
1546     // 栈底地址
1547     stack_bottom: VirtAddr,
1548     // 当前已映射的大小
1549     mapped_size: usize,
1550     /// 栈顶地址(这个值需要仔细确定!因为它可能不会实时与用户栈的真实栈顶保持一致!要小心!)
1551     current_sp: VirtAddr,
1552 }
1553 
1554 impl UserStack {
1555     /// 默认的用户栈底地址
1556     pub const DEFAULT_USER_STACK_BOTTOM: VirtAddr = MMArch::USER_STACK_START;
1557     /// 默认的用户栈大小为8MB
1558     pub const DEFAULT_USER_STACK_SIZE: usize = 8 * 1024 * 1024;
1559     /// 用户栈的保护页数量
1560     pub const GUARD_PAGES_NUM: usize = 4;
1561 
1562     /// 创建一个用户栈
1563     pub fn new(
1564         vm: &mut InnerAddressSpace,
1565         stack_bottom: Option<VirtAddr>,
1566         stack_size: usize,
1567     ) -> Result<Self, SystemError> {
1568         let stack_bottom = stack_bottom.unwrap_or(Self::DEFAULT_USER_STACK_BOTTOM);
1569         assert!(stack_bottom.check_aligned(MMArch::PAGE_SIZE));
1570 
1571         // 分配用户栈的保护页
1572         let guard_size = Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE;
1573         let actual_stack_bottom = stack_bottom - guard_size;
1574 
1575         let mut prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE;
1576         let map_flags = MapFlags::MAP_PRIVATE
1577             | MapFlags::MAP_ANONYMOUS
1578             | MapFlags::MAP_FIXED_NOREPLACE
1579             | MapFlags::MAP_GROWSDOWN;
1580         // kdebug!(
1581         //     "map anonymous stack: {:?} {}",
1582         //     actual_stack_bottom,
1583         //     guard_size
1584         // );
1585         vm.map_anonymous(
1586             actual_stack_bottom,
1587             guard_size,
1588             prot_flags,
1589             map_flags,
1590             false,
1591             false,
1592         )?;
1593         // test_buddy();
1594         // 设置保护页只读
1595         prot_flags.remove(ProtFlags::PROT_WRITE);
1596         // kdebug!(
1597         //     "to mprotect stack guard pages: {:?} {}",
1598         //     actual_stack_bottom,
1599         //     guard_size
1600         // );
1601         vm.mprotect(
1602             VirtPageFrame::new(actual_stack_bottom),
1603             PageFrameCount::new(Self::GUARD_PAGES_NUM),
1604             prot_flags,
1605         )?;
1606 
1607         // kdebug!(
1608         //     "mprotect stack guard pages done: {:?} {}",
1609         //     actual_stack_bottom,
1610         //     guard_size
1611         // );
1612 
1613         let mut user_stack = UserStack {
1614             stack_bottom: actual_stack_bottom,
1615             mapped_size: guard_size,
1616             current_sp: actual_stack_bottom - guard_size,
1617         };
1618 
1619         // kdebug!("extend user stack: {:?} {}", stack_bottom, stack_size);
1620         // 分配用户栈
1621         user_stack.initial_extend(vm, stack_size)?;
1622         // kdebug!("user stack created: {:?} {}", stack_bottom, stack_size);
1623         return Ok(user_stack);
1624     }
1625 
1626     fn initial_extend(
1627         &mut self,
1628         vm: &mut InnerAddressSpace,
1629         mut bytes: usize,
1630     ) -> Result<(), SystemError> {
1631         let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
1632         let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS | MapFlags::MAP_GROWSDOWN;
1633 
1634         bytes = page_align_up(bytes);
1635         self.mapped_size += bytes;
1636 
1637         vm.map_anonymous(
1638             self.stack_bottom - self.mapped_size,
1639             bytes,
1640             prot_flags,
1641             map_flags,
1642             false,
1643             false,
1644         )?;
1645 
1646         return Ok(());
1647     }
1648 
1649     /// 扩展用户栈
1650     ///
1651     /// ## 参数
1652     ///
1653     /// - `vm` 用户地址空间结构体
1654     /// - `bytes` 要扩展的字节数
1655     ///
1656     /// ## 返回值
1657     ///
1658     /// - **Ok(())** 扩展成功
1659     /// - **Err(SystemError)** 扩展失败
1660     #[allow(dead_code)]
1661     pub fn extend(
1662         &mut self,
1663         vm: &mut InnerAddressSpace,
1664         mut bytes: usize,
1665     ) -> Result<(), SystemError> {
1666         let prot_flags = ProtFlags::PROT_READ | ProtFlags::PROT_WRITE | ProtFlags::PROT_EXEC;
1667         let map_flags = MapFlags::MAP_PRIVATE | MapFlags::MAP_ANONYMOUS;
1668 
1669         bytes = page_align_up(bytes);
1670         self.mapped_size += bytes;
1671 
1672         vm.map_anonymous(
1673             self.stack_bottom - self.mapped_size,
1674             bytes,
1675             prot_flags,
1676             map_flags,
1677             false,
1678             false,
1679         )?;
1680 
1681         return Ok(());
1682     }
1683 
1684     /// 获取栈顶地址
1685     ///
1686     /// 请注意,如果用户栈的栈顶地址发生变化,这个值可能不会实时更新!
1687     pub fn sp(&self) -> VirtAddr {
1688         return self.current_sp;
1689     }
1690 
1691     pub unsafe fn set_sp(&mut self, sp: VirtAddr) {
1692         self.current_sp = sp;
1693     }
1694 
1695     /// 仅仅克隆用户栈的信息,不会克隆用户栈的内容/映射
1696     pub unsafe fn clone_info_only(&self) -> Self {
1697         return Self {
1698             stack_bottom: self.stack_bottom,
1699             mapped_size: self.mapped_size,
1700             current_sp: self.current_sp,
1701         };
1702     }
1703 
1704     /// 获取当前用户栈的大小(不包括保护页)
1705     pub fn stack_size(&self) -> usize {
1706         return self.mapped_size - Self::GUARD_PAGES_NUM * MMArch::PAGE_SIZE;
1707     }
1708 }
1709