Skip to content

Commit

Permalink
Kernel: Clean up the page fault handling code a bit
Browse files Browse the repository at this point in the history
Not using "else" after "return" unnests the code and makes it easier to
follow. Also use an enum for the two different page fault types.
  • Loading branch information
awesomekling committed Aug 6, 2019
1 parent f58b0c2 commit af4cf01
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 18 deletions.
7 changes: 7 additions & 0 deletions Kernel/Arch/i386/CPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,16 @@ class PageFault {
{
}

enum class Type {
PageNotPresent,
ProtectionViolation,
};

VirtualAddress vaddr() const { return m_vaddr; }
u16 code() const { return m_code; }

Type type() const { return (Type)(m_code & 1); }

bool is_not_present() const { return (m_code & 1) == PageFaultFlags::NotPresent; }
bool is_protection_violation() const { return (m_code & 1) == PageFaultFlags::ProtectionViolation; }
bool is_read() const { return (m_code & 2) == PageFaultFlags::Read; }
Expand Down
32 changes: 14 additions & 18 deletions Kernel/VM/MemoryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
dbgprintf("MM: handle_page_fault(%w) at L%x\n", fault.code(), fault.vaddr().get());
#endif
ASSERT(fault.vaddr() != m_quickmap_addr);
if (fault.is_not_present() && fault.vaddr().get() >= 0xc0000000) {
if (fault.type() == PageFault::Type::PageNotPresent && fault.vaddr().get() >= 0xc0000000) {
u32 page_directory_index = (fault.vaddr().get() >> 22) & 0x3ff;
auto& kernel_pde = kernel_page_directory().entries()[page_directory_index];
if (kernel_pde.is_present()) {
Expand All @@ -422,34 +422,30 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
return PageFaultResponse::ShouldCrash;
}
auto page_index_in_region = region->page_index_from_address(fault.vaddr());
if (fault.is_not_present()) {
if (fault.type() == PageFault::Type::PageNotPresent) {
if (region->vmo().inode()) {
#ifdef PAGE_FAULT_DEBUG
dbgprintf("NP(inode) fault in Region{%p}[%u]\n", region, page_index_in_region);
#endif
page_in_from_inode(*region, page_index_in_region);
return PageFaultResponse::Continue;
} else {
}
#ifdef PAGE_FAULT_DEBUG
dbgprintf("NP(zero) fault in Region{%p}[%u]\n", region, page_index_in_region);
dbgprintf("NP(zero) fault in Region{%p}[%u]\n", region, page_index_in_region);
#endif
zero_page(*region, page_index_in_region);
return PageFaultResponse::Continue;
}
} else if (fault.is_protection_violation()) {
if (region->should_cow(page_index_in_region)) {
zero_page(*region, page_index_in_region);
return PageFaultResponse::Continue;
}
ASSERT(fault.type() == PageFault::Type::ProtectionViolation);
if (region->should_cow(page_index_in_region)) {
#ifdef PAGE_FAULT_DEBUG
dbgprintf("PV(cow) fault in Region{%p}[%u]\n", region, page_index_in_region);
dbgprintf("PV(cow) fault in Region{%p}[%u]\n", region, page_index_in_region);
#endif
bool success = copy_on_write(*region, page_index_in_region);
ASSERT(success);
return PageFaultResponse::Continue;
}
kprintf("PV(error) fault in Region{%p}[%u] at L%x\n", region, page_index_in_region, fault.vaddr().get());
} else {
ASSERT_NOT_REACHED();
bool success = copy_on_write(*region, page_index_in_region);
ASSERT(success);
return PageFaultResponse::Continue;
}

kprintf("PV(error) fault in Region{%p}[%u] at L%x\n", region, page_index_in_region, fault.vaddr().get());
return PageFaultResponse::ShouldCrash;
}

Expand Down

0 comments on commit af4cf01

Please sign in to comment.