mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 18:32:28 -05:00
52deb09382
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.
43 lines
1.4 KiB
C++
43 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <AK/HashMap.h>
|
|
#include <AK/RefCounted.h>
|
|
#include <AK/RefPtr.h>
|
|
#include <Kernel/VM/PhysicalPage.h>
|
|
#include <Kernel/VM/RangeAllocator.h>
|
|
|
|
class Process;
|
|
|
|
class PageDirectory : public RefCounted<PageDirectory> {
|
|
friend class MemoryManager;
|
|
|
|
public:
|
|
static NonnullRefPtr<PageDirectory> create_for_userspace(Process& process, const RangeAllocator* parent_range_allocator = nullptr)
|
|
{
|
|
return adopt(*new PageDirectory(process, parent_range_allocator));
|
|
}
|
|
static NonnullRefPtr<PageDirectory> create_at_fixed_address(PhysicalAddress paddr) { return adopt(*new PageDirectory(paddr)); }
|
|
static RefPtr<PageDirectory> find_by_cr3(u32);
|
|
|
|
~PageDirectory();
|
|
|
|
u32 cr3() const { return m_directory_table->paddr().get(); }
|
|
PageDirectoryPointerTable& table() { return *reinterpret_cast<PageDirectoryPointerTable*>(cr3()); }
|
|
|
|
void flush(VirtualAddress);
|
|
|
|
RangeAllocator& range_allocator() { return m_range_allocator; }
|
|
|
|
Process* process() { return m_process; }
|
|
const Process* process() const { return m_process; }
|
|
|
|
private:
|
|
PageDirectory(Process&, const RangeAllocator* parent_range_allocator);
|
|
explicit PageDirectory(PhysicalAddress);
|
|
|
|
Process* m_process { nullptr };
|
|
RangeAllocator m_range_allocator;
|
|
RefPtr<PhysicalPage> m_directory_table;
|
|
RefPtr<PhysicalPage> m_directory_pages[4];
|
|
HashMap<unsigned, RefPtr<PhysicalPage>> m_physical_pages;
|
|
};
|