base: support to attach RAM dataspaces readonly

Fixes #1633
This commit is contained in:
Alexander Boettcher 2018-05-08 11:21:10 +02:00 committed by Christian Helmuth
parent 487e8ea934
commit e6d20aba93
29 changed files with 122 additions and 78 deletions

View File

@ -26,7 +26,7 @@ using namespace Genode;
Region_map::Local_addr Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size, Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Region_map::Local_addr, bool) Region_map::Local_addr, bool, bool writeable)
{ {
auto lambda = [&] (Dataspace_component *ds) -> Local_addr { auto lambda = [&] (Dataspace_component *ds) -> Local_addr {
if (!ds) if (!ds)
@ -61,8 +61,9 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
/* map the dataspace's physical pages to corresponding virtual addresses */ /* map the dataspace's physical pages to corresponding virtual addresses */
unsigned num_pages = page_rounded_size >> get_page_size_log2(); unsigned num_pages = page_rounded_size >> get_page_size_log2();
Page_flags const flags { ds->writable() ? RW : RO, NO_EXEC, KERN, Page_flags const flags { (writeable && ds->writable()) ? RW : RO,
GLOBAL, ds->io_mem() ? DEVICE : RAM, NO_EXEC, KERN, GLOBAL,
ds->io_mem() ? DEVICE : RAM,
ds->cacheability() }; ds->cacheability() };
if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages, flags)) if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages, flags))
return nullptr; return nullptr;

View File

@ -94,8 +94,8 @@ void Genode::Cpu::mmu_fault(Context & regs, Kernel::Thread_fault & fault)
}; };
auto fault_lambda = [] (addr_t err) { auto fault_lambda = [] (addr_t err) {
if (!(err & ERR_P)) return Fault::PAGE_MISSING;
if (err & ERR_W) return Fault::WRITE; if (err & ERR_W) return Fault::WRITE;
if (!(err & ERR_P)) return Fault::PAGE_MISSING;
if (err & ERR_I) return Fault::EXEC; if (err & ERR_I) return Fault::EXEC;
else return Fault::UNKNOWN; else return Fault::UNKNOWN;
}; };

View File

@ -53,7 +53,8 @@ class Genode::Region_map_component : public Rpc_object<Region_map>,
void add_client(Rm_client &) { } void add_client(Rm_client &) { }
void remove_client(Rm_client &) { } void remove_client(Rm_client &) { }
Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) { Local_addr attach(Dataspace_capability, size_t, off_t, bool,
Local_addr, bool, bool) {
return (addr_t)0; } return (addr_t)0; }
void detach(Local_addr) { } void detach(Local_addr) { }

View File

@ -43,7 +43,8 @@ class Stack_area_region_map : public Genode::Region_map
* Attach backing store to stack area * Attach backing store to stack area
*/ */
Local_addr attach(Genode::Dataspace_capability, Genode::size_t size, Local_addr attach(Genode::Dataspace_capability, Genode::size_t size,
Genode::off_t, bool, Local_addr local_addr, bool) Genode::off_t, bool, Local_addr local_addr, bool,
bool) override
{ {
using namespace Genode; using namespace Genode;
@ -61,17 +62,17 @@ class Stack_area_region_map : public Genode::Region_map
return local_addr; return local_addr;
} }
void detach(Local_addr local_addr) void detach(Local_addr local_addr) override
{ {
Genode::warning("stack area detach from ", (void*)local_addr, Genode::warning("stack area detach from ", (void*)local_addr,
" - not implemented"); " - not implemented");
} }
void fault_handler(Genode::Signal_context_capability) { } void fault_handler(Genode::Signal_context_capability) override { }
State state() { return State(); } State state() override { return State(); }
Genode::Dataspace_capability dataspace() { Genode::Dataspace_capability dataspace() override {
return Genode::Dataspace_capability(); } return Genode::Dataspace_capability(); }
}; };

View File

@ -77,7 +77,8 @@ class Genode::Region_map_mmap : public Region_map, public Dataspace
bool use_local_addr, bool use_local_addr,
addr_t local_addr, addr_t local_addr,
bool executable, bool executable,
bool overmap = false); bool overmap,
bool writeable);
/** /**
* Determine size of dataspace * Determine size of dataspace
@ -115,25 +116,25 @@ class Genode::Region_map_mmap : public Region_map, public Dataspace
** Region map interface ** ** Region map interface **
**************************/ **************************/
Local_addr attach(Dataspace_capability ds, size_t size, Local_addr attach(Dataspace_capability, size_t size, off_t, bool,
off_t, bool, Local_addr, bool executable); Local_addr, bool, bool) override;
void detach(Local_addr local_addr); void detach(Local_addr) override;
void fault_handler(Signal_context_capability) { } void fault_handler(Signal_context_capability) override { }
State state() { return State(); } State state() override { return State(); }
/************************* /*************************
** Dataspace interface ** ** Dataspace interface **
*************************/ *************************/
size_t size() { return _size; } size_t size() override { return _size; }
addr_t phys_addr() { return 0; } addr_t phys_addr() override { return 0; }
bool writable() { return true; } bool writable() override { return true; }
/** /**
* Return pseudo dataspace capability of the RM session * Return pseudo dataspace capability of the RM session
@ -142,7 +143,7 @@ class Genode::Region_map_mmap : public Region_map, public Dataspace
* as argument to 'Region_map_mmap::attach'. It is not a * as argument to 'Region_map_mmap::attach'. It is not a
* real capability. * real capability.
*/ */
Dataspace_capability dataspace() { Dataspace_capability dataspace() override {
return Local_capability<Dataspace>::local_cap(this); } return Local_capability<Dataspace>::local_cap(this); }
}; };

View File

@ -39,10 +39,10 @@ Region_map::Local_addr
Region_map_client::attach(Dataspace_capability ds, size_t size, Region_map_client::attach(Dataspace_capability ds, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Region_map::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable, bool writeable)
{ {
return _local(*this)->attach(ds, size, offset, use_local_addr, return _local(*this)->attach(ds, size, offset, use_local_addr,
local_addr, executable); local_addr, executable, writeable);
} }

View File

@ -123,10 +123,11 @@ void *Region_map_mmap::_map_local(Dataspace_capability ds,
bool use_local_addr, bool use_local_addr,
addr_t local_addr, addr_t local_addr,
bool executable, bool executable,
bool overmap) bool overmap,
bool writeable)
{ {
int const fd = _dataspace_fd(ds); int const fd = _dataspace_fd(ds);
bool const writable = _dataspace_writable(ds); bool const writable = _dataspace_writable(ds) && writeable;
int const flags = MAP_SHARED | (overmap ? MAP_FIXED : 0); int const flags = MAP_SHARED | (overmap ? MAP_FIXED : 0);
int const prot = PROT_READ int const prot = PROT_READ
@ -172,7 +173,7 @@ Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds,
size_t size, off_t offset, size_t size, off_t offset,
bool use_local_addr, bool use_local_addr,
Region_map::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable, bool writeable)
{ {
Lock::Guard lock_guard(lock()); Lock::Guard lock_guard(lock());
@ -239,7 +240,7 @@ Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds,
* argument as the region was reserved by a PROT_NONE mapping. * argument as the region was reserved by a PROT_NONE mapping.
*/ */
if (_is_attached()) if (_is_attached())
_map_local(ds, region_size, offset, true, _base + (addr_t)local_addr, executable, true); _map_local(ds, region_size, offset, true, _base + (addr_t)local_addr, executable, true, writeable);
return (void *)local_addr; return (void *)local_addr;
@ -290,7 +291,7 @@ Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds,
*/ */
_map_local(region.dataspace(), region.size(), region.offset(), _map_local(region.dataspace(), region.size(), region.offset(),
true, rm->_base + region.start() + region.offset(), true, rm->_base + region.start() + region.offset(),
executable, true); executable, true, writeable);
} }
return rm->_base; return rm->_base;
@ -304,7 +305,7 @@ Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds,
* Note, we do not overmap. * Note, we do not overmap.
*/ */
void *addr = _map_local(ds, region_size, offset, use_local_addr, void *addr = _map_local(ds, region_size, offset, use_local_addr,
local_addr, executable); local_addr, executable, false, writeable);
_add_to_rmap(Region((addr_t)addr, offset, ds, region_size)); _add_to_rmap(Region((addr_t)addr, offset, ds, region_size));

View File

@ -51,7 +51,7 @@ Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t, Core_region_map::attach(Dataspace_capability ds_cap, size_t,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Region_map::Local_addr, Region_map::Local_addr,
bool executable) bool executable, bool writeable)
{ {
auto lambda = [&] (Dataspace_component *ds) -> Local_addr { auto lambda = [&] (Dataspace_component *ds) -> Local_addr {
if (!ds) if (!ds)
@ -76,7 +76,7 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t,
/* map it */ /* map it */
Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb()); Nova::Utcb * const utcb = reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
const Nova::Rights rights(true, ds->writable(), executable); const Nova::Rights rights(true, writeable && ds->writable(), executable);
if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr), if (map_local(utcb, ds->phys_addr(), reinterpret_cast<addr_t>(virt_ptr),
page_rounded_size >> get_page_size_log2(), rights, true)) { page_rounded_size >> get_page_size_log2(), rights, true)) {

View File

@ -66,10 +66,13 @@ void Pd_session_component::map(addr_t virt, addr_t size)
/* one item ever fits on the UTCB */ /* one item ever fits on the UTCB */
(void)res; (void)res;
Nova::Rights const map_rights (true,
region->write() && dsc->writable(),
region->executable());
/* receive window in destination pd */ /* receive window in destination pd */
Nova::Mem_crd crd_mem(mapping.dst_addr() >> 12, Nova::Mem_crd crd_mem(mapping.dst_addr() >> 12,
mapping.mem_crd().order(), mapping.mem_crd().order(), map_rights);
Nova::Rights(true, dsc->writable(), region->executable()));
err = Nova::delegate(pd_core, pd_dst, crd_mem); err = Nova::delegate(pd_core, pd_dst, crd_mem);
} while (err == Nova::NOVA_PD_OOM && } while (err == Nova::NOVA_PD_OOM &&

View File

@ -24,10 +24,10 @@ Region_map_client::Region_map_client(Capability<Region_map> session)
Region_map::Local_addr Region_map::Local_addr
Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset, Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset,
bool use_local_addr, Local_addr local_addr, bool use_local_addr, Local_addr local_addr,
bool executable) bool executable, bool writeable)
{ {
return call<Rpc_attach>(ds, size, offset, use_local_addr, local_addr, return call<Rpc_attach>(ds, size, offset, use_local_addr, local_addr,
executable); executable, writeable);
} }

View File

@ -22,7 +22,7 @@ using namespace Genode;
Region_map::Local_addr Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size, Core_region_map::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Region_map::Local_addr, bool) Region_map::Local_addr, bool, bool)
{ {
using namespace Okl4; using namespace Okl4;

View File

@ -24,7 +24,7 @@ using namespace Genode;
Region_map::Local_addr Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t size, off_t offset, Core_region_map::attach(Dataspace_capability ds_cap, size_t size, off_t offset,
bool use_local_addr, Region_map::Local_addr, bool) bool use_local_addr, Region_map::Local_addr, bool, bool)
{ {
auto lambda = [&] (Dataspace_component *ds) -> Local_addr { auto lambda = [&] (Dataspace_component *ds) -> Local_addr {
if (!ds) if (!ds)

View File

@ -58,7 +58,7 @@ class Stack_area_region_map : public Region_map
* Allocate and attach on-the-fly backing store to the stack area * Allocate and attach on-the-fly backing store to the stack area
*/ */
Local_addr attach(Dataspace_capability, size_t size, off_t, Local_addr attach(Dataspace_capability, size_t size, off_t,
bool, Local_addr local_addr, bool) override bool, Local_addr local_addr, bool, bool) override
{ {
size = round_page(size); size = round_page(size);

View File

@ -44,7 +44,8 @@ class Genode::Region_map_client : public Rpc_client<Region_map>
Local_addr attach(Dataspace_capability ds, size_t size = 0, Local_addr attach(Dataspace_capability ds, size_t size = 0,
off_t offset = 0, bool use_local_addr = false, off_t offset = 0, bool use_local_addr = false,
Local_addr local_addr = (void *)0, Local_addr local_addr = (void *)0,
bool executable = false) override; bool executable = false,
bool writeable = true) override;
void detach(Local_addr) override; void detach(Local_addr) override;
void fault_handler(Signal_context_capability) override; void fault_handler(Signal_context_capability) override;

View File

@ -103,6 +103,7 @@ struct Genode::Region_map : Interface
* the specified 'local_addr' * the specified 'local_addr'
* \param local_addr local destination address * \param local_addr local destination address
* \param executable if the mapping should be executable * \param executable if the mapping should be executable
* \param writeable if the mapping should be writeable
* *
* \throw Invalid_dataspace * \throw Invalid_dataspace
* \throw Region_conflict * \throw Region_conflict
@ -116,7 +117,8 @@ struct Genode::Region_map : Interface
size_t size = 0, off_t offset = 0, size_t size = 0, off_t offset = 0,
bool use_local_addr = false, bool use_local_addr = false,
Local_addr local_addr = (void *)0, Local_addr local_addr = (void *)0,
bool executable = false) = 0; bool executable = false,
bool writeable = true) = 0;
/** /**
* Shortcut for attaching a dataspace at a predefined local address * Shortcut for attaching a dataspace at a predefined local address
@ -165,7 +167,8 @@ struct Genode::Region_map : Interface
GENODE_RPC_THROW(Rpc_attach, Local_addr, attach, GENODE_RPC_THROW(Rpc_attach, Local_addr, attach,
GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict, GENODE_TYPE_LIST(Invalid_dataspace, Region_conflict,
Out_of_ram, Out_of_caps), Out_of_ram, Out_of_caps),
Dataspace_capability, size_t, off_t, bool, Local_addr, bool); Dataspace_capability, size_t, off_t, bool, Local_addr,
bool, bool);
GENODE_RPC(Rpc_detach, void, detach, Local_addr); GENODE_RPC(Rpc_detach, void, detach, Local_addr);
GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability);
GENODE_RPC(Rpc_state, State, state); GENODE_RPC(Rpc_state, State, state);

View File

@ -162,7 +162,7 @@ _ZN6Genode17Native_capabilityC1Ev T
_ZN6Genode17Native_capabilityC2Ev T _ZN6Genode17Native_capabilityC2Ev T
_ZN6Genode17Region_map_client13fault_handlerENS_10CapabilityINS_14Signal_contextEEE T _ZN6Genode17Region_map_client13fault_handlerENS_10CapabilityINS_14Signal_contextEEE T
_ZN6Genode17Region_map_client5stateEv T _ZN6Genode17Region_map_client5stateEv T
_ZN6Genode17Region_map_client6attachENS_10CapabilityINS_9DataspaceEEEmlbNS_10Region_map10Local_addrEb T _ZN6Genode17Region_map_client6attachENS_10CapabilityINS_9DataspaceEEEmlbNS_10Region_map10Local_addrEbb T
_ZN6Genode17Region_map_client6detachENS_10Region_map10Local_addrE T _ZN6Genode17Region_map_client6detachENS_10Region_map10Local_addrE T
_ZN6Genode17Region_map_client9dataspaceEv T _ZN6Genode17Region_map_client9dataspaceEv T
_ZN6Genode17Region_map_clientC1ENS_10CapabilityINS_10Region_mapEEE T _ZN6Genode17Region_map_clientC1ENS_10CapabilityINS_10Region_mapEEE T

View File

@ -23,7 +23,7 @@ using namespace Genode;
Region_map::Local_addr Region_map::Local_addr
Core_region_map::attach(Dataspace_capability ds_cap, size_t, off_t, bool, Core_region_map::attach(Dataspace_capability ds_cap, size_t, off_t, bool,
Region_map::Local_addr, bool) Region_map::Local_addr, bool, bool)
{ {
auto lambda = [] (Dataspace_component *ds) { auto lambda = [] (Dataspace_component *ds) {
if (!ds) if (!ds)

View File

@ -37,7 +37,8 @@ class Genode::Core_region_map : public Region_map
Local_addr attach(Dataspace_capability, size_t size = 0, Local_addr attach(Dataspace_capability, size_t size = 0,
off_t offset=0, bool use_local_addr = false, off_t offset=0, bool use_local_addr = false,
Local_addr local_addr = 0, Local_addr local_addr = 0,
bool executable = false) override; bool executable = false,
bool writeable = true) override;
void detach(Local_addr); void detach(Local_addr);

View File

@ -444,7 +444,8 @@ class Genode::Region_map_component : private Weak_object<Region_map_component>,
** Region map interface ** ** Region map interface **
**************************/ **************************/
Local_addr attach (Dataspace_capability, size_t, off_t, bool, Local_addr, bool) override; Local_addr attach (Dataspace_capability, size_t, off_t,
bool, Local_addr, bool, bool) override;
void detach (Local_addr) override; void detach (Local_addr) override;
void fault_handler (Signal_context_capability handler) override; void fault_handler (Signal_context_capability handler) override;
State state () override; State state () override;

View File

@ -213,7 +213,8 @@ int Rm_client::pager(Ipc_pager &pager)
/* /*
* Check if dataspace is compatible with page-fault type * Check if dataspace is compatible with page-fault type
*/ */
if (pf_type == Region_map::State::WRITE_FAULT && !dsc->writable()) { if (pf_type == Region_map::State::WRITE_FAULT &&
(!region->write() || !dsc->writable())) {
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);
@ -337,7 +338,8 @@ Mapping Region_map_component::create_map_item(Region_map_component *,
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(), region->executable()); map_size_log2, region->write() && dsc->writable(),
region->executable());
}; };
@ -345,7 +347,7 @@ Region_map::Local_addr
Region_map_component::attach(Dataspace_capability ds_cap, size_t size, Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Region_map::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable, bool writeable)
{ {
/* serialize access */ /* serialize access */
Lock::Guard lock_guard(_lock); Lock::Guard lock_guard(_lock);
@ -427,7 +429,8 @@ 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,
dsc->writable() && writeable,
dsc, offset, this, executable)); dsc, offset, this, executable));
} }
catch (Allocator_avl_tpl<Rm_region>::Assign_metadata_failed) { catch (Allocator_avl_tpl<Rm_region>::Assign_metadata_failed) {

View File

@ -67,7 +67,7 @@ class Stack_area_region_map : public Region_map
* Allocate and attach on-the-fly backing store to stack area * Allocate and attach on-the-fly backing store to stack area
*/ */
Local_addr attach(Dataspace_capability, size_t size, off_t, Local_addr attach(Dataspace_capability, size_t size, off_t,
bool, Local_addr local_addr, bool) override bool, Local_addr local_addr, bool, bool) override
{ {
/* allocate physical memory */ /* allocate physical memory */
size = round_page(size); size = round_page(size);

View File

@ -35,7 +35,7 @@ struct Genode::Expanding_region_map_client : Region_map_client
Local_addr attach(Dataspace_capability ds, size_t size, off_t offset, Local_addr attach(Dataspace_capability ds, size_t size, off_t offset,
bool use_local_addr, Local_addr local_addr, bool use_local_addr, Local_addr local_addr,
bool executable) override bool executable, bool writeable) override
{ {
return retry<Out_of_ram>( return retry<Out_of_ram>(
[&] () { [&] () {
@ -44,7 +44,8 @@ struct Genode::Expanding_region_map_client : Region_map_client
return Region_map_client::attach(ds, size, offset, return Region_map_client::attach(ds, size, offset,
use_local_addr, use_local_addr,
local_addr, local_addr,
executable); }, executable,
writeable); },
[&] { _pd_client.upgrade_caps(2); }); [&] { _pd_client.upgrade_caps(2); });
}, },
[&] () { _pd_client.upgrade_ram(8*1024); }); [&] () { _pd_client.upgrade_ram(8*1024); });

View File

@ -23,10 +23,10 @@ Region_map_client::Region_map_client(Capability<Region_map> cap)
Region_map::Local_addr Region_map::Local_addr
Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset, Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset,
bool use_local_addr, Local_addr local_addr, bool use_local_addr, Local_addr local_addr,
bool executable) bool executable, bool writeable)
{ {
return call<Rpc_attach>(ds, size, offset, use_local_addr, local_addr, return call<Rpc_attach>(ds, size, offset, use_local_addr, local_addr,
executable); executable, writeable);
} }

View File

@ -301,25 +301,45 @@ struct Main_parent
_address_space.detach((void *)child_virt_addr); _address_space.detach((void *)child_virt_addr);
} }
void _test_write_fault(addr_t const child_virt_addr) void _test_write_fault(addr_t const child_virt_addr, unsigned round)
{ {
if (_child_value() == WRITE_TEST) { if (_child_value() != WRITE_TEST) {
_child_stop() = STOP_TEST; Genode::log("test WRITE faults on read-only binary and "
"read-only attached RAM");
Genode::log("got write fault on ROM ", Hex(child_virt_addr)); _child_value() = WRITE_TEST;
/* let client continue by providing a dataspace it may write to */
_address_space.detach((void *)child_virt_addr);
_address_space.attach_at(_ds.cap(), child_virt_addr);
_address_space.attach_at(_binary.dataspace(), child_virt_addr);
return; return;
} }
Genode::log("test WRITE fault on read-only binary"); enum { ROUND_FAULT_ON_ROM_BINARY = 1, ROUND_FAULT_ON_RO_RAM = 2 };
_child_value() = WRITE_TEST; if (round == ROUND_FAULT_ON_RO_RAM)
_child_stop() = STOP_TEST;
_address_space.attach_at(_binary.dataspace(), child_virt_addr); Genode::log("got write fault on ", Hex(child_virt_addr),
(round == ROUND_FAULT_ON_ROM_BINARY) ? " ROM (binary)" :
(round == ROUND_FAULT_ON_RO_RAM) ? " read-only attached RAM"
: " unknown");
/* detach region where fault happened */
_address_space.detach((void *)child_virt_addr);
if (round == ROUND_FAULT_ON_ROM_BINARY) {
/* attach a RAM dataspace read-only */
enum {
SIZE = 4096, OFFSET = 0, ATTACH_AT = true, NON_EXEC = false,
READONLY = false
};
_address_space.attach(_ds.cap(), SIZE, OFFSET, ATTACH_AT,
child_virt_addr, NON_EXEC, READONLY);
} else
if (round == ROUND_FAULT_ON_RO_RAM) {
/* let client continue by attaching RAM dataspace writeable */
_address_space.attach_at(_ds.cap(), child_virt_addr);
}
} }
void _test_exec_fault(Region_map::State &state) void _test_exec_fault(Region_map::State &state)
@ -344,7 +364,7 @@ struct Main_parent
void _handle_fault() void _handle_fault()
{ {
enum { FAULT_CNT_READ = 4, FAULT_CNT_WRITE = 5 }; enum { FAULT_CNT_READ = 4, FAULT_CNT_WRITE = 6 };
log("received region-map fault signal, request fault state"); log("received region-map fault signal, request fault state");
@ -364,7 +384,7 @@ struct Main_parent
_test_read_fault(child_virt_addr); _test_read_fault(child_virt_addr);
if (_fault_cnt <= FAULT_CNT_WRITE && _fault_cnt >= FAULT_CNT_READ) if (_fault_cnt <= FAULT_CNT_WRITE && _fault_cnt >= FAULT_CNT_READ)
_test_write_fault(child_virt_addr); _test_write_fault(child_virt_addr, _fault_cnt - FAULT_CNT_READ);
if (!_config.xml().attribute_value("executable_fault_test", true) && if (!_config.xml().attribute_value("executable_fault_test", true) &&
_fault_cnt >=FAULT_CNT_WRITE) _fault_cnt >=FAULT_CNT_WRITE)

View File

@ -59,7 +59,8 @@ class Platform::Device_pd
Genode::size_t size = 0, Genode::off_t offset = 0, Genode::size_t size = 0, Genode::off_t offset = 0,
bool use_local_addr = false, bool use_local_addr = false,
Local_addr local_addr = (void *)0, Local_addr local_addr = (void *)0,
bool executable = false) override bool executable = false,
bool writeable = true) override
{ {
return Genode::retry<Genode::Out_of_ram>( return Genode::retry<Genode::Out_of_ram>(
[&] () { [&] () {
@ -68,7 +69,8 @@ class Platform::Device_pd
return Region_map_client::attach(ds, size, offset, return Region_map_client::attach(ds, size, offset,
use_local_addr, use_local_addr,
local_addr, local_addr,
executable); }, executable,
writeable); },
[&] () { [&] () {
enum { UPGRADE_CAP_QUOTA = 2 }; enum { UPGRADE_CAP_QUOTA = 2 };
Genode::Cap_quota const caps { UPGRADE_CAP_QUOTA }; Genode::Cap_quota const caps { UPGRADE_CAP_QUOTA };

View File

@ -54,7 +54,7 @@ Region_map::Local_addr
Region_map_component::attach(Dataspace_capability ds_cap, size_t size, Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
off_t offset, bool use_local_addr, off_t offset, bool use_local_addr,
Region_map::Local_addr local_addr, Region_map::Local_addr local_addr,
bool executable) bool executable, bool const writeable)
{ {
size_t ds_size = Dataspace_client(ds_cap).size(); size_t ds_size = Dataspace_client(ds_cap).size();
@ -72,7 +72,7 @@ Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
void *addr = _parent_region_map.attach(ds_cap, size, offset, void *addr = _parent_region_map.attach(ds_cap, size, offset,
use_local_addr, local_addr, use_local_addr, local_addr,
executable); executable, writeable);
Lock::Guard lock_guard(_region_map_lock); Lock::Guard lock_guard(_region_map_lock);
_region_map.insert(new (_alloc) Region(addr, (void*)((addr_t)addr + size - 1), ds_cap, offset)); _region_map.insert(new (_alloc) Region(addr, (void*)((addr_t)addr + size - 1), ds_cap, offset));

View File

@ -102,7 +102,8 @@ namespace Gdb_monitor {
**************************************/ **************************************/
Local_addr attach (Dataspace_capability, size_t, Local_addr attach (Dataspace_capability, size_t,
off_t, bool, Local_addr, bool) override; off_t, bool, Local_addr, bool,
bool) override;
void detach (Local_addr) override; void detach (Local_addr) override;
void fault_handler (Signal_context_capability) override; void fault_handler (Signal_context_capability) override;
State state () override; State state () override;

View File

@ -232,10 +232,11 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
**************************/ **************************/
Local_addr attach(Dataspace_capability ds, Local_addr attach(Dataspace_capability ds,
size_t size = 0, off_t offset = 0, size_t size, off_t offset,
bool use_local_addr = false, bool use_local_addr,
Local_addr local_addr = (addr_t)0, Local_addr local_addr,
bool executable = false) override bool executable,
bool writeable) override
{ {
/* /*
* Region map subtracts offset from size if size is 0 * Region map subtracts offset from size if size is 0
@ -245,7 +246,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
for (;;) { for (;;) {
try { try {
local_addr = _rm.attach(ds, size, offset, use_local_addr, local_addr = _rm.attach(ds, size, offset, use_local_addr,
local_addr, executable); local_addr, executable, writeable);
break; break;
} }
catch (Out_of_ram) { _pd.upgrade_ram(8*1024); } catch (Out_of_ram) { _pd.upgrade_ram(8*1024); }

View File

@ -47,7 +47,8 @@ class Sub_rm_connection : private Genode::Rm_connection,
Genode::size_t size = 0, Genode::off_t offset = 0, Genode::size_t size = 0, Genode::off_t offset = 0,
bool use_local_addr = false, bool use_local_addr = false,
Local_addr local_addr = (void *)0, Local_addr local_addr = (void *)0,
bool executable = false) override bool executable = false,
bool writeable = true) override
{ {
Local_addr addr = Genode::retry<Genode::Out_of_ram>( Local_addr addr = Genode::retry<Genode::Out_of_ram>(
[&] () { [&] () {
@ -56,7 +57,8 @@ class Sub_rm_connection : private Genode::Rm_connection,
return Region_map_client::attach(ds, size, offset, return Region_map_client::attach(ds, size, offset,
use_local_addr, use_local_addr,
local_addr, local_addr,
executable); }, executable,
writeable); },
[&] () { upgrade_caps(2); }); [&] () { upgrade_caps(2); });
}, },
[&] () { upgrade_ram(8192); }); [&] () { upgrade_ram(8192); });