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