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:
Martin Stein 2014-01-28 14:07:36 +01:00 committed by Norman Feske
parent f7149623ca
commit c2af646ad8
7 changed files with 334 additions and 250 deletions

View File

@ -48,6 +48,11 @@ namespace Noux {
{ {
return call<Rpc_next_open_fd>(start_fd); 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);
}
}; };
} }

View File

@ -17,6 +17,7 @@
#include <base/stdint.h> #include <base/stdint.h>
#include <session/session.h> #include <session/session.h>
#include <dataspace/capability.h> #include <dataspace/capability.h>
#include <rm_session/capability.h>
#define NOUX_DECL_SYSCALL_NAME(name) \ #define NOUX_DECL_SYSCALL_NAME(name) \
case SYSCALL_##name: return #name; case SYSCALL_##name: return #name;
@ -33,6 +34,13 @@ namespace Noux {
virtual Dataspace_capability sysio_dataspace() = 0; 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 { enum Syscall {
SYSCALL_WRITE, SYSCALL_WRITE,
SYSCALL_READ, SYSCALL_READ,
@ -154,10 +162,13 @@ namespace Noux {
*********************/ *********************/
GENODE_RPC(Rpc_sysio_dataspace, Dataspace_capability, sysio_dataspace); 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_syscall, bool, syscall, Syscall);
GENODE_RPC(Rpc_next_open_fd, int, next_open_fd, int); 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);
}; };
} }

View File

@ -86,6 +86,16 @@ class Noux_connection
_sysio = _obtain_sysio(); _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::Session *session() { return &_connection; }
Noux::Sysio *sysio() { return _sysio; } Noux::Sysio *sysio() { return _sysio; }
}; };

View File

@ -425,6 +425,11 @@ namespace Noux {
return _sysio_ds.cap(); 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); bool syscall(Syscall sc);
int next_open_fd(int start_fd) int next_open_fd(int start_fd)

View File

@ -103,6 +103,17 @@ namespace Noux {
* \param len length of source buffer in bytes * \param len length of source buffer in bytes
*/ */
virtual void poke(addr_t dst_offset, void const *src, size_t len) = 0; 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();
}
}; };

View File

@ -85,6 +85,12 @@ namespace Noux {
} }
_sub_rm->poke(dst_offset, src, len); _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);
}
}; };

View File

@ -1,6 +1,7 @@
/* /*
* \brief RM session implementation used by Noux processes * \brief RM session implementation used by Noux processes
* \author Norman Feske * \author Norman Feske
* \author Martin Stein
* \date 2012-02-22 * \date 2012-02-22
* *
* The custom RM implementation is used for recording all RM regions attached * The custom RM implementation is used for recording all RM regions attached
@ -22,12 +23,18 @@
#include <rm_session/connection.h> #include <rm_session/connection.h>
#include <base/rpc_server.h> #include <base/rpc_server.h>
namespace Noux { namespace Noux
{
static bool verbose_attach = false; 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: private:
/** /**
@ -54,8 +61,7 @@ namespace Noux {
*/ */
bool contains(addr_t addr) const bool contains(addr_t addr) const
{ {
return (addr >= local_addr) return (addr >= local_addr) && (addr < local_addr + size);
&& (addr < local_addr + size);
} }
Region *next_region() Region *next_region()
@ -88,12 +94,18 @@ namespace Noux {
public: public:
Rm_session_component(Dataspace_registry &ds_registry, /**
* Constructor
*/
Rm_session_component(Dataspace_registry & ds_registry,
addr_t start = ~0UL, size_t size = 0) addr_t start = ~0UL, size_t size = 0)
: :
_rm(start, size), _ds_registry(ds_registry) _rm(start, size), _ds_registry(ds_registry)
{ } { }
/**
* Destructor
*/
~Rm_session_component() ~Rm_session_component()
{ {
Region *curr; Region *curr;
@ -101,6 +113,34 @@ namespace Noux {
detach(curr->local_addr); 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 * Replay attachments onto specified RM session
* *
@ -219,14 +259,12 @@ namespace Noux {
/* /*
* Rm_session subtracts offset from size if size is 0 * Rm_session subtracts offset from size if size is 0
*/ */
if (size == 0) if (size == 0) size = Dataspace_client(ds).size() - offset;
size = Dataspace_client(ds).size() - offset;
local_addr = _rm.attach(ds, size, offset, local_addr = _rm.attach(ds, size, offset, use_local_addr,
use_local_addr, local_addr, local_addr, executable);
executable);
Region *region = new (env()->heap()) Region * region = new (env()->heap())
Region(*this, ds, size, offset, local_addr); Region(*this, ds, size, offset, local_addr);
/* register region as user of RAM dataspaces */ /* register region as user of RAM dataspaces */
@ -252,7 +290,6 @@ namespace Noux {
Lock::Guard guard(_region_lock); Lock::Guard guard(_region_lock);
_regions.insert(region); _regions.insert(region);
return local_addr; return local_addr;
} }
@ -273,8 +310,7 @@ namespace Noux {
{ {
Object_pool<Dataspace_info>::Guard info(_ds_registry.lookup_info(region->ds)); Object_pool<Dataspace_info>::Guard info(_ds_registry.lookup_info(region->ds));
if (info) if (info) info->unregister_user(*region);
info->unregister_user(*region);
} }
destroy(env()->heap(), region); destroy(env()->heap(), region);
@ -307,13 +343,13 @@ namespace Noux {
{ {
return _rm.dataspace(); return _rm.dataspace();
} }
}; };
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); rm.detach(local_addr);
}
} }
#endif /* _NOUX__RM_SESSION_COMPONENT_H_ */ #endif /* _NOUX__RM_SESSION_COMPONENT_H_ */