mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
hw: evaluate write fault on RO page
rm_fault.run triggers write on read-only ROM provided by core, which fails without this patch: arm - "raised unhandled data abort" x86 - (silent/invisible) busy loop because write fault gets never resolved
This commit is contained in:
parent
5adda2d934
commit
de06eefbac
@ -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 */
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user