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" 51 siginfo_t *info =
reinterpret_cast<siginfo_t *
>(state.getRegister(1));
53 uintptr_t page =
reinterpret_cast<uintptr_t
>(
page_align(info->si_addr));
54 uintptr_t unaligned_page =
reinterpret_cast<uintptr_t
>(info->si_addr);
55 uintptr_t code = info->si_code;
58 if (va.
isMapped(reinterpret_cast<void *>(page)))
60 physical_uintptr_t phys;
62 va.
getMapping(reinterpret_cast<void *>(page), phys, flags);
71 <<
" PageFaultHandler: copy-on-write for v=" << page);
80 uintptr_t tempAddr = 0;
85 phys, reinterpret_cast<void *>(tempAddr),
88 FATAL(
"PageFaultHandler: CoW temporary map() failed");
94 va.
unmap(reinterpret_cast<void *>(page));
97 physical_uintptr_t p =
101 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 *>(tempAddr), pageSz);
120 va.
unmap(reinterpret_cast<void *>(tempAddr));
130 if (page < reinterpret_cast<uintptr_t>(KERNEL_SPACE_START))
134 it != m_Handlers.end(); it++)
136 if ((*it)->trap(page, code == SEGV_ACCERR))
145 uintptr_t ucontext_loc = state.getRegister(2);
146 ucontext_t *ctx =
reinterpret_cast<ucontext_t *
>(ucontext_loc);
147 state.setInstructionPointer(ctx->uc_mcontext.gregs[REG_RIP]);
148 state.setStackPointer(ctx->uc_mcontext.gregs[REG_RSP]);
149 state.setBasePointer(ctx->uc_mcontext.gregs[REG_RBP]);
154 sError.append(
"Page Fault Exception at 0x");
155 sError.append(unaligned_page, 16, 8,
'0');
156 sError.append(
", error code 0x");
157 sError.append(code, 16, 8,
'0');
158 sError.append(
", EIP 0x");
159 sError.append(state.getInstructionPointer(), 16, 8,
'0');
164 sCode.append(
"Details: PID=");
169 if (code == SEGV_MAPERR)
170 sCode.append(
"NOT ");
171 sCode.append(
"PRESENT | ");
173 ERROR(static_cast<const char *>(sError));
174 ERROR(static_cast<const char *>(sCode));
177 if (state.kernelMode())
194 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)
void free(T address, T length, bool merge=true)
static ProcessorInformation & information()
bool allocate(T length, T &address)
virtual void interrupt(size_t interruptNumber, InterruptState &state)
static const size_t Write
void start(InterruptState &state, LargeStaticString &description)
static const size_t KernelMode
static Scheduler & instance()
Process * getParent() const
PageFaultHandler() INITIALISATION_ONLY
EXPORTED_PUBLIC void * page_align(void *p) PURE
virtual void freePage(physical_uintptr_t page)=0
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
static InterruptManager & instance()
static const size_t CopyOnWrite
MemoryAllocator & getSpaceAllocator()
static EXPORTED_PUBLIC PageFaultHandler m_Instance