mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
parent
487e8ea934
commit
e6d20aba93
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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) { }
|
||||||
|
@ -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(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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)) {
|
||||||
|
@ -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 &&
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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); });
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 };
|
||||||
|
@ -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));
|
||||||
|
@ -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;
|
||||||
|
@ -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); }
|
||||||
|
@ -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); });
|
||||||
|
Loading…
Reference in New Issue
Block a user