page.rs 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966
  1. use alloc::{string::ToString, vec::Vec};
  2. use core::{
  3. fmt::{self, Debug, Error, Formatter},
  4. marker::PhantomData,
  5. mem,
  6. ops::Add,
  7. sync::atomic::{compiler_fence, Ordering},
  8. };
  9. use system_error::SystemError;
  10. use unified_init::macros::unified_init;
  11. use alloc::sync::Arc;
  12. use hashbrown::{HashMap, HashSet};
  13. use log::{error, info};
  14. use lru::LruCache;
  15. use crate::{
  16. arch::{interrupt::ipi::send_ipi, mm::LockedFrameAllocator, MMArch},
  17. exception::ipi::{IpiKind, IpiTarget},
  18. filesystem::{page_cache::PageCache, vfs::FilePrivateData},
  19. init::initcall::INITCALL_CORE,
  20. ipc::shm::ShmId,
  21. libs::{
  22. rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
  23. spinlock::{SpinLock, SpinLockGuard},
  24. },
  25. process::{ProcessControlBlock, ProcessManager},
  26. time::{sleep::nanosleep, PosixTimeSpec},
  27. };
  28. use super::{
  29. allocator::page_frame::{
  30. deallocate_page_frames, FrameAllocator, PageFrameCount, PhysPageFrame,
  31. },
  32. syscall::ProtFlags,
  33. ucontext::LockedVMA,
  34. MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
  35. };
  36. pub const PAGE_4K_SHIFT: usize = 12;
  37. #[allow(dead_code)]
  38. pub const PAGE_2M_SHIFT: usize = 21;
  39. pub const PAGE_1G_SHIFT: usize = 30;
  40. pub const PAGE_4K_SIZE: usize = 1 << PAGE_4K_SHIFT;
  41. pub const PAGE_2M_SIZE: usize = 1 << PAGE_2M_SHIFT;
  42. /// 全局物理页信息管理器
  43. pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None;
  44. /// 初始化PAGE_MANAGER
  45. pub fn page_manager_init() {
  46. info!("page_manager_init");
  47. let page_manager = SpinLock::new(PageManager::new());
  48. compiler_fence(Ordering::SeqCst);
  49. unsafe { PAGE_MANAGER = Some(page_manager) };
  50. compiler_fence(Ordering::SeqCst);
  51. info!("page_manager_init done");
  52. }
  53. pub fn page_manager_lock_irqsave() -> SpinLockGuard<'static, PageManager> {
  54. unsafe { PAGE_MANAGER.as_ref().unwrap().lock_irqsave() }
  55. }
  56. // 物理页管理器
  57. pub struct PageManager {
  58. phys2page: HashMap<PhysAddr, Arc<Page>>,
  59. }
  60. impl PageManager {
  61. pub fn new() -> Self {
  62. Self {
  63. phys2page: HashMap::new(),
  64. }
  65. }
  66. #[allow(dead_code)]
  67. pub fn contains(&self, paddr: &PhysAddr) -> bool {
  68. self.phys2page.contains_key(paddr)
  69. }
  70. pub fn get(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> {
  71. if let Some(p) = page_reclaimer_lock_irqsave().get(paddr) {
  72. return Some(p);
  73. }
  74. self.phys2page.get(paddr).cloned()
  75. }
  76. pub fn get_unwrap(&mut self, paddr: &PhysAddr) -> Arc<Page> {
  77. if let Some(p) = page_reclaimer_lock_irqsave().get(paddr) {
  78. return p;
  79. }
  80. self.phys2page
  81. .get(paddr)
  82. .unwrap_or_else(|| panic!("Phys Page not found, {:?}", paddr))
  83. .clone()
  84. }
  85. fn insert(&mut self, page: &Arc<Page>) -> Result<Arc<Page>, SystemError> {
  86. let phys = page.phys_address();
  87. if !self.phys2page.contains_key(&phys) {
  88. self.phys2page.insert(phys, page.clone());
  89. Ok(page.clone())
  90. } else {
  91. log::error!("phys page: {phys:?} already exists.");
  92. Err(SystemError::EINVAL)
  93. }
  94. }
  95. pub fn remove_page(&mut self, paddr: &PhysAddr) {
  96. self.phys2page.remove(paddr);
  97. }
  98. /// # 创建一个新页面并加入管理器
  99. ///
  100. /// ## 参数
  101. ///
  102. /// - `shared`: 是否共享
  103. /// - `page_type`: 页面类型
  104. /// - `flags`: 页面标志
  105. /// - `allocator`: 物理页帧分配器
  106. ///
  107. /// ## 返回值
  108. ///
  109. /// - `Ok(Arc<Page>)`: 新页面
  110. /// - `Err(SystemError)`: 错误码
  111. pub fn create_one_page(
  112. &mut self,
  113. page_type: PageType,
  114. flags: PageFlags,
  115. allocator: &mut dyn FrameAllocator,
  116. ) -> Result<Arc<Page>, SystemError> {
  117. self.create_pages(page_type, flags, allocator, PageFrameCount::ONE)?
  118. .1
  119. .first()
  120. .ok_or(SystemError::ENOMEM)
  121. .cloned()
  122. }
  123. /// # 创建新页面并加入管理器
  124. ///
  125. /// ## 参数
  126. ///
  127. /// - `shared`: 是否共享
  128. /// - `page_type`: 页面类型
  129. /// - `flags`: 页面标志
  130. /// - `allocator`: 物理页帧分配器
  131. /// - `count`: 页面数量
  132. ///
  133. /// ## 返回值
  134. ///
  135. /// - `Ok((PhysAddr, Vec<Arc<Page>>))`: 页面起始物理地址,新页面集合
  136. /// - `Err(SystemError)`: 错误码
  137. pub fn create_pages(
  138. &mut self,
  139. page_type: PageType,
  140. flags: PageFlags,
  141. allocator: &mut dyn FrameAllocator,
  142. count: PageFrameCount,
  143. ) -> Result<(PhysAddr, Vec<Arc<Page>>), SystemError> {
  144. compiler_fence(Ordering::SeqCst);
  145. let (start_paddr, count) = unsafe { allocator.allocate(count).ok_or(SystemError::ENOMEM)? };
  146. compiler_fence(Ordering::SeqCst);
  147. unsafe {
  148. let vaddr = MMArch::phys_2_virt(start_paddr).unwrap();
  149. MMArch::write_bytes(vaddr, 0, MMArch::PAGE_SIZE * count.data());
  150. }
  151. let mut cur_phys = PhysPageFrame::new(start_paddr);
  152. let mut ret: Vec<Arc<Page>> = Vec::new();
  153. for _ in 0..count.data() {
  154. let page = Page::new(cur_phys.phys_address(), page_type.clone(), flags);
  155. if let Err(e) = self.insert(&page) {
  156. for insert_page in ret {
  157. self.remove_page(&insert_page.read_irqsave().phys_addr);
  158. }
  159. return Err(e);
  160. }
  161. ret.push(page);
  162. cur_phys = cur_phys.next();
  163. }
  164. Ok((start_paddr, ret))
  165. }
  166. /// # 拷贝管理器中原有页面并加入管理器,同时拷贝原页面内容
  167. ///
  168. /// ## 参数
  169. ///
  170. /// - `old_phys`: 原页面的物理地址
  171. /// - `allocator`: 物理页帧分配器
  172. ///
  173. /// ## 返回值
  174. ///
  175. /// - `Ok(Arc<Page>)`: 新页面
  176. /// - `Err(SystemError)`: 错误码
  177. pub fn copy_page(
  178. &mut self,
  179. old_phys: &PhysAddr,
  180. allocator: &mut dyn FrameAllocator,
  181. ) -> Result<Arc<Page>, SystemError> {
  182. let old_page = self.get(old_phys).ok_or(SystemError::EINVAL)?;
  183. let paddr = unsafe { allocator.allocate_one().ok_or(SystemError::ENOMEM)? };
  184. assert!(!self.contains(&paddr), "phys page: {paddr:?} already exist");
  185. let page = Page::copy(old_page.read_irqsave(), paddr)
  186. .inspect_err(|_| unsafe { allocator.free_one(paddr) })?;
  187. self.insert(&page)?;
  188. Ok(page)
  189. }
  190. }
  191. pub static mut PAGE_RECLAIMER: Option<SpinLock<PageReclaimer>> = None;
  192. pub fn page_reclaimer_init() {
  193. info!("page_reclaimer_init");
  194. let page_reclaimer = SpinLock::new(PageReclaimer::new());
  195. compiler_fence(Ordering::SeqCst);
  196. unsafe { PAGE_RECLAIMER = Some(page_reclaimer) };
  197. compiler_fence(Ordering::SeqCst);
  198. info!("page_reclaimer_init done");
  199. }
  200. /// 页面回收线程
  201. static mut PAGE_RECLAIMER_THREAD: Option<Arc<ProcessControlBlock>> = None;
  202. /// 页面回收线程初始化函数
  203. #[unified_init(INITCALL_CORE)]
  204. fn page_reclaimer_thread_init() -> Result<(), SystemError> {
  205. let closure = crate::process::kthread::KernelThreadClosure::StaticEmptyClosure((
  206. &(page_reclaim_thread as fn() -> i32),
  207. (),
  208. ));
  209. let pcb = crate::process::kthread::KernelThreadMechanism::create_and_run(
  210. closure,
  211. "page_reclaim".to_string(),
  212. )
  213. .ok_or("")
  214. .expect("create tty_refresh thread failed");
  215. unsafe {
  216. PAGE_RECLAIMER_THREAD = Some(pcb);
  217. }
  218. Ok(())
  219. }
  220. /// 页面回收线程执行的函数
  221. fn page_reclaim_thread() -> i32 {
  222. loop {
  223. let usage = unsafe { LockedFrameAllocator.usage() };
  224. // log::info!("usage{:?}", usage);
  225. // 保留4096个页面,总计16MB的空闲空间
  226. if usage.free().data() < 4096 {
  227. let page_to_free = 4096;
  228. page_reclaimer_lock_irqsave().shrink_list(PageFrameCount::new(page_to_free));
  229. } else {
  230. //TODO 暂时让页面回收线程负责脏页回写任务,后续需要分离
  231. page_reclaimer_lock_irqsave().flush_dirty_pages();
  232. // 休眠5秒
  233. // log::info!("sleep");
  234. let _ = nanosleep(PosixTimeSpec::new(0, 500_000_000));
  235. }
  236. }
  237. }
  238. /// 获取页面回收器
  239. pub fn page_reclaimer_lock_irqsave() -> SpinLockGuard<'static, PageReclaimer> {
  240. unsafe { PAGE_RECLAIMER.as_ref().unwrap().lock_irqsave() }
  241. }
  242. /// 页面回收器
  243. pub struct PageReclaimer {
  244. lru: LruCache<PhysAddr, Arc<Page>>,
  245. }
  246. impl PageReclaimer {
  247. pub fn new() -> Self {
  248. Self {
  249. lru: LruCache::unbounded(),
  250. }
  251. }
  252. pub fn get(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> {
  253. self.lru.get(paddr).cloned()
  254. }
  255. pub fn insert_page(&mut self, paddr: PhysAddr, page: &Arc<Page>) {
  256. self.lru.put(paddr, page.clone());
  257. }
  258. pub fn remove_page(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> {
  259. self.lru.pop(paddr)
  260. }
  261. /// lru链表缩减
  262. /// ## 参数
  263. ///
  264. /// - `count`: 需要缩减的页面数量
  265. pub fn shrink_list(&mut self, count: PageFrameCount) {
  266. for _ in 0..count.data() {
  267. let (_, page) = self.lru.pop_lru().expect("pagecache is empty");
  268. let mut guard = page.write_irqsave();
  269. if let PageType::File(info) = guard.page_type().clone() {
  270. let page_cache = &info.page_cache;
  271. let page_index = info.index;
  272. let paddr = guard.phys_address();
  273. if guard.flags().contains(PageFlags::PG_DIRTY) {
  274. // 先回写脏页
  275. Self::page_writeback(&mut guard, true);
  276. }
  277. // 删除页面
  278. page_cache.lock_irqsave().remove_page(page_index);
  279. page_manager_lock_irqsave().remove_page(&paddr);
  280. self.remove_page(&paddr);
  281. }
  282. }
  283. }
  284. /// 唤醒页面回收线程
  285. pub fn wakeup_claim_thread() {
  286. // log::info!("wakeup_claim_thread");
  287. let _ = ProcessManager::wakeup(unsafe { PAGE_RECLAIMER_THREAD.as_ref().unwrap() });
  288. }
  289. /// 脏页回写函数
  290. /// ## 参数
  291. ///
  292. /// - `guard`: 需要回写的脏页
  293. /// - `unmap`: 是否取消映射
  294. ///
  295. /// ## 返回值
  296. /// - VmFaultReason: 页面错误处理信息标志
  297. pub fn page_writeback(guard: &mut RwLockWriteGuard<InnerPage>, unmap: bool) {
  298. // log::debug!("page writeback: {:?}", guard.phys_addr);
  299. let (page_cache, page_index) = match guard.page_type() {
  300. PageType::File(info) => (info.page_cache.clone(), info.index),
  301. _ => {
  302. log::warn!("try to writeback a non-file page");
  303. return;
  304. }
  305. };
  306. let paddr = guard.phys_address();
  307. let inode = page_cache.inode().clone().unwrap().upgrade().unwrap();
  308. for vma in guard.vma_set() {
  309. let address_space = vma.lock_irqsave().address_space().and_then(|x| x.upgrade());
  310. if address_space.is_none() {
  311. continue;
  312. }
  313. let address_space = address_space.unwrap();
  314. let mut guard = address_space.write();
  315. let mapper = &mut guard.user_mapper.utable;
  316. let virt = vma.lock_irqsave().page_address(page_index).unwrap();
  317. if unmap {
  318. unsafe {
  319. // 取消页表映射
  320. mapper.unmap(virt, false).unwrap().flush();
  321. }
  322. } else {
  323. unsafe {
  324. // 保护位设为只读
  325. mapper.remap(
  326. virt,
  327. mapper.get_entry(virt, 0).unwrap().flags().set_write(false),
  328. )
  329. };
  330. }
  331. }
  332. let len = if let Ok(metadata) = inode.metadata() {
  333. let size = metadata.size as usize;
  334. if size < page_index * MMArch::PAGE_SIZE {
  335. 0
  336. } else {
  337. size - page_index * MMArch::PAGE_SIZE
  338. }
  339. } else {
  340. MMArch::PAGE_SIZE
  341. };
  342. if len > 0 {
  343. inode
  344. .write_direct(
  345. page_index * MMArch::PAGE_SIZE,
  346. len,
  347. unsafe {
  348. core::slice::from_raw_parts(
  349. MMArch::phys_2_virt(paddr).unwrap().data() as *mut u8,
  350. len,
  351. )
  352. },
  353. SpinLock::new(FilePrivateData::Unused).lock(),
  354. )
  355. .unwrap();
  356. }
  357. // 清除标记
  358. guard.remove_flags(PageFlags::PG_DIRTY);
  359. }
  360. /// lru脏页刷新
  361. pub fn flush_dirty_pages(&mut self) {
  362. // log::info!("flush_dirty_pages");
  363. let iter = self.lru.iter();
  364. for (_paddr, page) in iter {
  365. let mut guard = page.write_irqsave();
  366. if guard.flags().contains(PageFlags::PG_DIRTY) {
  367. Self::page_writeback(&mut guard, false);
  368. }
  369. }
  370. }
  371. }
  372. bitflags! {
  373. pub struct PageFlags: u64 {
  374. const PG_LOCKED = 1 << 0;
  375. const PG_WRITEBACK = 1 << 1;
  376. const PG_REFERENCED = 1 << 2;
  377. const PG_UPTODATE = 1 << 3;
  378. const PG_DIRTY = 1 << 4;
  379. const PG_LRU = 1 << 5;
  380. const PG_HEAD = 1 << 6;
  381. const PG_WAITERS = 1 << 7;
  382. const PG_ACTIVE = 1 << 8;
  383. const PG_WORKINGSET = 1 << 9;
  384. const PG_ERROR = 1 << 10;
  385. const PG_SLAB = 1 << 11;
  386. const PG_RESERVED = 1 << 14;
  387. const PG_PRIVATE = 1 << 15;
  388. const PG_RECLAIM = 1 << 18;
  389. const PG_SWAPBACKED = 1 << 19;
  390. const PG_UNEVICTABLE = 1 << 20;
  391. }
  392. }
  393. #[derive(Debug)]
  394. pub struct Page {
  395. inner: RwLock<InnerPage>,
  396. /// 页面所在物理地址
  397. phys_addr: PhysAddr,
  398. }
  399. impl Page {
  400. /// # 创建新页面
  401. ///
  402. /// ## 参数
  403. ///
  404. /// - `shared`: 是否共享
  405. /// - `phys_addr`: 物理地址
  406. /// - `page_type`: 页面类型
  407. /// - `flags`: 页面标志
  408. ///
  409. /// ## 返回值
  410. ///
  411. /// - `Arc<Page>`: 新页面
  412. fn new(phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Arc<Page> {
  413. let inner = InnerPage::new(phys_addr, page_type, flags);
  414. let page = Arc::new(Self {
  415. inner: RwLock::new(inner),
  416. phys_addr,
  417. });
  418. if page.read_irqsave().flags == PageFlags::PG_LRU {
  419. page_reclaimer_lock_irqsave().insert_page(phys_addr, &page);
  420. };
  421. page
  422. }
  423. /// # 拷贝页面及内容
  424. ///
  425. /// ## 参数
  426. ///
  427. /// - `old_guard`: 源页面的读守卫
  428. /// - `new_phys`: 新页面的物理地址
  429. ///
  430. /// ## 返回值
  431. ///
  432. /// - `Ok(Arc<Page>)`: 新页面
  433. /// - `Err(SystemError)`: 错误码
  434. fn copy(
  435. old_guard: RwLockReadGuard<InnerPage>,
  436. new_phys: PhysAddr,
  437. ) -> Result<Arc<Page>, SystemError> {
  438. let page_type = old_guard.page_type().clone();
  439. let flags = *old_guard.flags();
  440. let inner = InnerPage::new(new_phys, page_type, flags);
  441. unsafe {
  442. let old_vaddr =
  443. MMArch::phys_2_virt(old_guard.phys_address()).ok_or(SystemError::EFAULT)?;
  444. let new_vaddr = MMArch::phys_2_virt(new_phys).ok_or(SystemError::EFAULT)?;
  445. (new_vaddr.data() as *mut u8)
  446. .copy_from_nonoverlapping(old_vaddr.data() as *mut u8, MMArch::PAGE_SIZE);
  447. }
  448. Ok(Arc::new(Self {
  449. inner: RwLock::new(inner),
  450. phys_addr: new_phys,
  451. }))
  452. }
  453. #[inline(always)]
  454. pub fn phys_address(&self) -> PhysAddr {
  455. self.phys_addr
  456. }
  457. pub fn read_irqsave(&self) -> RwLockReadGuard<InnerPage> {
  458. self.inner.read_irqsave()
  459. }
  460. pub fn write_irqsave(&self) -> RwLockWriteGuard<InnerPage> {
  461. self.inner.write_irqsave()
  462. }
  463. }
  464. #[derive(Debug)]
  465. /// 物理页面信息
  466. pub struct InnerPage {
  467. /// 映射到当前page的VMA
  468. vma_set: HashSet<Arc<LockedVMA>>,
  469. /// 标志
  470. flags: PageFlags,
  471. /// 页面所在物理地址
  472. phys_addr: PhysAddr,
  473. /// 页面类型
  474. page_type: PageType,
  475. }
  476. impl InnerPage {
  477. pub fn new(phys_addr: PhysAddr, page_type: PageType, flags: PageFlags) -> Self {
  478. Self {
  479. vma_set: HashSet::new(),
  480. flags,
  481. phys_addr,
  482. page_type,
  483. }
  484. }
  485. /// 将vma加入anon_vma
  486. pub fn insert_vma(&mut self, vma: Arc<LockedVMA>) {
  487. self.vma_set.insert(vma);
  488. }
  489. /// 将vma从anon_vma中删去
  490. pub fn remove_vma(&mut self, vma: &LockedVMA) {
  491. self.vma_set.remove(vma);
  492. }
  493. /// 判断当前物理页是否能被回
  494. pub fn can_deallocate(&self) -> bool {
  495. self.map_count() == 0 && !self.flags.contains(PageFlags::PG_UNEVICTABLE)
  496. }
  497. pub fn shared(&self) -> bool {
  498. self.map_count() > 1
  499. }
  500. pub fn page_cache(&self) -> Option<Arc<PageCache>> {
  501. match &self.page_type {
  502. PageType::File(info) => Some(info.page_cache.clone()),
  503. _ => None,
  504. }
  505. }
  506. pub fn page_type(&self) -> &PageType {
  507. &self.page_type
  508. }
  509. pub fn set_page_type(&mut self, page_type: PageType) {
  510. self.page_type = page_type;
  511. }
  512. #[inline(always)]
  513. pub fn vma_set(&self) -> &HashSet<Arc<LockedVMA>> {
  514. &self.vma_set
  515. }
  516. #[inline(always)]
  517. pub fn map_count(&self) -> usize {
  518. self.vma_set.len()
  519. }
  520. #[inline(always)]
  521. pub fn flags(&self) -> &PageFlags {
  522. &self.flags
  523. }
  524. #[inline(always)]
  525. pub fn set_flags(&mut self, flags: PageFlags) {
  526. self.flags = flags
  527. }
  528. #[inline(always)]
  529. pub fn add_flags(&mut self, flags: PageFlags) {
  530. self.flags = self.flags.union(flags);
  531. }
  532. #[inline(always)]
  533. pub fn remove_flags(&mut self, flags: PageFlags) {
  534. self.flags = self.flags.difference(flags);
  535. }
  536. #[inline(always)]
  537. fn phys_address(&self) -> PhysAddr {
  538. self.phys_addr
  539. }
  540. pub unsafe fn as_slice(&self) -> &[u8] {
  541. core::slice::from_raw_parts(
  542. MMArch::phys_2_virt(self.phys_addr).unwrap().data() as *const u8,
  543. MMArch::PAGE_SIZE,
  544. )
  545. }
  546. pub unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
  547. core::slice::from_raw_parts_mut(
  548. MMArch::phys_2_virt(self.phys_addr).unwrap().data() as *mut u8,
  549. MMArch::PAGE_SIZE,
  550. )
  551. }
  552. pub unsafe fn copy_from_slice(&mut self, slice: &[u8]) {
  553. assert_eq!(
  554. slice.len(),
  555. MMArch::PAGE_SIZE,
  556. "length of slice not match PAGE_SIZE"
  557. );
  558. core::slice::from_raw_parts_mut(
  559. MMArch::phys_2_virt(self.phys_addr).unwrap().data() as *mut u8,
  560. MMArch::PAGE_SIZE,
  561. )
  562. .copy_from_slice(slice);
  563. }
  564. pub unsafe fn truncate(&mut self, len: usize) {
  565. if len > MMArch::PAGE_SIZE {
  566. return;
  567. }
  568. let vaddr = unsafe { MMArch::phys_2_virt(self.phys_addr).unwrap() };
  569. unsafe {
  570. core::slice::from_raw_parts_mut(
  571. (vaddr.data() + len) as *mut u8,
  572. MMArch::PAGE_SIZE - len,
  573. )
  574. .fill(0)
  575. };
  576. }
  577. }
  578. impl Drop for InnerPage {
  579. fn drop(&mut self) {
  580. assert!(
  581. self.map_count() == 0,
  582. "page drop when map count is non-zero"
  583. );
  584. unsafe {
  585. deallocate_page_frames(PhysPageFrame::new(self.phys_addr), PageFrameCount::new(1))
  586. };
  587. }
  588. }
  589. /// 页面类型,包含额外的页面信息
  590. #[derive(Debug, Clone)]
  591. pub enum PageType {
  592. /// 普通页面,不含额外信息
  593. Normal,
  594. /// 文件映射页,含文件映射相关信息
  595. File(FileMapInfo),
  596. /// 共享内存页,记录ShmId
  597. Shm(ShmId),
  598. }
  599. #[derive(Debug, Clone)]
  600. pub struct FileMapInfo {
  601. pub page_cache: Arc<PageCache>,
  602. /// 在pagecache中的偏移
  603. pub index: usize,
  604. }
  605. #[derive(Debug)]
  606. pub struct PageTable<Arch> {
  607. /// 当前页表表示的虚拟地址空间的起始地址
  608. base: VirtAddr,
  609. /// 当前页表所在的物理地址
  610. phys: PhysAddr,
  611. /// 当前页表的层级(请注意,最顶级页表的level为[Arch::PAGE_LEVELS - 1])
  612. level: usize,
  613. phantom: PhantomData<Arch>,
  614. }
  615. #[allow(dead_code)]
  616. impl<Arch: MemoryManagementArch> PageTable<Arch> {
  617. pub unsafe fn new(base: VirtAddr, phys: PhysAddr, level: usize) -> Self {
  618. Self {
  619. base,
  620. phys,
  621. level,
  622. phantom: PhantomData,
  623. }
  624. }
  625. /// 获取顶级页表
  626. ///
  627. /// ## 参数
  628. ///
  629. /// - table_kind 页表类型
  630. ///
  631. /// ## 返回值
  632. ///
  633. /// 返回顶级页表
  634. pub unsafe fn top_level_table(table_kind: PageTableKind) -> Self {
  635. return Self::new(
  636. VirtAddr::new(0),
  637. Arch::table(table_kind),
  638. Arch::PAGE_LEVELS - 1,
  639. );
  640. }
  641. /// 获取当前页表的物理地址
  642. #[inline(always)]
  643. pub fn phys(&self) -> PhysAddr {
  644. self.phys
  645. }
  646. /// 当前页表表示的虚拟地址空间的起始地址
  647. #[inline(always)]
  648. pub fn base(&self) -> VirtAddr {
  649. self.base
  650. }
  651. /// 获取当前页表的层级
  652. #[inline(always)]
  653. pub fn level(&self) -> usize {
  654. self.level
  655. }
  656. /// 获取当前页表自身所在的虚拟地址
  657. #[inline(always)]
  658. pub unsafe fn virt(&self) -> VirtAddr {
  659. return Arch::phys_2_virt(self.phys).unwrap();
  660. }
  661. /// 获取第i个页表项所表示的虚拟内存空间的起始地址
  662. pub fn entry_base(&self, i: usize) -> Option<VirtAddr> {
  663. if i < Arch::PAGE_ENTRY_NUM {
  664. let shift = self.level * Arch::PAGE_ENTRY_SHIFT + Arch::PAGE_SHIFT;
  665. return Some(self.base.add(i << shift));
  666. } else {
  667. return None;
  668. }
  669. }
  670. /// 获取当前页表的第i个页表项所在的虚拟地址(注意与entry_base进行区分)
  671. pub unsafe fn entry_virt(&self, i: usize) -> Option<VirtAddr> {
  672. if i < Arch::PAGE_ENTRY_NUM {
  673. return Some(self.virt().add(i * Arch::PAGE_ENTRY_SIZE));
  674. } else {
  675. return None;
  676. }
  677. }
  678. /// 获取当前页表的第i个页表项
  679. pub unsafe fn entry(&self, i: usize) -> Option<PageEntry<Arch>> {
  680. let entry_virt = self.entry_virt(i)?;
  681. return Some(PageEntry::from_usize(Arch::read::<usize>(entry_virt)));
  682. }
  683. /// 设置当前页表的第i个页表项
  684. pub unsafe fn set_entry(&self, i: usize, entry: PageEntry<Arch>) -> Option<()> {
  685. let entry_virt = self.entry_virt(i)?;
  686. Arch::write::<usize>(entry_virt, entry.data());
  687. return Some(());
  688. }
  689. /// 判断当前页表的第i个页表项是否已经填写了值
  690. ///
  691. /// ## 参数
  692. /// - Some(true) 如果已经填写了值
  693. /// - Some(false) 如果未填写值
  694. /// - None 如果i超出了页表项的范围
  695. pub fn entry_mapped(&self, i: usize) -> Option<bool> {
  696. let etv = unsafe { self.entry_virt(i) }?;
  697. if unsafe { Arch::read::<usize>(etv) } != 0 {
  698. return Some(true);
  699. } else {
  700. return Some(false);
  701. }
  702. }
  703. /// 根据虚拟地址,获取对应的页表项在页表中的下标
  704. ///
  705. /// ## 参数
  706. ///
  707. /// - addr: 虚拟地址
  708. ///
  709. /// ## 返回值
  710. ///
  711. /// 页表项在页表中的下标。如果addr不在当前页表所表示的虚拟地址空间中,则返回None
  712. pub fn index_of(&self, addr: VirtAddr) -> Option<usize> {
  713. let addr = VirtAddr::new(addr.data() & Arch::PAGE_ADDRESS_MASK);
  714. let shift = self.level * Arch::PAGE_ENTRY_SHIFT + Arch::PAGE_SHIFT;
  715. let mask = (MMArch::PAGE_ENTRY_NUM << shift) - 1;
  716. if addr < self.base || addr >= self.base.add(mask) {
  717. return None;
  718. } else {
  719. return Some((addr.data() >> shift) & MMArch::PAGE_ENTRY_MASK);
  720. }
  721. }
  722. /// 获取第i个页表项指向的下一级页表
  723. pub unsafe fn next_level_table(&self, index: usize) -> Option<Self> {
  724. if self.level == 0 {
  725. return None;
  726. }
  727. // 返回下一级页表
  728. return Some(PageTable::new(
  729. self.entry_base(index)?,
  730. self.entry(index)?.address().ok()?,
  731. self.level - 1,
  732. ));
  733. }
  734. /// 拷贝页表
  735. /// ## 参数
  736. ///
  737. /// - `allocator`: 物理页框分配器
  738. /// - `copy_on_write`: 是否写时复制
  739. pub unsafe fn clone(
  740. &self,
  741. allocator: &mut impl FrameAllocator,
  742. copy_on_write: bool,
  743. ) -> Option<PageTable<Arch>> {
  744. // 分配新页面作为新的页表
  745. let phys = allocator.allocate_one()?;
  746. let frame = MMArch::phys_2_virt(phys).unwrap();
  747. MMArch::write_bytes(frame, 0, MMArch::PAGE_SIZE);
  748. let new_table = PageTable::new(self.base, phys, self.level);
  749. if self.level == 0 {
  750. for i in 0..Arch::PAGE_ENTRY_NUM {
  751. if let Some(mut entry) = self.entry(i) {
  752. if entry.present() {
  753. if copy_on_write {
  754. let mut new_flags = entry.flags().set_write(false);
  755. entry.set_flags(new_flags);
  756. self.set_entry(i, entry);
  757. new_flags = new_flags.set_dirty(false);
  758. entry.set_flags(new_flags);
  759. new_table.set_entry(i, entry);
  760. } else {
  761. let phys = allocator.allocate_one()?;
  762. let mut page_manager_guard = page_manager_lock_irqsave();
  763. let old_phys = entry.address().unwrap();
  764. page_manager_guard.copy_page(&old_phys, allocator).ok()?;
  765. new_table.set_entry(i, PageEntry::new(phys, entry.flags()));
  766. }
  767. }
  768. }
  769. }
  770. } else {
  771. // 非一级页表拷贝时,对每个页表项对应的页表都进行拷贝
  772. for i in 0..MMArch::PAGE_ENTRY_NUM {
  773. if let Some(next_table) = self.next_level_table(i) {
  774. let table = next_table.clone(allocator, copy_on_write)?;
  775. let old_entry = self.entry(i).unwrap();
  776. let entry = PageEntry::new(table.phys(), old_entry.flags());
  777. new_table.set_entry(i, entry);
  778. }
  779. }
  780. }
  781. Some(new_table)
  782. }
  783. }
  784. /// 页表项
  785. #[repr(C, align(8))]
  786. #[derive(Copy, Clone)]
  787. pub struct PageEntry<Arch> {
  788. data: usize,
  789. phantom: PhantomData<Arch>,
  790. }
  791. impl<Arch> Debug for PageEntry<Arch> {
  792. fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
  793. f.write_fmt(format_args!("PageEntry({:#x})", self.data))
  794. }
  795. }
  796. impl<Arch: MemoryManagementArch> PageEntry<Arch> {
  797. #[inline(always)]
  798. pub fn new(paddr: PhysAddr, flags: EntryFlags<Arch>) -> Self {
  799. Self {
  800. data: MMArch::make_entry(paddr, flags.data()),
  801. phantom: PhantomData,
  802. }
  803. }
  804. #[inline(always)]
  805. pub fn from_usize(data: usize) -> Self {
  806. Self {
  807. data,
  808. phantom: PhantomData,
  809. }
  810. }
  811. #[inline(always)]
  812. pub fn data(&self) -> usize {
  813. self.data
  814. }
  815. /// 获取当前页表项指向的物理地址
  816. ///
  817. /// ## 返回值
  818. ///
  819. /// - Ok(PhysAddr) 如果当前页面存在于物理内存中, 返回物理地址
  820. /// - Err(PhysAddr) 如果当前页表项不存在, 返回物理地址
  821. #[inline(always)]
  822. pub fn address(&self) -> Result<PhysAddr, PhysAddr> {
  823. let paddr: PhysAddr = {
  824. #[cfg(target_arch = "x86_64")]
  825. {
  826. PhysAddr::new(self.data & Arch::PAGE_ADDRESS_MASK)
  827. }
  828. #[cfg(target_arch = "riscv64")]
  829. {
  830. let ppn = ((self.data & (!((1 << 10) - 1))) >> 10) & ((1 << 54) - 1);
  831. super::allocator::page_frame::PhysPageFrame::from_ppn(ppn).phys_address()
  832. }
  833. #[cfg(target_arch = "loongarch64")]
  834. {
  835. todo!("la64: PageEntry::address")
  836. }
  837. };
  838. if self.present() {
  839. Ok(paddr)
  840. } else {
  841. Err(paddr)
  842. }
  843. }
  844. #[inline(always)]
  845. pub fn flags(&self) -> EntryFlags<Arch> {
  846. unsafe { EntryFlags::from_data(self.data & Arch::ENTRY_FLAGS_MASK) }
  847. }
  848. #[inline(always)]
  849. pub fn set_flags(&mut self, flags: EntryFlags<Arch>) {
  850. self.data = (self.data & !Arch::ENTRY_FLAGS_MASK) | flags.data();
  851. }
  852. #[inline(always)]
  853. pub fn present(&self) -> bool {
  854. return self.data & Arch::ENTRY_FLAG_PRESENT != 0;
  855. }
  856. #[inline(always)]
  857. pub fn empty(&self) -> bool {
  858. self.data & !(Arch::ENTRY_FLAG_DIRTY & Arch::ENTRY_FLAG_ACCESSED) == 0
  859. }
  860. #[inline(always)]
  861. pub fn protnone(&self) -> bool {
  862. return self.data & (Arch::ENTRY_FLAG_PRESENT | Arch::ENTRY_FLAG_GLOBAL)
  863. == Arch::ENTRY_FLAG_GLOBAL;
  864. }
  865. #[inline(always)]
  866. pub fn write(&self) -> bool {
  867. return self.data & Arch::ENTRY_FLAG_READWRITE != 0;
  868. }
  869. }
  870. /// 页表项的标志位
  871. #[derive(Copy, Clone, Hash)]
  872. pub struct EntryFlags<Arch> {
  873. data: usize,
  874. phantom: PhantomData<Arch>,
  875. }
  876. impl<Arch: MemoryManagementArch> Default for EntryFlags<Arch> {
  877. fn default() -> Self {
  878. Self::new()
  879. }
  880. }
  881. #[allow(dead_code)]
  882. impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
  883. #[inline(always)]
  884. pub fn new() -> Self {
  885. let mut r = unsafe {
  886. Self::from_data(
  887. Arch::ENTRY_FLAG_DEFAULT_PAGE
  888. | Arch::ENTRY_FLAG_READONLY
  889. | Arch::ENTRY_FLAG_NO_EXEC,
  890. )
  891. };
  892. #[cfg(target_arch = "x86_64")]
  893. {
  894. if crate::arch::mm::X86_64MMArch::is_xd_reserved() {
  895. r = r.set_execute(true);
  896. }
  897. }
  898. return r;
  899. }
  900. /// 根据ProtFlags生成EntryFlags
  901. ///
  902. /// ## 参数
  903. ///
  904. /// - prot_flags: 页的保护标志
  905. /// - user: 用户空间是否可访问
  906. pub fn from_prot_flags(prot_flags: ProtFlags, user: bool) -> Self {
  907. if Arch::PAGE_FAULT_ENABLED {
  908. let vm_flags = super::VmFlags::from(prot_flags);
  909. Arch::vm_get_page_prot(vm_flags).set_user(user)
  910. } else {
  911. EntryFlags::new()
  912. .set_user(user)
  913. .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC))
  914. .set_write(prot_flags.contains(ProtFlags::PROT_WRITE))
  915. }
  916. }
  917. #[inline(always)]
  918. pub fn data(&self) -> usize {
  919. self.data
  920. }
  921. #[inline(always)]
  922. pub const unsafe fn from_data(data: usize) -> Self {
  923. return Self {
  924. data,
  925. phantom: PhantomData,
  926. };
  927. }
  928. /// 为新页表的页表项设置默认值
  929. ///
  930. /// 默认值为:
  931. /// - present
  932. /// - read only
  933. /// - kernel space
  934. /// - no exec
  935. #[inline(always)]
  936. pub fn new_page_table(user: bool) -> Self {
  937. return unsafe {
  938. let r = {
  939. #[cfg(target_arch = "x86_64")]
  940. {
  941. Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE | Arch::ENTRY_FLAG_READWRITE)
  942. }
  943. #[cfg(target_arch = "riscv64")]
  944. {
  945. // riscv64指向下一级页表的页表项,不应设置R/W/X权限位
  946. Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
  947. }
  948. #[cfg(target_arch = "loongarch64")]
  949. {
  950. Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
  951. }
  952. };
  953. #[cfg(target_arch = "x86_64")]
  954. {
  955. if user {
  956. r.set_user(true)
  957. } else {
  958. r
  959. }
  960. }
  961. #[cfg(target_arch = "riscv64")]
  962. {
  963. r
  964. }
  965. #[cfg(target_arch = "loongarch64")]
  966. {
  967. todo!("loongarch64: new_page_table")
  968. }
  969. };
  970. }
  971. /// 取得当前页表项的所有权,更新当前页表项的标志位,并返回更新后的页表项。
  972. ///
  973. /// ## 参数
  974. /// - flag 要更新的标志位的值
  975. /// - value 如果为true,那么将flag对应的位设置为1,否则设置为0
  976. ///
  977. /// ## 返回值
  978. ///
  979. /// 更新后的页表项
  980. #[inline(always)]
  981. #[must_use]
  982. pub fn update_flags(mut self, flag: usize, value: bool) -> Self {
  983. if value {
  984. self.data |= flag;
  985. } else {
  986. self.data &= !flag;
  987. }
  988. return self;
  989. }
  990. /// 判断当前页表项是否存在指定的flag(只有全部flag都存在才返回true)
  991. #[inline(always)]
  992. pub fn has_flag(&self, flag: usize) -> bool {
  993. return self.data & flag == flag;
  994. }
  995. #[inline(always)]
  996. pub fn present(&self) -> bool {
  997. return self.has_flag(Arch::ENTRY_FLAG_PRESENT);
  998. }
  999. /// 设置当前页表项的权限
  1000. ///
  1001. /// @param value 如果为true,那么将当前页表项的权限设置为用户态可访问
  1002. #[must_use]
  1003. #[inline(always)]
  1004. pub fn set_user(self, value: bool) -> Self {
  1005. return self.update_flags(Arch::ENTRY_FLAG_USER, value);
  1006. }
  1007. /// 用户态是否可以访问当前页表项
  1008. #[inline(always)]
  1009. pub fn has_user(&self) -> bool {
  1010. return self.has_flag(Arch::ENTRY_FLAG_USER);
  1011. }
  1012. /// 设置当前页表项的可写性, 如果为true,那么将当前页表项的权限设置为可写, 否则设置为只读
  1013. ///
  1014. /// ## 返回值
  1015. ///
  1016. /// 更新后的页表项.
  1017. ///
  1018. /// **请注意,**本函数会取得当前页表项的所有权,因此返回的页表项不是原来的页表项
  1019. #[must_use]
  1020. #[inline(always)]
  1021. pub fn set_write(self, value: bool) -> Self {
  1022. #[cfg(target_arch = "x86_64")]
  1023. {
  1024. // 有的架构同时具有可写和不可写的标志位,因此需要同时更新
  1025. return self
  1026. .update_flags(Arch::ENTRY_FLAG_READONLY, !value)
  1027. .update_flags(Arch::ENTRY_FLAG_READWRITE, value);
  1028. }
  1029. #[cfg(target_arch = "riscv64")]
  1030. {
  1031. if value {
  1032. return self.update_flags(Arch::ENTRY_FLAG_READWRITE, true);
  1033. } else {
  1034. return self
  1035. .update_flags(Arch::ENTRY_FLAG_READONLY, true)
  1036. .update_flags(Arch::ENTRY_FLAG_WRITEABLE, false);
  1037. }
  1038. }
  1039. #[cfg(target_arch = "loongarch64")]
  1040. {
  1041. todo!("la64: set_write")
  1042. }
  1043. }
  1044. /// 当前页表项是否可写
  1045. #[inline(always)]
  1046. pub fn has_write(&self) -> bool {
  1047. // 有的架构同时具有可写和不可写的标志位,因此需要同时判断
  1048. return self.data & (Arch::ENTRY_FLAG_READWRITE | Arch::ENTRY_FLAG_READONLY)
  1049. == Arch::ENTRY_FLAG_READWRITE;
  1050. }
  1051. /// 设置当前页表项的可执行性, 如果为true,那么将当前页表项的权限设置为可执行, 否则设置为不可执行
  1052. #[must_use]
  1053. #[inline(always)]
  1054. pub fn set_execute(self, mut value: bool) -> Self {
  1055. #[cfg(target_arch = "x86_64")]
  1056. {
  1057. // 如果xd位被保留,那么将可执行性设置为true
  1058. if crate::arch::mm::X86_64MMArch::is_xd_reserved() {
  1059. value = true;
  1060. }
  1061. }
  1062. // 有的架构同时具有可执行和不可执行的标志位,因此需要同时更新
  1063. return self
  1064. .update_flags(Arch::ENTRY_FLAG_NO_EXEC, !value)
  1065. .update_flags(Arch::ENTRY_FLAG_EXEC, value);
  1066. }
  1067. /// 当前页表项是否可执行
  1068. #[inline(always)]
  1069. pub fn has_execute(&self) -> bool {
  1070. // 有的架构同时具有可执行和不可执行的标志位,因此需要同时判断
  1071. return self.data & (Arch::ENTRY_FLAG_EXEC | Arch::ENTRY_FLAG_NO_EXEC)
  1072. == Arch::ENTRY_FLAG_EXEC;
  1073. }
  1074. /// 设置当前页表项的缓存策略
  1075. ///
  1076. /// ## 参数
  1077. ///
  1078. /// - value: 如果为true,那么将当前页表项的缓存策略设置为不缓存。
  1079. #[inline(always)]
  1080. pub fn set_page_cache_disable(self, value: bool) -> Self {
  1081. return self.update_flags(Arch::ENTRY_FLAG_CACHE_DISABLE, value);
  1082. }
  1083. /// 获取当前页表项的缓存策略
  1084. ///
  1085. /// ## 返回值
  1086. ///
  1087. /// 如果当前页表项的缓存策略为不缓存,那么返回true,否则返回false。
  1088. #[inline(always)]
  1089. pub fn has_page_cache_disable(&self) -> bool {
  1090. return self.has_flag(Arch::ENTRY_FLAG_CACHE_DISABLE);
  1091. }
  1092. /// 设置当前页表项的写穿策略
  1093. ///
  1094. /// ## 参数
  1095. ///
  1096. /// - value: 如果为true,那么将当前页表项的写穿策略设置为写穿。
  1097. #[inline(always)]
  1098. pub fn set_page_write_through(self, value: bool) -> Self {
  1099. return self.update_flags(Arch::ENTRY_FLAG_WRITE_THROUGH, value);
  1100. }
  1101. #[inline(always)]
  1102. pub fn set_page_global(self, value: bool) -> Self {
  1103. return self.update_flags(MMArch::ENTRY_FLAG_GLOBAL, value);
  1104. }
  1105. /// 获取当前页表项的写穿策略
  1106. ///
  1107. /// ## 返回值
  1108. ///
  1109. /// 如果当前页表项的写穿策略为写穿,那么返回true,否则返回false。
  1110. #[inline(always)]
  1111. pub fn has_page_write_through(&self) -> bool {
  1112. return self.has_flag(Arch::ENTRY_FLAG_WRITE_THROUGH);
  1113. }
  1114. /// 设置当前页表是否为脏页
  1115. ///
  1116. /// ## 参数
  1117. ///
  1118. /// - value: 如果为true,那么将当前页表项的写穿策略设置为写穿。
  1119. #[inline(always)]
  1120. pub fn set_dirty(self, value: bool) -> Self {
  1121. return self.update_flags(Arch::ENTRY_FLAG_DIRTY, value);
  1122. }
  1123. /// 设置当前页表被访问
  1124. ///
  1125. /// ## 参数
  1126. ///
  1127. /// - value: 如果为true,那么将当前页表项的访问标志设置为已访问。
  1128. #[inline(always)]
  1129. pub fn set_access(self, value: bool) -> Self {
  1130. return self.update_flags(Arch::ENTRY_FLAG_ACCESSED, value);
  1131. }
  1132. /// 设置指向的页是否为大页
  1133. ///
  1134. /// ## 参数
  1135. ///
  1136. /// - value: 如果为true,那么将当前页表项的访问标志设置为已访问。
  1137. #[inline(always)]
  1138. pub fn set_huge_page(self, value: bool) -> Self {
  1139. return self.update_flags(Arch::ENTRY_FLAG_HUGE_PAGE, value);
  1140. }
  1141. /// MMIO内存的页表项标志
  1142. #[inline(always)]
  1143. pub fn mmio_flags() -> Self {
  1144. #[cfg(target_arch = "x86_64")]
  1145. {
  1146. Self::new()
  1147. .set_user(false)
  1148. .set_write(true)
  1149. .set_execute(true)
  1150. .set_page_cache_disable(true)
  1151. .set_page_write_through(true)
  1152. .set_page_global(true)
  1153. }
  1154. #[cfg(target_arch = "riscv64")]
  1155. {
  1156. Self::new()
  1157. .set_user(false)
  1158. .set_write(true)
  1159. .set_execute(true)
  1160. .set_page_global(true)
  1161. }
  1162. #[cfg(target_arch = "loongarch64")]
  1163. {
  1164. todo!("la64: mmio_flags()")
  1165. }
  1166. }
  1167. }
  1168. impl<Arch: MemoryManagementArch> fmt::Debug for EntryFlags<Arch> {
  1169. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  1170. f.debug_struct("EntryFlags")
  1171. .field("bits", &format_args!("{:#0x}", self.data))
  1172. .field("present", &self.present())
  1173. .field("has_write", &self.has_write())
  1174. .field("has_execute", &self.has_execute())
  1175. .field("has_user", &self.has_user())
  1176. .finish()
  1177. }
  1178. }
  1179. /// 页表映射器
  1180. #[derive(Hash)]
  1181. pub struct PageMapper<Arch, F> {
  1182. /// 页表类型
  1183. table_kind: PageTableKind,
  1184. /// 根页表物理地址
  1185. table_paddr: PhysAddr,
  1186. /// 页分配器
  1187. frame_allocator: F,
  1188. phantom: PhantomData<fn() -> Arch>,
  1189. }
  1190. impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
  1191. /// 创建新的页面映射器
  1192. ///
  1193. /// ## 参数
  1194. /// - table_kind 页表类型
  1195. /// - table_paddr 根页表物理地址
  1196. /// - allocator 页分配器
  1197. ///
  1198. /// ## 返回值
  1199. ///
  1200. /// 页面映射器
  1201. pub unsafe fn new(table_kind: PageTableKind, table_paddr: PhysAddr, allocator: F) -> Self {
  1202. return Self {
  1203. table_kind,
  1204. table_paddr,
  1205. frame_allocator: allocator,
  1206. phantom: PhantomData,
  1207. };
  1208. }
  1209. /// 创建页表,并为这个页表创建页面映射器
  1210. pub unsafe fn create(table_kind: PageTableKind, mut allocator: F) -> Option<Self> {
  1211. let table_paddr = allocator.allocate_one()?;
  1212. // 清空页表
  1213. let table_vaddr = Arch::phys_2_virt(table_paddr)?;
  1214. Arch::write_bytes(table_vaddr, 0, Arch::PAGE_SIZE);
  1215. return Some(Self::new(table_kind, table_paddr, allocator));
  1216. }
  1217. /// 获取当前页表的页面映射器
  1218. #[inline(always)]
  1219. pub unsafe fn current(table_kind: PageTableKind, allocator: F) -> Self {
  1220. let table_paddr = Arch::table(table_kind);
  1221. return Self::new(table_kind, table_paddr, allocator);
  1222. }
  1223. /// 判断当前页表分配器所属的页表是否是当前页表
  1224. #[inline(always)]
  1225. pub fn is_current(&self) -> bool {
  1226. return unsafe { self.table().phys() == Arch::table(self.table_kind) };
  1227. }
  1228. /// 将当前页表分配器所属的页表设置为当前页表
  1229. #[inline(always)]
  1230. pub unsafe fn make_current(&self) {
  1231. Arch::set_table(self.table_kind, self.table_paddr);
  1232. }
  1233. /// 获取当前页表分配器所属的根页表的结构体
  1234. #[inline(always)]
  1235. pub fn table(&self) -> PageTable<Arch> {
  1236. // 由于只能通过new方法创建PageMapper,因此这里假定table_paddr是有效的
  1237. return unsafe {
  1238. PageTable::new(VirtAddr::new(0), self.table_paddr, Arch::PAGE_LEVELS - 1)
  1239. };
  1240. }
  1241. /// 获取当前PageMapper所对应的页分配器实例的引用
  1242. #[inline(always)]
  1243. #[allow(dead_code)]
  1244. pub fn allocator_ref(&self) -> &F {
  1245. return &self.frame_allocator;
  1246. }
  1247. /// 获取当前PageMapper所对应的页分配器实例的可变引用
  1248. #[inline(always)]
  1249. pub fn allocator_mut(&mut self) -> &mut F {
  1250. return &mut self.frame_allocator;
  1251. }
  1252. /// 从当前PageMapper的页分配器中分配一个物理页,并将其映射到指定的虚拟地址
  1253. pub unsafe fn map(
  1254. &mut self,
  1255. virt: VirtAddr,
  1256. flags: EntryFlags<Arch>,
  1257. ) -> Option<PageFlush<Arch>> {
  1258. let mut page_manager_guard: SpinLockGuard<'static, PageManager> =
  1259. page_manager_lock_irqsave();
  1260. let page = page_manager_guard
  1261. .create_one_page(
  1262. PageType::Normal,
  1263. PageFlags::empty(),
  1264. &mut self.frame_allocator,
  1265. )
  1266. .ok()?;
  1267. drop(page_manager_guard);
  1268. let phys = page.phys_address();
  1269. return self.map_phys(virt, phys, flags);
  1270. }
  1271. /// 映射一个物理页到指定的虚拟地址
  1272. pub unsafe fn map_phys(
  1273. &mut self,
  1274. virt: VirtAddr,
  1275. phys: PhysAddr,
  1276. flags: EntryFlags<Arch>,
  1277. ) -> Option<PageFlush<Arch>> {
  1278. // 验证虚拟地址和物理地址是否对齐
  1279. if !(virt.check_aligned(Arch::PAGE_SIZE) && phys.check_aligned(Arch::PAGE_SIZE)) {
  1280. error!(
  1281. "Try to map unaligned page: virt={:?}, phys={:?}",
  1282. virt, phys
  1283. );
  1284. return None;
  1285. }
  1286. let virt = VirtAddr::new(virt.data() & (!Arch::PAGE_NEGATIVE_MASK));
  1287. // TODO: 验证flags是否合法
  1288. // 创建页表项
  1289. let entry = PageEntry::new(phys, flags);
  1290. let mut table = self.table();
  1291. loop {
  1292. let i = table.index_of(virt)?;
  1293. assert!(i < Arch::PAGE_ENTRY_NUM);
  1294. if table.level() == 0 {
  1295. compiler_fence(Ordering::SeqCst);
  1296. table.set_entry(i, entry);
  1297. compiler_fence(Ordering::SeqCst);
  1298. return Some(PageFlush::new(virt));
  1299. } else {
  1300. let next_table = table.next_level_table(i);
  1301. if let Some(next_table) = next_table {
  1302. table = next_table;
  1303. // debug!("Mapping {:?} to next level table...", virt);
  1304. } else {
  1305. // 分配下一级页表
  1306. let frame = self.frame_allocator.allocate_one()?;
  1307. // 清空这个页帧
  1308. MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
  1309. // 设置页表项的flags
  1310. let flags: EntryFlags<Arch> =
  1311. EntryFlags::new_page_table(virt.kind() == PageTableKind::User);
  1312. // 把新分配的页表映射到当前页表
  1313. table.set_entry(i, PageEntry::new(frame, flags));
  1314. // 获取新分配的页表
  1315. table = table.next_level_table(i)?;
  1316. }
  1317. }
  1318. }
  1319. }
  1320. /// 进行大页映射
  1321. pub unsafe fn map_huge_page(
  1322. &mut self,
  1323. virt: VirtAddr,
  1324. flags: EntryFlags<Arch>,
  1325. ) -> Option<PageFlush<Arch>> {
  1326. // 验证虚拟地址是否对齐
  1327. if !(virt.check_aligned(Arch::PAGE_SIZE)) {
  1328. error!("Try to map unaligned page: virt={:?}", virt);
  1329. return None;
  1330. }
  1331. let virt = VirtAddr::new(virt.data() & (!Arch::PAGE_NEGATIVE_MASK));
  1332. let mut table = self.table();
  1333. loop {
  1334. let i = table.index_of(virt)?;
  1335. assert!(i < Arch::PAGE_ENTRY_NUM);
  1336. let next_table = table.next_level_table(i);
  1337. if let Some(next_table) = next_table {
  1338. table = next_table;
  1339. } else {
  1340. break;
  1341. }
  1342. }
  1343. // 支持2M、1G大页,即页表层级为1、2级的页表可以映射大页
  1344. if table.level == 0 || table.level > 2 {
  1345. return None;
  1346. }
  1347. let (phys, count) = self.frame_allocator.allocate(PageFrameCount::new(
  1348. Arch::PAGE_ENTRY_NUM.pow(table.level as u32),
  1349. ))?;
  1350. MMArch::write_bytes(
  1351. MMArch::phys_2_virt(phys).unwrap(),
  1352. 0,
  1353. MMArch::PAGE_SIZE * count.data(),
  1354. );
  1355. table.set_entry(
  1356. table.index_of(virt)?,
  1357. PageEntry::new(phys, flags.set_huge_page(true)),
  1358. )?;
  1359. Some(PageFlush::new(virt))
  1360. }
  1361. /// 为虚拟地址分配指定层级的页表
  1362. /// ## 参数
  1363. ///
  1364. /// - `virt`: 虚拟地址
  1365. /// - `level`: 指定页表层级
  1366. ///
  1367. /// ## 返回值
  1368. /// - Some(PageTable<Arch>): 虚拟地址对应层级的页表
  1369. /// - None: 对应页表不存在
  1370. pub unsafe fn allocate_table(
  1371. &mut self,
  1372. virt: VirtAddr,
  1373. level: usize,
  1374. ) -> Option<PageTable<Arch>> {
  1375. let table = self.get_table(virt, level + 1)?;
  1376. let i = table.index_of(virt)?;
  1377. let frame = self.frame_allocator.allocate_one()?;
  1378. // 清空这个页帧
  1379. MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
  1380. // 设置页表项的flags
  1381. let flags: EntryFlags<Arch> =
  1382. EntryFlags::new_page_table(virt.kind() == PageTableKind::User);
  1383. table.set_entry(i, PageEntry::new(frame, flags));
  1384. table.next_level_table(i)
  1385. }
  1386. /// 获取虚拟地址的指定层级页表
  1387. /// ## 参数
  1388. ///
  1389. /// - `virt`: 虚拟地址
  1390. /// - `level`: 指定页表层级
  1391. ///
  1392. /// ## 返回值
  1393. /// - Some(PageTable<Arch>): 虚拟地址对应层级的页表
  1394. /// - None: 对应页表不存在
  1395. pub fn get_table(&self, virt: VirtAddr, level: usize) -> Option<PageTable<Arch>> {
  1396. let mut table = self.table();
  1397. if level > Arch::PAGE_LEVELS - 1 {
  1398. return None;
  1399. }
  1400. unsafe {
  1401. loop {
  1402. if table.level == level {
  1403. return Some(table);
  1404. }
  1405. let i = table.index_of(virt)?;
  1406. assert!(i < Arch::PAGE_ENTRY_NUM);
  1407. table = table.next_level_table(i)?;
  1408. }
  1409. }
  1410. }
  1411. /// 获取虚拟地址在指定层级页表的PageEntry
  1412. /// ## 参数
  1413. ///
  1414. /// - `virt`: 虚拟地址
  1415. /// - `level`: 指定页表层级
  1416. ///
  1417. /// ## 返回值
  1418. /// - Some(PageEntry<Arch>): 虚拟地址在指定层级的页表的有效PageEntry
  1419. /// - None: 无对应的有效PageEntry
  1420. pub fn get_entry(&self, virt: VirtAddr, level: usize) -> Option<PageEntry<Arch>> {
  1421. let table = self.get_table(virt, level)?;
  1422. let i = table.index_of(virt)?;
  1423. let entry = unsafe { table.entry(i) }?;
  1424. if !entry.empty() {
  1425. Some(entry)
  1426. } else {
  1427. None
  1428. }
  1429. // let mut table = self.table();
  1430. // if level > Arch::PAGE_LEVELS - 1 {
  1431. // return None;
  1432. // }
  1433. // unsafe {
  1434. // loop {
  1435. // let i = table.index_of(virt)?;
  1436. // assert!(i < Arch::PAGE_ENTRY_NUM);
  1437. // if table.level == level {
  1438. // let entry = table.entry(i)?;
  1439. // if !entry.empty() {
  1440. // return Some(entry);
  1441. // } else {
  1442. // return None;
  1443. // }
  1444. // }
  1445. // table = table.next_level_table(i)?;
  1446. // }
  1447. // }
  1448. }
  1449. /// 拷贝用户空间映射
  1450. /// ## 参数
  1451. ///
  1452. /// - `umapper`: 要拷贝的用户空间
  1453. /// - `copy_on_write`: 是否写时复制
  1454. pub unsafe fn clone_user_mapping(&mut self, umapper: &mut Self, copy_on_write: bool) {
  1455. let old_table = umapper.table();
  1456. let new_table = self.table();
  1457. let allocator = self.allocator_mut();
  1458. // 顶级页表的[0, PAGE_KERNEL_INDEX)项为用户空间映射
  1459. for entry_index in 0..Arch::PAGE_KERNEL_INDEX {
  1460. if let Some(next_table) = old_table.next_level_table(entry_index) {
  1461. let table = next_table.clone(allocator, copy_on_write).unwrap();
  1462. let old_entry = old_table.entry(entry_index).unwrap();
  1463. let entry = PageEntry::new(table.phys(), old_entry.flags());
  1464. new_table.set_entry(entry_index, entry);
  1465. }
  1466. }
  1467. }
  1468. /// 将物理地址映射到具有线性偏移量的虚拟地址
  1469. #[allow(dead_code)]
  1470. pub unsafe fn map_linearly(
  1471. &mut self,
  1472. phys: PhysAddr,
  1473. flags: EntryFlags<Arch>,
  1474. ) -> Option<(VirtAddr, PageFlush<Arch>)> {
  1475. let virt: VirtAddr = Arch::phys_2_virt(phys)?;
  1476. return self.map_phys(virt, phys, flags).map(|flush| (virt, flush));
  1477. }
  1478. /// 修改虚拟地址的页表项的flags,并返回页表项刷新器
  1479. ///
  1480. /// 请注意,需要在修改完flags后,调用刷新器的flush方法,才能使修改生效
  1481. ///
  1482. /// ## 参数
  1483. /// - virt 虚拟地址
  1484. /// - flags 新的页表项的flags
  1485. ///
  1486. /// ## 返回值
  1487. ///
  1488. /// 如果修改成功,返回刷新器,否则返回None
  1489. pub unsafe fn remap(
  1490. &mut self,
  1491. virt: VirtAddr,
  1492. flags: EntryFlags<Arch>,
  1493. ) -> Option<PageFlush<Arch>> {
  1494. return self
  1495. .visit(virt, |p1, i| {
  1496. let mut entry = p1.entry(i)?;
  1497. entry.set_flags(flags);
  1498. p1.set_entry(i, entry);
  1499. Some(PageFlush::new(virt))
  1500. })
  1501. .flatten();
  1502. }
  1503. /// 根据虚拟地址,查找页表,获取对应的物理地址和页表项的flags
  1504. ///
  1505. /// ## 参数
  1506. ///
  1507. /// - virt 虚拟地址
  1508. ///
  1509. /// ## 返回值
  1510. ///
  1511. /// 如果查找成功,返回物理地址和页表项的flags,否则返回None
  1512. pub fn translate(&self, virt: VirtAddr) -> Option<(PhysAddr, EntryFlags<Arch>)> {
  1513. let entry: PageEntry<Arch> = self.visit(virt, |p1, i| unsafe { p1.entry(i) })??;
  1514. let paddr = entry.address().ok()?;
  1515. let flags = entry.flags();
  1516. return Some((paddr, flags));
  1517. }
  1518. /// 取消虚拟地址的映射,释放页面,并返回页表项刷新器
  1519. ///
  1520. /// 请注意,需要在取消映射后,调用刷新器的flush方法,才能使修改生效
  1521. ///
  1522. /// ## 参数
  1523. ///
  1524. /// - virt 虚拟地址
  1525. /// - unmap_parents 是否在父页表内,取消空闲子页表的映射
  1526. ///
  1527. /// ## 返回值
  1528. /// 如果取消成功,返回刷新器,否则返回None
  1529. #[allow(dead_code)]
  1530. pub unsafe fn unmap(&mut self, virt: VirtAddr, unmap_parents: bool) -> Option<PageFlush<Arch>> {
  1531. let (paddr, _, flusher) = self.unmap_phys(virt, unmap_parents)?;
  1532. self.frame_allocator.free_one(paddr);
  1533. return Some(flusher);
  1534. }
  1535. /// 取消虚拟地址的映射,并返回物理地址和页表项的flags
  1536. ///
  1537. /// ## 参数
  1538. ///
  1539. /// - vaddr 虚拟地址
  1540. /// - unmap_parents 是否在父页表内,取消空闲子页表的映射
  1541. ///
  1542. /// ## 返回值
  1543. ///
  1544. /// 如果取消成功,返回物理地址和页表项的flags,否则返回None
  1545. pub unsafe fn unmap_phys(
  1546. &mut self,
  1547. virt: VirtAddr,
  1548. unmap_parents: bool,
  1549. ) -> Option<(PhysAddr, EntryFlags<Arch>, PageFlush<Arch>)> {
  1550. if !virt.check_aligned(Arch::PAGE_SIZE) {
  1551. error!("Try to unmap unaligned page: virt={:?}", virt);
  1552. return None;
  1553. }
  1554. let table = self.table();
  1555. return unmap_phys_inner(virt, &table, unmap_parents, self.allocator_mut())
  1556. .map(|(paddr, flags)| (paddr, flags, PageFlush::<Arch>::new(virt)));
  1557. }
  1558. /// 在页表中,访问虚拟地址对应的页表项,并调用传入的函数F
  1559. fn visit<T>(
  1560. &self,
  1561. virt: VirtAddr,
  1562. f: impl FnOnce(&mut PageTable<Arch>, usize) -> T,
  1563. ) -> Option<T> {
  1564. let mut table = self.table();
  1565. unsafe {
  1566. loop {
  1567. let i = table.index_of(virt)?;
  1568. if table.level() == 0 {
  1569. return Some(f(&mut table, i));
  1570. } else {
  1571. table = table.next_level_table(i)?;
  1572. }
  1573. }
  1574. }
  1575. }
  1576. }
  1577. /// 取消页面映射,返回被取消映射的页表项的:【物理地址】和【flags】
  1578. ///
  1579. /// ## 参数
  1580. ///
  1581. /// - vaddr 虚拟地址
  1582. /// - table 页表
  1583. /// - unmap_parents 是否在父页表内,取消空闲子页表的映射
  1584. /// - allocator 页面分配器(如果页表从这个分配器分配,那么在取消映射时,也需要归还到这个分配器内)
  1585. ///
  1586. /// ## 返回值
  1587. ///
  1588. /// 如果取消成功,返回被取消映射的页表项的:【物理地址】和【flags】,否则返回None
  1589. unsafe fn unmap_phys_inner<Arch: MemoryManagementArch>(
  1590. vaddr: VirtAddr,
  1591. table: &PageTable<Arch>,
  1592. unmap_parents: bool,
  1593. allocator: &mut impl FrameAllocator,
  1594. ) -> Option<(PhysAddr, EntryFlags<Arch>)> {
  1595. // 获取页表项的索引
  1596. let i = table.index_of(vaddr)?;
  1597. // 如果当前是最后一级页表,直接取消页面映射
  1598. if table.level() == 0 {
  1599. let entry = table.entry(i)?;
  1600. table.set_entry(i, PageEntry::from_usize(0));
  1601. return Some((entry.address().ok()?, entry.flags()));
  1602. }
  1603. let subtable = table.next_level_table(i)?;
  1604. // 递归地取消映射
  1605. let result = unmap_phys_inner(vaddr, &subtable, unmap_parents, allocator)?;
  1606. // TODO: This is a bad idea for architectures where the kernel mappings are done in the process tables,
  1607. // as these mappings may become out of sync
  1608. if unmap_parents {
  1609. // 如果子页表已经没有映射的页面了,就取消子页表的映射
  1610. // 检查子页表中是否还有映射的页面
  1611. let x = (0..Arch::PAGE_ENTRY_NUM)
  1612. .map(|k| subtable.entry(k).expect("invalid page entry"))
  1613. .any(|e| e.present());
  1614. if !x {
  1615. // 如果没有,就取消子页表的映射
  1616. table.set_entry(i, PageEntry::from_usize(0));
  1617. // 释放子页表
  1618. allocator.free_one(subtable.phys());
  1619. }
  1620. }
  1621. return Some(result);
  1622. }
  1623. impl<Arch, F: Debug> Debug for PageMapper<Arch, F> {
  1624. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  1625. f.debug_struct("PageMapper")
  1626. .field("table_paddr", &self.table_paddr)
  1627. .field("frame_allocator", &self.frame_allocator)
  1628. .finish()
  1629. }
  1630. }
  1631. /// 页表刷新器的trait
  1632. pub trait Flusher<Arch: MemoryManagementArch> {
  1633. /// 取消对指定的page flusher的刷新
  1634. fn consume(&mut self, flush: PageFlush<Arch>);
  1635. }
  1636. /// 用于刷新某个虚拟地址的刷新器。这个刷新器一经产生,就必须调用flush()方法,
  1637. /// 否则会造成对页表的更改被忽略,这是不安全的
  1638. #[must_use = "The flusher must call the 'flush()', or the changes to page table will be unsafely ignored."]
  1639. pub struct PageFlush<Arch: MemoryManagementArch> {
  1640. virt: VirtAddr,
  1641. phantom: PhantomData<Arch>,
  1642. }
  1643. impl<Arch: MemoryManagementArch> PageFlush<Arch> {
  1644. pub fn new(virt: VirtAddr) -> Self {
  1645. return Self {
  1646. virt,
  1647. phantom: PhantomData,
  1648. };
  1649. }
  1650. pub fn flush(self) {
  1651. unsafe { Arch::invalidate_page(self.virt) };
  1652. }
  1653. /// 忽略掉这个刷新器
  1654. pub unsafe fn ignore(self) {
  1655. mem::forget(self);
  1656. }
  1657. }
  1658. impl<Arch: MemoryManagementArch> Drop for PageFlush<Arch> {
  1659. fn drop(&mut self) {
  1660. unsafe {
  1661. MMArch::invalidate_page(self.virt);
  1662. }
  1663. }
  1664. }
  1665. /// 用于刷新整个页表的刷新器。这个刷新器一经产生,就必须调用flush()方法,
  1666. /// 否则会造成对页表的更改被忽略,这是不安全的
  1667. #[must_use = "The flusher must call the 'flush()', or the changes to page table will be unsafely ignored."]
  1668. pub struct PageFlushAll<Arch: MemoryManagementArch> {
  1669. phantom: PhantomData<fn() -> Arch>,
  1670. }
  1671. #[allow(dead_code)]
  1672. impl<Arch: MemoryManagementArch> PageFlushAll<Arch> {
  1673. pub fn new() -> Self {
  1674. return Self {
  1675. phantom: PhantomData,
  1676. };
  1677. }
  1678. pub fn flush(self) {
  1679. unsafe { Arch::invalidate_all() };
  1680. }
  1681. /// 忽略掉这个刷新器
  1682. pub unsafe fn ignore(self) {
  1683. mem::forget(self);
  1684. }
  1685. }
  1686. impl<Arch: MemoryManagementArch> Flusher<Arch> for PageFlushAll<Arch> {
  1687. /// 为page flush all 实现consume,消除对单个页面的刷新。(刷新整个页表了就不需要刷新单个页面了)
  1688. fn consume(&mut self, flush: PageFlush<Arch>) {
  1689. unsafe { flush.ignore() };
  1690. }
  1691. }
  1692. impl<Arch: MemoryManagementArch, T: Flusher<Arch> + ?Sized> Flusher<Arch> for &mut T {
  1693. /// 允许一个flusher consume掉另一个flusher
  1694. fn consume(&mut self, flush: PageFlush<Arch>) {
  1695. <T as Flusher<Arch>>::consume(self, flush);
  1696. }
  1697. }
  1698. impl<Arch: MemoryManagementArch> Flusher<Arch> for () {
  1699. fn consume(&mut self, _flush: PageFlush<Arch>) {}
  1700. }
  1701. impl<Arch: MemoryManagementArch> Drop for PageFlushAll<Arch> {
  1702. fn drop(&mut self) {
  1703. unsafe {
  1704. Arch::invalidate_all();
  1705. }
  1706. }
  1707. }
  1708. /// 未在当前CPU上激活的页表的刷新器
  1709. ///
  1710. /// 如果页表没有在当前cpu上激活,那么需要发送ipi到其他核心,尝试在其他核心上刷新页表
  1711. ///
  1712. /// TODO: 这个方式很暴力,也许把它改成在指定的核心上刷新页表会更好。(可以测试一下开销)
  1713. #[derive(Debug)]
  1714. pub struct InactiveFlusher;
  1715. impl InactiveFlusher {
  1716. pub fn new() -> Self {
  1717. return Self {};
  1718. }
  1719. }
  1720. impl Flusher<MMArch> for InactiveFlusher {
  1721. fn consume(&mut self, flush: PageFlush<MMArch>) {
  1722. unsafe {
  1723. flush.ignore();
  1724. }
  1725. }
  1726. }
  1727. impl Drop for InactiveFlusher {
  1728. fn drop(&mut self) {
  1729. // 发送刷新页表的IPI
  1730. send_ipi(IpiKind::FlushTLB, IpiTarget::Other);
  1731. }
  1732. }
  1733. /// # 把一个地址向下对齐到页大小
  1734. pub fn round_down_to_page_size(addr: usize) -> usize {
  1735. addr & !(MMArch::PAGE_SIZE - 1)
  1736. }
  1737. /// # 把一个地址向上对齐到页大小
  1738. pub fn round_up_to_page_size(addr: usize) -> usize {
  1739. round_down_to_page_size(addr + MMArch::PAGE_SIZE - 1)
  1740. }