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