base: enable executable memory fault handling

Fixes #1723
This commit is contained in:
Alexander Boettcher
2017-10-13 15:26:33 +02:00
committed by Christian Helmuth
parent 03b8e70d3f
commit db329b02b5
11 changed files with 77 additions and 32 deletions

View File

@ -65,6 +65,7 @@ class Genode::Rm_region : public List<Rm_region>::Element
addr_t _base = 0;
size_t _size = 0;
bool _write = false;
bool _exec = false;
Dataspace_component *_dsc = nullptr;
off_t _off = 0;
@ -80,8 +81,8 @@ class Genode::Rm_region : public List<Rm_region>::Element
Rm_region(addr_t base, size_t size, bool write,
Dataspace_component *dsc, off_t offset,
Region_map_component *rm)
: _base(base), _size(size), _write(write),
Region_map_component *rm, bool exec)
: _base(base), _size(size), _write(write), _exec(exec),
_dsc(dsc), _off(offset), _rm(rm) { }
@ -89,12 +90,13 @@ class Genode::Rm_region : public List<Rm_region>::Element
** Accessors **
***************/
addr_t base() const { return _base; }
size_t size() const { return _size; }
bool write() const { return _write; }
Dataspace_component* dataspace() const { return _dsc; }
off_t offset() const { return _off; }
Region_map_component* rm() const { return _rm; }
addr_t base() const { return _base; }
size_t size() const { return _size; }
bool write() const { return _write; }
bool executable() const { return _exec; }
Dataspace_component* dataspace() const { return _dsc; }
off_t offset() const { return _off; }
Region_map_component* rm() const { return _rm; }
};

View File

@ -156,8 +156,9 @@ static void print_page_fault(char const *msg,
Pager_object const &obj)
{
log(msg, " (",
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
" pf_addr=", Hex(pf_addr), " pf_ip=", Hex(pf_ip), " from ", obj, ")");
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" :
pf_type == Region_map::State::READ_FAULT ? "READ" : "EXEC",
" pf_addr=", Hex(pf_addr), " pf_ip=", Hex(pf_ip), " from ", obj, ") ");
}
@ -173,6 +174,9 @@ int Rm_client::pager(Ipc_pager &pager)
{
Region_map::State::Fault_type pf_type = pager.write_fault() ? Region_map::State::WRITE_FAULT
: Region_map::State::READ_FAULT;
if (pager.exec_fault())
pf_type = Region_map::State::EXEC_FAULT;
addr_t pf_addr = pager.fault_addr();
addr_t pf_ip = pager.fault_ip();
@ -211,7 +215,6 @@ int Rm_client::pager(Ipc_pager &pager)
*/
if (pf_type == Region_map::State::WRITE_FAULT && !dsc->writable()) {
/* attempted there is no attachment return an error condition */
print_page_fault("attempted write at read-only memory",
pf_addr, pf_ip, pf_type, *this);
@ -221,6 +224,17 @@ int Rm_client::pager(Ipc_pager &pager)
return 2;
}
if (pf_type == Region_map::State::EXEC_FAULT) {
print_page_fault("attempted exec at non-executable memory",
pf_addr, pf_ip, pf_type, *this);
/* register fault at responsible region map */
if (region_map)
region_map->fault(this, pf_addr - region_offset, pf_type);
return 3;
}
Mapping mapping = Region_map_component::create_map_item(region_map,
region,
ds_offset,
@ -323,7 +337,7 @@ Mapping Region_map_component::create_map_item(Region_map_component *region_map,
return Mapping(dst_fault_area.base(), src_fault_area.base(),
dsc->cacheability(), dsc->io_mem(),
map_size_log2, dsc->writable());
map_size_log2, dsc->writable(), region->executable());
};
@ -414,7 +428,7 @@ Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
/* store attachment info in meta data */
try {
_map.metadata(attach_at, Rm_region((addr_t)attach_at, size, true,
dsc, offset, this));
dsc, offset, this, executable));
} catch (Allocator_avl_tpl<Rm_region>::Assign_metadata_failed) {