fault.rs 24 KB

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