summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2023-01-08 17:03:40 +0100
committerAndreas Kling <kling@serenityos.org>2023-01-27 11:41:43 +0100
commitade27fa6b93cfc018df5fd7e9756076747228ad3 (patch)
tree630fa81bc315f73fe7e0d74ecf3e259fa7184622
parentfb1077486217917f41c4cd47df9502b51c622799 (diff)
downloadserenity-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.h58
-rw-r--r--Kernel/Arch/x86_64/Interrupts.cpp6
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);