mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 14:25:08 +00:00
Kernel: Add mapping from page directory base (PDB) to PageDirectory
This allows the page fault code to find the owning PageDirectory and corresponding process for faulting regions. The mapping is implemented as a global hash map right now, which is definitely not optimal. We can come up with something better when it becomes necessary.
This commit is contained in:
parent
8d07bce12a
commit
2ad963d261
5 changed files with 60 additions and 16 deletions
|
@ -257,7 +257,8 @@ void MemoryManager::initialize()
|
|||
|
||||
Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr)
|
||||
{
|
||||
ASSERT(vaddr.get() >= 0xc0000000);
|
||||
if (vaddr.get() < 0xc0000000)
|
||||
return nullptr;
|
||||
for (auto& region : MM.m_kernel_regions) {
|
||||
if (region->contains(vaddr))
|
||||
return region;
|
||||
|
@ -279,18 +280,15 @@ Region* MemoryManager::user_region_from_vaddr(Process& process, VirtualAddress v
|
|||
Region* MemoryManager::region_from_vaddr(Process& process, VirtualAddress vaddr)
|
||||
{
|
||||
ASSERT_INTERRUPTS_DISABLED();
|
||||
|
||||
if (vaddr.get() >= 0xc0000000)
|
||||
return kernel_region_from_vaddr(vaddr);
|
||||
|
||||
if (auto* region = kernel_region_from_vaddr(vaddr))
|
||||
return region;
|
||||
return user_region_from_vaddr(process, vaddr);
|
||||
}
|
||||
|
||||
const Region* MemoryManager::region_from_vaddr(const Process& process, VirtualAddress vaddr)
|
||||
{
|
||||
if (vaddr.get() >= 0xc0000000)
|
||||
return kernel_region_from_vaddr(vaddr);
|
||||
|
||||
if (auto* region = kernel_region_from_vaddr(vaddr))
|
||||
return region;
|
||||
return user_region_from_vaddr(const_cast<Process&>(process), vaddr);
|
||||
}
|
||||
|
||||
|
@ -398,6 +396,17 @@ bool MemoryManager::page_in_from_inode(Region& region, unsigned page_index_in_re
|
|||
return true;
|
||||
}
|
||||
|
||||
Region* MemoryManager::region_from_vaddr(VirtualAddress vaddr)
|
||||
{
|
||||
if (auto* region = kernel_region_from_vaddr(vaddr))
|
||||
return region;
|
||||
auto page_directory = PageDirectory::find_by_pdb(cpu_cr3());
|
||||
if (!page_directory)
|
||||
return nullptr;
|
||||
ASSERT(page_directory->process());
|
||||
return user_region_from_vaddr(*page_directory->process(), vaddr);
|
||||
}
|
||||
|
||||
PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
|
||||
{
|
||||
ASSERT_INTERRUPTS_DISABLED();
|
||||
|
@ -417,7 +426,7 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
|
|||
return PageFaultResponse::Continue;
|
||||
}
|
||||
}
|
||||
auto* region = region_from_vaddr(current->process(), fault.vaddr());
|
||||
auto* region = region_from_vaddr(fault.vaddr());
|
||||
if (!region) {
|
||||
kprintf("NP(error) fault at invalid address L%x\n", fault.vaddr().get());
|
||||
return PageFaultResponse::ShouldCrash;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue