fault.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. use core::{
  2. alloc::Layout,
  3. cmp::{max, min},
  4. intrinsics::unlikely,
  5. panic,
  6. };
  7. use alloc::{sync::Arc, vec::Vec};
  8. use crate::{
  9. arch::{mm::PageMapper, MMArch},
  10. libs::align::align_down,
  11. mm::{
  12. page::{page_manager_lock_irqsave, EntryFlags},
  13. ucontext::LockedVMA,
  14. VirtAddr, VmFaultReason, VmFlags,
  15. },
  16. process::{ProcessManager, ProcessState},
  17. };
  18. use crate::mm::MemoryManagementArch;
  19. use super::{
  20. allocator::page_frame::{FrameAllocator, PhysPageFrame},
  21. page::{Page, PageFlags},
  22. phys_2_virt,
  23. };
  24. bitflags! {
  25. pub struct FaultFlags: u64{
  26. const FAULT_FLAG_WRITE = 1 << 0;
  27. const FAULT_FLAG_MKWRITE = 1 << 1;
  28. const FAULT_FLAG_ALLOW_RETRY = 1 << 2;
  29. const FAULT_FLAG_RETRY_NOWAIT = 1 << 3;
  30. const FAULT_FLAG_KILLABLE = 1 << 4;
  31. const FAULT_FLAG_TRIED = 1 << 5;
  32. const FAULT_FLAG_USER = 1 << 6;
  33. const FAULT_FLAG_REMOTE = 1 << 7;
  34. const FAULT_FLAG_INSTRUCTION = 1 << 8;
  35. const FAULT_FLAG_INTERRUPTIBLE =1 << 9;
  36. const FAULT_FLAG_UNSHARE = 1 << 10;
  37. const FAULT_FLAG_ORIG_PTE_VALID = 1 << 11;
  38. const FAULT_FLAG_VMA_LOCK = 1 << 12;
  39. }
  40. }
  41. /// # 缺页异常信息结构体
  42. /// 包含了页面错误处理的相关信息,例如出错的地址、VMA等
  43. #[derive(Debug)]
  44. pub struct PageFaultMessage {
  45. /// 产生缺页的VMA结构体
  46. vma: Arc<LockedVMA>,
  47. /// 缺页地址
  48. address: VirtAddr,
  49. /// 异常处理标志
  50. flags: FaultFlags,
  51. /// 缺页的文件页在文件中的偏移量
  52. file_pgoff: Option<usize>,
  53. }
  54. impl PageFaultMessage {
  55. pub fn new(vma: Arc<LockedVMA>, address: VirtAddr, flags: FaultFlags) -> Self {
  56. let guard = vma.lock();
  57. let file_pgoff = if let Some(file_page_offset) = guard.file_page_offset() {
  58. Some(((address - guard.region().start()) >> MMArch::PAGE_SHIFT) + file_page_offset)
  59. } else {
  60. None
  61. };
  62. Self {
  63. vma: vma.clone(),
  64. address,
  65. flags,
  66. file_pgoff,
  67. }
  68. }
  69. #[inline(always)]
  70. #[allow(dead_code)]
  71. pub fn vma(&self) -> Arc<LockedVMA> {
  72. self.vma.clone()
  73. }
  74. #[inline(always)]
  75. #[allow(dead_code)]
  76. pub fn address(&self) -> &VirtAddr {
  77. &self.address
  78. }
  79. #[inline(always)]
  80. #[allow(dead_code)]
  81. pub fn address_aligned_down(&self) -> VirtAddr {
  82. VirtAddr::new(crate::libs::align::page_align_down(self.address.data()))
  83. }
  84. #[inline(always)]
  85. #[allow(dead_code)]
  86. pub fn flags(&self) -> &FaultFlags {
  87. &self.flags
  88. }
  89. }
  90. impl Clone for PageFaultMessage {
  91. fn clone(&self) -> Self {
  92. Self {
  93. vma: self.vma.clone(),
  94. address: self.address,
  95. flags: self.flags,
  96. file_pgoff: self.file_pgoff,
  97. }
  98. }
  99. }
  100. /// 缺页中断处理结构体
  101. pub struct PageFaultHandler;
  102. impl PageFaultHandler {
  103. /// 处理缺页异常
  104. /// ## 参数
  105. ///
  106. /// - `pfm`: 缺页异常信息
  107. /// - `mapper`: 页表映射器
  108. ///
  109. /// ## 返回值
  110. /// - VmFaultReason: 页面错误处理信息标志
  111. pub unsafe fn handle_mm_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  112. let flags = pfm.flags();
  113. let vma = pfm.vma();
  114. let current_pcb = ProcessManager::current_pcb();
  115. let mut guard = current_pcb.sched_info().inner_lock_write_irqsave();
  116. guard.set_state(ProcessState::Runnable);
  117. if !MMArch::vma_access_permitted(
  118. vma.clone(),
  119. flags.contains(FaultFlags::FAULT_FLAG_WRITE),
  120. flags.contains(FaultFlags::FAULT_FLAG_INSTRUCTION),
  121. flags.contains(FaultFlags::FAULT_FLAG_REMOTE),
  122. ) {
  123. return VmFaultReason::VM_FAULT_SIGSEGV;
  124. }
  125. let guard = vma.lock();
  126. let vm_flags = *guard.vm_flags();
  127. drop(guard);
  128. if unlikely(vm_flags.contains(VmFlags::VM_HUGETLB)) {
  129. //TODO: 添加handle_hugetlb_fault处理大页缺页异常
  130. } else {
  131. Self::handle_normal_fault(pfm, mapper);
  132. }
  133. VmFaultReason::VM_FAULT_COMPLETED
  134. }
  135. /// 处理普通页缺页异常
  136. /// ## 参数
  137. ///
  138. /// - `pfm`: 缺页异常信息
  139. /// - `mapper`: 页表映射器
  140. ///
  141. /// ## 返回值
  142. /// - VmFaultReason: 页面错误处理信息标志
  143. pub unsafe fn handle_normal_fault(
  144. pfm: PageFaultMessage,
  145. mapper: &mut PageMapper,
  146. ) -> VmFaultReason {
  147. let address = pfm.address_aligned_down();
  148. let vma = pfm.vma.clone();
  149. if mapper.get_entry(address, 3).is_none() {
  150. mapper
  151. .allocate_table(address, 2)
  152. .expect("failed to allocate PUD table");
  153. }
  154. let page_flags = vma.lock().flags();
  155. for level in 2..=3 {
  156. let level = MMArch::PAGE_LEVELS - level;
  157. if mapper.get_entry(address, level).is_none() {
  158. if vma.is_hugepage() {
  159. if vma.is_anonymous() {
  160. mapper.map_huge_page(address, page_flags);
  161. }
  162. } else if mapper.allocate_table(address, level - 1).is_none() {
  163. return VmFaultReason::VM_FAULT_OOM;
  164. }
  165. }
  166. }
  167. Self::handle_pte_fault(pfm, mapper)
  168. }
  169. /// 处理页表项异常
  170. /// ## 参数
  171. ///
  172. /// - `pfm`: 缺页异常信息
  173. /// - `mapper`: 页表映射器
  174. ///
  175. /// ## 返回值
  176. /// - VmFaultReason: 页面错误处理信息标志
  177. pub unsafe fn handle_pte_fault(
  178. pfm: PageFaultMessage,
  179. mapper: &mut PageMapper,
  180. ) -> VmFaultReason {
  181. let address = pfm.address_aligned_down();
  182. let flags = pfm.flags;
  183. let vma = pfm.vma.clone();
  184. let mut ret = VmFaultReason::VM_FAULT_COMPLETED;
  185. if let Some(mut entry) = mapper.get_entry(address, 0) {
  186. if !entry.present() {
  187. ret = Self::do_swap_page(pfm.clone(), mapper);
  188. }
  189. if entry.protnone() && vma.is_accessible() {
  190. ret = Self::do_numa_page(pfm.clone(), mapper);
  191. }
  192. if flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) {
  193. if !entry.write() {
  194. ret = Self::do_wp_page(pfm.clone(), mapper);
  195. } else {
  196. entry.set_flags(EntryFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
  197. }
  198. }
  199. } else if vma.is_anonymous() {
  200. ret = Self::do_anonymous_page(pfm.clone(), mapper);
  201. } else {
  202. ret = Self::do_fault(pfm.clone(), mapper);
  203. }
  204. vma.lock().set_mapped(true);
  205. return ret;
  206. }
  207. /// 处理匿名映射页缺页异常
  208. /// ## 参数
  209. ///
  210. /// - `pfm`: 缺页异常信息
  211. /// - `mapper`: 页表映射器
  212. ///
  213. /// ## 返回值
  214. /// - VmFaultReason: 页面错误处理信息标志
  215. pub unsafe fn do_anonymous_page(
  216. pfm: PageFaultMessage,
  217. mapper: &mut PageMapper,
  218. ) -> VmFaultReason {
  219. let address = pfm.address_aligned_down();
  220. let vma = pfm.vma.clone();
  221. let guard = vma.lock();
  222. if let Some(flush) = mapper.map(address, guard.flags()) {
  223. flush.flush();
  224. crate::debug::klog::mm::mm_debug_log(
  225. klog_types::AllocatorLogType::LazyAlloc(klog_types::AllocLogItem::new(
  226. Layout::from_size_align(MMArch::PAGE_SIZE, MMArch::PAGE_SIZE).unwrap(),
  227. Some(address.data()),
  228. Some(mapper.translate(address).unwrap().0.data()),
  229. )),
  230. klog_types::LogSource::Buddy,
  231. );
  232. let paddr = mapper.translate(address).unwrap().0;
  233. let mut anon_vma_guard = page_manager_lock_irqsave();
  234. let page = anon_vma_guard.get_mut(&paddr);
  235. page.insert_vma(vma.clone());
  236. VmFaultReason::VM_FAULT_COMPLETED
  237. } else {
  238. VmFaultReason::VM_FAULT_OOM
  239. }
  240. }
  241. /// 处理文件映射页的缺页异常
  242. /// ## 参数
  243. ///
  244. /// - `pfm`: 缺页异常信息
  245. /// - `mapper`: 页表映射器
  246. ///
  247. /// ## 返回值
  248. /// - VmFaultReason: 页面错误处理信息标志
  249. #[allow(unused_variables)]
  250. pub unsafe fn do_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  251. // panic!(
  252. // "do_fault has not yet been implemented,
  253. // fault message: {:?},
  254. // pid: {}\n",
  255. // pfm,
  256. // crate::process::ProcessManager::current_pid().data()
  257. // );
  258. // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_fault
  259. if !pfm.flags().contains(FaultFlags::FAULT_FLAG_WRITE) {
  260. return Self::do_read_fault(pfm, mapper);
  261. } else if !pfm.vma().lock().vm_flags().contains(VmFlags::VM_SHARED) {
  262. return Self::do_cow_fault(pfm, mapper);
  263. } else {
  264. return Self::do_shared_fault(pfm, mapper);
  265. }
  266. }
  267. /// 处理私有文件映射的写时复制
  268. /// ## 参数
  269. ///
  270. /// - `pfm`: 缺页异常信息
  271. /// - `mapper`: 页表映射器
  272. ///
  273. /// ## 返回值
  274. /// - VmFaultReason: 页面错误处理信息标志
  275. #[allow(dead_code, unused_variables)]
  276. pub unsafe fn do_cow_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  277. panic!(
  278. "do_cow_fault has not yet been implemented,
  279. fault message: {:?},
  280. pid: {}\n",
  281. pfm,
  282. crate::process::ProcessManager::current_pid().data()
  283. );
  284. // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_cow_fault
  285. }
  286. /// 处理文件映射页的缺页异常
  287. /// ## 参数
  288. ///
  289. /// - `pfm`: 缺页异常信息
  290. /// - `mapper`: 页表映射器
  291. ///
  292. /// ## 返回值
  293. /// - VmFaultReason: 页面错误处理信息标志
  294. #[allow(dead_code, unused_variables)]
  295. pub unsafe fn do_read_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  296. // panic!(
  297. // "do_read_fault has not yet been implemented,
  298. // fault message: {:?},
  299. // pid: {}\n",
  300. // pfm,
  301. // crate::process::ProcessManager::current_pid().data()
  302. // );
  303. // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_read_fault
  304. let ret = Self::do_fault_around(pfm.clone(), mapper);
  305. if !ret.is_empty() {
  306. return ret;
  307. }
  308. return Self::filemap_fault(pfm.clone(), mapper);
  309. }
  310. /// 处理对共享文件映射区写入引起的缺页
  311. /// ## 参数
  312. ///
  313. /// - `pfm`: 缺页异常信息
  314. /// - `mapper`: 页表映射器
  315. ///
  316. /// ## 返回值
  317. /// - VmFaultReason: 页面错误处理信息标志
  318. #[allow(dead_code, unused_variables)]
  319. pub unsafe fn do_shared_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  320. panic!(
  321. "do_shared_fault has not yet been implemented,
  322. fault message: {:?},
  323. pid: {}\n",
  324. pfm,
  325. crate::process::ProcessManager::current_pid().data()
  326. );
  327. // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_shared_fault
  328. }
  329. /// 处理被置换页面的缺页异常
  330. /// ## 参数
  331. ///
  332. /// - `pfm`: 缺页异常信息
  333. /// - `mapper`: 页表映射器
  334. ///
  335. /// ## 返回值
  336. /// - VmFaultReason: 页面错误处理信息标志
  337. #[allow(unused_variables)]
  338. pub unsafe fn do_swap_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  339. panic!(
  340. "do_swap_page has not yet been implemented,
  341. fault message: {:?},
  342. pid: {}\n",
  343. pfm,
  344. crate::process::ProcessManager::current_pid().data()
  345. );
  346. // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_swap_page
  347. }
  348. /// 处理NUMA的缺页异常
  349. /// ## 参数
  350. ///
  351. /// - `pfm`: 缺页异常信息
  352. /// - `mapper`: 页表映射器
  353. ///
  354. /// ## 返回值
  355. /// - VmFaultReason: 页面错误处理信息标志
  356. #[allow(unused_variables)]
  357. pub unsafe fn do_numa_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  358. panic!(
  359. "do_numa_page has not yet been implemented,
  360. fault message: {:?},
  361. pid: {}\n",
  362. pfm,
  363. crate::process::ProcessManager::current_pid().data()
  364. );
  365. // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_numa_page
  366. }
  367. /// 处理写保护页面的写保护异常
  368. /// ## 参数
  369. ///
  370. /// - `pfm`: 缺页异常信息
  371. /// - `mapper`: 页表映射器
  372. ///
  373. /// ## 返回值
  374. /// - VmFaultReason: 页面错误处理信息标志
  375. pub unsafe fn do_wp_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  376. let address = pfm.address_aligned_down();
  377. let vma = pfm.vma.clone();
  378. let old_paddr = mapper.translate(address).unwrap().0;
  379. let mut page_manager = page_manager_lock_irqsave();
  380. let map_count = page_manager.get_mut(&old_paddr).map_count();
  381. drop(page_manager);
  382. let mut entry = mapper.get_entry(address, 0).unwrap();
  383. let new_flags = entry.flags().set_write(true);
  384. if map_count == 1 {
  385. let table = mapper.get_table(address, 0).unwrap();
  386. let i = table.index_of(address).unwrap();
  387. entry.set_flags(new_flags);
  388. table.set_entry(i, entry);
  389. VmFaultReason::VM_FAULT_COMPLETED
  390. } else if let Some(flush) = mapper.map(address, new_flags) {
  391. let mut page_manager = page_manager_lock_irqsave();
  392. let old_page = page_manager.get_mut(&old_paddr);
  393. old_page.remove_vma(&vma);
  394. drop(page_manager);
  395. flush.flush();
  396. let paddr = mapper.translate(address).unwrap().0;
  397. let mut anon_vma_guard = page_manager_lock_irqsave();
  398. let page = anon_vma_guard.get_mut(&paddr);
  399. page.insert_vma(vma.clone());
  400. (MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8).copy_from_nonoverlapping(
  401. MMArch::phys_2_virt(old_paddr).unwrap().data() as *mut u8,
  402. MMArch::PAGE_SIZE,
  403. );
  404. VmFaultReason::VM_FAULT_COMPLETED
  405. } else {
  406. VmFaultReason::VM_FAULT_OOM
  407. }
  408. }
  409. pub unsafe fn do_fault_around(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  410. if mapper.get_table(*pfm.address(), 0).is_none() {
  411. mapper
  412. .allocate_table(*pfm.address(), 0)
  413. .expect("failed to allocate pte table");
  414. }
  415. let vma = pfm.vma();
  416. let vma_guard = vma.lock();
  417. let vma_region = vma_guard.region();
  418. // 缺页在VMA中的偏移量
  419. let vm_pgoff = (*pfm.address() - vma_region.start()) >> MMArch::PAGE_SHIFT;
  420. // 缺页在PTE中的偏移量
  421. let pte_pgoff =
  422. (pfm.address().data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_ENTRY_SHIFT);
  423. // 缺页在文件中的偏移量
  424. let file_pgoff = pfm.file_pgoff.expect("no file_pgoff");
  425. let vma_pages_count = (vma_region.end() - vma_region.start()) >> MMArch::PAGE_SHIFT;
  426. let fault_around_page_number = 16;
  427. // 开始位置不能超出当前pte和vma头部
  428. let from_pte = max(
  429. align_down(pte_pgoff, fault_around_page_number),
  430. pte_pgoff - min(vm_pgoff, pte_pgoff),
  431. );
  432. // pte结束位置不能超过:
  433. // 1.最大预读上限(默认16)
  434. // 2.最大pte(512)
  435. // 3.vma结束位置(pte_pgoff + (vma_pages_count - vm_pgoff)计算出vma结束页号对当前pte开头的偏移)
  436. let to_pte = min(
  437. from_pte + fault_around_page_number,
  438. min(
  439. 1 << MMArch::PAGE_SHIFT,
  440. pte_pgoff + (vma_pages_count - vm_pgoff),
  441. ),
  442. );
  443. // 预先分配pte页表(如果不存在)
  444. if mapper.get_table(*pfm.address(), 0).is_none()
  445. && mapper.allocate_table(*pfm.address(), 0).is_none()
  446. {
  447. return VmFaultReason::VM_FAULT_OOM;
  448. }
  449. // from_pte - pte_pgoff得出预读起始pte相对缺失页的偏移,加上pfm.file_pgoff(缺失页在文件中的偏移)得出起始页在文件中的偏移,结束pte同理
  450. Self::filemap_map_pages(
  451. pfm.clone(),
  452. mapper,
  453. file_pgoff + (from_pte - pte_pgoff),
  454. file_pgoff + (to_pte - pte_pgoff),
  455. );
  456. VmFaultReason::empty()
  457. }
  458. pub unsafe fn filemap_map_pages(
  459. pfm: PageFaultMessage,
  460. mapper: &mut PageMapper,
  461. start_pgoff: usize,
  462. end_pgoff: usize,
  463. ) -> VmFaultReason {
  464. let vma = pfm.vma();
  465. let vma_guard = vma.lock();
  466. let file = vma_guard.vm_file().expect("no vm_file in vma");
  467. let page_cache = file.inode().page_cache().unwrap();
  468. // 起始页地址
  469. let addr = vma_guard.region().start
  470. + ((start_pgoff
  471. - vma_guard
  472. .file_page_offset()
  473. .expect("file_page_offset is none"))
  474. << MMArch::PAGE_SHIFT);
  475. // let pages = page_cache.get_pages(start_pgoff, end_pgoff);
  476. // let uptodate_pages = pages
  477. // .iter()
  478. // .filter(|page| page.flags().contains(PageFlags::PG_UPTODATE));
  479. for pgoff in start_pgoff..=end_pgoff {
  480. if let Some(page) = page_cache.get_page(pgoff) {
  481. if page.flags().contains(PageFlags::PG_UPTODATE) {
  482. let phys = page.phys_frame().phys_address();
  483. let virt = phys_2_virt(phys.data());
  484. let address =
  485. VirtAddr::new(addr.data() + ((pgoff - start_pgoff) << MMArch::PAGE_SHIFT));
  486. mapper.map(address, vma_guard.flags()).unwrap().flush();
  487. let frame = virt as *mut u8;
  488. let new_frame =
  489. phys_2_virt(mapper.translate(address).unwrap().0.data()) as *mut u8;
  490. new_frame.copy_from_nonoverlapping(frame, MMArch::PAGE_SIZE);
  491. }
  492. }
  493. }
  494. VmFaultReason::empty()
  495. }
  496. pub unsafe fn filemap_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
  497. let vma = pfm.vma();
  498. let vma_guard = vma.lock();
  499. let file = vma_guard.vm_file().expect("no vm_file in vma");
  500. let mut page_cache = file.inode().page_cache().unwrap();
  501. let file_pgoff = pfm.file_pgoff.expect("no file_pgoff");
  502. if let Some(page) = page_cache.get_page(file_pgoff) {
  503. // TODO 异步从磁盘中预读页面进PageCache
  504. let address = vma_guard.region().start
  505. + ((file_pgoff
  506. - vma_guard
  507. .file_page_offset()
  508. .expect("file_page_offset is none"))
  509. << MMArch::PAGE_SHIFT);
  510. mapper.map(address, vma_guard.flags()).unwrap().flush();
  511. let frame = phys_2_virt(page.phys_frame().phys_address().data()) as *mut u8;
  512. let new_frame = phys_2_virt(mapper.translate(address).unwrap().0.data()) as *mut u8;
  513. new_frame.copy_from_nonoverlapping(frame, MMArch::PAGE_SIZE);
  514. } else {
  515. // TODO 同步预读
  516. let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE];
  517. file.pread(
  518. file_pgoff * MMArch::PAGE_SIZE,
  519. MMArch::PAGE_SIZE,
  520. &mut buf[..],
  521. )
  522. .unwrap();
  523. let allocator = mapper.allocator_mut();
  524. // 分配一个物理页面作为加入PageCache的新页
  525. let new_cache_page = allocator.allocate_one().unwrap();
  526. (phys_2_virt(new_cache_page.data()) as *mut u8)
  527. .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
  528. page_cache.add_page(
  529. file_pgoff,
  530. Arc::new(Page::new(false, PhysPageFrame::new(new_cache_page))),
  531. );
  532. // 分配空白页并映射到缺页地址
  533. mapper.map(pfm.address, vma_guard.flags()).unwrap().flush();
  534. let new_frame = phys_2_virt(mapper.translate(pfm.address).unwrap().0.data());
  535. (new_frame as *mut u8).copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
  536. }
  537. VmFaultReason::VM_FAULT_COMPLETED
  538. }
  539. }