瀏覽代碼

优化protection_map的初始化方式

MemoryShore 9 月之前
父節點
當前提交
8f338fb44a
共有 3 個文件被更改,包括 124 次插入58 次删除
  1. 31 22
      kernel/src/arch/riscv64/mm/mod.rs
  2. 65 25
      kernel/src/arch/x86_64/mm/mod.rs
  3. 28 11
      kernel/src/mm/mod.rs

+ 31 - 22
kernel/src/arch/riscv64/mm/mod.rs

@@ -257,28 +257,6 @@ impl MemoryManagementArch for RiscV64MMArch {
         true
     }
 
-    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;
-        map
-    }
-
     const PAGE_NONE: usize = Self::ENTRY_FLAG_GLOBAL | Self::ENTRY_FLAG_READONLY;
 
     const PAGE_READ: usize = PAGE_ENTRY_BASE | Self::ENTRY_FLAG_READONLY;
@@ -304,6 +282,37 @@ impl MemoryManagementArch for RiscV64MMArch {
     const PAGE_COPY_NOEXEC: usize = 0;
     const PAGE_READONLY: usize = 0;
     const PAGE_READONLY_EXEC: usize = 0;
+
+    const PROTECTION_MAP: [usize; 16] = protection_map();
+}
+
+const fn protection_map() -> [usize; 16] {
+    type Arch = RiscV64MMArch;
+    let mut map = [0; 16];
+    map[VmFlags::VM_NONE.bits()] = Arch::PAGE_NONE;
+    map[VmFlags::VM_READ.bits()] = Arch::PAGE_READONLY;
+    map[VmFlags::VM_WRITE.bits()] = Arch::PAGE_COPY;
+    map[VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] = Arch::PAGE_COPY;
+    map[VmFlags::VM_EXEC.bits()] = Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] = Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] = Arch::PAGE_COPY_EXEC;
+    map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
+        Arch::PAGE_COPY_EXEC;
+    map[VmFlags::VM_SHARED.bits()] = Arch::PAGE_NONE;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_READ.bits()] = Arch::PAGE_READONLY;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits()] = Arch::PAGE_SHARED;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
+        Arch::PAGE_SHARED;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits()] = Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
+        Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
+        Arch::PAGE_SHARED_EXEC;
+    map[VmFlags::VM_SHARED.bits()
+        | VmFlags::VM_EXEC.bits()
+        | VmFlags::VM_WRITE.bits()
+        | VmFlags::VM_READ.bits()] = Arch::PAGE_SHARED_EXEC;
+    map
 }
 
 const PAGE_ENTRY_BASE: usize = RiscV64MMArch::ENTRY_FLAG_PRESENT

+ 65 - 25
kernel/src/arch/x86_64/mm/mod.rs

@@ -327,31 +327,33 @@ 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
-    }
+    // 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: [usize; 16] = protection_map();
 
     const PAGE_NONE: usize =
         Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_ACCESSED | Self::ENTRY_FLAG_GLOBAL;
@@ -395,6 +397,44 @@ impl MemoryManagementArch for X86_64MMArch {
     const PAGE_EXEC: usize = 0;
 }
 
+/// 获取保护标志的映射表
+///
+///
+/// ## 返回值
+/// - `[usize; 16]`: 长度为16的映射表
+const fn protection_map() -> [usize; 16] {
+    type Arch = X86_64MMArch;
+    let mut map = [0; 16];
+    map[VmFlags::VM_NONE.bits()] = Arch::PAGE_NONE;
+    map[VmFlags::VM_READ.bits()] = Arch::PAGE_READONLY;
+    map[VmFlags::VM_WRITE.bits()] = Arch::PAGE_COPY;
+    map[VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] = Arch::PAGE_COPY;
+    map[VmFlags::VM_EXEC.bits()] = Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] = Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] = Arch::PAGE_COPY_EXEC;
+    map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
+        Arch::PAGE_COPY_EXEC;
+    map[VmFlags::VM_SHARED.bits()] = X86_64MMArch::PAGE_NONE;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_READ.bits()] = Arch::PAGE_READONLY;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits()] = Arch::PAGE_SHARED;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
+        Arch::PAGE_SHARED;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits()] = Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
+        Arch::PAGE_READONLY_EXEC;
+    map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
+        Arch::PAGE_SHARED_EXEC;
+    map[VmFlags::VM_SHARED.bits()
+        | VmFlags::VM_EXEC.bits()
+        | VmFlags::VM_WRITE.bits()
+        | VmFlags::VM_READ.bits()] = Arch::PAGE_SHARED_EXEC;
+
+    // if X86_64MMArch::is_xd_reserved() {
+    //     map.iter_mut().for_each(|x| *x &= !Self::ENTRY_FLAG_NO_EXEC)
+    // }
+    map
+}
+
 impl X86_64MMArch {
     unsafe fn get_load_base_paddr() -> PhysAddr {
         let mut mb2_lb_info: [multiboot_tag_load_base_addr_t; 512] = mem::zeroed();

+ 28 - 11
kernel/src/mm/mod.rs

@@ -679,15 +679,17 @@ 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
-    }
+    // /// 获取保护标志的映射表
+    // ///
+    // ///
+    // /// ## 返回值
+    // /// - `[usize; 16]`: 长度为16的映射表
+    // fn protection_map() -> [usize; 16] {
+    //     let map = [0; 16];
+    //     map
+    // }
+
+    const PROTECTION_MAP: [usize; 16];
 
     /// 页面保护标志转换函数
     /// ## 参数
@@ -697,8 +699,23 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
     /// ## 返回值
     /// - EntryFlags: 页面的保护位
     fn vm_get_page_prot(vm_flags: VmFlags) -> EntryFlags<Self> {
-        let map = Self::protection_map();
-        unsafe { EntryFlags::from_data(map[vm_flags]) }
+        let map = Self::PROTECTION_MAP;
+        let mut ret = unsafe {
+            EntryFlags::from_data(
+                map[vm_flags.intersection(
+                    VmFlags::VM_READ | VmFlags::VM_WRITE | VmFlags::VM_EXEC | VmFlags::VM_SHARED,
+                )],
+            )
+        };
+
+        #[cfg(target_arch = "x86_64")]
+        {
+            // 如果xd位被保留,那么将可执行性设置为true
+            if crate::arch::mm::X86_64MMArch::is_xd_reserved() {
+                ret = ret.set_execute(true);
+            }
+        }
+        ret
     }
 }