Skip to content

Commit e1b24a3

Browse files
MRNIUclaude
andcommitted
fix(P3): add EXECUTE and GLOBAL flags to kernel page mappings
kernel_rw() lacked X (execute) and G (global) bits — Sv39 hardware checks X on instruction fetch, so enabling paging would immediately trigger an instruction page fault (scause=12). Add kernel_rwx() preset with V|R|W|X|G|A|D for the initial identity mapping, matching the C++ GetKernelPagePermissions() defaults. Also add GLOBAL to all kernel_* presets for TLB efficiency across ASID switches. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
1 parent e7e8298 commit e1b24a3

2 files changed

Lines changed: 36 additions & 10 deletions

File tree

src/memory/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ pub fn memory_init() {
7070
// Step 3: Create kernel page table with identity mapping
7171
let mut pt = PageTable::new().expect("failed to create kernel page table");
7272

73-
// Identity-map the entire physical memory region
73+
// Identity-map the entire physical memory region (RWX,初期不区分代码/数据段)
7474
identity_map_range(
7575
&mut pt,
7676
mem_start,
7777
mem_start + mem_size,
78-
PageFlags::kernel_rw(),
78+
PageFlags::kernel_rwx(),
7979
)
8080
.expect("failed to identity-map memory");
8181

src/memory/page_table.rs

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,36 @@ bitflags! {
3535
}
3636

3737
impl PageFlags {
38-
/// Kernel read-write data mapping (V | R | W | A | D).
38+
/// 内核读写数据映射 (V | R | W | G | A | D)
3939
#[inline]
4040
pub fn kernel_rw() -> Self {
41-
Self::VALID | Self::READ | Self::WRITE | Self::ACCESSED | Self::DIRTY
41+
Self::VALID | Self::READ | Self::WRITE | Self::GLOBAL | Self::ACCESSED | Self::DIRTY
4242
}
4343

44-
/// Kernel read-execute mapping (V | R | X | A).
44+
/// 内核读-执行映射 (V | R | X | G | A)。
4545
#[inline]
4646
pub fn kernel_rx() -> Self {
47-
Self::VALID | Self::READ | Self::EXECUTE | Self::ACCESSED
47+
Self::VALID | Self::READ | Self::EXECUTE | Self::GLOBAL | Self::ACCESSED
4848
}
4949

50-
/// Kernel read-only mapping (V | R | A).
50+
/// 内核只读映射 (V | R | G | A)。
5151
#[inline]
5252
pub fn kernel_ro() -> Self {
53-
Self::VALID | Self::READ | Self::ACCESSED
53+
Self::VALID | Self::READ | Self::GLOBAL | Self::ACCESSED
54+
}
55+
56+
/// 内核读写执行映射 (V | R | W | X | G | A | D)。
57+
///
58+
/// 用于初期 identity mapping,后续可细化为 text=RX, data=RW。
59+
#[inline]
60+
pub fn kernel_rwx() -> Self {
61+
Self::VALID
62+
| Self::READ
63+
| Self::WRITE
64+
| Self::EXECUTE
65+
| Self::GLOBAL
66+
| Self::ACCESSED
67+
| Self::DIRTY
5468
}
5569
}
5670

@@ -245,7 +259,7 @@ impl PageTableEntry {
245259

246260
#[cfg(not(test))]
247261
mod inner {
248-
use super::{PPN_MASK, PageFlags, PageTableEntry};
262+
use super::{PageFlags, PageTableEntry};
249263
use crate::config::PAGE_SIZE;
250264
use crate::error::{ErrorCode, KResult};
251265
use crate::memory::address::{PhysAddr, VirtAddr};
@@ -407,7 +421,7 @@ mod inner {
407421
}
408422

409423
#[cfg(not(test))]
410-
pub use inner::{ENTRIES_PER_PAGE, PT_LEVELS, PageTable};
424+
pub use inner::PageTable;
411425

412426
// ─────────────────────────────────────────────────────────────────────────────
413427
// activate_page_table
@@ -517,6 +531,7 @@ mod tests {
517531
assert!(rw.contains(PageFlags::VALID));
518532
assert!(rw.contains(PageFlags::READ));
519533
assert!(rw.contains(PageFlags::WRITE));
534+
assert!(rw.contains(PageFlags::GLOBAL));
520535
assert!(rw.contains(PageFlags::ACCESSED));
521536
assert!(rw.contains(PageFlags::DIRTY));
522537
assert!(!rw.contains(PageFlags::EXECUTE));
@@ -525,15 +540,26 @@ mod tests {
525540
assert!(rx.contains(PageFlags::VALID));
526541
assert!(rx.contains(PageFlags::READ));
527542
assert!(rx.contains(PageFlags::EXECUTE));
543+
assert!(rx.contains(PageFlags::GLOBAL));
528544
assert!(rx.contains(PageFlags::ACCESSED));
529545
assert!(!rx.contains(PageFlags::WRITE));
530546

531547
let ro = PageFlags::kernel_ro();
532548
assert!(ro.contains(PageFlags::VALID));
533549
assert!(ro.contains(PageFlags::READ));
550+
assert!(ro.contains(PageFlags::GLOBAL));
534551
assert!(ro.contains(PageFlags::ACCESSED));
535552
assert!(!ro.contains(PageFlags::WRITE));
536553
assert!(!ro.contains(PageFlags::EXECUTE));
554+
555+
let rwx = PageFlags::kernel_rwx();
556+
assert!(rwx.contains(PageFlags::VALID));
557+
assert!(rwx.contains(PageFlags::READ));
558+
assert!(rwx.contains(PageFlags::WRITE));
559+
assert!(rwx.contains(PageFlags::EXECUTE));
560+
assert!(rwx.contains(PageFlags::GLOBAL));
561+
assert!(rwx.contains(PageFlags::ACCESSED));
562+
assert!(rwx.contains(PageFlags::DIRTY));
537563
}
538564

539565
#[test]

0 commit comments

Comments
 (0)