mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
parent
03b8e70d3f
commit
db329b02b5
@ -48,11 +48,10 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute cacheability, bool io_mem,
|
Cache_attribute cacheability, bool io_mem,
|
||||||
unsigned l2size = L4_LOG2_PAGESIZE,
|
unsigned l2size, bool rw, bool executable)
|
||||||
bool rw = true, bool grant = false)
|
|
||||||
:
|
:
|
||||||
_dst_addr(dst_addr),
|
_dst_addr(dst_addr),
|
||||||
_fpage(Fiasco::l4_fpage(src_addr, l2size, rw, grant))
|
_fpage(Fiasco::l4_fpage(src_addr, l2size, rw, false))
|
||||||
{
|
{
|
||||||
if (cacheability == WRITE_COMBINED)
|
if (cacheability == WRITE_COMBINED)
|
||||||
_fpage.fp.cache = Fiasco::L4_FPAGE_BUFFERABLE;
|
_fpage.fp.cache = Fiasco::L4_FPAGE_BUFFERABLE;
|
||||||
@ -163,6 +162,8 @@ namespace Genode {
|
|||||||
|
|
||||||
bool write_fault() const { return (_pf_addr & 2); }
|
bool write_fault() const { return (_pf_addr & 2); }
|
||||||
|
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if last fault was an exception
|
* Return true if last fault was an exception
|
||||||
*/
|
*/
|
||||||
|
@ -45,7 +45,6 @@ namespace Genode {
|
|||||||
bool _iomem;
|
bool _iomem;
|
||||||
unsigned _log2size;
|
unsigned _log2size;
|
||||||
bool _rw;
|
bool _rw;
|
||||||
bool _grant;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -54,20 +53,20 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute c, bool io_mem,
|
Cache_attribute c, bool io_mem,
|
||||||
unsigned l2size = L4_LOG2_PAGESIZE,
|
unsigned l2size,
|
||||||
bool rw = true, bool grant = false)
|
bool rw, bool executable)
|
||||||
: _dst_addr(dst_addr), _src_addr(src_addr),
|
: _dst_addr(dst_addr), _src_addr(src_addr),
|
||||||
_cacheability(c), _iomem(io_mem), _log2size(l2size),
|
_cacheability(c), _iomem(io_mem), _log2size(l2size),
|
||||||
_rw(rw), _grant(grant) { }
|
_rw(rw) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct invalid flexpage
|
* Construct invalid flexpage
|
||||||
*/
|
*/
|
||||||
Mapping() : _dst_addr(0), _src_addr(0), _cacheability(UNCACHED),
|
Mapping() : _dst_addr(0), _src_addr(0), _cacheability(UNCACHED),
|
||||||
_iomem(false), _log2size(0), _rw(false), _grant(false) { }
|
_iomem(false), _log2size(0), _rw(false) { }
|
||||||
|
|
||||||
Fiasco::l4_umword_t dst_addr() const { return _dst_addr; }
|
Fiasco::l4_umword_t dst_addr() const { return _dst_addr; }
|
||||||
bool grant() const { return _grant; }
|
bool grant() const { return false; }
|
||||||
|
|
||||||
Fiasco::l4_fpage_t fpage() const
|
Fiasco::l4_fpage_t fpage() const
|
||||||
{
|
{
|
||||||
@ -176,6 +175,8 @@ namespace Genode {
|
|||||||
|
|
||||||
bool write_fault() const { return (_pf_addr & 2); }
|
bool write_fault() const { return (_pf_addr & 2); }
|
||||||
|
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if last fault was an exception
|
* Return true if last fault was an exception
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +65,8 @@ struct Genode::Mapping : Hw::Mapping
|
|||||||
Cache_attribute cacheable,
|
Cache_attribute cacheable,
|
||||||
bool io,
|
bool io,
|
||||||
unsigned size_log2,
|
unsigned size_log2,
|
||||||
bool writeable)
|
bool writeable,
|
||||||
|
bool executable)
|
||||||
: Hw::Mapping(phys, virt, 1 << size_log2,
|
: Hw::Mapping(phys, virt, 1 << size_log2,
|
||||||
{ writeable ? Hw::RW : Hw::RO, Hw::EXEC, Hw::USER,
|
{ writeable ? Hw::RW : Hw::RO, Hw::EXEC, Hw::USER,
|
||||||
Hw::NO_GLOBAL, io ? Hw::DEVICE : Hw::RAM, cacheable }) {}
|
Hw::NO_GLOBAL, io ? Hw::DEVICE : Hw::RAM, cacheable }) {}
|
||||||
@ -108,6 +109,11 @@ class Genode::Ipc_pager
|
|||||||
*/
|
*/
|
||||||
bool write_fault() const;
|
bool write_fault() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executable permission fault
|
||||||
|
*/
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input mapping data as reply to current page fault
|
* Input mapping data as reply to current page fault
|
||||||
*/
|
*/
|
||||||
|
@ -43,8 +43,8 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Mapping(addr_t dst_addr, addr_t map_addr,
|
Mapping(addr_t dst_addr, addr_t map_addr,
|
||||||
Cache_attribute c, bool io_mem,
|
Cache_attribute c, bool io_mem,
|
||||||
unsigned size_log2 = PAGE_SIZE_LOG2,
|
unsigned size_log2,
|
||||||
bool rw = true)
|
bool rw, bool executable)
|
||||||
:
|
:
|
||||||
_dst_addr(dst_addr), _core_local_addr(map_addr),
|
_dst_addr(dst_addr), _core_local_addr(map_addr),
|
||||||
_attr(c), _size_log2(size_log2), _rw(rw)
|
_attr(c), _size_log2(size_log2), _rw(rw)
|
||||||
@ -125,6 +125,11 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
bool write_fault() const { return _fault_type & ERR_W; }
|
bool write_fault() const { return _fault_type & ERR_W; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if fault was a non-executable fault
|
||||||
|
*/
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if last fault was an exception
|
* Return true if last fault was an exception
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +41,7 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute cacheability, bool io_mem,
|
Cache_attribute cacheability, bool io_mem,
|
||||||
unsigned l2size = 12, bool rw = true);
|
unsigned l2size, bool rw, bool executable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct invalid mapping
|
* Construct invalid mapping
|
||||||
@ -162,6 +162,11 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
bool write_fault() const { return L4_Label(_faulter_tag) & 2; }
|
bool write_fault() const { return L4_Label(_faulter_tag) & 2; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if last fault was a executable fault
|
||||||
|
*/
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if last fault was an exception
|
* Return true if last fault was an exception
|
||||||
*/
|
*/
|
||||||
|
@ -73,7 +73,7 @@ static inline Okl4::L4_ThreadId_t thread_get_my_global_id()
|
|||||||
|
|
||||||
Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute cacheability, bool io_mem,
|
Cache_attribute cacheability, bool io_mem,
|
||||||
unsigned l2size, bool rw)
|
unsigned l2size, bool rw, bool executable)
|
||||||
:
|
:
|
||||||
_fpage(L4_FpageLog2(dst_addr, l2size)),
|
_fpage(L4_FpageLog2(dst_addr, l2size)),
|
||||||
/*
|
/*
|
||||||
|
@ -46,8 +46,8 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute, bool io_mem,
|
Cache_attribute, bool io_mem,
|
||||||
unsigned l2size = Pistachio::get_page_size_log2(),
|
unsigned l2size,
|
||||||
bool rw = true, bool grant = false);
|
bool rw, bool executable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct invalid mapping
|
* Construct invalid mapping
|
||||||
@ -169,6 +169,11 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
bool write_fault() const { return (_flags & 2); }
|
bool write_fault() const { return (_flags & 2); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if last fault was a executable fault
|
||||||
|
*/
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if last fault was an exception
|
* Return true if last fault was an exception
|
||||||
*/
|
*/
|
||||||
|
@ -41,8 +41,10 @@ using namespace Pistachio;
|
|||||||
|
|
||||||
Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute, bool io_mem, unsigned l2size,
|
Cache_attribute, bool io_mem, unsigned l2size,
|
||||||
bool rw, bool grant)
|
bool rw, bool executable)
|
||||||
{
|
{
|
||||||
|
bool const grant = false;
|
||||||
|
|
||||||
L4_Fpage_t fpage = L4_FpageLog2(src_addr, l2size);
|
L4_Fpage_t fpage = L4_FpageLog2(src_addr, l2size);
|
||||||
|
|
||||||
fpage += rw ? L4_FullyAccessible : L4_Readable;
|
fpage += rw ? L4_FullyAccessible : L4_Readable;
|
||||||
|
@ -44,8 +44,7 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Mapping(addr_t dst_addr, addr_t src_addr,
|
Mapping(addr_t dst_addr, addr_t src_addr,
|
||||||
Cache_attribute const cacheability, bool io_mem,
|
Cache_attribute const cacheability, bool io_mem,
|
||||||
unsigned l2size = PAGE_SIZE_LOG2,
|
unsigned l2size, bool rw, bool executable)
|
||||||
bool rw = true)
|
|
||||||
:
|
:
|
||||||
_from_phys_addr(src_addr),
|
_from_phys_addr(src_addr),
|
||||||
_to_virt_addr(dst_addr),
|
_to_virt_addr(dst_addr),
|
||||||
@ -142,6 +141,11 @@ namespace Genode {
|
|||||||
* Return true if page fault was a write fault
|
* Return true if page fault was a write fault
|
||||||
*/
|
*/
|
||||||
bool write_fault() const { return _pf_write; }
|
bool write_fault() const { return _pf_write; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if page fault was on non-executable memory
|
||||||
|
*/
|
||||||
|
bool exec_fault() const { return false; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ class Genode::Rm_region : public List<Rm_region>::Element
|
|||||||
addr_t _base = 0;
|
addr_t _base = 0;
|
||||||
size_t _size = 0;
|
size_t _size = 0;
|
||||||
bool _write = false;
|
bool _write = false;
|
||||||
|
bool _exec = false;
|
||||||
|
|
||||||
Dataspace_component *_dsc = nullptr;
|
Dataspace_component *_dsc = nullptr;
|
||||||
off_t _off = 0;
|
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,
|
Rm_region(addr_t base, size_t size, bool write,
|
||||||
Dataspace_component *dsc, off_t offset,
|
Dataspace_component *dsc, off_t offset,
|
||||||
Region_map_component *rm)
|
Region_map_component *rm, bool exec)
|
||||||
: _base(base), _size(size), _write(write),
|
: _base(base), _size(size), _write(write), _exec(exec),
|
||||||
_dsc(dsc), _off(offset), _rm(rm) { }
|
_dsc(dsc), _off(offset), _rm(rm) { }
|
||||||
|
|
||||||
|
|
||||||
@ -92,6 +93,7 @@ class Genode::Rm_region : public List<Rm_region>::Element
|
|||||||
addr_t base() const { return _base; }
|
addr_t base() const { return _base; }
|
||||||
size_t size() const { return _size; }
|
size_t size() const { return _size; }
|
||||||
bool write() const { return _write; }
|
bool write() const { return _write; }
|
||||||
|
bool executable() const { return _exec; }
|
||||||
Dataspace_component* dataspace() const { return _dsc; }
|
Dataspace_component* dataspace() const { return _dsc; }
|
||||||
off_t offset() const { return _off; }
|
off_t offset() const { return _off; }
|
||||||
Region_map_component* rm() const { return _rm; }
|
Region_map_component* rm() const { return _rm; }
|
||||||
|
@ -156,8 +156,9 @@ static void print_page_fault(char const *msg,
|
|||||||
Pager_object const &obj)
|
Pager_object const &obj)
|
||||||
{
|
{
|
||||||
log(msg, " (",
|
log(msg, " (",
|
||||||
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" : "READ",
|
pf_type == Region_map::State::WRITE_FAULT ? "WRITE" :
|
||||||
" pf_addr=", Hex(pf_addr), " pf_ip=", Hex(pf_ip), " from ", obj, ")");
|
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::Fault_type pf_type = pager.write_fault() ? Region_map::State::WRITE_FAULT
|
||||||
: Region_map::State::READ_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_addr = pager.fault_addr();
|
||||||
addr_t pf_ip = pager.fault_ip();
|
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()) {
|
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",
|
print_page_fault("attempted write at read-only memory",
|
||||||
pf_addr, pf_ip, pf_type, *this);
|
pf_addr, pf_ip, pf_type, *this);
|
||||||
|
|
||||||
@ -221,6 +224,17 @@ int Rm_client::pager(Ipc_pager &pager)
|
|||||||
return 2;
|
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,
|
Mapping mapping = Region_map_component::create_map_item(region_map,
|
||||||
region,
|
region,
|
||||||
ds_offset,
|
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(),
|
return Mapping(dst_fault_area.base(), src_fault_area.base(),
|
||||||
dsc->cacheability(), dsc->io_mem(),
|
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 */
|
/* store attachment info in meta data */
|
||||||
try {
|
try {
|
||||||
_map.metadata(attach_at, Rm_region((addr_t)attach_at, size, true,
|
_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) {
|
} catch (Allocator_avl_tpl<Rm_region>::Assign_metadata_failed) {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user