ucontext.rs 61 KB

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