fault.rs 21 KB

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