1#include "pedigree/kernel/Log.h"
2#include "pedigree/kernel/Metrics.h"
3#include "pedigree/kernel/Subsystem.h"
4#include "pedigree/kernel/panic.h"
5#include "pedigree/kernel/process/Process.h"
6#include "pedigree/kernel/process/Thread.h"
7#include "pedigree/kernel/processor/InterruptManager.h"
8#include "pedigree/kernel/processor/PageFaultHandler.h"
9#include "pedigree/kernel/processor/Processor.h"
10#include "pedigree/kernel/processor/VirtualAddressSpace.h"
11#include "pedigree/kernel/processor/state.h"
22 Metrics::increment(Metrics::PageFault);
25 const uintptr_t address = state.faultAddress;
26 const uintptr_t page = address & ~(PAGE_SIZE - 1);
27 const bool fetch = state.vector == 3;
28 const bool write = !fetch && (state.faultStatus & (1U << 11));
29 const size_t status = (state.faultStatus & 15) | ((state.faultStatus >> 6) & 16);
30 const bool present = status == 0xd || status == 0xf;
32 if (present && write &&
35 Metrics::increment(Metrics::PageFaultCopyOnWrite);
39 if (dispatchHandlers(state, address, write, present)) {
41 Metrics::increment(Metrics::PageFaultHandled);
47 if (thread && !state.kernelMode()) {
49 if (process && process->getSubsystem()) {
50 const uintptr_t errorCode = (present ? 1 : 0) | (write ? 2 : 0) | 4 | (fetch ? 16 : 0);
54 Metrics::increment(Metrics::PageFaultDeferred);
59 ERROR(
"ARMv7: page fault at " <<
Hex << address <<
" PC " << state.pc <<
" FSR "
60 << state.faultStatus);
61 panic(
"ARMv7: unrecoverable page fault");
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 ProcessorInformation & information()
static size_t m_Initialised
bool deferSubsystemException(size_t type, uintptr_t faultAddress, uintptr_t errorCode)
Process * getParent() const
virtual bool handleCopyOnWriteFault(void *virtualAddress, bool userMode)=0
void EXPORTED_PUBLIC panic(const char *msg) NORETURN