Browse Source

Revert "Revert "Merge branch 'patch-add-file-mapping' into patch-fix-mmap""

This reverts commit 9261cb79f08d12bbe4b3b5bf29c84625db059c13.
MemoryShore 11 months ago
parent
commit
653180e131

+ 3 - 3
kernel/src/arch/riscv64/mm/mod.rs

@@ -12,7 +12,7 @@ use crate::{
             page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
         },
         kernel_mapper::KernelMapper,
-        page::{PageEntry, PageFlags, PAGE_1G_SHIFT},
+        page::{EntryFlags, PageEntry, PAGE_1G_SHIFT},
         ucontext::UserMapper,
         MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
     },
@@ -270,8 +270,8 @@ impl VirtAddr {
 }
 
 /// 获取内核地址默认的页面标志
-pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> PageFlags<A> {
-    PageFlags::from_data(RiscV64MMArch::ENTRY_FLAG_DEFAULT_PAGE)
+pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> EntryFlags<A> {
+    EntryFlags::from_data(RiscV64MMArch::ENTRY_FLAG_DEFAULT_PAGE)
         .set_user(false)
         .set_execute(true)
 }

+ 2 - 2
kernel/src/arch/x86_64/kvm/vmx/ept.rs

@@ -1,7 +1,7 @@
 use crate::arch::mm::LockedFrameAllocator;
 use crate::arch::mm::PageMapper;
 use crate::arch::MMArch;
-use crate::mm::page::PageFlags;
+use crate::mm::page::EntryFlags;
 use crate::mm::{PageTableKind, PhysAddr, VirtAddr};
 use crate::smp::core::smp_get_processor_id;
 use crate::smp::cpu::AtomicProcessorId;
@@ -92,7 +92,7 @@ impl EptMapper {
         &mut self,
         gpa: u64,
         hpa: u64,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
     ) -> Result<(), SystemError> {
         if self.readonly {
             return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);

+ 2 - 2
kernel/src/arch/x86_64/kvm/vmx/mmu.rs

@@ -1,7 +1,7 @@
 use crate::{
     arch::kvm::vmx::ept::EptMapper,
     libs::mutex::Mutex,
-    mm::{page::PageFlags, syscall::ProtFlags},
+    mm::{page::EntryFlags, syscall::ProtFlags},
     virt::kvm::host_mem::{__gfn_to_pfn, kvm_vcpu_gfn_to_memslot, PAGE_MASK, PAGE_SHIFT},
 };
 use bitfield_struct::bitfield;
@@ -218,7 +218,7 @@ pub fn __direct_map(
     }
     // 把gpa映射到hpa
     let mut ept_mapper = EptMapper::lock();
-    let page_flags = PageFlags::from_prot_flags(ProtFlags::from_bits_truncate(0x7_u64), false);
+    let page_flags = EntryFlags::from_prot_flags(ProtFlags::from_bits_truncate(0x7_u64), false);
     unsafe {
         assert!(ept_mapper.walk(gpa, pfn << PAGE_SHIFT, page_flags).is_ok());
     }

+ 5 - 5
kernel/src/arch/x86_64/mm/mod.rs

@@ -28,7 +28,7 @@ use crate::{
 };
 
 use crate::mm::kernel_mapper::KernelMapper;
-use crate::mm::page::{PageEntry, PageFlags, PAGE_1G_SHIFT};
+use crate::mm::page::{EntryFlags, PageEntry, PAGE_1G_SHIFT};
 use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr};
 
 use system_error::SystemError;
@@ -650,17 +650,17 @@ impl FrameAllocator for LockedFrameAllocator {
 }
 
 /// 获取内核地址默认的页面标志
-pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(virt: VirtAddr) -> PageFlags<A> {
+pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(virt: VirtAddr) -> EntryFlags<A> {
     let info: X86_64MMBootstrapInfo = BOOTSTRAP_MM_INFO.unwrap();
 
     if virt.data() >= info.kernel_code_start && virt.data() < info.kernel_code_end {
         // Remap kernel code  execute
-        return PageFlags::new().set_execute(true).set_write(true);
+        return EntryFlags::new().set_execute(true).set_write(true);
     } else if virt.data() >= info.kernel_data_end && virt.data() < info.kernel_rodata_end {
         // Remap kernel rodata read only
-        return PageFlags::new().set_execute(true);
+        return EntryFlags::new().set_execute(true);
     } else {
-        return PageFlags::new().set_write(true).set_execute(true);
+        return EntryFlags::new().set_write(true).set_execute(true);
     }
 }
 

+ 2 - 2
kernel/src/driver/net/dma.rs

@@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
 use crate::arch::MMArch;
 
 use crate::mm::kernel_mapper::KernelMapper;
-use crate::mm::page::{page_manager_lock_irqsave, PageFlags};
+use crate::mm::page::{page_manager_lock_irqsave, EntryFlags};
 use crate::mm::{
     allocator::page_frame::{
         allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
@@ -25,7 +25,7 @@ pub fn dma_alloc(pages: usize) -> (usize, NonNull<u8>) {
         // 清空这块区域,防止出现脏数据
         core::ptr::write_bytes(virt.data() as *mut u8, 0, count.data() * MMArch::PAGE_SIZE);
 
-        let dma_flags: PageFlags<MMArch> = PageFlags::mmio_flags();
+        let dma_flags: EntryFlags<MMArch> = EntryFlags::mmio_flags();
 
         let mut kernel_mapper = KernelMapper::lock();
         let kernel_mapper = kernel_mapper.as_mut().unwrap();

+ 2 - 2
kernel/src/driver/video/mod.rs

@@ -10,7 +10,7 @@ use crate::{
         spinlock::SpinLock,
     },
     mm::{
-        allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::PageFlags,
+        allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::EntryFlags,
         MemoryManagementArch,
     },
     time::timer::{Timer, TimerFunction},
@@ -95,7 +95,7 @@ impl VideoRefreshManager {
         let count = PageFrameCount::new(
             page_align_up(frame_buffer_info_guard.buf_size()) / MMArch::PAGE_SIZE,
         );
-        let page_flags: PageFlags<MMArch> = PageFlags::new().set_execute(true).set_write(true);
+        let page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true);
 
         let mut kernel_mapper = KernelMapper::lock();
         let mut kernel_mapper = kernel_mapper.as_mut();

+ 2 - 2
kernel/src/driver/virtio/virtio_impl.rs

@@ -3,7 +3,7 @@ use crate::arch::mm::kernel_page_flags;
 use crate::arch::MMArch;
 
 use crate::mm::kernel_mapper::KernelMapper;
-use crate::mm::page::{page_manager_lock_irqsave, PageFlags};
+use crate::mm::page::{page_manager_lock_irqsave, EntryFlags};
 use crate::mm::{
     allocator::page_frame::{
         allocate_page_frames, deallocate_page_frames, PageFrameCount, PhysPageFrame,
@@ -32,7 +32,7 @@ unsafe impl Hal for HalImpl {
             // 清空这块区域,防止出现脏数据
             core::ptr::write_bytes(virt.data() as *mut u8, 0, count.data() * MMArch::PAGE_SIZE);
 
-            let dma_flags: PageFlags<MMArch> = PageFlags::mmio_flags();
+            let dma_flags: EntryFlags<MMArch> = EntryFlags::mmio_flags();
 
             let mut kernel_mapper = KernelMapper::lock();
             let kernel_mapper = kernel_mapper.as_mut().unwrap();

+ 41 - 0
kernel/src/filesystem/vfs/file.rs

@@ -5,6 +5,7 @@ use alloc::{
     sync::{Arc, Weak},
     vec::Vec,
 };
+use hashbrown::HashMap;
 use log::error;
 use system_error::SystemError;
 
@@ -16,6 +17,7 @@ use crate::{
     filesystem::procfs::ProcfsFilePrivateData,
     ipc::pipe::{LockedPipeInode, PipeFsPrivateData},
     libs::{rwlock::RwLock, spinlock::SpinLock},
+    mm::page::Page,
     net::{
         event_poll::{EPollItem, EPollPrivateData, EventPoll},
         socket::SocketInode,
@@ -118,6 +120,45 @@ impl FileMode {
         return self.bits() & FileMode::O_ACCMODE.bits();
     }
 }
+
+#[allow(dead_code)]
+pub struct PageCache {
+    inode_ref: Weak<dyn IndexNode>,
+    map: HashMap<usize, Arc<Page>>,
+}
+
+impl PageCache {
+    pub fn new(inode_ref: Weak<dyn IndexNode>) -> PageCache {
+        Self {
+            inode_ref,
+            map: HashMap::new(),
+        }
+    }
+
+    pub fn add_page(&mut self, offset: usize, page: Arc<Page>) {
+        self.map.insert(offset, page);
+    }
+
+    pub fn get_page(&self, offset: usize) -> Option<Arc<Page>> {
+        self.map.get(&offset).cloned()
+    }
+
+    // pub fn get_pages(&self, start_pgoff: usize, end_pgoff: usize) -> Vec<Arc<Page>> {
+    //     let mut vec = Vec::new();
+    //     for pgoff in start_pgoff..=end_pgoff {
+    //         if let Some(page) = self.map.get(&pgoff) {
+    //             vec.push(page.clone());
+    //         }
+    //     }
+    //     vec
+    // }
+}
+
+pub trait PageCacheOperations: IndexNode {
+    fn write_page(&self, page: Page);
+    fn read_ahead(&self);
+}
+
 /// @brief 抽象文件结构体
 #[derive(Debug)]
 pub struct File {

+ 10 - 1
kernel/src/filesystem/vfs/mod.rs

@@ -23,7 +23,12 @@ use crate::{
     time::PosixTimeSpec,
 };
 
-use self::{core::generate_inode_id, file::FileMode, syscall::ModeType, utils::DName};
+use self::{
+    core::generate_inode_id,
+    file::{FileMode, PageCache},
+    syscall::ModeType,
+    utils::DName,
+};
 pub use self::{core::ROOT_INODE, file::FilePrivateData, mount::MountFS};
 
 /// vfs容许的最大的路径名称长度
@@ -548,6 +553,10 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync {
     fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> {
         return self.find("..");
     }
+
+    fn page_cache(&self) -> Option<PageCache> {
+        None
+    }
 }
 
 impl DowncastArc for dyn IndexNode {

+ 1 - 1
kernel/src/ipc/shm.rs

@@ -165,7 +165,7 @@ impl ShmManager {
         let mut page_manager_guard = page_manager_lock_irqsave();
         let mut cur_phys = PhysPageFrame::new(phys_page.0);
         for _ in 0..page_count.data() {
-            let mut page = Page::new(true);
+            let mut page = Page::new(true, cur_phys);
             page.set_shm_id(shm_id);
             let paddr = cur_phys.phys_address();
             page_manager_guard.insert(paddr, page);

+ 4 - 4
kernel/src/ipc/syscall.rs

@@ -20,7 +20,7 @@ use crate::{
     libs::spinlock::SpinLock,
     mm::{
         allocator::page_frame::{PageFrameCount, PhysPageFrame, VirtPageFrame},
-        page::{page_manager_lock_irqsave, PageFlags, PageFlushAll},
+        page::{page_manager_lock_irqsave, EntryFlags, PageFlushAll},
         syscall::ProtFlags,
         ucontext::{AddressSpace, VMA},
         VirtAddr, VmFlags,
@@ -324,8 +324,8 @@ impl Syscall {
                     .ok_or(SystemError::EINVAL)?;
                 let vm_flags = VmFlags::from(shmflg);
                 let destination = VirtPageFrame::new(region.start());
-                let page_flags: PageFlags<MMArch> =
-                    PageFlags::from_prot_flags(ProtFlags::from(vm_flags), true);
+                let page_flags: EntryFlags<MMArch> =
+                    EntryFlags::from_prot_flags(ProtFlags::from(vm_flags), true);
                 let flusher: PageFlushAll<MMArch> = PageFlushAll::new();
 
                 // 将共享内存映射到对应虚拟区域
@@ -358,7 +358,7 @@ impl Syscall {
                 // 验证用户虚拟内存区域是否有效
                 let _ = UserBufferReader::new(vaddr.data() as *const u8, size, true)?;
 
-                // 必须在取消映射前获取到PageFlags
+                // 必须在取消映射前获取到EntryFlags
                 let page_flags = address_write_guard
                     .user_mapper
                     .utable

+ 2 - 2
kernel/src/mm/c_adapter.rs

@@ -15,7 +15,7 @@ use crate::{
 
 use super::{
     allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, mmio_buddy::mmio_pool,
-    no_init::pseudo_map_phys, page::PageFlags, MemoryManagementArch, PhysAddr, VirtAddr,
+    no_init::pseudo_map_phys, page::EntryFlags, MemoryManagementArch, PhysAddr, VirtAddr,
 };
 
 lazy_static! {
@@ -40,7 +40,7 @@ pub unsafe extern "C" fn rs_map_phys(vaddr: usize, paddr: usize, size: usize, fl
     let count = PageFrameCount::new(page_align_up(size) / MMArch::PAGE_SIZE);
     // debug!("rs_map_phys: vaddr: {vaddr:?}, paddr: {paddr:?}, count: {count:?}, flags: {flags:?}");
 
-    let mut page_flags: PageFlags<MMArch> = PageFlags::new().set_execute(true).set_write(true);
+    let mut page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true);
     if flags & PAGE_U_S as usize != 0 {
         page_flags = page_flags.set_user(true);
     }

+ 203 - 35
kernel/src/mm/fault.rs

@@ -1,11 +1,11 @@
-use core::{alloc::Layout, intrinsics::unlikely, panic};
+use core::{alloc::Layout, cmp::min, intrinsics::unlikely, panic};
 
-use alloc::sync::Arc;
+use alloc::{sync::Arc, vec::Vec};
 
 use crate::{
     arch::{mm::PageMapper, MMArch},
     mm::{
-        page::{page_manager_lock_irqsave, PageFlags},
+        page::{page_manager_lock_irqsave, EntryFlags},
         ucontext::LockedVMA,
         VirtAddr, VmFaultReason, VmFlags,
     },
@@ -14,21 +14,27 @@ use crate::{
 
 use crate::mm::MemoryManagementArch;
 
+use super::{
+    allocator::page_frame::{FrameAllocator, PhysPageFrame},
+    page::{Page, PageFlags},
+    phys_2_virt,
+};
+
 bitflags! {
     pub struct FaultFlags: u64{
-    const FAULT_FLAG_WRITE = 1 << 0;
-    const FAULT_FLAG_MKWRITE = 1 << 1;
-    const FAULT_FLAG_ALLOW_RETRY = 1 << 2;
-    const FAULT_FLAG_RETRY_NOWAIT = 1 << 3;
-    const FAULT_FLAG_KILLABLE = 1 << 4;
-    const FAULT_FLAG_TRIED = 1 << 5;
-    const FAULT_FLAG_USER = 1 << 6;
-    const FAULT_FLAG_REMOTE = 1 << 7;
-    const FAULT_FLAG_INSTRUCTION = 1 << 8;
-    const FAULT_FLAG_INTERRUPTIBLE =1 << 9;
-    const FAULT_FLAG_UNSHARE = 1 << 10;
-    const FAULT_FLAG_ORIG_PTE_VALID = 1 << 11;
-    const FAULT_FLAG_VMA_LOCK = 1 << 12;
+        const FAULT_FLAG_WRITE = 1 << 0;
+        const FAULT_FLAG_MKWRITE = 1 << 1;
+        const FAULT_FLAG_ALLOW_RETRY = 1 << 2;
+        const FAULT_FLAG_RETRY_NOWAIT = 1 << 3;
+        const FAULT_FLAG_KILLABLE = 1 << 4;
+        const FAULT_FLAG_TRIED = 1 << 5;
+        const FAULT_FLAG_USER = 1 << 6;
+        const FAULT_FLAG_REMOTE = 1 << 7;
+        const FAULT_FLAG_INSTRUCTION = 1 << 8;
+        const FAULT_FLAG_INTERRUPTIBLE =1 << 9;
+        const FAULT_FLAG_UNSHARE = 1 << 10;
+        const FAULT_FLAG_ORIG_PTE_VALID = 1 << 11;
+        const FAULT_FLAG_VMA_LOCK = 1 << 12;
     }
 }
 
@@ -36,9 +42,14 @@ bitflags! {
 /// 包含了页面错误处理的相关信息,例如出错的地址、VMA等
 #[derive(Debug)]
 pub struct PageFaultMessage {
+    /// 产生缺页的VMA结构体
     vma: Arc<LockedVMA>,
+    /// 缺页地址
     address: VirtAddr,
+    /// 异常处理标志
     flags: FaultFlags,
+    /// 缺页的文件页在文件中的偏移量
+    file_pgoff: usize,
 }
 
 impl PageFaultMessage {
@@ -47,6 +58,8 @@ impl PageFaultMessage {
             vma: vma.clone(),
             address,
             flags,
+            file_pgoff: ((address - vma.lock().region().start()) >> MMArch::PAGE_SHIFT)
+                + vma.lock().file_page_offset().unwrap(),
         }
     }
 
@@ -58,8 +71,8 @@ impl PageFaultMessage {
 
     #[inline(always)]
     #[allow(dead_code)]
-    pub fn address(&self) -> VirtAddr {
-        self.address
+    pub fn address(&self) -> &VirtAddr {
+        &self.address
     }
 
     #[inline(always)]
@@ -70,8 +83,8 @@ impl PageFaultMessage {
 
     #[inline(always)]
     #[allow(dead_code)]
-    pub fn flags(&self) -> FaultFlags {
-        self.flags
+    pub fn flags(&self) -> &FaultFlags {
+        &self.flags
     }
 }
 
@@ -81,6 +94,7 @@ impl Clone for PageFaultMessage {
             vma: self.vma.clone(),
             address: self.address,
             flags: self.flags,
+            file_pgoff: self.file_pgoff,
         }
     }
 }
@@ -189,7 +203,7 @@ impl PageFaultHandler {
                 if !entry.write() {
                     ret = Self::do_wp_page(pfm.clone(), mapper);
                 } else {
-                    entry.set_flags(PageFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
+                    entry.set_flags(EntryFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
                 }
             }
         } else if vma.is_anonymous() {
@@ -248,14 +262,22 @@ impl PageFaultHandler {
     /// - VmFaultReason: 页面错误处理信息标志
     #[allow(unused_variables)]
     pub unsafe fn do_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
-        panic!(
-            "do_fault has not yet been implemented, 
-        fault message: {:?}, 
-        pid: {}\n",
-            pfm,
-            crate::process::ProcessManager::current_pid().data()
-        );
+        // panic!(
+        //     "do_fault has not yet been implemented,
+        // fault message: {:?},
+        // pid: {}\n",
+        //     pfm,
+        //     crate::process::ProcessManager::current_pid().data()
+        // );
         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_fault
+
+        if !pfm.flags().contains(FaultFlags::FAULT_FLAG_WRITE) {
+            return Self::do_read_fault(pfm, mapper);
+        } else if !pfm.vma().lock().vm_flags().contains(VmFlags::VM_SHARED) {
+            return Self::do_cow_fault(pfm, mapper);
+        } else {
+            return Self::do_shared_fault(pfm, mapper);
+        }
     }
 
     /// 处理私有文件映射的写时复制
@@ -288,14 +310,20 @@ impl PageFaultHandler {
     /// - VmFaultReason: 页面错误处理信息标志
     #[allow(dead_code, unused_variables)]
     pub unsafe fn do_read_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
-        panic!(
-            "do_read_fault has not yet been implemented, 
-        fault message: {:?}, 
-        pid: {}\n",
-            pfm,
-            crate::process::ProcessManager::current_pid().data()
-        );
+        // panic!(
+        //     "do_read_fault has not yet been implemented,
+        // fault message: {:?},
+        // pid: {}\n",
+        //     pfm,
+        //     crate::process::ProcessManager::current_pid().data()
+        // );
+
         // TODO https://code.dragonos.org.cn/xref/linux-6.6.21/mm/memory.c#do_read_fault
+        let ret = Self::do_fault_around(pfm.clone(), mapper);
+        if !ret.is_empty() {
+            return ret;
+        }
+        return Self::filemap_fault(pfm.clone(), mapper);
     }
 
     /// 处理对共享文件映射区写入引起的缺页
@@ -405,4 +433,144 @@ impl PageFaultHandler {
             VmFaultReason::VM_FAULT_OOM
         }
     }
+
+    pub unsafe fn do_fault_around(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
+        if mapper.get_table(*pfm.address(), 0).is_none() {
+            mapper
+                .allocate_table(*pfm.address(), 0)
+                .expect("failed to allocate pte table");
+        }
+        let vma = pfm.vma();
+        let vma_guard = vma.lock();
+        let vma_region = vma_guard.region();
+        // 缺页在VMA中的偏移量
+        let vm_pgoff = (*pfm.address() - vma_region.start()) >> MMArch::PAGE_SHIFT;
+
+        // 缺页在PTE中的偏移量
+        let pte_pgoff =
+            (pfm.address().data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_ENTRY_SHIFT);
+
+        let vma_pages_count = (vma_region.end() - vma_region.start()) >> MMArch::PAGE_SHIFT;
+
+        // 开始位置不能超出当前pte和vma头部
+        let from_pte = pte_pgoff - min(vm_pgoff, pte_pgoff);
+
+        let fault_around_page_number = 16;
+
+        // pte结束位置不能超过:
+        // 1.最大预读上限(默认16)
+        // 2.最大pte(512)
+        // 3.vma结束位置(pte_pgoff + (vma_pages_count - vm_pgoff)计算出vma结束页号对当前pte开头的偏移)
+        let to_pte = min(
+            from_pte + fault_around_page_number,
+            min(
+                1 << MMArch::PAGE_SHIFT,
+                pte_pgoff + (vma_pages_count - vm_pgoff),
+            ),
+        );
+
+        // 预先分配pte页表(如果不存在)
+        if mapper.get_table(*pfm.address(), 0).is_none()
+            && mapper.allocate_table(*pfm.address(), 0).is_none()
+        {
+            return VmFaultReason::VM_FAULT_OOM;
+        }
+
+        // from_pte - pte_pgoff得出预读起始pte相对缺失页的偏移,加上pfm.file_pgoff(缺失页在文件中的偏移)得出起始页在文件中的偏移,结束pte同理
+        Self::filemap_map_pages(
+            pfm.clone(),
+            mapper,
+            pfm.file_pgoff + (from_pte - pte_pgoff),
+            pfm.file_pgoff + (to_pte - pte_pgoff),
+        );
+
+        VmFaultReason::empty()
+    }
+
+    pub unsafe fn filemap_map_pages(
+        pfm: PageFaultMessage,
+        mapper: &mut PageMapper,
+        start_pgoff: usize,
+        end_pgoff: usize,
+    ) -> VmFaultReason {
+        let vma = pfm.vma();
+        let vma_guard = vma.lock();
+        let file = vma_guard.vm_file().expect("no vm_file in vma");
+        let page_cache = file.inode().page_cache().unwrap();
+
+        // 起始页地址
+        let addr = vma_guard.region().start
+            + ((start_pgoff
+                - vma_guard
+                    .file_page_offset()
+                    .expect("file_page_offset is none"))
+                << MMArch::PAGE_SHIFT);
+        // let pages = page_cache.get_pages(start_pgoff, end_pgoff);
+        // let uptodate_pages = pages
+        //     .iter()
+        //     .filter(|page| page.flags().contains(PageFlags::PG_UPTODATE));
+        for pgoff in start_pgoff..=end_pgoff {
+            if let Some(page) = page_cache.get_page(pgoff) {
+                if page.flags().contains(PageFlags::PG_UPTODATE) {
+                    let phys = page.phys_frame().phys_address();
+                    let virt = phys_2_virt(phys.data());
+
+                    let address =
+                        VirtAddr::new(addr.data() + ((pgoff - start_pgoff) << MMArch::PAGE_SHIFT));
+                    mapper.map(address, vma_guard.flags()).unwrap().flush();
+                    let frame = virt as *mut u8;
+                    let new_frame =
+                        phys_2_virt(mapper.translate(address).unwrap().0.data()) as *mut u8;
+                    new_frame.copy_from_nonoverlapping(frame, MMArch::PAGE_SIZE);
+                }
+            }
+        }
+        VmFaultReason::empty()
+    }
+
+    pub unsafe fn filemap_fault(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
+        let vma = pfm.vma();
+        let vma_guard = vma.lock();
+        let file = vma_guard.vm_file().expect("no vm_file in vma");
+        let mut page_cache = file.inode().page_cache().unwrap();
+
+        if let Some(page) = page_cache.get_page(pfm.file_pgoff) {
+            // TODO 异步从磁盘中预读页面进PageCache
+            let address = vma_guard.region().start
+                + ((pfm.file_pgoff
+                    - vma_guard
+                        .file_page_offset()
+                        .expect("file_page_offset is none"))
+                    << MMArch::PAGE_SHIFT);
+            mapper.map(address, vma_guard.flags()).unwrap().flush();
+            let frame = phys_2_virt(page.phys_frame().phys_address().data()) as *mut u8;
+            let new_frame = phys_2_virt(mapper.translate(address).unwrap().0.data()) as *mut u8;
+            new_frame.copy_from_nonoverlapping(frame, MMArch::PAGE_SIZE);
+        } else {
+            // TODO 同步预读
+            let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE];
+            file.pread(
+                pfm.file_pgoff * MMArch::PAGE_SIZE,
+                MMArch::PAGE_SIZE,
+                &mut buf[..],
+            )
+            .unwrap();
+            let allocator = mapper.allocator_mut();
+
+            // 分配一个物理页面作为加入PageCache的新页
+            let new_cache_page = allocator.allocate_one().unwrap();
+            (phys_2_virt(new_cache_page.data()) as *mut u8)
+                .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
+            page_cache.add_page(
+                pfm.file_pgoff,
+                Arc::new(Page::new(false, PhysPageFrame::new(new_cache_page))),
+            );
+
+            // 分配空白页并映射到缺页地址
+            mapper.map(pfm.address, vma_guard.flags()).unwrap().flush();
+            let new_frame = phys_2_virt(mapper.translate(pfm.address).unwrap().0.data());
+            (new_frame as *mut u8).copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
+        }
+        VmFaultReason::VM_FAULT_COMPLETED
+    }
 }

+ 2 - 2
kernel/src/mm/kernel_mapper.rs

@@ -1,6 +1,6 @@
 use system_error::SystemError;
 
-use super::{page::PageFlags, PageTableKind, PhysAddr, VirtAddr};
+use super::{page::EntryFlags, PageTableKind, PhysAddr, VirtAddr};
 use crate::{
     arch::{
         mm::{LockedFrameAllocator, PageMapper},
@@ -104,7 +104,7 @@ impl KernelMapper {
         mut vaddr: VirtAddr,
         mut paddr: PhysAddr,
         size: usize,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
         flush: bool,
     ) -> Result<(), SystemError> {
         if self.readonly {

+ 3 - 3
kernel/src/mm/mmio_buddy.rs

@@ -12,7 +12,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
 use log::{debug, error, info, warn};
 use system_error::SystemError;
 
-use super::page::{PageFlags, PAGE_4K_SIZE};
+use super::page::{EntryFlags, PAGE_4K_SIZE};
 use super::{PhysAddr, VirtAddr};
 
 // 最大的伙伴块的幂
@@ -549,7 +549,7 @@ impl MmioBuddyMemPool {
             unsafe {
                 let x: Option<(
                     PhysAddr,
-                    PageFlags<MMArch>,
+                    EntryFlags<MMArch>,
                     crate::mm::page::PageFlush<MMArch>,
                 )> = kernel_mapper
                     .as_mut()
@@ -674,7 +674,7 @@ impl MMIOSpaceGuard {
             return Err(SystemError::EINVAL);
         }
 
-        let flags = PageFlags::mmio_flags();
+        let flags = EntryFlags::mmio_flags();
 
         let mut kernel_mapper = KernelMapper::lock();
         let r = kernel_mapper.map_phys_with_size(self.vaddr, paddr, length, flags, true);

+ 1 - 1
kernel/src/mm/mod.rs

@@ -610,7 +610,7 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
 
     /// 创建页表项
     ///
-    /// 这是一个低阶api,用于根据物理地址以及指定好的pageflags,创建页表项
+    /// 这是一个低阶api,用于根据物理地址以及指定好的EntryFlags,创建页表项
     ///
     /// ## 参数
     ///

+ 4 - 4
kernel/src/mm/no_init.rs

@@ -19,7 +19,7 @@ use core::marker::PhantomData;
 
 use super::{
     allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage},
-    page::PageFlags,
+    page::EntryFlags,
     PageTableKind, VirtAddr,
 };
 
@@ -141,7 +141,7 @@ impl<MMA: MemoryManagementArch> FrameAllocator for PseudoAllocator<MMA> {
 /// 并且,内核引导文件必须以4K页为粒度,填写了前100M的内存映射关系。(具体以本文件开头的注释为准)
 #[inline(never)]
 pub unsafe fn pseudo_map_phys(vaddr: VirtAddr, paddr: PhysAddr, count: PageFrameCount) {
-    let flags: PageFlags<MMArch> = PageFlags::new().set_write(true);
+    let flags: EntryFlags<MMArch> = EntryFlags::new().set_write(true);
 
     pseudo_map_phys_with_flags(vaddr, paddr, count, flags);
 }
@@ -150,7 +150,7 @@ pub unsafe fn pseudo_map_phys(vaddr: VirtAddr, paddr: PhysAddr, count: PageFrame
 /// with READ_ONLY and EXECUTE flags.
 #[inline(never)]
 pub unsafe fn pseudo_map_phys_ro(vaddr: VirtAddr, paddr: PhysAddr, count: PageFrameCount) {
-    let flags: PageFlags<MMArch> = PageFlags::new().set_write(false).set_execute(true);
+    let flags: EntryFlags<MMArch> = EntryFlags::new().set_write(false).set_execute(true);
 
     pseudo_map_phys_with_flags(vaddr, paddr, count, flags);
 }
@@ -160,7 +160,7 @@ pub unsafe fn pseudo_map_phys_with_flags(
     vaddr: VirtAddr,
     paddr: PhysAddr,
     count: PageFrameCount,
-    flags: PageFlags<MMArch>,
+    flags: EntryFlags<MMArch>,
 ) {
     assert!(vaddr.check_aligned(MMArch::PAGE_SIZE));
     assert!(paddr.check_aligned(MMArch::PAGE_SIZE));

+ 70 - 26
kernel/src/mm/page.rs

@@ -18,7 +18,7 @@ use crate::{
 };
 
 use super::{
-    allocator::page_frame::{FrameAllocator, PageFrameCount},
+    allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame},
     syscall::ProtFlags,
     ucontext::LockedVMA,
     MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
@@ -86,6 +86,27 @@ impl PageManager {
     }
 }
 
+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;
+    }
+}
+
 /// 物理页面信息
 pub struct Page {
     /// 映射计数
@@ -98,10 +119,14 @@ pub struct Page {
     shm_id: Option<ShmId>,
     /// 映射到当前page的VMA
     anon_vma: HashSet<Arc<LockedVMA>>,
+    /// 标志
+    flags: PageFlags,
+    /// 页所在的物理页帧号
+    phys_frame: PhysPageFrame,
 }
 
 impl Page {
-    pub fn new(shared: bool) -> Self {
+    pub fn new(shared: bool, phys_frame: PhysPageFrame) -> Self {
         let dealloc_when_zero = !shared;
         Self {
             map_count: 0,
@@ -109,6 +134,8 @@ impl Page {
             free_when_zero: dealloc_when_zero,
             shm_id: None,
             anon_vma: HashSet::new(),
+            flags: PageFlags::empty(),
+            phys_frame,
         }
     }
 
@@ -154,6 +181,16 @@ impl Page {
     pub fn map_count(&self) -> usize {
         self.map_count
     }
+
+    #[inline(always)]
+    pub fn flags(&self) -> &PageFlags {
+        &self.flags
+    }
+
+    #[inline(always)]
+    pub fn phys_frame(&self) -> &PhysPageFrame {
+        &self.phys_frame
+    }
 }
 
 #[derive(Debug)]
@@ -330,7 +367,7 @@ impl<Arch: MemoryManagementArch> PageTable<Arch> {
                         } else {
                             let phys = allocator.allocate_one()?;
                             let mut anon_vma_guard = page_manager_lock_irqsave();
-                            anon_vma_guard.insert(phys, Page::new(false));
+                            anon_vma_guard.insert(phys, Page::new(false, PhysPageFrame::new(phys)));
                             let old_phys = entry.address().unwrap();
                             let frame = MMArch::phys_2_virt(phys).unwrap().data() as *mut u8;
                             frame.copy_from_nonoverlapping(
@@ -372,7 +409,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 +457,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,13 +490,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 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 {
@@ -480,14 +523,14 @@ 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()
+    pub fn from_prot_flags(prot_flags: ProtFlags, user: bool) -> EntryFlags<Arch> {
+        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));
@@ -757,9 +800,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())
@@ -855,7 +898,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()?;
@@ -869,7 +912,7 @@ 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, Page::new(false, PhysPageFrame::new(phys)))
         }
 
         return self.map_phys(virt, phys, flags);
@@ -880,7 +923,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)) {
@@ -920,8 +963,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));
@@ -937,7 +980,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)) {
@@ -1003,7 +1046,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)
@@ -1105,7 +1149,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));
@@ -1125,7 +1169,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| {
@@ -1147,7 +1191,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();
@@ -1186,7 +1230,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;
@@ -1234,7 +1278,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)?;
 

+ 35 - 18
kernel/src/mm/ucontext.rs

@@ -20,6 +20,7 @@ use system_error::SystemError;
 use crate::{
     arch::{mm::PageMapper, CurrentIrqArch, MMArch},
     exception::InterruptArch,
+    filesystem::vfs::file::File,
     libs::{
         align::page_align_up,
         rwlock::RwLock,
@@ -34,7 +35,7 @@ use super::{
     allocator::page_frame::{
         deallocate_page_frames, PageFrameCount, PhysPageFrame, VirtPageFrame, VirtPageFrameIter,
     },
-    page::{Flusher, InactiveFlusher, PageFlags, PageFlushAll},
+    page::{EntryFlags, Flusher, InactiveFlusher, PageFlushAll},
     syscall::{MadvFlags, MapFlags, MremapFlags, ProtFlags},
     MemoryManagementArch, PageTableKind, VirtAddr, VirtRegion, VmFlags,
 };
@@ -333,7 +334,7 @@ impl InnerAddressSpace {
         F: FnOnce(
             VirtPageFrame,
             PageFrameCount,
-            PageFlags<MMArch>,
+            EntryFlags<MMArch>,
             &mut PageMapper,
             &mut dyn Flusher<MMArch>,
         ) -> Result<Arc<LockedVMA>, SystemError>,
@@ -380,7 +381,7 @@ impl InnerAddressSpace {
         self.mappings.insert_vma(map_func(
             page,
             page_count,
-            PageFlags::from_prot_flags(prot_flags, true),
+            EntryFlags::from_prot_flags(prot_flags, true),
             &mut self.user_mapper.utable,
             flusher,
         )?);
@@ -556,7 +557,7 @@ impl InnerAddressSpace {
                 return Err(SystemError::EACCES);
             }
 
-            let new_flags: PageFlags<MMArch> = r_guard
+            let new_flags: EntryFlags<MMArch> = r_guard
                 .flags()
                 .set_execute(prot_flags.contains(ProtFlags::PROT_EXEC))
                 .set_write(prot_flags.contains(ProtFlags::PROT_WRITE));
@@ -1022,7 +1023,7 @@ impl LockedVMA {
     ///
     pub fn remap(
         &self,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
         mapper: &mut PageMapper,
         mut flusher: impl Flusher<MMArch>,
     ) -> Result<(), SystemError> {
@@ -1233,13 +1234,17 @@ pub struct VMA {
     /// 虚拟内存区域标志
     vm_flags: VmFlags,
     /// VMA内的页帧的标志
-    flags: PageFlags<MMArch>,
+    flags: EntryFlags<MMArch>,
     /// VMA内的页帧是否已经映射到页表
     mapped: bool,
     /// VMA所属的用户地址空间
     user_address_space: Option<Weak<AddressSpace>>,
     self_ref: Weak<LockedVMA>,
 
+    vm_file: Option<Arc<File>>,
+    /// VMA映射的文件部分相对于整个文件的偏移页数
+    file_pgoff: Option<usize>,
+
     provider: Provider,
 }
 
@@ -1262,7 +1267,7 @@ impl VMA {
     pub fn new(
         region: VirtRegion,
         vm_flags: VmFlags,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
         mapped: bool,
     ) -> Self {
         VMA {
@@ -1273,6 +1278,8 @@ impl VMA {
             user_address_space: None,
             self_ref: Weak::default(),
             provider: Provider::Allocated,
+            file_pgoff: None,
+            vm_file: None,
         }
     }
 
@@ -1284,6 +1291,10 @@ impl VMA {
         return &self.vm_flags;
     }
 
+    pub fn vm_file(&self) -> Option<Arc<File>> {
+        return self.vm_file.clone();
+    }
+
     pub fn set_vm_flags(&mut self, vm_flags: VmFlags) {
         self.vm_flags = vm_flags;
     }
@@ -1310,6 +1321,8 @@ impl VMA {
             user_address_space: self.user_address_space.clone(),
             self_ref: self.self_ref.clone(),
             provider: Provider::Allocated,
+            file_pgoff: self.file_pgoff,
+            vm_file: self.vm_file.clone(),
         };
     }
 
@@ -1322,14 +1335,21 @@ impl VMA {
             user_address_space: None,
             self_ref: Weak::default(),
             provider: Provider::Allocated,
+            file_pgoff: self.file_pgoff,
+            vm_file: self.vm_file.clone(),
         };
     }
 
     #[inline(always)]
-    pub fn flags(&self) -> PageFlags<MMArch> {
+    pub fn flags(&self) -> EntryFlags<MMArch> {
         return self.flags;
     }
 
+    #[inline(always)]
+    pub fn file_page_offset(&self) -> Option<usize> {
+        return self.file_pgoff;
+    }
+
     pub fn pages(&self) -> VirtPageFrameIter {
         return VirtPageFrameIter::new(
             VirtPageFrame::new(self.region.start()),
@@ -1339,7 +1359,7 @@ impl VMA {
 
     pub fn remap(
         &mut self,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
         mapper: &mut PageMapper,
         mut flusher: impl Flusher<MMArch>,
     ) -> Result<(), SystemError> {
@@ -1392,7 +1412,7 @@ impl VMA {
         destination: VirtPageFrame,
         count: PageFrameCount,
         vm_flags: VmFlags,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
         mapper: &mut PageMapper,
         mut flusher: impl Flusher<MMArch>,
     ) -> Result<Arc<LockedVMA>, SystemError> {
@@ -1414,15 +1434,12 @@ impl VMA {
             cur_dest = cur_dest.next();
         }
 
-        let r: Arc<LockedVMA> = LockedVMA::new(VMA {
-            region: VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE),
+        let r: Arc<LockedVMA> = LockedVMA::new(VMA::new(
+            VirtRegion::new(destination.virt_address(), count.data() * MMArch::PAGE_SIZE),
             vm_flags,
             flags,
-            mapped: true,
-            user_address_space: None,
-            self_ref: Weak::default(),
-            provider: Provider::Allocated,
-        });
+            true,
+        ));
 
         // 将VMA加入到anon_vma中
         let mut page_manager_guard = page_manager_lock_irqsave();
@@ -1450,7 +1467,7 @@ impl VMA {
         destination: VirtPageFrame,
         page_count: PageFrameCount,
         vm_flags: VmFlags,
-        flags: PageFlags<MMArch>,
+        flags: EntryFlags<MMArch>,
         mapper: &mut PageMapper,
         mut flusher: impl Flusher<MMArch>,
     ) -> Result<Arc<LockedVMA>, SystemError> {

+ 2 - 2
kernel/src/virt/kvm/host_mem.rs

@@ -2,7 +2,7 @@ use log::debug;
 use system_error::SystemError;
 
 use super::{vcpu::Vcpu, vm};
-use crate::mm::{kernel_mapper::KernelMapper, page::PageFlags, VirtAddr};
+use crate::mm::{kernel_mapper::KernelMapper, page::EntryFlags, VirtAddr};
 
 /*
  * Address types:
@@ -152,7 +152,7 @@ fn hva_to_pfn(addr: u64, _atomic: bool, _writable: &mut bool) -> Result<u64, Sys
         return Ok(hpa.data() as u64 >> PAGE_SHIFT);
     }
     unsafe {
-        mapper.map(hva, PageFlags::mmio_flags());
+        mapper.map(hva, EntryFlags::mmio_flags());
     }
     let (hpa, _) = mapper.translate(hva).unwrap();
     return Ok(hpa.data() as u64 >> PAGE_SHIFT);