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);
|
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 <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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user