From f51cd00f00f445b364f2dde5825acb3e15ad6d7e Mon Sep 17 00:00:00 2001 From: Andrey Turkin Date: Fri, 12 Jul 2024 08:58:01 +0300 Subject: [PATCH] Remove read/write flags from common PDE flags. RISC-V convention marks PDE with no read/write/execute, so we can't have none of this flags set there. Remove their setting from PDE handling code and instead set them as appropriate in arch-specific defaults. Also enable both readonly and readwrite flags to be non-zero (as long as their intersection completely masks both of them), as required for RISC-V PTE handling. --- src/arch/aarch64.rs | 1 + src/arch/riscv64/sv39.rs | 9 +++------ src/arch/riscv64/sv48.rs | 9 +++------ src/arch/x86.rs | 2 +- src/arch/x86_64.rs | 2 +- src/page/flags.rs | 18 ++++++++++-------- src/page/mapper.rs | 3 +-- 7 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/arch/aarch64.rs b/src/arch/aarch64.rs index 5999d60a44..82e4983183 100644 --- a/src/arch/aarch64.rs +++ b/src/arch/aarch64.rs @@ -18,6 +18,7 @@ impl Arch for AArch64Arch { | Self::ENTRY_FLAG_NO_GLOBAL; const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT + | Self::ENTRY_FLAG_READWRITE | 1 << 1 // Table flag | 1 << 10 // Access flag ; diff --git a/src/arch/riscv64/sv39.rs b/src/arch/riscv64/sv39.rs index f13e649ee4..607f4a2b1e 100644 --- a/src/arch/riscv64/sv39.rs +++ b/src/arch/riscv64/sv39.rs @@ -13,14 +13,11 @@ impl Arch for RiscV64Sv39Arch { const ENTRY_ADDRESS_WIDTH: usize = 44; const ENTRY_ADDRESS_SHIFT: usize = 10; - const ENTRY_FLAG_DEFAULT_PAGE: usize - = Self::ENTRY_FLAG_PRESENT - | 1 << 1 // Read flag - ; + const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READONLY; const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; const ENTRY_FLAG_PRESENT: usize = 1 << 0; - const ENTRY_FLAG_READONLY: usize = 0; - const ENTRY_FLAG_READWRITE: usize = 1 << 2; + const ENTRY_FLAG_READONLY: usize = 1 << 1; + const ENTRY_FLAG_READWRITE: usize = 3 << 1; const ENTRY_FLAG_PAGE_USER: usize = 1 << 4; const ENTRY_FLAG_TABLE_USER: usize = 0; const ENTRY_FLAG_NO_EXEC: usize = 0; diff --git a/src/arch/riscv64/sv48.rs b/src/arch/riscv64/sv48.rs index a63f887afd..e80e52a000 100644 --- a/src/arch/riscv64/sv48.rs +++ b/src/arch/riscv64/sv48.rs @@ -13,14 +13,11 @@ impl Arch for RiscV64Sv48Arch { const ENTRY_ADDRESS_WIDTH: usize = 44; const ENTRY_ADDRESS_SHIFT: usize = 10; - const ENTRY_FLAG_DEFAULT_PAGE: usize - = Self::ENTRY_FLAG_PRESENT - | 1 << 1 // Read flag - ; + const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READONLY; const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; const ENTRY_FLAG_PRESENT: usize = 1 << 0; - const ENTRY_FLAG_READONLY: usize = 0; - const ENTRY_FLAG_READWRITE: usize = 1 << 2; + const ENTRY_FLAG_READONLY: usize = 1 << 1; + const ENTRY_FLAG_READWRITE: usize = 3 << 1; const ENTRY_FLAG_PAGE_USER: usize = 1 << 4; const ENTRY_FLAG_TABLE_USER: usize = 0; const ENTRY_FLAG_NO_EXEC: usize = 0; diff --git a/src/arch/x86.rs b/src/arch/x86.rs index 3c4ac924f7..b0e333a342 100644 --- a/src/arch/x86.rs +++ b/src/arch/x86.rs @@ -13,7 +13,7 @@ impl Arch for X86Arch { const ENTRY_ADDRESS_WIDTH: usize = 20; const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT; - const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; + const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READWRITE; const ENTRY_FLAG_PRESENT: usize = 1 << 0; const ENTRY_FLAG_READONLY: usize = 0; const ENTRY_FLAG_READWRITE: usize = 1 << 1; diff --git a/src/arch/x86_64.rs b/src/arch/x86_64.rs index 316323adc3..25fa84691d 100644 --- a/src/arch/x86_64.rs +++ b/src/arch/x86_64.rs @@ -12,7 +12,7 @@ impl Arch for X8664Arch { const ENTRY_ADDRESS_WIDTH: usize = 40; const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT; - const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; + const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT | Self::ENTRY_FLAG_READWRITE; const ENTRY_FLAG_PRESENT: usize = 1 << 0; const ENTRY_FLAG_READONLY: usize = 0; const ENTRY_FLAG_READWRITE: usize = 1 << 1; diff --git a/src/page/flags.rs b/src/page/flags.rs index ca03d1ce0f..9de75484ef 100644 --- a/src/page/flags.rs +++ b/src/page/flags.rs @@ -27,10 +27,7 @@ impl PageFlags { unsafe { Self::from_data( // Flags set to present, kernel space, read-only, no-execute by default - A::ENTRY_FLAG_DEFAULT_TABLE - | A::ENTRY_FLAG_READONLY - | A::ENTRY_FLAG_NO_EXEC - | A::ENTRY_FLAG_NO_GLOBAL, + A::ENTRY_FLAG_DEFAULT_TABLE | A::ENTRY_FLAG_NO_EXEC | A::ENTRY_FLAG_NO_GLOBAL, ) } } @@ -83,14 +80,19 @@ impl PageFlags { #[must_use] #[inline(always)] pub fn write(self, value: bool) -> Self { - // Architecture may use readonly or readwrite, support either - self.custom_flag(A::ENTRY_FLAG_READONLY, !value) - .custom_flag(A::ENTRY_FLAG_READWRITE, value) + // Architecture may use readonly or readwrite, or both, support either + if value { + self.custom_flag(A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE, false) + .custom_flag(A::ENTRY_FLAG_READWRITE, true) + } else { + self.custom_flag(A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE, false) + .custom_flag(A::ENTRY_FLAG_READONLY, true) + } } #[inline(always)] pub fn has_write(&self) -> bool { - // Architecture may use readonly or readwrite, support either + // Architecture may use readonly or readwrite, or both, support either self.data & (A::ENTRY_FLAG_READONLY | A::ENTRY_FLAG_READWRITE) == A::ENTRY_FLAG_READWRITE } diff --git a/src/page/mapper.rs b/src/page/mapper.rs index 842d5b1125..a6aa726be8 100644 --- a/src/page/mapper.rs +++ b/src/page/mapper.rs @@ -120,8 +120,7 @@ impl PageMapper { None => { let next_phys = self.allocator.allocate_one()?; //TODO: correct flags? - let flags = A::ENTRY_FLAG_READWRITE - | A::ENTRY_FLAG_DEFAULT_TABLE + let flags = A::ENTRY_FLAG_DEFAULT_TABLE | if virt.kind() == TableKind::User { A::ENTRY_FLAG_TABLE_USER } else {