noux: Noux_connection::context_area_rm_session()
This enables a forked process to update the capability of its context area RM session. ref #989
This commit is contained in:
parent
f7149623ca
commit
c2af646ad8
|
@ -48,6 +48,11 @@ namespace Noux {
|
|||
{
|
||||
return call<Rpc_next_open_fd>(start_fd);
|
||||
}
|
||||
|
||||
Rm_session_capability lookup_rm_session(addr_t const addr)
|
||||
{
|
||||
return call<Rpc_lookup_rm_session>(addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <base/stdint.h>
|
||||
#include <session/session.h>
|
||||
#include <dataspace/capability.h>
|
||||
#include <rm_session/capability.h>
|
||||
|
||||
#define NOUX_DECL_SYSCALL_NAME(name) \
|
||||
case SYSCALL_##name: return #name;
|
||||
|
@ -33,6 +34,13 @@ namespace Noux {
|
|||
|
||||
virtual Dataspace_capability sysio_dataspace() = 0;
|
||||
|
||||
/**
|
||||
* Return leaf RM session that covers a given address
|
||||
*
|
||||
* \param addr address that is covered by the requested RM session
|
||||
*/
|
||||
virtual Rm_session_capability lookup_rm_session(addr_t const addr) = 0;
|
||||
|
||||
enum Syscall {
|
||||
SYSCALL_WRITE,
|
||||
SYSCALL_READ,
|
||||
|
@ -154,10 +162,13 @@ namespace Noux {
|
|||
*********************/
|
||||
|
||||
GENODE_RPC(Rpc_sysio_dataspace, Dataspace_capability, sysio_dataspace);
|
||||
GENODE_RPC(Rpc_lookup_rm_session, Rm_session_capability,
|
||||
lookup_rm_session, addr_t);
|
||||
GENODE_RPC(Rpc_syscall, bool, syscall, Syscall);
|
||||
GENODE_RPC(Rpc_next_open_fd, int, next_open_fd, int);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_sysio_dataspace, Rpc_syscall, Rpc_next_open_fd);
|
||||
GENODE_RPC_INTERFACE(Rpc_sysio_dataspace, Rpc_lookup_rm_session,
|
||||
Rpc_syscall, Rpc_next_open_fd);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,16 @@ class Noux_connection
|
|||
_sysio = _obtain_sysio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the capability of the local context-area RM session
|
||||
*/
|
||||
Genode::Rm_session_capability context_area_rm_session()
|
||||
{
|
||||
using namespace Genode;
|
||||
addr_t const addr = Native_config::context_area_virtual_base();
|
||||
return _connection.lookup_rm_session(addr);
|
||||
}
|
||||
|
||||
Noux::Session *session() { return &_connection; }
|
||||
Noux::Sysio *sysio() { return _sysio; }
|
||||
};
|
||||
|
|
|
@ -425,6 +425,11 @@ namespace Noux {
|
|||
return _sysio_ds.cap();
|
||||
}
|
||||
|
||||
Rm_session_capability lookup_rm_session(addr_t const addr)
|
||||
{
|
||||
return _resources.rm.lookup_rm_session(addr);
|
||||
}
|
||||
|
||||
bool syscall(Syscall sc);
|
||||
|
||||
int next_open_fd(int start_fd)
|
||||
|
|
|
@ -103,6 +103,17 @@ namespace Noux {
|
|||
* \param len length of source buffer in bytes
|
||||
*/
|
||||
virtual void poke(addr_t dst_offset, void const *src, size_t len) = 0;
|
||||
|
||||
/**
|
||||
* Return leaf RM session that covers a given address
|
||||
*
|
||||
* \param addr address that is covered by the requested RM session
|
||||
*/
|
||||
virtual Rm_session_capability lookup_rm_session(addr_t const addr)
|
||||
{
|
||||
/* by default a dataspace is no sub RM, so return invalid */
|
||||
return Rm_session_capability();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -85,6 +85,12 @@ namespace Noux {
|
|||
}
|
||||
_sub_rm->poke(dst_offset, src, len);
|
||||
}
|
||||
|
||||
Rm_session_capability lookup_rm_session(addr_t const addr)
|
||||
{
|
||||
/* the dataspace is a sub RM, so traverse into it */
|
||||
return _sub_rm->lookup_rm_session(addr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* \brief RM session implementation used by Noux processes
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-22
|
||||
*
|
||||
* The custom RM implementation is used for recording all RM regions attached
|
||||
|
@ -22,11 +23,17 @@
|
|||
#include <rm_session/connection.h>
|
||||
#include <base/rpc_server.h>
|
||||
|
||||
namespace Noux {
|
||||
|
||||
namespace Noux
|
||||
{
|
||||
static bool verbose_attach = false;
|
||||
|
||||
class Rm_session_component : public Rpc_object<Rm_session>
|
||||
/**
|
||||
* Server sided back-end of an RM session of a Noux process
|
||||
*/
|
||||
class Rm_session_component;
|
||||
}
|
||||
|
||||
class Noux::Rm_session_component : public Rpc_object<Rm_session>
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -54,8 +61,7 @@ namespace Noux {
|
|||
*/
|
||||
bool contains(addr_t addr) const
|
||||
{
|
||||
return (addr >= local_addr)
|
||||
&& (addr < local_addr + size);
|
||||
return (addr >= local_addr) && (addr < local_addr + size);
|
||||
}
|
||||
|
||||
Region *next_region()
|
||||
|
@ -88,12 +94,18 @@ namespace Noux {
|
|||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Rm_session_component(Dataspace_registry & ds_registry,
|
||||
addr_t start = ~0UL, size_t size = 0)
|
||||
:
|
||||
_rm(start, size), _ds_registry(ds_registry)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Rm_session_component()
|
||||
{
|
||||
Region *curr;
|
||||
|
@ -101,6 +113,34 @@ namespace Noux {
|
|||
detach(curr->local_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return leaf RM session that covers a given address
|
||||
*
|
||||
* \param addr address that is covered by the requested RM session
|
||||
*/
|
||||
Rm_session_capability lookup_rm_session(addr_t const addr)
|
||||
{
|
||||
/* if there's no region that could be a sub RM then we're a leaf */
|
||||
Region * const region = _lookup_region_by_addr(addr);
|
||||
if (!region) { return cap(); }
|
||||
|
||||
/* if there is no info for the region it can't be a sub RM */
|
||||
Dataspace_capability ds_cap = region->ds;
|
||||
typedef Object_pool<Dataspace_info>::Guard Info_guard;
|
||||
Info_guard info(_ds_registry.lookup_info(ds_cap));
|
||||
if (!info) { return cap(); }
|
||||
|
||||
/* ask the dataspace info for an appropriate sub RM */
|
||||
addr_t const region_base = region->local_addr;
|
||||
addr_t const region_off = region->offset;
|
||||
addr_t const sub_addr = addr - region_base + region_off;
|
||||
Rm_session_capability sub_rm = info->lookup_rm_session(sub_addr);
|
||||
|
||||
/* if the result is invalid the dataspace is no sub RM */
|
||||
if (!sub_rm.valid()) { return cap(); }
|
||||
return sub_rm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replay attachments onto specified RM session
|
||||
*
|
||||
|
@ -219,12 +259,10 @@ namespace Noux {
|
|||
/*
|
||||
* Rm_session subtracts offset from size if size is 0
|
||||
*/
|
||||
if (size == 0)
|
||||
size = Dataspace_client(ds).size() - offset;
|
||||
if (size == 0) size = Dataspace_client(ds).size() - offset;
|
||||
|
||||
local_addr = _rm.attach(ds, size, offset,
|
||||
use_local_addr, local_addr,
|
||||
executable);
|
||||
local_addr = _rm.attach(ds, size, offset, use_local_addr,
|
||||
local_addr, executable);
|
||||
|
||||
Region * region = new (env()->heap())
|
||||
Region(*this, ds, size, offset, local_addr);
|
||||
|
@ -252,7 +290,6 @@ namespace Noux {
|
|||
Lock::Guard guard(_region_lock);
|
||||
_regions.insert(region);
|
||||
|
||||
|
||||
return local_addr;
|
||||
}
|
||||
|
||||
|
@ -273,8 +310,7 @@ namespace Noux {
|
|||
|
||||
{
|
||||
Object_pool<Dataspace_info>::Guard info(_ds_registry.lookup_info(region->ds));
|
||||
if (info)
|
||||
info->unregister_user(*region);
|
||||
if (info) info->unregister_user(*region);
|
||||
}
|
||||
|
||||
destroy(env()->heap(), region);
|
||||
|
@ -310,10 +346,10 @@ namespace Noux {
|
|||
};
|
||||
|
||||
|
||||
inline void Rm_session_component::Region::dissolve(Dataspace_info &ds)
|
||||
inline void Noux::Rm_session_component::Region::dissolve(Dataspace_info &ds)
|
||||
{
|
||||
rm.detach(local_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* _NOUX__RM_SESSION_COMPONENT_H_ */
|
||||
|
|
Loading…
Reference in New Issue