mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 11:37:44 +00:00
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.
This commit is contained in:
parent
fb10774862
commit
ade27fa6b9
2 changed files with 48 additions and 16 deletions
|
@ -8,10 +8,12 @@
|
||||||
|
|
||||||
#include <AK/Platform.h>
|
#include <AK/Platform.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
#include <Kernel/ExecutionMode.h>
|
||||||
#include <Kernel/VirtualAddress.h>
|
#include <Kernel/VirtualAddress.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
// NOTE: These flags are x86_64 specific.
|
||||||
struct PageFaultFlags {
|
struct PageFaultFlags {
|
||||||
enum Flags {
|
enum Flags {
|
||||||
NotPresent = 0x00,
|
NotPresent = 0x00,
|
||||||
|
@ -28,8 +30,17 @@ struct PageFaultFlags {
|
||||||
class PageFault {
|
class PageFault {
|
||||||
public:
|
public:
|
||||||
PageFault(u16 code, VirtualAddress vaddr)
|
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; }
|
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); }
|
void set_type(Type type) { m_type = type; }
|
||||||
Access access() const { return (Access)(m_code & 2); }
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
bool is_not_present() const { return (m_code & 1) == PageFaultFlags::NotPresent; }
|
void set_access(Access access) { m_access = access; }
|
||||||
bool is_protection_violation() const { return (m_code & 1) == PageFaultFlags::ProtectionViolation; }
|
Access access() const { return m_access; }
|
||||||
bool is_read() const { return (m_code & 2) == PageFaultFlags::Read; }
|
|
||||||
bool is_write() const { return (m_code & 2) == PageFaultFlags::Write; }
|
void set_mode(ExecutionMode execution_mode) { m_execution_mode = execution_mode; }
|
||||||
bool is_user() const { return (m_code & 4) == PageFaultFlags::UserMode; }
|
ExecutionMode mode() const { return m_execution_mode; }
|
||||||
bool is_supervisor() const { return (m_code & 4) == PageFaultFlags::SupervisorMode; }
|
|
||||||
bool is_instruction_fetch() const { return (m_code & 16) == PageFaultFlags::InstructionFetch; }
|
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:
|
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;
|
VirtualAddress m_vaddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -263,9 +263,9 @@ void page_fault_handler(TrapFrame* trap)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgln("Unrecoverable page fault, {}{}{} address {}",
|
dbgln("Unrecoverable page fault, {}{}{} address {}",
|
||||||
regs.exception_code & PageFaultFlags::ReservedBitViolation ? "reserved bit violation / " : "",
|
fault.is_reserved_bit_violation() ? "reserved bit violation / " : "",
|
||||||
regs.exception_code & PageFaultFlags::InstructionFetch ? "instruction fetch / " : "",
|
fault.is_instruction_fetch() ? "instruction fetch / " : "",
|
||||||
regs.exception_code & PageFaultFlags::Write ? "write to" : "read from",
|
fault.is_write() ? "write to" : "read from",
|
||||||
VirtualAddress(fault_address));
|
VirtualAddress(fault_address));
|
||||||
constexpr FlatPtr malloc_scrub_pattern = explode_byte(MALLOC_SCRUB_BYTE);
|
constexpr FlatPtr malloc_scrub_pattern = explode_byte(MALLOC_SCRUB_BYTE);
|
||||||
constexpr FlatPtr free_scrub_pattern = explode_byte(FREE_SCRUB_BYTE);
|
constexpr FlatPtr free_scrub_pattern = explode_byte(FREE_SCRUB_BYTE);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue