diff options
author | Timon Kruiper <timonkruiper@gmail.com> | 2023-01-08 17:03:40 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-01-27 11:41:43 +0100 |
commit | ade27fa6b93cfc018df5fd7e9756076747228ad3 (patch) | |
tree | 630fa81bc315f73fe7e0d74ecf3e259fa7184622 | |
parent | fb1077486217917f41c4cd47df9502b51c622799 (diff) | |
download | serenity-ade27fa6b93cfc018df5fd7e9756076747228ad3.zip |
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.
-rw-r--r-- | Kernel/Arch/PageFault.h | 58 | ||||
-rw-r--r-- | 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 <AK/Platform.h> #include <AK/Types.h> +#include <Kernel/ExecutionMode.h> #include <Kernel/VirtualAddress.h> 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; + } + + void set_type(Type type) { m_type = type; } + Type type() const { return m_type; } - Type type() const { return (Type)(m_code & 1); } - Access access() const { return (Access)(m_code & 2); } + void set_access(Access access) { m_access = access; } + Access access() const { return m_access; } - 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_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); |