20 #include "pedigree/kernel/processor/PageFaultHandler.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/Subsystem.h" 23 #include "pedigree/kernel/debugger/Debugger.h" 24 #include "pedigree/kernel/panic.h" 25 #include "pedigree/kernel/process/Process.h" 26 #include "pedigree/kernel/process/Scheduler.h" 27 #include "pedigree/kernel/process/Thread.h" 28 #include "pedigree/kernel/processor/InterruptManager.h" 29 #include "pedigree/kernel/processor/MemoryRegion.h" 30 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 31 #include "pedigree/kernel/processor/Processor.h" 32 #include "pedigree/kernel/processor/ProcessorInformation.h" 33 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 34 #include "pedigree/kernel/processor/state.h" 35 #include "pedigree/kernel/utilities/Iterator.h" 36 #include "pedigree/kernel/utilities/StaticString.h" 37 #include "pedigree/kernel/utilities/utility.h" 41 #define PAGE_FAULT_EXCEPTION 0x0E 42 #define PFE_PAGE_PRESENT 0x01 43 #define PFE_ATTEMPTED_WRITE 0x02 44 #define PFE_USER_MODE 0x04 45 #define PFE_RESERVED_BIT 0x08 46 #define PFE_INSTRUCTION_FETCH 0x10 58 asm volatile(
"mov %%cr2, %%rax" :
"=a"(cr2));
59 code = state.m_Errorcode;
66 if (va.
isMapped(reinterpret_cast<void *>(page)))
68 physical_uintptr_t phys;
70 va.
getMapping(reinterpret_cast<void *>(page), phys, flags);
79 <<
" PageFaultHandler: copy-on-write for v=" <<
Hex << page);
91 "PageFaultHandler: CoW temporary map() failed @" <<
Hex 97 va.
unmap(reinterpret_cast<void *>(page));
98 physical_uintptr_t p =
102 FATAL(
"PageFaultHandler: CoW OOM'd!");
108 if (!va.
map(p, reinterpret_cast<void *>(page), flags))
110 FATAL(
"PageFaultHandler: CoW new map() failed.");
116 reinterpret_cast<uint8_t *>(page),
117 reinterpret_cast<uint8_t *>(tmpRegion.virtualAddress()),
137 it != m_Handlers.
end(); it++)
139 if ((*it)->trap(state, cr2, code & PFE_ATTEMPTED_WRITE))
151 sError.append(
"Page Fault Exception at 0x");
152 sError.append(cr2, 16, 16,
'0');
153 sError.append(
", EIP 0x");
154 sError.append(state.getInstructionPointer(), 16, 16,
'0');
155 sError.append(
", error code 0x");
156 sError.append(code, 16, 8,
'0');
161 sCode.append(
"Details: CPU=");
168 sCode.append(
" PID=");
169 sCode.append(pParent->
getId());
171 sCode.append(
" TID=");
172 sCode.append(pThread->
getId());
176 if (!(code & PFE_PAGE_PRESENT))
177 sCode.append(
"NOT ");
178 sCode.append(
"PRESENT | ");
180 if (code & PFE_ATTEMPTED_WRITE)
181 sCode.append(
"WRITE | ");
183 sCode.append(
"READ | ");
185 if (code & PFE_USER_MODE)
186 sCode.append(
"USER ");
188 sCode.append(
"KERNEL ");
189 sCode.append(
"MODE | ");
191 if (code & PFE_RESERVED_BIT)
192 sCode.append(
"RESERVED BIT SET | ");
193 if (code & PFE_INSTRUCTION_FETCH)
194 sCode.append(
"FETCH |");
199 ERROR(static_cast<const char *>(sError));
200 ERROR(static_cast<const char *>(sCode));
206 if (!(code & PFE_USER_MODE))
221 Subsystem *pSubsystem = pProcess->getSubsystem();
222 if (pSubsystem && !state.kernelMode())
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()
static const size_t continuous
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
static const size_t force
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 const size_t KernelMode
virtual bool memIsInKernelHeap(void *pMem)=0
Special memory entity in the kernel's virtual address space.
static const size_t anonymous
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