mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
parent
24a2b15eec
commit
a8ed11e75b
@ -93,6 +93,7 @@ class Genode::Ipc_pager : public Native_capability
|
||||
addr_t _fault_type = 0; /* type of fault */
|
||||
bool _pf_write = false; /* true on write fault */
|
||||
bool _pf_exec = false; /* true on exec fault */
|
||||
bool _pf_align = false; /* true on unaligned fault */
|
||||
|
||||
Mapping _reply_mapping { };
|
||||
|
||||
@ -151,6 +152,16 @@ class Genode::Ipc_pager : public Native_capability
|
||||
* Return true if page fault was on non-executable memory
|
||||
*/
|
||||
bool exec_fault() const { return _pf_exec; }
|
||||
|
||||
/**
|
||||
* Return true if page fault was due to unaligned memory access
|
||||
*/
|
||||
bool align_fault() const { return _pf_align; }
|
||||
|
||||
/**
|
||||
* Install memory mapping after pager code executed.
|
||||
*/
|
||||
bool install_mapping();
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__IPC_PAGER_H_ */
|
||||
|
@ -389,22 +389,30 @@ class Genode::Vm_space
|
||||
_cap_sel_alloc.free(_vm_pad_cnode.sel());
|
||||
}
|
||||
|
||||
void map(addr_t const from_phys, addr_t const to_virt,
|
||||
bool map(addr_t const from_phys, addr_t const to_virt,
|
||||
size_t const num_pages, Cache_attribute const cacheability,
|
||||
bool const writable, bool const executable, bool flush_support)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
bool ok = true;
|
||||
|
||||
for (size_t i = 0; i < num_pages; i++) {
|
||||
off_t const offset = i << get_page_size_log2();
|
||||
|
||||
if (!_map_frame(from_phys + offset, to_virt + offset,
|
||||
cacheability, writable, executable,
|
||||
flush_support))
|
||||
warning("mapping failed ", Hex(from_phys + offset),
|
||||
" -> ", Hex(to_virt + offset), " ",
|
||||
!flush_support ? "core" : "");
|
||||
if (_map_frame(from_phys + offset, to_virt + offset,
|
||||
cacheability, writable, executable,
|
||||
flush_support))
|
||||
continue;
|
||||
|
||||
ok = false;
|
||||
|
||||
warning("mapping failed ", Hex(from_phys + offset),
|
||||
" -> ", Hex(to_virt + offset), " ",
|
||||
!flush_support ? "core" : "");
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool unmap(addr_t const virt, size_t const num_pages,
|
||||
|
@ -47,12 +47,14 @@ void Ipc_pager::wait_for_fault()
|
||||
reply_and_wait_for_fault();
|
||||
}
|
||||
|
||||
bool Ipc_pager::install_mapping()
|
||||
{
|
||||
_badge = Genode::install_mapping(_reply_mapping, _badge);
|
||||
return _badge;
|
||||
}
|
||||
|
||||
void Ipc_pager::reply_and_wait_for_fault()
|
||||
{
|
||||
if (_badge)
|
||||
_badge = install_mapping(_reply_mapping, _badge);
|
||||
|
||||
seL4_Word badge = Rpc_obj_key::INVALID;
|
||||
|
||||
seL4_MessageInfo_t page_fault_msg_info;
|
||||
@ -76,6 +78,7 @@ void Ipc_pager::reply_and_wait_for_fault()
|
||||
_pf_write = fault_info.write;
|
||||
_pf_exec = fault_info.exec_fault();
|
||||
_fault_type = seL4_MessageInfo_get_label(page_fault_msg_info);
|
||||
_pf_align = fault_info.align_fault();
|
||||
|
||||
_badge = badge;
|
||||
}
|
||||
@ -187,6 +190,23 @@ void Pager_entrypoint::entry()
|
||||
" ip=", Hex(_pager.fault_ip()),
|
||||
" pf-addr=", Hex(_pager.fault_addr()));
|
||||
_pager.reply_save_caller(obj->reply_cap_sel());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
/* install memory mappings */
|
||||
if (_pager.install_mapping())
|
||||
return;
|
||||
|
||||
/* on alignment fault don't reply and submit signal */
|
||||
if (_pager.align_fault()) {
|
||||
warning("alignment fault, addr=", Hex(_pager.fault_addr()),
|
||||
" ip=", Hex(_pager.fault_ip()));
|
||||
throw 1;
|
||||
}
|
||||
} catch (...) {
|
||||
reply_pending = false;
|
||||
obj->submit_exception_signal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -160,10 +160,14 @@ bool Platform_pd::install_mapping(Mapping const &mapping,
|
||||
_vm_space.alloc_page_tables(mapping.to_virt(),
|
||||
mapping.num_pages() * get_page_size());
|
||||
|
||||
_vm_space.map(mapping.from_phys(), mapping.to_virt(),
|
||||
mapping.num_pages(), mapping.cacheability(),
|
||||
mapping.writeable(), mapping.executable(), FLUSHABLE);
|
||||
return true;
|
||||
if (_vm_space.map(mapping.from_phys(), mapping.to_virt(),
|
||||
mapping.num_pages(), mapping.cacheability(),
|
||||
mapping.writeable(), mapping.executable(), FLUSHABLE))
|
||||
return true;
|
||||
|
||||
Genode::warning("mapping failure for thread '", thread_name,
|
||||
"' in pd '", _vm_space.pd_label(), "'");
|
||||
return false;
|
||||
} catch (...) {
|
||||
char const * fault_name = "unknown";
|
||||
|
||||
@ -185,11 +189,12 @@ bool Platform_pd::install_mapping(Mapping const &mapping,
|
||||
break;
|
||||
}
|
||||
|
||||
/* pager ep would die when we re-throw - let core survive */
|
||||
Genode::error("unexpected exception during fault '", fault_name, "'",
|
||||
" - thread '", thread_name, "' in pd '",
|
||||
_vm_space.pd_label(),"' stopped");
|
||||
return false;
|
||||
|
||||
/* catched by Pager_entrypoint::entry() in base-sel4/pager.cc */
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,14 +13,16 @@
|
||||
|
||||
struct Fault_info
|
||||
{
|
||||
Genode::addr_t ip = 0;
|
||||
Genode::addr_t pf = 0;
|
||||
bool data_abort = 0;
|
||||
bool write = 0;
|
||||
Genode::addr_t const ip;
|
||||
Genode::addr_t const pf;
|
||||
bool data_abort;
|
||||
bool const write;
|
||||
bool const align;
|
||||
|
||||
enum {
|
||||
IFSR_FAULT = 1,
|
||||
IFSR_FAULT_PERMISSION = 0xf,
|
||||
DFSR_ALIGN_FAULT = 1UL << 0,
|
||||
DFSR_WRITE_FAULT = 1UL << 11
|
||||
};
|
||||
|
||||
@ -30,11 +32,13 @@ struct Fault_info
|
||||
pf(seL4_GetMR(1)),
|
||||
data_abort(seL4_GetMR(2) != IFSR_FAULT),
|
||||
/* Instruction Fault Status Register (IFSR) resp. Data FSR (DFSR) */
|
||||
write(data_abort && (seL4_GetMR(3) & DFSR_WRITE_FAULT))
|
||||
write(data_abort && (seL4_GetMR(3) & DFSR_WRITE_FAULT)),
|
||||
align(data_abort && (seL4_GetMR(3) == DFSR_ALIGN_FAULT))
|
||||
{
|
||||
if (!data_abort && seL4_GetMR(3) != IFSR_FAULT_PERMISSION)
|
||||
data_abort = true;
|
||||
}
|
||||
|
||||
bool exec_fault() const { return !data_abort; }
|
||||
bool align_fault() const { return align; }
|
||||
};
|
||||
|
@ -37,4 +37,5 @@ struct Fault_info
|
||||
{ }
|
||||
|
||||
bool exec_fault() const { return false; }
|
||||
bool align_fault() const { return false; }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user