20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/Subsystem.h"
22#include "pedigree/kernel/debugger/Debugger.h"
23#include "pedigree/kernel/panic.h"
24#include "pedigree/kernel/process/Process.h"
25#include "pedigree/kernel/process/Scheduler.h"
26#include "pedigree/kernel/process/Thread.h"
27#include "pedigree/kernel/processor/InterruptManager.h"
28#include "pedigree/kernel/processor/PageFaultHandler.h"
29#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
30#include "pedigree/kernel/processor/Processor.h"
31#include "pedigree/kernel/processor/ProcessorInformation.h"
32#include "pedigree/kernel/processor/VirtualAddressSpace.h"
33#include "pedigree/kernel/processor/state.h"
34#include "pedigree/kernel/utilities/Iterator.h"
35#include "pedigree/kernel/utilities/StaticString.h"
36#include "pedigree/kernel/utilities/utility.h"
40#define PAGE_FAULT_EXCEPTION 0x0E
41#define PFE_PAGE_PRESENT 0x01
42#define PFE_ATTEMPTED_WRITE 0x02
43#define PFE_USER_MODE 0x04
44#define PFE_RESERVED_BIT 0x08
45#define PFE_INSTRUCTION_FETCH 0x10
46#define PFE_PROTECTION_KEY 0x20
47#define PFE_SHADOW_STACK 0x40
57 asm volatile(
"mov %%cr2, %%rax" :
"=a"(cr2));
58 code = state.m_Errorcode;
63 const bool copyOnWriteFault =
64 (code & (PFE_PAGE_PRESENT | PFE_ATTEMPTED_WRITE)) ==
65 (PFE_PAGE_PRESENT | PFE_ATTEMPTED_WRITE) &&
66 !(code & (PFE_RESERVED_BIT | PFE_INSTRUCTION_FETCH | PFE_PROTECTION_KEY | PFE_SHADOW_STACK));
67 if (copyOnWriteFault &&
75 if (dispatchHandlers(state, cr2, code & PFE_ATTEMPTED_WRITE, code & PFE_PAGE_PRESENT)) {
82 if (pThread && !state.kernelMode()) {
84 if (process && process->getSubsystem()) {
93 sError.append(
"Page Fault Exception at 0x");
94 sError.append(cr2, 16, 16,
'0');
95 sError.append(
", EIP 0x");
96 sError.append(state.getInstructionPointer(), 16, 16,
'0');
97 sError.append(
", error code 0x");
98 sError.append(code, 16, 8,
'0');
103 sCode.append(
"Details: CPU=");
108 sCode.append(
" PID=");
109 sCode.append(pParent->
getId());
111 sCode.append(
" TID=");
112 sCode.append(pThread->
getId());
116 if (!(code & PFE_PAGE_PRESENT))
117 sCode.append(
"NOT ");
118 sCode.append(
"PRESENT | ");
120 if (code & PFE_ATTEMPTED_WRITE)
121 sCode.append(
"WRITE | ");
123 sCode.append(
"READ | ");
125 if (code & PFE_USER_MODE)
126 sCode.append(
"USER ");
128 sCode.append(
"KERNEL ");
129 sCode.append(
"MODE | ");
131 if (code & PFE_RESERVED_BIT)
132 sCode.append(
"RESERVED BIT SET | ");
133 if (code & PFE_INSTRUCTION_FETCH)
134 sCode.append(
"FETCH |");
139 ERROR(
static_cast<const char*
>(sError));
140 ERROR(
static_cast<const char*
>(sCode));
146 if (!(code & PFE_USER_MODE))
158 Subsystem* pSubsystem = pProcess->getSubsystem();
159 if (!pSubsystem || state.kernelMode()) {
void start(InterruptState &state, LargeStaticString &description)
static Debugger & instance()
Handles interrupts and interrupt registrations from kernel components.
static EXPORTED_PUBLIC InterruptManager & instance()
virtual bool registerInterruptHandler(size_t nInterruptNumber, InterruptHandler *pHandler)=0
static EXPORTED_PUBLIC PageFaultHandler m_Instance
virtual void interrupt(size_t interruptNumber, InterruptState &state)
static PhysicalMemoryManager & instance()
static constexpr size_t getPageSize() PURE
static ProcessorInformation & information()
This class manages how processes and threads are scheduled across processors.
static Scheduler & instance()
bool deferSubsystemException(size_t type, uintptr_t faultAddress, uintptr_t errorCode)
Process * getParent() const
virtual bool handleCopyOnWriteFault(void *virtualAddress, bool userMode)=0
virtual bool memIsInKernelHeap(void *pMem)=0
void EXPORTED_PUBLIC panic(const char *msg) NORETURN