Browse Source

优化代码结构,添加部分注释

MemoryShore 8 months ago
parent
commit
732a6d7d4d

+ 1 - 1
kernel/Cargo.toml

@@ -88,4 +88,4 @@ debug = true   # Controls whether the compiler passes `-g`
 
 # The release profile, used for `cargo build --release`
 [profile.release]
-debug = false
+debug = true

+ 3 - 5
kernel/src/arch/x86_64/mm/fault.rs

@@ -223,7 +223,7 @@ impl X86_64MMArch {
         }
 
         let current_address_space: Arc<AddressSpace> = AddressSpace::current().unwrap();
-        let mut space_guard = current_address_space.write();
+        let mut space_guard = current_address_space.write_irqsave();
         let mut fault;
         loop {
             let vma = space_guard.mappings.find_nearest(address);
@@ -269,11 +269,9 @@ impl X86_64MMArch {
                 );
             }
             let mapper = &mut space_guard.user_mapper.utable;
+            let message = PageFaultMessage::new(vma.clone(), address, flags, mapper);
 
-            fault = PageFaultHandler::handle_mm_fault(
-                &mut PageFaultMessage::new(vma.clone(), address, flags),
-                mapper,
-            );
+            fault = PageFaultHandler::handle_mm_fault(message);
 
             if fault.contains(VmFaultReason::VM_FAULT_COMPLETED) {
                 return;

+ 0 - 26
kernel/src/arch/x86_64/mm/mod.rs

@@ -327,32 +327,6 @@ impl MemoryManagementArch for X86_64MMArch {
         pkru::pkru_allows_pkey(pkru::vma_pkey(vma), write)
     }
 
-    // fn protection_map() -> [usize; 16] {
-    //     let mut map = [0; 16];
-    //     map[VmFlags::VM_NONE] = Self::PAGE_NONE;
-    //     map[VmFlags::VM_READ] = Self::PAGE_READONLY;
-    //     map[VmFlags::VM_WRITE] = Self::PAGE_COPY;
-    //     map[VmFlags::VM_WRITE | VmFlags::VM_READ] = Self::PAGE_COPY;
-    //     map[VmFlags::VM_EXEC] = Self::PAGE_READONLY_EXEC;
-    //     map[VmFlags::VM_EXEC | VmFlags::VM_READ] = Self::PAGE_READONLY_EXEC;
-    //     map[VmFlags::VM_EXEC | VmFlags::VM_WRITE] = Self::PAGE_COPY_EXEC;
-    //     map[VmFlags::VM_EXEC | VmFlags::VM_WRITE | VmFlags::VM_READ] = Self::PAGE_COPY_EXEC;
-    //     map[VmFlags::VM_SHARED] = Self::PAGE_NONE;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_READ] = Self::PAGE_READONLY;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_WRITE] = Self::PAGE_SHARED;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_WRITE | VmFlags::VM_READ] = Self::PAGE_SHARED;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_EXEC] = Self::PAGE_READONLY_EXEC;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_EXEC | VmFlags::VM_READ] = Self::PAGE_READONLY_EXEC;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_EXEC | VmFlags::VM_WRITE] = Self::PAGE_SHARED_EXEC;
-    //     map[VmFlags::VM_SHARED | VmFlags::VM_EXEC | VmFlags::VM_WRITE | VmFlags::VM_READ] =
-    //         Self::PAGE_SHARED_EXEC;
-
-    //     if Self::is_xd_reserved() {
-    //         map.iter_mut().for_each(|x| *x &= !Self::ENTRY_FLAG_NO_EXEC)
-    //     }
-    //     map
-    // }
-
     const PROTECTION_MAP: [EntryFlags<MMArch>; 16] = protection_map();
 
     const PAGE_NONE: usize =

+ 3 - 5
kernel/src/filesystem/fat/fs.rs

@@ -12,7 +12,6 @@ use alloc::{
     vec::Vec,
 };
 
-use crate::arch::mm::PageMapper;
 use crate::driver::base::device::device_number::DeviceNumber;
 use crate::filesystem::vfs::file::PageCache;
 use crate::filesystem::vfs::utils::DName;
@@ -292,18 +291,17 @@ impl FileSystem for FATFileSystem {
         )
     }
 
-    unsafe fn fault(&self, pfm: &mut PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
-        PageFaultHandler::filemap_fault(pfm, mapper)
+    unsafe fn fault(&self, pfm: &mut PageFaultMessage) -> VmFaultReason {
+        PageFaultHandler::filemap_fault(pfm)
     }
 
     unsafe fn map_pages(
         &self,
         pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
         start_pgoff: usize,
         end_pgoff: usize,
     ) -> VmFaultReason {
-        PageFaultHandler::filemap_map_pages(pfm, mapper, start_pgoff, end_pgoff)
+        PageFaultHandler::filemap_map_pages(pfm, start_pgoff, end_pgoff)
     }
 }
 

+ 1 - 11
kernel/src/filesystem/vfs/file.rs

@@ -122,7 +122,7 @@ impl FileMode {
     }
 }
 
-#[allow(dead_code)]
+/// 页面缓存
 pub struct PageCache {
     xarray: SpinLock<XArray<Arc<Page>>>,
     pub inode: Option<Weak<dyn IndexNode>>,
@@ -174,16 +174,6 @@ impl PageCache {
     pub fn set_inode(&mut self, inode: Weak<dyn IndexNode>) {
         self.inode = Some(inode)
     }
-
-    // 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
-    // }
 }
 
 impl Default for PageCache {

+ 6 - 4
kernel/src/filesystem/vfs/mod.rs

@@ -12,7 +12,6 @@ use intertrait::CastFromSync;
 use system_error::SystemError;
 
 use crate::{
-    arch::mm::PageMapper,
     driver::base::{
         block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber,
     },
@@ -565,7 +564,11 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync {
     }
 
     fn page_cache(&self) -> Option<Arc<PageCache>> {
-        panic!("function page_cache() has not yet been implemented");
+        log::error!(
+            "function page_cache() has not yet been implemented for inode:{}",
+            crate::libs::name::get_type_name(&self)
+        );
+        None
     }
 }
 
@@ -817,7 +820,7 @@ pub trait FileSystem: Any + Sync + Send + Debug {
 
     fn super_block(&self) -> SuperBlock;
 
-    unsafe fn fault(&self, _pfm: &mut PageFaultMessage, _mapper: &mut PageMapper) -> VmFaultReason {
+    unsafe fn fault(&self, _pfm: &mut PageFaultMessage) -> VmFaultReason {
         panic!(
             "fault() has not yet been implemented for filesystem: {}",
             crate::libs::name::get_type_name(&self)
@@ -827,7 +830,6 @@ pub trait FileSystem: Any + Sync + Send + Debug {
     unsafe fn map_pages(
         &self,
         _pfm: &mut PageFaultMessage,
-        _mapper: &mut PageMapper,
         _start_pgoff: usize,
         _end_pgoff: usize,
     ) -> VmFaultReason {

+ 3 - 6
kernel/src/filesystem/vfs/mount.rs

@@ -12,7 +12,6 @@ use alloc::{
 use system_error::SystemError;
 
 use crate::{
-    arch::mm::PageMapper,
     driver::base::device::device_number::DeviceNumber,
     filesystem::vfs::ROOT_INODE,
     libs::{
@@ -537,19 +536,17 @@ impl FileSystem for MountFS {
         SuperBlock::new(Magic::MOUNT_MAGIC, MOUNTFS_BLOCK_SIZE, MOUNTFS_MAX_NAMELEN)
     }
 
-    unsafe fn fault(&self, pfm: &mut PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
-        self.inner_filesystem.fault(pfm, mapper)
+    unsafe fn fault(&self, pfm: &mut PageFaultMessage) -> VmFaultReason {
+        self.inner_filesystem.fault(pfm)
     }
 
     unsafe fn map_pages(
         &self,
         pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
         start_pgoff: usize,
         end_pgoff: usize,
     ) -> VmFaultReason {
-        self.inner_filesystem
-            .map_pages(pfm, mapper, start_pgoff, end_pgoff)
+        self.inner_filesystem.map_pages(pfm, start_pgoff, end_pgoff)
     }
 }
 

+ 0 - 2
kernel/src/init/initcall.rs

@@ -10,7 +10,6 @@ define_public_unified_initializer_slice!(INITCALL_FS);
 define_public_unified_initializer_slice!(INITCALL_ROOTFS);
 define_public_unified_initializer_slice!(INITCALL_DEVICE);
 define_public_unified_initializer_slice!(INITCALL_LATE);
-define_public_unified_initializer_slice!(INITCALL_MM);
 
 pub fn do_initcalls() -> Result<(), SystemError> {
     unified_init!(INITCALL_PURE);
@@ -22,6 +21,5 @@ pub fn do_initcalls() -> Result<(), SystemError> {
     unified_init!(INITCALL_ROOTFS);
     unified_init!(INITCALL_DEVICE);
     unified_init!(INITCALL_LATE);
-    unified_init!(INITCALL_MM);
     return Ok(());
 }

+ 151 - 191
kernel/src/mm/fault.rs

@@ -5,7 +5,7 @@ use core::{
     panic,
 };
 
-use alloc::{sync::Arc, vec::Vec};
+use alloc::sync::Arc;
 
 use crate::{
     arch::{mm::PageMapper, MMArch},
@@ -46,21 +46,30 @@ bitflags! {
 /// # 缺页异常信息结构体
 /// 包含了页面错误处理的相关信息,例如出错的地址、VMA等
 #[derive(Debug)]
-pub struct PageFaultMessage {
+pub struct PageFaultMessage<'a> {
     /// 产生缺页的VMA结构体
     vma: Arc<LockedVMA>,
     /// 缺页地址
     address: VirtAddr,
     /// 异常处理标志
     flags: FaultFlags,
+    /// 页表映射器
+    mapper: &'a mut PageMapper,
     /// 缺页的文件页在文件中的偏移量
     file_pgoff: Option<usize>,
-    /// 缺页对应PageCache中的文件页的物理地址
+    /// 缺页对应PageCache中的文件页
     page: Option<Arc<Page>>,
+    /// 写时拷贝需要的页面
+    cow_page: Option<Arc<Page>>,
 }
 
-impl PageFaultMessage {
-    pub fn new(vma: Arc<LockedVMA>, address: VirtAddr, flags: FaultFlags) -> Self {
+impl<'a> PageFaultMessage<'a> {
+    pub fn new(
+        vma: Arc<LockedVMA>,
+        address: VirtAddr,
+        flags: FaultFlags,
+        mapper: &'a mut PageMapper,
+    ) -> Self {
         let guard = vma.lock_irqsave();
         let file_pgoff = guard.file_page_offset().map(|file_page_offset| {
             ((address - guard.region().start()) >> MMArch::PAGE_SHIFT) + file_page_offset
@@ -71,6 +80,8 @@ impl PageFaultMessage {
             flags,
             file_pgoff,
             page: None,
+            mapper,
+            cow_page: None,
         }
     }
 
@@ -82,8 +93,8 @@ impl PageFaultMessage {
 
     #[inline(always)]
     #[allow(dead_code)]
-    pub fn address(&self) -> &VirtAddr {
-        &self.address
+    pub fn address(&self) -> VirtAddr {
+        self.address
     }
 
     #[inline(always)]
@@ -94,20 +105,8 @@ impl PageFaultMessage {
 
     #[inline(always)]
     #[allow(dead_code)]
-    pub fn flags(&self) -> &FaultFlags {
-        &self.flags
-    }
-}
-
-impl Clone for PageFaultMessage {
-    fn clone(&self) -> Self {
-        Self {
-            vma: self.vma.clone(),
-            address: self.address,
-            flags: self.flags,
-            file_pgoff: self.file_pgoff,
-            page: None,
-        }
+    pub fn flags(&self) -> FaultFlags {
+        self.flags
     }
 }
 
@@ -123,10 +122,7 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn handle_mm_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    pub unsafe fn handle_mm_fault(mut pfm: PageFaultMessage) -> VmFaultReason {
         let flags = pfm.flags();
         let vma = pfm.vma();
         let current_pcb = ProcessManager::current_pcb();
@@ -148,7 +144,7 @@ impl PageFaultHandler {
         if unlikely(vm_flags.contains(VmFlags::VM_HUGETLB)) {
             //TODO: 添加handle_hugetlb_fault处理大页缺页异常
         } else {
-            Self::handle_normal_fault(pfm, mapper);
+            Self::handle_normal_fault(&mut pfm);
         }
 
         VmFaultReason::VM_FAULT_COMPLETED
@@ -162,12 +158,10 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn handle_normal_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    pub unsafe fn handle_normal_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let address = pfm.address_aligned_down();
         let vma = pfm.vma.clone();
+        let mapper = &mut pfm.mapper;
         if mapper.get_entry(address, 3).is_none() {
             mapper
                 .allocate_table(address, 2)
@@ -188,7 +182,7 @@ impl PageFaultHandler {
             }
         }
 
-        Self::handle_pte_fault(pfm, mapper)
+        Self::handle_pte_fault(pfm)
     }
 
     /// 处理页表项异常
@@ -199,36 +193,34 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn handle_pte_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    pub unsafe fn handle_pte_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let address = pfm.address_aligned_down();
         let flags = pfm.flags;
         let vma = pfm.vma.clone();
         let mut ret = VmFaultReason::VM_FAULT_COMPLETED;
+        let mapper = &pfm.mapper;
 
         // pte存在
         if let Some(mut entry) = mapper.get_entry(address, 0) {
             if !entry.present() {
-                ret = Self::do_swap_page(pfm.clone(), mapper);
+                ret = Self::do_swap_page(pfm);
             }
 
             if entry.protnone() && vma.is_accessible() {
-                ret = Self::do_numa_page(pfm.clone(), mapper);
+                ret = Self::do_numa_page(pfm);
             }
 
             if flags.intersects(FaultFlags::FAULT_FLAG_WRITE | FaultFlags::FAULT_FLAG_UNSHARE) {
                 if !entry.write() {
-                    ret = Self::do_wp_page(pfm.clone(), mapper);
+                    ret = Self::do_wp_page(pfm);
                 } else {
                     entry.set_flags(EntryFlags::from_data(MMArch::ENTRY_FLAG_DIRTY));
                 }
             }
         } else if vma.is_anonymous() {
-            ret = Self::do_anonymous_page(pfm, mapper);
+            ret = Self::do_anonymous_page(pfm);
         } else {
-            ret = Self::do_fault(pfm, mapper);
+            ret = Self::do_fault(pfm);
         }
 
         vma.lock_irqsave().set_mapped(true);
@@ -244,13 +236,12 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn do_anonymous_page(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    pub unsafe fn do_anonymous_page(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let address = pfm.address_aligned_down();
         let vma = pfm.vma.clone();
         let guard = vma.lock_irqsave();
+        let mapper = &mut pfm.mapper;
+
         if let Some(flush) = mapper.map(address, guard.flags()) {
             flush.flush();
             crate::debug::klog::mm::mm_debug_log(
@@ -279,28 +270,18 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    #[allow(unused_variables)]
-    pub unsafe fn do_fault(pfm: &mut PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
-        // 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
-
+    pub unsafe fn do_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
         if !pfm.flags().contains(FaultFlags::FAULT_FLAG_WRITE) {
-            return Self::do_read_fault(pfm, mapper);
+            return Self::do_read_fault(pfm);
         } else if !pfm
             .vma()
             .lock_irqsave()
             .vm_flags()
             .contains(VmFlags::VM_SHARED)
         {
-            return Self::do_cow_fault(pfm, mapper);
+            return Self::do_cow_fault(pfm);
         } else {
-            return Self::do_shared_fault(pfm, mapper);
+            return Self::do_shared_fault(pfm);
         }
     }
 
@@ -312,24 +293,52 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    #[allow(dead_code, unused_variables)]
-    pub unsafe fn do_cow_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
-        // panic!(
-        //     "do_cow_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_cow_fault
-        let file = pfm.vma().lock_irqsave().vm_file().unwrap();
+    pub unsafe fn do_cow_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
+        let cache_page = pfm.page.clone().unwrap();
+        let mapper = &mut pfm.mapper;
+
+        let cow_page_phys = mapper.allocator_mut().allocate_one();
+        if cow_page_phys.is_none() {
+            return VmFaultReason::VM_FAULT_OOM;
+        }
+        let cow_page_phys = cow_page_phys.unwrap();
+
+        let cow_page = Arc::new(Page::new(false, cow_page_phys));
+        pfm.cow_page = Some(cow_page.clone());
 
-        let mut ret = Self::filemap_fault(pfm, mapper);
+        let mut ret = Self::filemap_fault(pfm);
+
+        if unlikely(ret.intersects(
+            VmFaultReason::VM_FAULT_ERROR
+                | VmFaultReason::VM_FAULT_NOPAGE
+                | VmFaultReason::VM_FAULT_RETRY
+                | VmFaultReason::VM_FAULT_DONE_COW,
+        )) {
+            return ret;
+        }
 
-        ret = ret.union(Self::finish_fault(pfm, mapper));
+        //复制PageCache内容到新的页内
+        let new_frame = MMArch::phys_2_virt(cow_page_phys).unwrap();
+        (new_frame.data() as *mut u8).copy_from_nonoverlapping(
+            MMArch::phys_2_virt(cache_page.read_irqsave().phys_address())
+                .unwrap()
+                .data() as *mut u8,
+            MMArch::PAGE_SIZE,
+        );
+
+        let mut page_manager_guard = page_manager_lock_irqsave();
+
+        // 新页加入页管理器中
+        page_manager_guard.insert(cow_page_phys, &cow_page);
+        cow_page.write_irqsave().set_page_cache_index(
+            cow_page.read_irqsave().page_cache(),
+            cow_page.read_irqsave().index(),
+        );
+
+        // 将vma插入页的vma表中
+        cow_page.write_irqsave().insert_vma(pfm.vma());
+
+        ret = ret.union(Self::finish_fault(pfm));
 
         ret
     }
@@ -342,21 +351,17 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    #[allow(dead_code, unused_variables)]
-    pub unsafe fn do_read_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    pub unsafe fn do_read_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let fs = pfm.vma().lock_irqsave().vm_file().unwrap().inode().fs();
 
-        let mut ret = Self::do_fault_around(pfm, mapper);
+        let mut ret = Self::do_fault_around(pfm);
         if !ret.is_empty() {
             return ret;
         }
 
-        ret = fs.fault(pfm, mapper);
+        ret = fs.fault(pfm);
 
-        ret = ret.union(Self::finish_fault(pfm, mapper));
+        ret = ret.union(Self::finish_fault(pfm));
 
         ret
     }
@@ -369,23 +374,14 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    #[allow(dead_code, unused_variables)]
-    pub unsafe fn do_shared_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
-        // panic!(
-        //     "do_shared_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_shared_fault
+    pub unsafe fn do_shared_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
+        let mut ret = Self::filemap_fault(pfm);
 
-        let mut ret = Self::filemap_fault(pfm, mapper);
+        let cache_page = pfm.page.clone().expect("no cache_page in PageFaultMessage");
 
-        ret = ret.union(Self::finish_fault(pfm, mapper));
+        // 将pagecache页设为脏页,以便回收时能够回写
+        cache_page.write_irqsave().add_flags(PageFlags::PG_DIRTY);
+        ret = ret.union(Self::finish_fault(pfm));
 
         ret
     }
@@ -399,7 +395,7 @@ impl PageFaultHandler {
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
     #[allow(unused_variables)]
-    pub unsafe fn do_swap_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
+    pub unsafe fn do_swap_page(pfm: &mut PageFaultMessage) -> VmFaultReason {
         panic!(
             "do_swap_page has not yet been implemented, 
         fault message: {:?}, 
@@ -419,7 +415,7 @@ impl PageFaultHandler {
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
     #[allow(unused_variables)]
-    pub unsafe fn do_numa_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
+    pub unsafe fn do_numa_page(pfm: &mut PageFaultMessage) -> VmFaultReason {
         panic!(
             "do_numa_page has not yet been implemented, 
         fault message: {:?}, 
@@ -438,9 +434,11 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn do_wp_page(pfm: PageFaultMessage, mapper: &mut PageMapper) -> VmFaultReason {
+    pub unsafe fn do_wp_page(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let address = pfm.address_aligned_down();
         let vma = pfm.vma.clone();
+        let mapper = &mut pfm.mapper;
+
         let old_paddr = mapper.translate(address).unwrap().0;
         let mut page_manager = page_manager_lock_irqsave();
         let old_page = page_manager.get_unwrap(&old_paddr);
@@ -523,26 +521,25 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn do_fault_around(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
-        if mapper.get_table(*pfm.address(), 0).is_none() {
+    pub unsafe fn do_fault_around(pfm: &mut PageFaultMessage) -> VmFaultReason {
+        let vma = pfm.vma();
+        let address = pfm.address();
+        let mapper = &mut pfm.mapper;
+
+        if mapper.get_table(address, 0).is_none() {
             mapper
-                .allocate_table(*pfm.address(), 0)
+                .allocate_table(address, 0)
                 .expect("failed to allocate pte table");
         }
-        let vma = pfm.vma();
         let vma_guard = vma.lock_irqsave();
         let vma_region = *vma_guard.region();
         drop(vma_guard);
 
         // 缺页在VMA中的偏移量
-        let vm_pgoff = (*pfm.address() - vma_region.start()) >> MMArch::PAGE_SHIFT;
+        let vm_pgoff = (address - vma_region.start()) >> MMArch::PAGE_SHIFT;
 
         // 缺页在PTE中的偏移量
-        let pte_pgoff =
-            (pfm.address().data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_ENTRY_SHIFT);
+        let pte_pgoff = (address.data() >> MMArch::PAGE_SHIFT) & (1 << MMArch::PAGE_ENTRY_SHIFT);
 
         // 缺页在文件中的偏移量
         let file_pgoff = pfm.file_pgoff.expect("no file_pgoff");
@@ -570,9 +567,7 @@ impl PageFaultHandler {
         );
 
         // 预先分配pte页表(如果不存在)
-        if mapper.get_table(*pfm.address(), 0).is_none()
-            && mapper.allocate_table(*pfm.address(), 0).is_none()
-        {
+        if mapper.get_table(address, 0).is_none() && mapper.allocate_table(address, 0).is_none() {
             return VmFaultReason::VM_FAULT_OOM;
         }
 
@@ -580,7 +575,6 @@ impl PageFaultHandler {
         // from_pte - pte_pgoff得出预读起始pte相对缺失页的偏移,加上pfm.file_pgoff(缺失页在文件中的偏移)得出起始页在文件中的偏移,结束pte同理
         fs.map_pages(
             pfm,
-            mapper,
             file_pgoff + (from_pte - pte_pgoff),
             file_pgoff + (to_pte - pte_pgoff),
         );
@@ -598,7 +592,7 @@ impl PageFaultHandler {
     /// - VmFaultReason: 页面错误处理信息标志
     pub unsafe fn filemap_map_pages(
         pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
+
         start_pgoff: usize,
         end_pgoff: usize,
     ) -> VmFaultReason {
@@ -606,6 +600,7 @@ impl PageFaultHandler {
         let vma_guard = vma.lock_irqsave();
         let file = vma_guard.vm_file().expect("no vm_file in vma");
         let page_cache = file.inode().page_cache().unwrap();
+        let mapper = &mut pfm.mapper;
 
         // 起始页地址
         let addr = vma_guard.region().start
@@ -641,15 +636,13 @@ impl PageFaultHandler {
     ///
     /// ## 返回值
     /// - VmFaultReason: 页面错误处理信息标志
-    pub unsafe fn filemap_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    pub unsafe fn filemap_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let vma = pfm.vma();
         let vma_guard = vma.lock_irqsave();
         let file = vma_guard.vm_file().expect("no vm_file in vma");
         let page_cache = file.inode().page_cache().unwrap();
         let file_pgoff = pfm.file_pgoff.expect("no file_pgoff");
+        let mapper = &mut pfm.mapper;
         let mut ret = VmFaultReason::empty();
 
         if let Some(page) = page_cache.get_page(file_pgoff) {
@@ -661,19 +654,23 @@ impl PageFaultHandler {
             // TODO 同步预读
             //涉及磁盘IO,返回标志为VM_FAULT_MAJOR
             ret = VmFaultReason::VM_FAULT_MAJOR;
-            let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE];
-            file.pread(
-                file_pgoff * MMArch::PAGE_SIZE,
-                MMArch::PAGE_SIZE,
-                &mut buf[..],
-            )
-            .unwrap();
+            // let mut buf: Vec<u8> = vec![0; MMArch::PAGE_SIZE];
+
             let allocator = mapper.allocator_mut();
 
             // 分配一个物理页面作为加入PageCache的新页
             let new_cache_page = allocator.allocate_one().unwrap();
-            (MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8)
-                .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
+            // (MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8)
+            //     .copy_from_nonoverlapping(buf.as_mut_ptr(), MMArch::PAGE_SIZE);
+            file.pread(
+                file_pgoff * MMArch::PAGE_SIZE,
+                MMArch::PAGE_SIZE,
+                core::slice::from_raw_parts_mut(
+                    MMArch::phys_2_virt(new_cache_page).unwrap().data() as *mut u8,
+                    MMArch::PAGE_SIZE,
+                ),
+            )
+            .expect("failed to read file to create pagecache page");
 
             let page = Arc::new(Page::new(true, new_cache_page));
             pfm.page = Some(page.clone());
@@ -685,78 +682,41 @@ impl PageFaultHandler {
 
             page.write_irqsave()
                 .set_page_cache_index(Some(page_cache), Some(file_pgoff));
-
-            //     // 分配空白页并映射到缺页地址
-            //     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);
         }
         ret
     }
 
-    pub unsafe fn finish_fault(
-        pfm: &mut PageFaultMessage,
-        mapper: &mut PageMapper,
-    ) -> VmFaultReason {
+    /// 将文件页映射到缺页地址
+    /// ## 参数
+    ///
+    /// - `pfm`: 缺页异常信息
+    /// - `mapper`: 页表映射器
+    ///
+    /// ## 返回值
+    /// - VmFaultReason: 页面错误处理信息标志
+    pub unsafe fn finish_fault(pfm: &mut PageFaultMessage) -> VmFaultReason {
         let vma = pfm.vma();
         let vma_guard = vma.lock_irqsave();
-        let cache_page = pfm.page.clone().expect("no page in pfm");
-        let page_phys = cache_page.read_irqsave().phys_address();
-
-        if pfm.flags().contains(FaultFlags::FAULT_FLAG_WRITE)
-            && !pfm
-                .vma()
-                .lock_irqsave()
-                .vm_flags()
-                .contains(VmFlags::VM_SHARED)
-        {
-            // 私有文件映射的写时复制场景
-            // 分配空白页并映射到缺页地址
-            mapper
-                .map(
-                    pfm.address,
-                    vma_guard.flags().set_write(true).set_dirty(true),
-                )
-                .unwrap()
-                .flush();
-
-            //复制PageCache内容到新的页内
-            let new_phys = mapper.translate(pfm.address).unwrap().0;
-            let new_frame = MMArch::phys_2_virt(new_phys).unwrap();
-            (new_frame.data() as *mut u8).copy_from_nonoverlapping(
-                MMArch::phys_2_virt(page_phys).unwrap().data() as *mut u8,
-                MMArch::PAGE_SIZE,
-            );
-
-            let mut page_manager_guard = page_manager_lock_irqsave();
-            let page_guard = cache_page.read_irqsave();
-            let new_page = Arc::new(Page::new(page_guard.shared(), new_phys));
-
-            // 新页加入页管理器中
-            page_manager_guard.insert(new_phys, &new_page);
-            new_page.write_irqsave().set_page_cache_index(
-                cache_page.read_irqsave().page_cache(),
-                cache_page.read_irqsave().index(),
-            );
+        let flags = pfm.flags();
+        let cache_page = pfm.page.clone();
+        let cow_page = pfm.cow_page.clone();
+        let address = pfm.address();
+        let mapper = &mut pfm.mapper;
 
-            // 将vma插入页的vma链表中
-            new_page.write_irqsave().insert_vma(pfm.vma());
+        let page_to_map = if flags.contains(FaultFlags::FAULT_FLAG_WRITE)
+            && !vma_guard.vm_flags().contains(VmFlags::VM_SHARED)
+        {
+            // 私有文件映射的写时复制
+            cow_page.expect("no cow_page in PageFaultMessage")
         } else {
             // 直接映射到PageCache
-            mapper.map_phys(*pfm.address(), page_phys, vma_guard.flags());
-            cache_page.write_irqsave().insert_vma(pfm.vma());
-
-            if pfm.flags().contains(FaultFlags::FAULT_FLAG_WRITE)
-                && pfm
-                    .vma()
-                    .lock_irqsave()
-                    .vm_flags()
-                    .contains(VmFlags::VM_SHARED)
-            {
-                // 如果是共享写映射,将pagecache页设为脏页,以便回收时能够回写
-                cache_page.write_irqsave().add_flags(PageFlags::PG_DIRTY)
-            }
-        }
+            cache_page.expect("no cache_page in PageFaultMessage")
+        };
+
+        let page_phys = page_to_map.read_irqsave().phys_address();
+
+        mapper.map_phys(address, page_phys, vma_guard.flags());
+        page_to_map.write_irqsave().insert_vma(pfm.vma());
         VmFaultReason::VM_FAULT_COMPLETED
     }
 }

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

@@ -94,6 +94,7 @@ bitflags! {
         const VM_FAULT_NEEDDSYNC = 0x002000;
         const VM_FAULT_COMPLETED = 0x004000;
         const VM_FAULT_HINDEX_MASK = 0x0f0000;
+        const VM_FAULT_ERROR = 0x000001 | 0x000002 | 0x000040 | 0x000010 | 0x000020 | 0x000800;
     }
 
     pub struct MsFlags:usize {
@@ -668,16 +669,6 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
     const PAGE_WRITE_EXEC: usize;
     const PAGE_EXEC: usize;
 
-    // /// 获取保护标志的映射表
-    // ///
-    // ///
-    // /// ## 返回值
-    // /// - `[usize; 16]`: 长度为16的映射表
-    // fn protection_map() -> [usize; 16] {
-    //     let map = [0; 16];
-    //     map
-    // }
-
     const PROTECTION_MAP: [EntryFlags<Self>; 16];
 
     /// 页面保护标志转换函数

+ 21 - 2
kernel/src/mm/page.rs

@@ -18,7 +18,7 @@ use crate::{
     arch::{interrupt::ipi::send_ipi, mm::LockedFrameAllocator, MMArch},
     exception::ipi::{IpiKind, IpiTarget},
     filesystem::vfs::{file::PageCache, FilePrivateData},
-    init::initcall::INITCALL_MM,
+    init::initcall::INITCALL_CORE,
     ipc::shm::ShmId,
     libs::{
         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
@@ -113,9 +113,11 @@ pub fn page_reclaimer_init() {
     info!("page_reclaimer_init done");
 }
 
+/// 页面回收线程
 static mut PAGE_RECLAIMER_THREAD: Option<Arc<ProcessControlBlock>> = None;
 
-#[unified_init(INITCALL_MM)]
+/// 页面回收线程初始化函数
+#[unified_init(INITCALL_CORE)]
 fn page_reclaimer_thread_init() -> Result<(), SystemError> {
     let closure = crate::process::kthread::KernelThreadClosure::StaticEmptyClosure((
         &(page_reclaim_thread as fn() -> i32),
@@ -133,6 +135,7 @@ fn page_reclaimer_thread_init() -> Result<(), SystemError> {
     Ok(())
 }
 
+/// 页面回收线程执行的函数
 fn page_reclaim_thread() -> i32 {
     loop {
         let usage = unsafe { LockedFrameAllocator.usage() };
@@ -152,10 +155,12 @@ fn page_reclaim_thread() -> i32 {
     }
 }
 
+/// 获取页面回收器
 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>>,
 }
@@ -175,6 +180,10 @@ impl PageReclaimer {
         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");
@@ -197,11 +206,20 @@ impl PageReclaimer {
         }
     }
 
+    /// 唤醒页面回收线程
     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);
@@ -254,6 +272,7 @@ impl PageReclaimer {
             .unwrap();
     }
 
+    /// lru脏页刷新
     pub fn flush_dirty_pages(&self) {
         // log::info!("flush_dirty_pages");
         let iter = self.lru.iter();

+ 45 - 35
kernel/src/mm/syscall.rs

@@ -316,11 +316,6 @@ impl Syscall {
             );
             return Err(SystemError::EINVAL);
         }
-        // 暂时不支持除匿名页以外的映射
-        // if !map_flags.contains(MapFlags::MAP_ANONYMOUS) {
-        //     error!("mmap: not support file mapping");
-        //     return Err(SystemError::ENOSYS);
-        // }
 
         // 暂时不支持巨页映射
         if map_flags.contains(MapFlags::MAP_HUGETLB) {
@@ -329,6 +324,7 @@ impl Syscall {
         }
         let current_address_space = AddressSpace::current()?;
         let start_page = if map_flags.contains(MapFlags::MAP_ANONYMOUS) {
+            // 匿名映射
             current_address_space.write().map_anonymous(
                 start_vaddr,
                 len,
@@ -338,6 +334,7 @@ impl Syscall {
                 false,
             )?
         } else {
+            // 文件映射
             current_address_space.write().file_mapping(
                 start_vaddr,
                 len,
@@ -349,14 +346,7 @@ impl Syscall {
                 false,
             )?
         };
-        // let start_page = current_address_space.write().map_anonymous(
-        //     start_vaddr,
-        //     len,
-        //     prot_flags,
-        //     map_flags,
-        //     true,
-        //     false,
-        // )?;
+
         return Ok(start_page.virt_address().data());
     }
 
@@ -559,37 +549,46 @@ impl Syscall {
     /// - `len`:长度(已经对齐到页)
     /// - `flags`:标志
     pub fn msync(start: VirtAddr, len: usize, flags: usize) -> Result<usize, SystemError> {
+        if !start.check_aligned(MMArch::PAGE_SIZE) || !check_aligned(len, MMArch::PAGE_SIZE) {
+            return Err(SystemError::EINVAL);
+        }
+
+        if unlikely(verify_area(start, len).is_err()) {
+            return Err(SystemError::EINVAL);
+        }
+        if unlikely(len == 0) {
+            return Err(SystemError::EINVAL);
+        }
+
         let mut start = start.data();
         let end = start + len;
         let flags = MsFlags::from_bits_truncate(flags);
-        let mut err = Err(SystemError::EINVAL);
         let mut unmapped_error = Ok(0);
+
         if !flags.intersects(MsFlags::MS_ASYNC | MsFlags::MS_INVALIDATE | MsFlags::MS_SYNC) {
-            return err;
+            return Err(SystemError::EINVAL);
         }
+
         if flags.contains(MsFlags::MS_ASYNC | MsFlags::MS_SYNC) {
-            return err;
+            return Err(SystemError::EINVAL);
         }
 
-        err = Err(SystemError::ENOMEM);
         if end < start {
-            return err;
+            return Err(SystemError::ENOMEM);
         }
-        err = Ok(0);
 
         if start == end {
-            return err;
+            return Ok(0);
         }
 
         let current_address_space = AddressSpace::current()?;
+        let mut err = Err(SystemError::ENOMEM);
+        let mut next_vma = current_address_space
+            .read()
+            .mappings
+            .find_nearest(VirtAddr::new(start));
         loop {
-            err = Err(SystemError::ENOMEM);
-
-            if let Some(vma) = current_address_space
-                .read()
-                .mappings
-                .find_nearest(VirtAddr::new(start))
-            {
+            if let Some(vma) = next_vma.clone() {
                 let guard = vma.lock_irqsave();
                 let vm_start = guard.region().start().data();
                 let vm_end = guard.region().end().data();
@@ -625,20 +624,31 @@ impl Syscall {
                             from_raw_parts(old_start as *mut u8, fend - fstart + 1)
                         });
                         file.lseek(SeekFrom::SeekSet(old_pos as i64)).unwrap();
-
-                        if err.is_err() || start >= end {
-                            err = Ok(0);
+                        if err.is_err() {
+                            break;
+                        } else if start >= end {
+                            err = unmapped_error;
                             break;
                         }
+                        next_vma = current_address_space
+                            .read()
+                            .mappings
+                            .find_nearest(VirtAddr::new(start));
                     }
-                } else if start >= end {
-                    err = Ok(0);
-                    break;
+                } else {
+                    if start >= end {
+                        err = unmapped_error;
+                        break;
+                    }
+                    next_vma = current_address_space
+                        .read()
+                        .mappings
+                        .find_nearest(VirtAddr::new(vm_end));
                 }
             } else {
-                break;
+                return Err(SystemError::ENOMEM);
             }
         }
-        return if err.is_err() { err } else { unmapped_error };
+        return err;
     }
 }

+ 22 - 38
kernel/src/mm/ucontext.rs

@@ -283,23 +283,15 @@ impl InnerAddressSpace {
 
         // debug!("map_anonymous: len = {}", len);
 
-        let start_page: VirtPageFrame = if allocate_at_once {
-            self.mmap(
-                round_hint_to_min(start_vaddr),
-                PageFrameCount::from_bytes(len).unwrap(),
-                prot_flags,
-                map_flags,
-                move |page, count, flags, mapper, flusher| {
+        let start_page: VirtPageFrame = self.mmap(
+            round_hint_to_min(start_vaddr),
+            PageFrameCount::from_bytes(len).unwrap(),
+            prot_flags,
+            map_flags,
+            move |page, count, flags, mapper, flusher| {
+                if allocate_at_once {
                     VMA::zeroed(page, count, vm_flags, flags, mapper, flusher, None, None)
-                },
-            )?
-        } else {
-            self.mmap(
-                round_hint_to_min(start_vaddr),
-                PageFrameCount::from_bytes(len).unwrap(),
-                prot_flags,
-                map_flags,
-                move |page, count, flags, _mapper, _flusher| {
+                } else {
                     Ok(LockedVMA::new(VMA::new(
                         VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE),
                         vm_flags,
@@ -308,9 +300,9 @@ impl InnerAddressSpace {
                         None,
                         false,
                     )))
-                },
-            )?
-        };
+                }
+            },
+        )?;
 
         return Ok(start_page);
     }
@@ -391,13 +383,13 @@ impl InnerAddressSpace {
         }
         let pgoff = offset >> MMArch::PAGE_SHIFT;
 
-        let start_page: VirtPageFrame = if allocate_at_once {
-            self.mmap(
-                round_hint_to_min(start_vaddr),
-                PageFrameCount::from_bytes(len).unwrap(),
-                prot_flags,
-                map_flags,
-                move |page, count, flags, mapper, flusher| {
+        let start_page: VirtPageFrame = self.mmap(
+            round_hint_to_min(start_vaddr),
+            PageFrameCount::from_bytes(len).unwrap(),
+            prot_flags,
+            map_flags,
+            move |page, count, flags, mapper, flusher| {
+                if allocate_at_once {
                     VMA::zeroed(
                         page,
                         count,
@@ -408,15 +400,7 @@ impl InnerAddressSpace {
                         file,
                         Some(pgoff),
                     )
-                },
-            )?
-        } else {
-            self.mmap(
-                round_hint_to_min(start_vaddr),
-                PageFrameCount::from_bytes(len).unwrap(),
-                prot_flags,
-                map_flags,
-                move |page, count, flags, _mapper, _flusher| {
+                } else {
                     Ok(LockedVMA::new(VMA::new(
                         VirtRegion::new(page.virt_address(), count.data() * MMArch::PAGE_SIZE),
                         vm_flags,
@@ -425,9 +409,9 @@ impl InnerAddressSpace {
                         Some(pgoff),
                         false,
                     )))
-                },
-            )?
-        };
+                }
+            },
+        )?;
         return Ok(start_page);
     }