20 #include "pedigree/kernel/processor/PageFaultHandler.h" 21 #include "VirtualAddressSpace.h" 22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/debugger/Debugger.h" 24 #include "pedigree/kernel/panic.h" 25 #include "pedigree/kernel/process/Scheduler.h" 26 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 30 #define PAGE_FAULT_EXCEPTION 0x0E 31 #define PFE_PAGE_PRESENT 0x01 32 #define PFE_ATTEMPTED_WRITE 0x02 33 #define PFE_USER_MODE 0x04 34 #define PFE_RESERVED_BIT 0x08 35 #define PFE_INSTRUCTION_FETCH 0x10 47 asm volatile(
"mov %%cr2, %%eax" :
"=a"(cr2));
48 code = state.m_Errorcode;
55 if (va.
isMapped(reinterpret_cast<void *>(page)))
57 physical_uintptr_t phys;
59 va.
getMapping(reinterpret_cast<void *>(page), phys, flags);
68 <<
" PageFaultHandler: copy-on-write for v=" << page);
75 buffer, reinterpret_cast<uint8_t *>(page),
80 physical_uintptr_t p =
84 FATAL(
"PageFaultHandler: Out of memory!");
90 va.
unmap(reinterpret_cast<void *>(page));
94 if (!va.
map(p, reinterpret_cast<void *>(page), flags))
96 FATAL(
"PageFaultHandler: map() failed.");
102 reinterpret_cast<uint8_t *>(page), buffer,
112 if (cr2 < reinterpret_cast<uintptr_t>(KERNEL_SPACE_START))
116 it != m_Handlers.
end(); it++)
118 if ((*it)->trap(cr2, code & PFE_ATTEMPTED_WRITE))
128 sError.append(
"Page Fault Exception at 0x");
129 sError.append(cr2, 16, 8,
'0');
130 sError.append(
", error code 0x");
131 sError.append(code, 16, 8,
'0');
132 sError.append(
", EIP 0x");
133 sError.append(state.getInstructionPointer(), 16, 8,
'0');
138 sCode.append(
"Details: PID=");
143 if (!(code & PFE_PAGE_PRESENT))
144 sCode.append(
"NOT ");
145 sCode.append(
"PRESENT | ");
147 if (code & PFE_ATTEMPTED_WRITE)
148 sCode.append(
"WRITE | ");
150 sCode.append(
"READ | ");
152 if (code & PFE_USER_MODE)
153 sCode.append(
"USER ");
155 sCode.append(
"KERNEL ");
156 sCode.append(
"MODE | ");
158 if (code & PFE_RESERVED_BIT)
159 sCode.append(
"RESERVED BIT SET | ");
160 if (code & PFE_INSTRUCTION_FETCH)
161 sCode.append(
"FETCH |");
166 ERROR_NOLOCK(static_cast<const char *>(sError));
167 ERROR_NOLOCK(static_cast<const char *>(sCode));
171 uintptr_t physAddr = 0, flags = 0;
172 if (va.
isMapped(reinterpret_cast<void *>(state.getInstructionPointer())))
174 reinterpret_cast<void *>(state.getInstructionPointer()), physAddr,
179 if (!(code & PFE_USER_MODE))
196 Subsystem *pSubsystem = pProcess->getSubsystem();
virtual bool registerInterruptHandler(size_t nInterruptNumber, InterruptHandler *pHandler)=0
virtual void unmap(void *virtualAddress)=0
This class manages how processes and threads are scheduled across processors.
static size_t getPageSize() PURE
static PhysicalMemoryManager & instance()
virtual void getMapping(void *virtualAddress, physical_uintptr_t &physicalAddress, size_t &flags)=0
static Debugger & instance()
virtual physical_uintptr_t allocatePage(size_t pageConstraints=0)=0
virtual bool isMapped(void *virtualAddress)=0
virtual bool map(physical_uintptr_t physicalAddress, void *virtualAddress, size_t flags)=0
Handles interrupts and interrupt registrations from kernel components.
virtual void threadException(Thread *pThread, ExceptionType eType)
static ProcessorInformation & information()
virtual void interrupt(size_t interruptNumber, InterruptState &state)
static const size_t Write
void start(InterruptState &state, LargeStaticString &description)
static Scheduler & instance()
Process * getParent() const
PageFaultHandler() INITIALISATION_ONLY
virtual void freePage(physical_uintptr_t page)=0
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
static InterruptManager & instance()
static const size_t CopyOnWrite
static EXPORTED_PUBLIC PageFaultHandler m_Instance