diff --git a/repos/base-hw/src/core/spec/arm/cpu_support.h b/repos/base-hw/src/core/spec/arm/cpu_support.h index 210ba7eca0..9eea79a152 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/spec/arm/cpu_support.h @@ -148,8 +148,12 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu */ bool in_fault(addr_t & va, addr_t & w) const { - static constexpr Fsr::access_t section = 5; - static constexpr Fsr::access_t page = 7; + /* translation fault on section */ + static constexpr Fsr::access_t section = 5; + /* translation fault on page */ + static constexpr Fsr::access_t page = 7; + /* permission fault on page */ + static constexpr Fsr::access_t permission = 0xf; switch (cpu_exception) { @@ -167,9 +171,9 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu } case DATA_ABORT: { - /* check if fault was caused by translation miss */ + /* check if fault is of known type */ Dfsr::access_t const fs = Fsr::Fs::get(Dfsr::read()); - if (fs != section && fs != page) + if (fs != permission && fs != section && fs != page) return false; /* fetch fault data */ diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu.h b/repos/base-hw/src/core/spec/cortex_a15/cpu.h index fa67f0cfcc..317e7014fa 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/cpu.h +++ b/repos/base-hw/src/core/spec/cortex_a15/cpu.h @@ -203,6 +203,9 @@ class Genode::Cpu : public Arm_v7_cpu */ bool in_fault(addr_t & va, addr_t & w) const { + /* permission fault on page, 2nd level */ + static constexpr Fsr::access_t permission = 0b1111; + switch (cpu_exception) { case PREFETCH_ABORT: @@ -221,7 +224,8 @@ class Genode::Cpu : public Arm_v7_cpu { /* check if fault was caused by translation miss */ Fsr::access_t const fs = Fsr::Fs::get(Dfsr::read()); - if ((fs & 0b11100) != 0b100) return false; + if ((fs != permission) && (fs & 0b11100) != 0b100) + return false; /* fetch fault data */ Dfsr::access_t const dfsr = Dfsr::read(); diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc b/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc index 43580856b3..7eca97680e 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc @@ -24,11 +24,25 @@ void Kernel::Thread::_call_update_data_region() { } void Kernel::Thread::_call_update_instr_region() { } +/* + * Intel manual: 6.15 EXCEPTION AND INTERRUPT REFERENCE + * Interrupt 14—Page-Fault Exception (#PF) + */ +enum { + ERR_I = 1UL << 4, + ERR_R = 1UL << 3, + ERR_U = 1UL << 2, + ERR_W = 1UL << 1, + ERR_P = 1UL << 0, +}; + + void Kernel::Thread::_mmu_exception() { _become_inactive(AWAITS_RESTART); _fault_pd = (addr_t)_pd->platform_pd(); _fault_addr = Cpu::Cr2::read(); + _fault_writes = (errcode & ERR_P) && (errcode & ERR_W); /* * Core should never raise a page-fault. If this happens, print out an