Forráskód Böngészése

Merge pull request #1 from SMS-Derfflinger/master

Impl mm for riscv64 and remove anonymous flag.
greatbridf 8 hónapja
szülő
commit
87f8f7b5b5

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 build/
 
 .vscode/
+.idea/
 
 test/
 

+ 2 - 2
Cargo.lock

@@ -52,9 +52,9 @@ dependencies = [
 
 [[package]]
 name = "bitflags"
-version = "2.6.0"
+version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 
 [[package]]
 name = "buddy_allocator"

+ 16 - 4
arch/Cargo.lock

@@ -1,15 +1,23 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
 name = "arch"
 version = "0.1.0"
 dependencies = [
+ "bitflags",
  "cfg-if",
- "percpu",
+ "eonix_mm",
+ "percpu-macros",
 ]
 
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -17,12 +25,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
-name = "percpu"
+name = "eonix_mm"
 version = "0.1.0"
 dependencies = [
- "percpu-macros",
+ "intrusive_list",
 ]
 
+[[package]]
+name = "intrusive_list"
+version = "0.1.0"
+
 [[package]]
 name = "percpu-macros"
 version = "0.1.0"

+ 1 - 8
arch/percpu-macros/Cargo.lock

@@ -1,18 +1,11 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+version = 4
 
 [[package]]
 name = "percpu-macros"
 version = "0.1.0"
 dependencies = [
- "cfg-if",
  "proc-macro2",
  "quote",
  "syn",

+ 203 - 0
arch/src/riscv64/mm.rs

@@ -0,0 +1,203 @@
+use core::{marker::PhantomData, ptr::NonNull};
+use eonix_mm::{
+    address::{Addr as _, PAddr},
+    page_table::{PageAttribute, PageTableLevel, PagingMode, RawPageTable, PTE},
+    paging::{PageBlock, PFN},
+};
+
+pub const PAGE_SIZE: usize = 0x1000;
+const PAGE_TABLE_BASE: PFN = PFN::from_val(0x8030_0000 >> 12);
+
+const PA_V: u64 = 0b1 << 0;
+const PA_R: u64 = 0b1 << 1;
+const PA_W: u64 = 0b1 << 2;
+const PA_X: u64 = 0b1 << 3;
+const PA_U: u64 = 0b1 << 4;
+const PA_G: u64 = 0b1 << 5;
+const PA_A: u64 = 0b1 << 6;
+const PA_D: u64 = 0b1 << 7;
+
+// in RSW
+const PA_COW: u64 = 0b1 << 8;
+const PA_MMAP: u64 = 0b1 << 9;
+
+const PA_SHIFT: u64 = 10;
+const PA_MASK: u64 = 0xFFC0_0000_0000_03FF; // 44 bit PPN, from 10 to 53
+// Bit 0-9 (V, R, W, X, U, G, A, D, RSW)
+const PA_FLAGS_MASK: u64 = 0x3FF; // 0b11_1111_1111
+
+
+
+#[repr(transparent)]
+pub struct PTE64(u64);
+
+#[derive(Clone, Copy)]
+pub struct PageAttribute64(u64);
+
+pub struct RawPageTableSv39<'a>(NonNull<PTE64>, PhantomData<&'a ()>);
+
+pub struct PagingModeSv39;
+
+impl PTE for PTE64 {
+    type Attr = PageAttribute64;
+
+    fn set(&mut self, pfn: PFN, attr: Self::Attr) {
+        self.0 = (PAddr::from(pfn).addr() as u64 & !PA_MASK) | (attr.0 & PA_MASK);
+    }
+
+    fn get(&self) -> (PFN, Self::Attr) {
+        (
+            PFN::from(PAddr::from((self.0 & !PA_MASK) as usize)),
+            PageAttribute64(self.0 & PA_MASK),
+        )
+    }
+
+    fn take(&mut self) -> (PFN, Self::Attr) {
+        let pfn_attr = self.get();
+        self.0 = 0;
+        pfn_attr
+    }
+}
+
+impl PagingMode for PagingModeSv39 {
+    type Entry = PTE64;
+    type RawTable<'a> = RawPageTableSv39<'a>;
+    const LEVELS: &'static [PageTableLevel] = &[
+        PageTableLevel::new(30, 9),
+        PageTableLevel::new(21, 9),
+        PageTableLevel::new(12, 9),
+    ];
+    const KERNEL_ROOT_TABLE_PFN: PFN = PAGE_TABLE_BASE;
+}
+
+impl<'a> RawPageTable<'a> for RawPageTableSv39<'a> {
+    type Entry = PTE64;
+
+    fn index(&self, index: u16) -> &'a Self::Entry {
+        unsafe { &self.0.cast::<[PTE64; 512]>().as_ref()[index as usize] }
+    }
+
+    fn index_mut(&mut self, index: u16) -> &'a mut Self::Entry {
+        unsafe { &mut self.0.cast::<[PTE64; 512]>().as_mut()[index as usize] }
+    }
+
+    unsafe fn from_ptr(ptr: NonNull<PageBlock>) -> Self {
+        Self(ptr.cast(), PhantomData)
+    }
+}
+
+impl PageAttribute for PageAttribute64 {
+    fn new() -> Self {
+        Self(PA_R)
+    }
+
+    fn present(self, present: bool) -> Self {
+        if present {
+            Self(self.0 | PA_V)
+        } else {
+            Self(self.0 & !PA_V)
+        }
+    }
+
+    fn write(self, write: bool) -> Self {
+        if write {
+            Self(self.0 | PA_W)
+        } else {
+            Self(self.0 & !PA_W)
+        }
+    }
+
+    fn execute(self, execute: bool) -> Self {
+        if execute {
+            Self(self.0 | PA_X)
+        } else {
+            Self(self.0 & !PA_X)
+        }
+    }
+
+    fn user(self, user: bool) -> Self {
+        if user {
+            Self(self.0 | PA_U)
+        } else {
+            Self(self.0 & !PA_U)
+        }
+    }
+
+    fn accessed(self, accessed: bool) -> Self {
+        if accessed {
+            Self(self.0 | PA_A)
+        } else {
+            Self(self.0 & !PA_A)
+        }
+    }
+
+    fn dirty(self, dirty: bool) -> Self {
+        if dirty {
+            Self(self.0 | PA_D)
+        } else {
+            Self(self.0 & !PA_D)
+        }
+    }
+
+    fn global(self, global: bool) -> Self {
+        if global {
+            Self(self.0 | PA_G)
+        } else {
+            Self(self.0 & !PA_G)
+        }
+    }
+
+    fn copy_on_write(self, cow: bool) -> Self {
+        if cow {
+            Self(self.0 | PA_COW)
+        } else {
+            Self(self.0 & !PA_COW)
+        }
+    }
+
+    fn mapped(self, mmap: bool) -> Self {
+        if mmap {
+            Self(self.0 | PA_MMAP)
+        } else {
+            Self(self.0 & !PA_MMAP)
+        }
+    }
+
+    fn is_present(&self) -> bool {
+        self.0 & PA_V != 0
+    }
+
+    fn is_write(&self) -> bool {
+        self.0 & PA_W != 0
+    }
+
+    fn is_execute(&self) -> bool {
+        self.0 & PA_X != 0
+    }
+
+    fn is_user(&self) -> bool {
+        self.0 & PA_U != 0
+    }
+
+    fn is_accessed(&self) -> bool {
+        self.0 & PA_A != 0
+    }
+
+    fn is_dirty(&self) -> bool {
+        self.0 & PA_D != 0
+    }
+
+    fn is_global(&self) -> bool {
+        self.0 & PA_G != 0
+    }
+
+    fn is_copy_on_write(&self) -> bool {
+        self.0 & PA_COW != 0
+    }
+
+    fn is_mapped(&self) -> bool {
+        self.0 & PA_MMAP != 0
+    }
+}
+
+pub type DefaultPagingMode = PagingModeSv39;

+ 4 - 0
arch/src/riscv64/mod.rs

@@ -0,0 +1,4 @@
+mod start;
+mod mm;
+
+pub use self::start::*;

+ 0 - 12
arch/src/x86_64/mm.rs

@@ -167,14 +167,6 @@ impl PageAttribute for PageAttribute64 {
         }
     }
 
-    fn anonymous(self, anon: bool) -> Self {
-        if anon {
-            Self(self.0 | PA_ANON)
-        } else {
-            Self(self.0 & !PA_ANON)
-        }
-    }
-
     fn is_present(&self) -> bool {
         self.0 & PA_P != 0
     }
@@ -210,10 +202,6 @@ impl PageAttribute for PageAttribute64 {
     fn is_mapped(&self) -> bool {
         self.0 & PA_MMAP != 0
     }
-
-    fn is_anonymous(&self) -> bool {
-        self.0 & PA_ANON != 0
-    }
 }
 
 pub type DefaultPagingMode = PagingMode4Levels;

+ 129 - 0
crates/buddy_allocator/Cargo.lock

@@ -0,0 +1,129 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "arch"
+version = "0.1.0"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "eonix_mm",
+ "percpu-macros",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
+[[package]]
+name = "buddy_allocator"
+version = "0.1.0"
+dependencies = [
+ "eonix_mm",
+ "eonix_sync",
+ "intrusive_list",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "eonix_mm"
+version = "0.1.0"
+dependencies = [
+ "intrusive_list",
+]
+
+[[package]]
+name = "eonix_preempt"
+version = "0.1.0"
+dependencies = [
+ "arch",
+]
+
+[[package]]
+name = "eonix_sync"
+version = "0.1.0"
+dependencies = [
+ "arch",
+ "eonix_preempt",
+ "intrusive-collections",
+]
+
+[[package]]
+name = "intrusive-collections"
+version = "0.9.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86"
+dependencies = [
+ "memoffset",
+]
+
+[[package]]
+name = "intrusive_list"
+version = "0.1.0"
+
+[[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "percpu-macros"
+version = "0.1.0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

+ 0 - 2
crates/eonix_mm/src/page_table/pte.rs

@@ -13,7 +13,6 @@ pub trait PageAttribute: Copy {
     fn global(self, global: bool) -> Self;
     fn copy_on_write(self, cow: bool) -> Self;
     fn mapped(self, mmap: bool) -> Self;
-    fn anonymous(self, anon: bool) -> Self;
 
     fn is_present(&self) -> bool;
     fn is_write(&self) -> bool;
@@ -24,7 +23,6 @@ pub trait PageAttribute: Copy {
     fn is_global(&self) -> bool;
     fn is_copy_on_write(&self) -> bool;
     fn is_mapped(&self) -> bool;
-    fn is_anonymous(&self) -> bool;
 }
 
 pub trait PTE: Sized {

+ 9 - 2
src/kernel/mem/mm_area.rs

@@ -5,6 +5,8 @@ use crate::KResult;
 use core::{borrow::Borrow, cell::UnsafeCell, cmp::Ordering};
 use eonix_mm::address::{AddrOps as _, VAddr, VRange};
 use eonix_mm::page_table::{PageAttribute, PTE};
+use eonix_mm::paging::PFN;
+use super::mm_list::EMPTY_PAGE;
 
 #[derive(Debug)]
 pub struct MMArea {
@@ -97,7 +99,7 @@ impl MMArea {
         }
 
         let new_page;
-        if page_attr.is_anonymous() {
+        if is_anonymous(pfn) {
             new_page = Page::zeroed();
         } else {
             new_page = Page::alloc();
@@ -114,7 +116,6 @@ impl MMArea {
         }
 
         page_attr = page_attr.accessed(false);
-        page_attr = page_attr.anonymous(false);
 
         pte.set(new_page.into_raw(), page_attr);
 
@@ -174,6 +175,12 @@ impl MMArea {
     }
 }
 
+/// check pfn with EMPTY_PAGE's pfn
+fn is_anonymous(pfn: PFN) -> bool {
+    let empty_pfn = EMPTY_PAGE.pfn();
+    pfn == empty_pfn
+}
+
 impl Eq for MMArea {}
 impl PartialEq for MMArea {
     fn eq(&self, other: &Self) -> bool {

+ 1 - 3
src/kernel/mem/mm_list.rs

@@ -26,7 +26,7 @@ use eonix_sync::{LazyLock, Mutex};
 pub use mapping::{FileMapping, Mapping};
 pub use page_fault::handle_page_fault;
 
-static EMPTY_PAGE: LazyLock<Page> = LazyLock::new(|| Page::zeroed());
+pub static EMPTY_PAGE: LazyLock<Page> = LazyLock::new(|| Page::zeroed());
 static KERNEL_ROOT_TABLE_PAGE: LazyLock<PageUnmanaged> = LazyLock::new(|| unsafe {
     // SAFETY: The kernel page table is always valid.
     PageUnmanaged::from_raw_unchecked(DefaultPagingMode::KERNEL_ROOT_TABLE_PFN)
@@ -591,7 +591,6 @@ where
             .present(true)
             .user(true)
             .copy_on_write(true)
-            .anonymous(true)
             .execute(execute);
 
         self.set(EMPTY_PAGE.clone().into_raw(), attr);
@@ -603,7 +602,6 @@ where
         let attr = <Self as PTE>::Attr::new()
             .user(true)
             .copy_on_write(true)
-            .anonymous(true)
             .mapped(true)
             .execute(execute);