mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-23 12:13:22 +00:00
feat(mm): 简单实现fat文件系统的文件映射 (#840)
- 添加文件映射相关接口,目前已简单实现fat文件系统的私有映射和共享映射 - 添加msync系统调用(由于当前未实现脏页自动回写,需要手动调用msync进行同步) - 简单实现PageCache(暂时使用HashMap进行文件页号与页的映射) - 添加新的PageFlags标志结构,原PageFlags改名为EntryFlags - 参考linux使用protection_map映射表进行页面标志的获取 - 添加页面回收机制 - 添加页面回收内核线程 - 缺页中断使用的锁修改为irq_save; 添加脏页回写机制 - 修复do_cow_page死锁问题 - 访问非法地址时发送信号终止进程 - 修复重复插入反向vma表的错误 - 添加test_filemap文件映射测试程序
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
use alloc::string::ToString;
|
||||
use core::{
|
||||
fmt::{self, Debug, Error, Formatter},
|
||||
marker::PhantomData,
|
||||
@ -5,16 +6,26 @@ use core::{
|
||||
ops::Add,
|
||||
sync::atomic::{compiler_fence, Ordering},
|
||||
};
|
||||
use system_error::SystemError;
|
||||
use unified_init::macros::unified_init;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use log::{error, info};
|
||||
use lru::LruCache;
|
||||
|
||||
use crate::{
|
||||
arch::{interrupt::ipi::send_ipi, MMArch},
|
||||
arch::{interrupt::ipi::send_ipi, mm::LockedFrameAllocator, MMArch},
|
||||
exception::ipi::{IpiKind, IpiTarget},
|
||||
filesystem::vfs::{file::PageCache, FilePrivateData},
|
||||
init::initcall::INITCALL_CORE,
|
||||
ipc::shm::ShmId,
|
||||
libs::spinlock::{SpinLock, SpinLockGuard},
|
||||
libs::{
|
||||
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
spinlock::{SpinLock, SpinLockGuard},
|
||||
},
|
||||
process::{ProcessControlBlock, ProcessManager},
|
||||
time::{sleep::usleep, PosixTimeSpec},
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -53,7 +64,7 @@ pub fn page_manager_lock_irqsave() -> SpinLockGuard<'static, PageManager> {
|
||||
|
||||
// 物理页管理器
|
||||
pub struct PageManager {
|
||||
phys2page: HashMap<PhysAddr, Page>,
|
||||
phys2page: HashMap<PhysAddr, Arc<Page>>,
|
||||
}
|
||||
|
||||
impl PageManager {
|
||||
@ -67,18 +78,21 @@ impl PageManager {
|
||||
self.phys2page.contains_key(paddr)
|
||||
}
|
||||
|
||||
pub fn get(&self, paddr: &PhysAddr) -> Option<&Page> {
|
||||
self.phys2page.get(paddr)
|
||||
pub fn get(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> {
|
||||
page_reclaimer_lock_irqsave().get(paddr);
|
||||
self.phys2page.get(paddr).cloned()
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, paddr: &PhysAddr) -> &mut Page {
|
||||
pub fn get_unwrap(&mut self, paddr: &PhysAddr) -> Arc<Page> {
|
||||
page_reclaimer_lock_irqsave().get(paddr);
|
||||
self.phys2page
|
||||
.get_mut(paddr)
|
||||
.unwrap_or_else(|| panic!("{:?}", paddr))
|
||||
.get(paddr)
|
||||
.unwrap_or_else(|| panic!("Phys Page not found, {:?}", paddr))
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, paddr: PhysAddr, page: Page) {
|
||||
self.phys2page.insert(paddr, page);
|
||||
pub fn insert(&mut self, paddr: PhysAddr, page: &Arc<Page>) {
|
||||
self.phys2page.insert(paddr, page.clone());
|
||||
}
|
||||
|
||||
pub fn remove_page(&mut self, paddr: &PhysAddr) {
|
||||
@ -86,8 +100,236 @@ impl PageManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// 物理页面信息
|
||||
pub static mut PAGE_RECLAIMER: Option<SpinLock<PageReclaimer>> = None;
|
||||
|
||||
pub fn page_reclaimer_init() {
|
||||
info!("page_reclaimer_init");
|
||||
let page_reclaimer = SpinLock::new(PageReclaimer::new());
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
unsafe { PAGE_RECLAIMER = Some(page_reclaimer) };
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
info!("page_reclaimer_init done");
|
||||
}
|
||||
|
||||
/// 页面回收线程
|
||||
static mut PAGE_RECLAIMER_THREAD: Option<Arc<ProcessControlBlock>> = None;
|
||||
|
||||
/// 页面回收线程初始化函数
|
||||
#[unified_init(INITCALL_CORE)]
|
||||
fn page_reclaimer_thread_init() -> Result<(), SystemError> {
|
||||
let closure = crate::process::kthread::KernelThreadClosure::StaticEmptyClosure((
|
||||
&(page_reclaim_thread as fn() -> i32),
|
||||
(),
|
||||
));
|
||||
let pcb = crate::process::kthread::KernelThreadMechanism::create_and_run(
|
||||
closure,
|
||||
"page_reclaim".to_string(),
|
||||
)
|
||||
.ok_or("")
|
||||
.expect("create tty_refresh thread failed");
|
||||
unsafe {
|
||||
PAGE_RECLAIMER_THREAD = Some(pcb);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 页面回收线程执行的函数
|
||||
fn page_reclaim_thread() -> i32 {
|
||||
loop {
|
||||
let usage = unsafe { LockedFrameAllocator.usage() };
|
||||
// log::info!("usage{:?}", usage);
|
||||
|
||||
// 保留4096个页面,总计16MB的空闲空间
|
||||
if usage.free().data() < 4096 {
|
||||
let page_to_free = 4096;
|
||||
page_reclaimer_lock_irqsave().shrink_list(PageFrameCount::new(page_to_free));
|
||||
} else {
|
||||
//TODO 暂时让页面回收线程负责脏页回写任务,后续需要分离
|
||||
page_reclaimer_lock_irqsave().flush_dirty_pages();
|
||||
// 休眠5秒
|
||||
// log::info!("sleep");
|
||||
let _ = usleep(PosixTimeSpec::new(5, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取页面回收器
|
||||
pub fn page_reclaimer_lock_irqsave() -> SpinLockGuard<'static, PageReclaimer> {
|
||||
unsafe { PAGE_RECLAIMER.as_ref().unwrap().lock_irqsave() }
|
||||
}
|
||||
|
||||
/// 页面回收器
|
||||
pub struct PageReclaimer {
|
||||
lru: LruCache<PhysAddr, Arc<Page>>,
|
||||
}
|
||||
|
||||
impl PageReclaimer {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
lru: LruCache::unbounded(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&mut self, paddr: &PhysAddr) -> Option<Arc<Page>> {
|
||||
self.lru.get(paddr).cloned()
|
||||
}
|
||||
|
||||
pub fn insert_page(&mut self, paddr: PhysAddr, page: &Arc<Page>) {
|
||||
self.lru.put(paddr, page.clone());
|
||||
}
|
||||
|
||||
/// lru链表缩减
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `count`: 需要缩减的页面数量
|
||||
pub fn shrink_list(&mut self, count: PageFrameCount) {
|
||||
for _ in 0..count.data() {
|
||||
let (paddr, page) = self.lru.pop_lru().expect("pagecache is empty");
|
||||
let page_cache = page.read_irqsave().page_cache().unwrap();
|
||||
for vma in page.read_irqsave().anon_vma() {
|
||||
let address_space = vma.lock_irqsave().address_space().unwrap();
|
||||
let address_space = address_space.upgrade().unwrap();
|
||||
let mut guard = address_space.write();
|
||||
let mapper = &mut guard.user_mapper.utable;
|
||||
let virt = vma.lock_irqsave().page_address(&page).unwrap();
|
||||
unsafe {
|
||||
mapper.unmap(virt, false).unwrap().flush();
|
||||
}
|
||||
}
|
||||
page_cache.remove_page(page.read_irqsave().index().unwrap());
|
||||
page_manager_lock_irqsave().remove_page(&paddr);
|
||||
if page.read_irqsave().flags.contains(PageFlags::PG_DIRTY) {
|
||||
Self::page_writeback(&page, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 唤醒页面回收线程
|
||||
pub fn wakeup_claim_thread() {
|
||||
// log::info!("wakeup_claim_thread");
|
||||
let _ = ProcessManager::wakeup(unsafe { PAGE_RECLAIMER_THREAD.as_ref().unwrap() });
|
||||
}
|
||||
|
||||
/// 脏页回写函数
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `page`: 需要回写的脏页
|
||||
/// - `unmap`: 是否取消映射
|
||||
///
|
||||
/// ## 返回值
|
||||
/// - VmFaultReason: 页面错误处理信息标志
|
||||
pub fn page_writeback(page: &Arc<Page>, unmap: bool) {
|
||||
if !unmap {
|
||||
page.write_irqsave().remove_flags(PageFlags::PG_DIRTY);
|
||||
}
|
||||
|
||||
for vma in page.read_irqsave().anon_vma() {
|
||||
let address_space = vma.lock_irqsave().address_space().unwrap();
|
||||
let address_space = address_space.upgrade().unwrap();
|
||||
let mut guard = address_space.write();
|
||||
let mapper = &mut guard.user_mapper.utable;
|
||||
let virt = vma.lock_irqsave().page_address(page).unwrap();
|
||||
if unmap {
|
||||
unsafe {
|
||||
mapper.unmap(virt, false).unwrap().flush();
|
||||
}
|
||||
} else {
|
||||
unsafe {
|
||||
// 保护位设为只读
|
||||
mapper.remap(
|
||||
virt,
|
||||
mapper.get_entry(virt, 0).unwrap().flags().set_write(false),
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
let inode = page
|
||||
.read_irqsave()
|
||||
.page_cache
|
||||
.clone()
|
||||
.unwrap()
|
||||
.inode()
|
||||
.clone()
|
||||
.unwrap()
|
||||
.upgrade()
|
||||
.unwrap();
|
||||
inode
|
||||
.write_at(
|
||||
page.read_irqsave().index().unwrap(),
|
||||
MMArch::PAGE_SIZE,
|
||||
unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
MMArch::phys_2_virt(page.read_irqsave().phys_addr)
|
||||
.unwrap()
|
||||
.data() as *mut u8,
|
||||
MMArch::PAGE_SIZE,
|
||||
)
|
||||
},
|
||||
SpinLock::new(FilePrivateData::Unused).lock(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// lru脏页刷新
|
||||
pub fn flush_dirty_pages(&self) {
|
||||
// log::info!("flush_dirty_pages");
|
||||
let iter = self.lru.iter();
|
||||
for (_, page) in iter {
|
||||
if page.read_irqsave().flags().contains(PageFlags::PG_DIRTY) {
|
||||
Self::page_writeback(page, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct PageFlags: u64 {
|
||||
const PG_LOCKED = 1 << 0;
|
||||
const PG_WRITEBACK = 1 << 1;
|
||||
const PG_REFERENCED = 1 << 2;
|
||||
const PG_UPTODATE = 1 << 3;
|
||||
const PG_DIRTY = 1 << 4;
|
||||
const PG_LRU = 1 << 5;
|
||||
const PG_HEAD = 1 << 6;
|
||||
const PG_WAITERS = 1 << 7;
|
||||
const PG_ACTIVE = 1 << 8;
|
||||
const PG_WORKINGSET = 1 << 9;
|
||||
const PG_ERROR = 1 << 10;
|
||||
const PG_SLAB = 1 << 11;
|
||||
const PG_RESERVED = 1 << 14;
|
||||
const PG_PRIVATE = 1 << 15;
|
||||
const PG_RECLAIM = 1 << 18;
|
||||
const PG_SWAPBACKED = 1 << 19;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Page {
|
||||
inner: RwLock<InnerPage>,
|
||||
}
|
||||
|
||||
impl Page {
|
||||
pub fn new(shared: bool, phys_addr: PhysAddr) -> Self {
|
||||
let inner = InnerPage::new(shared, phys_addr);
|
||||
Self {
|
||||
inner: RwLock::new(inner),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_irqsave(&self) -> RwLockReadGuard<InnerPage> {
|
||||
self.inner.read_irqsave()
|
||||
}
|
||||
|
||||
pub fn write_irqsave(&self) -> RwLockWriteGuard<InnerPage> {
|
||||
self.inner.write_irqsave()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// 物理页面信息
|
||||
pub struct InnerPage {
|
||||
/// 映射计数
|
||||
map_count: usize,
|
||||
/// 是否为共享页
|
||||
@ -98,10 +340,17 @@ pub struct Page {
|
||||
shm_id: Option<ShmId>,
|
||||
/// 映射到当前page的VMA
|
||||
anon_vma: HashSet<Arc<LockedVMA>>,
|
||||
/// 标志
|
||||
flags: PageFlags,
|
||||
/// 页所在的物理页帧号
|
||||
phys_addr: PhysAddr,
|
||||
/// 在pagecache中的偏移
|
||||
index: Option<usize>,
|
||||
page_cache: Option<Arc<PageCache>>,
|
||||
}
|
||||
|
||||
impl Page {
|
||||
pub fn new(shared: bool) -> Self {
|
||||
impl InnerPage {
|
||||
pub fn new(shared: bool, phys_addr: PhysAddr) -> Self {
|
||||
let dealloc_when_zero = !shared;
|
||||
Self {
|
||||
map_count: 0,
|
||||
@ -109,6 +358,10 @@ impl Page {
|
||||
free_when_zero: dealloc_when_zero,
|
||||
shm_id: None,
|
||||
anon_vma: HashSet::new(),
|
||||
flags: PageFlags::empty(),
|
||||
phys_addr,
|
||||
index: None,
|
||||
page_cache: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,6 +390,31 @@ impl Page {
|
||||
self.shm_id
|
||||
}
|
||||
|
||||
pub fn index(&self) -> Option<usize> {
|
||||
self.index
|
||||
}
|
||||
|
||||
pub fn page_cache(&self) -> Option<Arc<PageCache>> {
|
||||
self.page_cache.clone()
|
||||
}
|
||||
|
||||
pub fn set_page_cache(&mut self, page_cache: Option<Arc<PageCache>>) {
|
||||
self.page_cache = page_cache;
|
||||
}
|
||||
|
||||
pub fn set_index(&mut self, index: Option<usize>) {
|
||||
self.index = index;
|
||||
}
|
||||
|
||||
pub fn set_page_cache_index(
|
||||
&mut self,
|
||||
page_cache: Option<Arc<PageCache>>,
|
||||
index: Option<usize>,
|
||||
) {
|
||||
self.page_cache = page_cache;
|
||||
self.index = index;
|
||||
}
|
||||
|
||||
pub fn set_shm_id(&mut self, shm_id: ShmId) {
|
||||
self.shm_id = Some(shm_id);
|
||||
}
|
||||
@ -154,6 +432,31 @@ impl Page {
|
||||
pub fn map_count(&self) -> usize {
|
||||
self.map_count
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn flags(&self) -> &PageFlags {
|
||||
&self.flags
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_flags(&mut self, flags: PageFlags) {
|
||||
self.flags = flags
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn add_flags(&mut self, flags: PageFlags) {
|
||||
self.flags = self.flags.union(flags);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn remove_flags(&mut self, flags: PageFlags) {
|
||||
self.flags = self.flags.difference(flags);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn phys_address(&self) -> PhysAddr {
|
||||
self.phys_addr
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -329,8 +632,19 @@ impl<Arch: MemoryManagementArch> PageTable<Arch> {
|
||||
new_table.set_entry(i, entry);
|
||||
} else {
|
||||
let phys = allocator.allocate_one()?;
|
||||
let mut anon_vma_guard = page_manager_lock_irqsave();
|
||||
anon_vma_guard.insert(phys, Page::new(false));
|
||||
let mut page_manager_guard = page_manager_lock_irqsave();
|
||||
let old_phys = entry.address().unwrap();
|
||||
let old_page = page_manager_guard.get_unwrap(&old_phys);
|
||||
let new_page =
|
||||
Arc::new(Page::new(old_page.read_irqsave().shared(), phys));
|
||||
if let Some(ref page_cache) = old_page.read_irqsave().page_cache() {
|
||||
new_page.write_irqsave().set_page_cache_index(
|
||||
Some(page_cache.clone()),
|
||||
old_page.read_irqsave().index(),
|
||||
);
|
||||
}
|
||||
|
||||
page_manager_guard.insert(phys, &new_page);
|
||||
let old_phys = entry.address().unwrap();
|
||||
let frame = MMArch::phys_2_virt(phys).unwrap().data() as *mut u8;
|
||||
frame.copy_from_nonoverlapping(
|
||||
@ -372,7 +686,7 @@ impl<Arch> Debug for PageEntry<Arch> {
|
||||
|
||||
impl<Arch: MemoryManagementArch> PageEntry<Arch> {
|
||||
#[inline(always)]
|
||||
pub fn new(paddr: PhysAddr, flags: PageFlags<Arch>) -> Self {
|
||||
pub fn new(paddr: PhysAddr, flags: EntryFlags<Arch>) -> Self {
|
||||
Self {
|
||||
data: MMArch::make_entry(paddr, flags.data()),
|
||||
phantom: PhantomData,
|
||||
@ -420,12 +734,12 @@ impl<Arch: MemoryManagementArch> PageEntry<Arch> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn flags(&self) -> PageFlags<Arch> {
|
||||
unsafe { PageFlags::from_data(self.data & Arch::ENTRY_FLAGS_MASK) }
|
||||
pub fn flags(&self) -> EntryFlags<Arch> {
|
||||
unsafe { EntryFlags::from_data(self.data & Arch::ENTRY_FLAGS_MASK) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_flags(&mut self, flags: PageFlags<Arch>) {
|
||||
pub fn set_flags(&mut self, flags: EntryFlags<Arch>) {
|
||||
self.data = (self.data & !Arch::ENTRY_FLAGS_MASK) | flags.data();
|
||||
}
|
||||
|
||||
@ -453,19 +767,19 @@ impl<Arch: MemoryManagementArch> PageEntry<Arch> {
|
||||
|
||||
/// 页表项的标志位
|
||||
#[derive(Copy, Clone, Hash)]
|
||||
pub struct PageFlags<Arch> {
|
||||
pub struct EntryFlags<Arch> {
|
||||
data: usize,
|
||||
phantom: PhantomData<Arch>,
|
||||
}
|
||||
|
||||
impl<Arch: MemoryManagementArch> Default for PageFlags<Arch> {
|
||||
impl<Arch: MemoryManagementArch> Default for EntryFlags<Arch> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<Arch: MemoryManagementArch> PageFlags<Arch> {
|
||||
impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
let mut r = unsafe {
|
||||
@ -486,18 +800,19 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
|
||||
return r;
|
||||
}
|
||||
|
||||
/// 根据ProtFlags生成PageFlags
|
||||
/// 根据ProtFlags生成EntryFlags
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - prot_flags: 页的保护标志
|
||||
/// - user: 用户空间是否可访问
|
||||
pub fn from_prot_flags(prot_flags: ProtFlags, user: bool) -> PageFlags<Arch> {
|
||||
let flags: PageFlags<Arch> = PageFlags::new()
|
||||
.set_user(user)
|
||||
.set_execute(prot_flags.contains(ProtFlags::PROT_EXEC))
|
||||
.set_write(prot_flags.contains(ProtFlags::PROT_WRITE));
|
||||
|
||||
pub fn from_prot_flags(prot_flags: ProtFlags, user: bool) -> Self {
|
||||
let vm_flags = super::VmFlags::from(prot_flags);
|
||||
// let flags: EntryFlags<Arch> = EntryFlags::new()
|
||||
// .set_user(user)
|
||||
// .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC))
|
||||
// .set_write(prot_flags.contains(ProtFlags::PROT_WRITE));
|
||||
let flags = Arch::vm_get_page_prot(vm_flags).set_user(user);
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -763,9 +1078,9 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Arch: MemoryManagementArch> fmt::Debug for PageFlags<Arch> {
|
||||
impl<Arch: MemoryManagementArch> fmt::Debug for EntryFlags<Arch> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("PageFlags")
|
||||
f.debug_struct("EntryFlags")
|
||||
.field("bits", &format_args!("{:#0x}", self.data))
|
||||
.field("present", &self.present())
|
||||
.field("has_write", &self.has_write())
|
||||
@ -861,7 +1176,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
pub unsafe fn map(
|
||||
&mut self,
|
||||
virt: VirtAddr,
|
||||
flags: PageFlags<Arch>,
|
||||
flags: EntryFlags<Arch>,
|
||||
) -> Option<PageFlush<Arch>> {
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
let phys: PhysAddr = self.frame_allocator.allocate_one()?;
|
||||
@ -875,9 +1190,9 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
let mut page_manager_guard: SpinLockGuard<'static, PageManager> =
|
||||
page_manager_lock_irqsave();
|
||||
if !page_manager_guard.contains(&phys) {
|
||||
page_manager_guard.insert(phys, Page::new(false))
|
||||
page_manager_guard.insert(phys, &Arc::new(Page::new(false, phys)))
|
||||
}
|
||||
|
||||
drop(page_manager_guard);
|
||||
return self.map_phys(virt, phys, flags);
|
||||
}
|
||||
|
||||
@ -886,7 +1201,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
&mut self,
|
||||
virt: VirtAddr,
|
||||
phys: PhysAddr,
|
||||
flags: PageFlags<Arch>,
|
||||
flags: EntryFlags<Arch>,
|
||||
) -> Option<PageFlush<Arch>> {
|
||||
// 验证虚拟地址和物理地址是否对齐
|
||||
if !(virt.check_aligned(Arch::PAGE_SIZE) && phys.check_aligned(Arch::PAGE_SIZE)) {
|
||||
@ -926,8 +1241,8 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
// 清空这个页帧
|
||||
MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
|
||||
// 设置页表项的flags
|
||||
let flags: PageFlags<Arch> =
|
||||
PageFlags::new_page_table(virt.kind() == PageTableKind::User);
|
||||
let flags: EntryFlags<Arch> =
|
||||
EntryFlags::new_page_table(virt.kind() == PageTableKind::User);
|
||||
|
||||
// 把新分配的页表映射到当前页表
|
||||
table.set_entry(i, PageEntry::new(frame, flags));
|
||||
@ -943,7 +1258,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
pub unsafe fn map_huge_page(
|
||||
&mut self,
|
||||
virt: VirtAddr,
|
||||
flags: PageFlags<Arch>,
|
||||
flags: EntryFlags<Arch>,
|
||||
) -> Option<PageFlush<Arch>> {
|
||||
// 验证虚拟地址是否对齐
|
||||
if !(virt.check_aligned(Arch::PAGE_SIZE)) {
|
||||
@ -1009,7 +1324,8 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
|
||||
|
||||
// 设置页表项的flags
|
||||
let flags: PageFlags<Arch> = PageFlags::new_page_table(virt.kind() == PageTableKind::User);
|
||||
let flags: EntryFlags<Arch> =
|
||||
EntryFlags::new_page_table(virt.kind() == PageTableKind::User);
|
||||
|
||||
table.set_entry(i, PageEntry::new(frame, flags));
|
||||
table.next_level_table(i)
|
||||
@ -1111,7 +1427,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
pub unsafe fn map_linearly(
|
||||
&mut self,
|
||||
phys: PhysAddr,
|
||||
flags: PageFlags<Arch>,
|
||||
flags: EntryFlags<Arch>,
|
||||
) -> Option<(VirtAddr, PageFlush<Arch>)> {
|
||||
let virt: VirtAddr = Arch::phys_2_virt(phys)?;
|
||||
return self.map_phys(virt, phys, flags).map(|flush| (virt, flush));
|
||||
@ -1131,7 +1447,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
pub unsafe fn remap(
|
||||
&mut self,
|
||||
virt: VirtAddr,
|
||||
flags: PageFlags<Arch>,
|
||||
flags: EntryFlags<Arch>,
|
||||
) -> Option<PageFlush<Arch>> {
|
||||
return self
|
||||
.visit(virt, |p1, i| {
|
||||
@ -1153,7 +1469,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 如果查找成功,返回物理地址和页表项的flags,否则返回None
|
||||
pub fn translate(&self, virt: VirtAddr) -> Option<(PhysAddr, PageFlags<Arch>)> {
|
||||
pub fn translate(&self, virt: VirtAddr) -> Option<(PhysAddr, EntryFlags<Arch>)> {
|
||||
let entry: PageEntry<Arch> = self.visit(virt, |p1, i| unsafe { p1.entry(i) })??;
|
||||
let paddr = entry.address().ok()?;
|
||||
let flags = entry.flags();
|
||||
@ -1192,7 +1508,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
&mut self,
|
||||
virt: VirtAddr,
|
||||
unmap_parents: bool,
|
||||
) -> Option<(PhysAddr, PageFlags<Arch>, PageFlush<Arch>)> {
|
||||
) -> Option<(PhysAddr, EntryFlags<Arch>, PageFlush<Arch>)> {
|
||||
if !virt.check_aligned(Arch::PAGE_SIZE) {
|
||||
error!("Try to unmap unaligned page: virt={:?}", virt);
|
||||
return None;
|
||||
@ -1240,7 +1556,7 @@ unsafe fn unmap_phys_inner<Arch: MemoryManagementArch>(
|
||||
table: &PageTable<Arch>,
|
||||
unmap_parents: bool,
|
||||
allocator: &mut impl FrameAllocator,
|
||||
) -> Option<(PhysAddr, PageFlags<Arch>)> {
|
||||
) -> Option<(PhysAddr, EntryFlags<Arch>)> {
|
||||
// 获取页表项的索引
|
||||
let i = table.index_of(vaddr)?;
|
||||
|
||||
|
Reference in New Issue
Block a user