Separate leaf page and directory pages USER flag
This is required for RISC-V. Privileged spec says: > For non-leaf PTEs, the D, A, and U bits are reserved for future standard use. > Until their use is defined by a standard extension, they must be cleared by software > for forward compatibility. QEMU fails address translation if it sees any of these flags set on non-leaf page entry.
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@ impl Arch for AArch64Arch {
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
const ENTRY_FLAG_READONLY: usize = 1 << 7;
|
||||
const ENTRY_FLAG_READWRITE: usize = 0;
|
||||
const ENTRY_FLAG_USER: usize = 1 << 6;
|
||||
const ENTRY_FLAG_PAGE_USER: usize = 1 << 6;
|
||||
// This sets both userspace and privileged execute never
|
||||
//TODO: Separate the two?
|
||||
const ENTRY_FLAG_NO_EXEC: usize = 0b11 << 53;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ impl Arch for EmulateArch {
|
||||
const ENTRY_FLAG_PRESENT: usize = X8664Arch::ENTRY_FLAG_PRESENT;
|
||||
const ENTRY_FLAG_READONLY: usize = X8664Arch::ENTRY_FLAG_READONLY;
|
||||
const ENTRY_FLAG_READWRITE: usize = X8664Arch::ENTRY_FLAG_READWRITE;
|
||||
const ENTRY_FLAG_USER: usize = X8664Arch::ENTRY_FLAG_USER;
|
||||
const ENTRY_FLAG_PAGE_USER: usize = X8664Arch::ENTRY_FLAG_PAGE_USER;
|
||||
const ENTRY_FLAG_NO_EXEC: usize = X8664Arch::ENTRY_FLAG_NO_EXEC;
|
||||
const ENTRY_FLAG_EXEC: usize = X8664Arch::ENTRY_FLAG_EXEC;
|
||||
|
||||
|
||||
+2
-1
@@ -36,7 +36,8 @@ pub trait Arch: Clone + Copy {
|
||||
const ENTRY_FLAG_PRESENT: usize;
|
||||
const ENTRY_FLAG_READONLY: usize;
|
||||
const ENTRY_FLAG_READWRITE: usize;
|
||||
const ENTRY_FLAG_USER: usize;
|
||||
const ENTRY_FLAG_PAGE_USER: usize; // Leaf table user page flag
|
||||
const ENTRY_FLAG_TABLE_USER: usize = Self::ENTRY_FLAG_PAGE_USER; // Directory user page table flag
|
||||
const ENTRY_FLAG_NO_EXEC: usize;
|
||||
const ENTRY_FLAG_EXEC: usize;
|
||||
const ENTRY_FLAG_GLOBAL: usize;
|
||||
|
||||
@@ -20,7 +20,8 @@ impl Arch for RiscV64Sv39Arch {
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
const ENTRY_FLAG_READWRITE: usize = 1 << 2;
|
||||
const ENTRY_FLAG_USER: usize = 1 << 4;
|
||||
const ENTRY_FLAG_PAGE_USER: usize = 1 << 4;
|
||||
const ENTRY_FLAG_TABLE_USER: usize = 0;
|
||||
const ENTRY_FLAG_NO_EXEC: usize = 0;
|
||||
const ENTRY_FLAG_EXEC: usize = 1 << 3;
|
||||
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
|
||||
|
||||
@@ -20,7 +20,8 @@ impl Arch for RiscV64Sv48Arch {
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
const ENTRY_FLAG_READWRITE: usize = 1 << 2;
|
||||
const ENTRY_FLAG_USER: usize = 1 << 4;
|
||||
const ENTRY_FLAG_PAGE_USER: usize = 1 << 4;
|
||||
const ENTRY_FLAG_TABLE_USER: usize = 0;
|
||||
const ENTRY_FLAG_NO_EXEC: usize = 0;
|
||||
const ENTRY_FLAG_EXEC: usize = 1 << 3;
|
||||
const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ impl Arch for X86Arch {
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
const ENTRY_FLAG_READWRITE: usize = 1 << 1;
|
||||
const ENTRY_FLAG_USER: usize = 1 << 2;
|
||||
const ENTRY_FLAG_PAGE_USER: usize = 1 << 2;
|
||||
// Not used: const ENTRY_FLAG_HUGE: usize = 1 << 7;
|
||||
const ENTRY_FLAG_GLOBAL: usize = 1 << 8;
|
||||
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ impl Arch for X8664Arch {
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
const ENTRY_FLAG_READWRITE: usize = 1 << 1;
|
||||
const ENTRY_FLAG_USER: usize = 1 << 2;
|
||||
const ENTRY_FLAG_PAGE_USER: usize = 1 << 2;
|
||||
// Not used: const ENTRY_FLAG_HUGE: usize = 1 << 7;
|
||||
const ENTRY_FLAG_GLOBAL: usize = 1 << 8;
|
||||
const ENTRY_FLAG_NO_GLOBAL: usize = 0;
|
||||
|
||||
+2
-2
@@ -72,12 +72,12 @@ impl<A: Arch> PageFlags<A> {
|
||||
#[must_use]
|
||||
#[inline(always)]
|
||||
pub fn user(self, value: bool) -> Self {
|
||||
self.custom_flag(A::ENTRY_FLAG_USER, value)
|
||||
self.custom_flag(A::ENTRY_FLAG_PAGE_USER, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn has_user(&self) -> bool {
|
||||
self.has_flag(A::ENTRY_FLAG_USER)
|
||||
self.has_flag(A::ENTRY_FLAG_PAGE_USER)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ impl<A: Arch, F: FrameAllocator> PageMapper<A, F> {
|
||||
let flags = A::ENTRY_FLAG_READWRITE
|
||||
| A::ENTRY_FLAG_DEFAULT_TABLE
|
||||
| if virt.kind() == TableKind::User {
|
||||
A::ENTRY_FLAG_USER
|
||||
A::ENTRY_FLAG_TABLE_USER
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user