From ade27fa6b93cfc018df5fd7e9756076747228ad3 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Sun, 8 Jan 2023 17:03:40 +0100 Subject: [PATCH] Kernel: Refactor PageFault for use in the aarch64 port The class used to look at the x86_64 specific exception code to figure out what kind of page fault happend, however this refactor allows aarch64 to use the same class. --- Kernel/Arch/PageFault.h | 58 ++++++++++++++++++++++++------- Kernel/Arch/x86_64/Interrupts.cpp | 6 ++-- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/Kernel/Arch/PageFault.h b/Kernel/Arch/PageFault.h index 1d939d8ea2..faa6fc4e1e 100644 --- a/Kernel/Arch/PageFault.h +++ b/Kernel/Arch/PageFault.h @@ -8,10 +8,12 @@ #include #include +#include #include namespace Kernel { +// NOTE: These flags are x86_64 specific. struct PageFaultFlags { enum Flags { NotPresent = 0x00, @@ -28,8 +30,17 @@ struct PageFaultFlags { class PageFault { public: PageFault(u16 code, VirtualAddress vaddr) - : m_code(code) - , m_vaddr(vaddr) + : m_vaddr(vaddr) + { + m_type = (Type)(code & PageFaultFlags::ProtectionViolation); + m_access = (Access)(code & PageFaultFlags::Write); + m_execution_mode = (code & PageFaultFlags::UserMode) != 0 ? ExecutionMode::User : ExecutionMode::Kernel; + m_is_reserved_bit_violation = (code & PageFaultFlags::ReservedBitViolation) != 0; + m_is_instruction_fetch = (code & PageFaultFlags::InstructionFetch) != 0; + } + + explicit PageFault(VirtualAddress vaddr) + : m_vaddr(vaddr) { } @@ -44,21 +55,42 @@ public: }; VirtualAddress vaddr() const { return m_vaddr; } - u16 code() const { return m_code; } + u16 code() const + { + u16 code = 0; + code |= (u16)m_type; + code |= (u16)m_access; + code |= m_execution_mode == ExecutionMode::User ? PageFaultFlags::UserMode : 0; + code |= m_is_reserved_bit_violation ? PageFaultFlags::ReservedBitViolation : 0; + code |= m_is_instruction_fetch ? PageFaultFlags::InstructionFetch : 0; + return code; + } - Type type() const { return (Type)(m_code & 1); } - Access access() const { return (Access)(m_code & 2); } + void set_type(Type type) { m_type = type; } + Type type() const { return m_type; } - 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; } - bool is_write() const { return (m_code & 2) == PageFaultFlags::Write; } - bool is_user() const { return (m_code & 4) == PageFaultFlags::UserMode; } - bool is_supervisor() const { return (m_code & 4) == PageFaultFlags::SupervisorMode; } - bool is_instruction_fetch() const { return (m_code & 16) == PageFaultFlags::InstructionFetch; } + void set_access(Access access) { m_access = access; } + Access access() const { return m_access; } + + void set_mode(ExecutionMode execution_mode) { m_execution_mode = execution_mode; } + ExecutionMode mode() const { return m_execution_mode; } + + bool is_not_present() const { return m_type == Type::PageNotPresent; } + bool is_protection_violation() const { return m_type == Type::ProtectionViolation; } + bool is_read() const { return m_access == Access::Read; } + bool is_write() const { return m_access == Access::Write; } + bool is_user() const { return m_execution_mode == ExecutionMode::User; } + bool is_kernel() const { return m_execution_mode == ExecutionMode::Kernel; } + bool is_reserved_bit_violation() const { return m_is_reserved_bit_violation; } + bool is_instruction_fetch() const { return m_is_instruction_fetch; } private: - u16 m_code; + Type m_type; + Access m_access; + ExecutionMode m_execution_mode; + bool m_is_reserved_bit_violation { false }; + bool m_is_instruction_fetch { false }; + VirtualAddress m_vaddr; }; diff --git a/Kernel/Arch/x86_64/Interrupts.cpp b/Kernel/Arch/x86_64/Interrupts.cpp index c889bb59bc..c9f98f3614 100644 --- a/Kernel/Arch/x86_64/Interrupts.cpp +++ b/Kernel/Arch/x86_64/Interrupts.cpp @@ -263,9 +263,9 @@ void page_fault_handler(TrapFrame* trap) } dbgln("Unrecoverable page fault, {}{}{} address {}", - regs.exception_code & PageFaultFlags::ReservedBitViolation ? "reserved bit violation / " : "", - regs.exception_code & PageFaultFlags::InstructionFetch ? "instruction fetch / " : "", - regs.exception_code & PageFaultFlags::Write ? "write to" : "read from", + fault.is_reserved_bit_violation() ? "reserved bit violation / " : "", + fault.is_instruction_fetch() ? "instruction fetch / " : "", + fault.is_write() ? "write to" : "read from", VirtualAddress(fault_address)); constexpr FlatPtr malloc_scrub_pattern = explode_byte(MALLOC_SCRUB_BYTE); constexpr FlatPtr free_scrub_pattern = explode_byte(FREE_SCRUB_BYTE);