mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 17:47:36 +00:00
Kernel: Enable PAE (Physical Address Extension)
Introduce one more (CPU) indirection layer in the paging code: the page directory pointer table (PDPT). Each PageDirectory now has 4 separate PageDirectoryEntry arrays, governing 1 GB of VM each. A really neat side-effect of this is that we can now share the physical page containing the >=3GB kernel-only address space metadata between all processes, instead of lazily cloning it on page faults. This will give us access to the NX (No eXecute) bit, allowing us to prevent execution of memory that's not supposed to be executed.
This commit is contained in:
parent
4883176fd8
commit
52deb09382
7 changed files with 84 additions and 81 deletions
|
@ -9,6 +9,7 @@
|
|||
#define PAGE_MASK 0xfffff000
|
||||
|
||||
class MemoryManager;
|
||||
class PageDirectory;
|
||||
class PageTableEntry;
|
||||
|
||||
struct [[gnu::packed]] TSS32
|
||||
|
@ -89,12 +90,12 @@ public:
|
|||
PageTableEntry* page_table_base() { return reinterpret_cast<PageTableEntry*>(m_raw & 0xfffff000u); }
|
||||
void set_page_table_base(u32 value)
|
||||
{
|
||||
m_raw &= 0xfff;
|
||||
m_raw &= 0x8000000000000fffULL;
|
||||
m_raw |= value & 0xfffff000;
|
||||
}
|
||||
|
||||
u32 raw() const { return m_raw; }
|
||||
void copy_from(Badge<MemoryManager>, const PageDirectoryEntry& other) { m_raw = other.m_raw; }
|
||||
u64 raw() const { return m_raw; }
|
||||
void copy_from(Badge<PageDirectory>, const PageDirectoryEntry& other) { m_raw = other.m_raw; }
|
||||
|
||||
enum Flags {
|
||||
Present = 1 << 0,
|
||||
|
@ -103,6 +104,7 @@ public:
|
|||
WriteThrough = 1 << 3,
|
||||
CacheDisabled = 1 << 4,
|
||||
Global = 1 << 8,
|
||||
NoExecute = 0x8000000000000000ULL,
|
||||
};
|
||||
|
||||
bool is_present() const { return raw() & Present; }
|
||||
|
@ -123,7 +125,10 @@ public:
|
|||
bool is_global() const { return raw() & Global; }
|
||||
void set_global(bool b) { set_bit(Global, b); }
|
||||
|
||||
void set_bit(u32 bit, bool value)
|
||||
bool is_execute_disabled() const { return raw() & NoExecute; }
|
||||
void set_execute_disabled(bool b) { set_bit(NoExecute, b); }
|
||||
|
||||
void set_bit(u64 bit, bool value)
|
||||
{
|
||||
if (value)
|
||||
m_raw |= bit;
|
||||
|
@ -132,7 +137,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
u32 m_raw;
|
||||
u64 m_raw;
|
||||
};
|
||||
|
||||
class PageTableEntry {
|
||||
|
@ -140,11 +145,11 @@ public:
|
|||
void* physical_page_base() { return reinterpret_cast<void*>(m_raw & 0xfffff000u); }
|
||||
void set_physical_page_base(u32 value)
|
||||
{
|
||||
m_raw &= 0xfff;
|
||||
m_raw &= 0x8000000000000fffULL;
|
||||
m_raw |= value & 0xfffff000;
|
||||
}
|
||||
|
||||
u32 raw() const { return m_raw; }
|
||||
u64 raw() const { return (u32)m_raw; }
|
||||
|
||||
enum Flags {
|
||||
Present = 1 << 0,
|
||||
|
@ -153,6 +158,7 @@ public:
|
|||
WriteThrough = 1 << 3,
|
||||
CacheDisabled = 1 << 4,
|
||||
Global = 1 << 8,
|
||||
NoExecute = 0x8000000000000000ULL,
|
||||
};
|
||||
|
||||
bool is_present() const { return raw() & Present; }
|
||||
|
@ -173,7 +179,10 @@ public:
|
|||
bool is_global() const { return raw() & Global; }
|
||||
void set_global(bool b) { set_bit(Global, b); }
|
||||
|
||||
void set_bit(u32 bit, bool value)
|
||||
bool is_execute_disabled() const { return raw() & NoExecute; }
|
||||
void set_execute_disabled(bool b) { set_bit(NoExecute, b); }
|
||||
|
||||
void set_bit(u64 bit, bool value)
|
||||
{
|
||||
if (value)
|
||||
m_raw |= bit;
|
||||
|
@ -182,11 +191,21 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
u32 m_raw;
|
||||
u64 m_raw;
|
||||
};
|
||||
|
||||
static_assert(sizeof(PageDirectoryEntry) == 4);
|
||||
static_assert(sizeof(PageTableEntry) == 4);
|
||||
static_assert(sizeof(PageDirectoryEntry) == 8);
|
||||
static_assert(sizeof(PageTableEntry) == 8);
|
||||
|
||||
class PageDirectoryPointerTable {
|
||||
public:
|
||||
PageDirectoryEntry* directory(size_t index)
|
||||
{
|
||||
return (PageDirectoryEntry*)(raw[index] & ~0xfffu);
|
||||
}
|
||||
|
||||
u64 raw[4];
|
||||
};
|
||||
|
||||
class IRQHandler;
|
||||
struct RegisterDump;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue