mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 22:23:16 +00:00
base/child.h: Child_policy::with_address_space
This patch replaces the former 'address_space' accessor by a new 'with_address_space' interface that grants access to the region map of the child's address space, but limits the interface lifetime to the scope of the caller. Issue #4917
This commit is contained in:
parent
f47c64e246
commit
30b70da6c1
@ -125,6 +125,11 @@ struct Genode::Child_policy
|
|||||||
virtual Pd_session &ref_pd() = 0;
|
virtual Pd_session &ref_pd() = 0;
|
||||||
virtual Pd_session_capability ref_pd_cap() const = 0;
|
virtual Pd_session_capability ref_pd_cap() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RAM allocator used as backing store for '_session_md_alloc'
|
||||||
|
*/
|
||||||
|
virtual Ram_allocator &session_md_ram() { return ref_pd(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Respond to the release of resources by the child
|
* Respond to the release of resources by the child
|
||||||
*
|
*
|
||||||
@ -188,22 +193,38 @@ struct Genode::Child_policy
|
|||||||
*/
|
*/
|
||||||
virtual bool initiate_env_sessions() const { return true; }
|
virtual bool initiate_env_sessions() const { return true; }
|
||||||
|
|
||||||
|
struct With_address_space_fn : Interface
|
||||||
|
{
|
||||||
|
virtual void call(Region_map &) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void _with_address_space(Pd_session &pd, With_address_space_fn const &fn)
|
||||||
|
{
|
||||||
|
Region_map_client region_map(pd.address_space());
|
||||||
|
fn.call(region_map);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return region map for the child's address space
|
* Call functor 'fn' with the child's address-space region map as argument
|
||||||
*
|
*
|
||||||
* \param pd the child's PD session capability
|
* In the common case where the child's PD is provided by core, the address
|
||||||
*
|
* space is accessed via the 'Region_map' RPC interface. However, in cases
|
||||||
* By default, the function returns a 'nullptr'. In this case, the 'Child'
|
* where the child's PD session interface is locally implemented - as is
|
||||||
* interacts with the address space of the child's PD session via RPC calls
|
* the case for a debug monitor - the address space must be accessed by
|
||||||
* to the 'Pd_session::address_space'.
|
* component-local method calls instead.
|
||||||
*
|
|
||||||
* By overriding the default, those RPC calls can be omitted, which is
|
|
||||||
* useful if the child's PD session (including the PD's address space) is
|
|
||||||
* virtualized by the parent. If the virtual PD session is served by the
|
|
||||||
* same entrypoint as the child's parent interface, an RPC call to 'pd'
|
|
||||||
* would otherwise produce a deadlock.
|
|
||||||
*/
|
*/
|
||||||
virtual Region_map *address_space(Pd_session &) { return nullptr; }
|
template <typename FN>
|
||||||
|
void with_address_space(Pd_session &pd, FN const &fn)
|
||||||
|
{
|
||||||
|
struct Impl : With_address_space_fn
|
||||||
|
{
|
||||||
|
FN const &_fn;
|
||||||
|
Impl(FN const &fn) : _fn(fn) { };
|
||||||
|
void call(Region_map &rm) const override { _fn(rm); }
|
||||||
|
};
|
||||||
|
|
||||||
|
_with_address_space(pd, Impl(fn));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if ELF loading should be inhibited
|
* Return true if ELF loading should be inhibited
|
||||||
@ -307,7 +328,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
Id_space<Client> _id_space { };
|
Id_space<Client> _id_space { };
|
||||||
|
|
||||||
/* allocator used for dynamically created session state objects */
|
/* allocator used for dynamically created session state objects */
|
||||||
Sliced_heap _session_md_alloc { _policy.ref_pd(), _local_rm };
|
Sliced_heap _session_md_alloc { _policy.session_md_ram(), _local_rm };
|
||||||
|
|
||||||
Session_state::Factory::Batch_size const
|
Session_state::Factory::Batch_size const
|
||||||
_session_batch_size { _policy.session_alloc_batch_size() };
|
_session_batch_size { _policy.session_alloc_batch_size() };
|
||||||
|
@ -731,30 +731,6 @@ void Child::heartbeat_sigh(Signal_context_capability sigh)
|
|||||||
void Child::heartbeat_response() { _outstanding_heartbeats = 0; }
|
void Child::heartbeat_response() { _outstanding_heartbeats = 0; }
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return interface for interacting with the child's address space
|
|
||||||
*
|
|
||||||
* Depending on the return value of 'Child_policy::address_space', we
|
|
||||||
* either interact with a local object of via an RPC client stub.
|
|
||||||
*/
|
|
||||||
struct Child_address_space
|
|
||||||
{
|
|
||||||
Region_map_client _rm_client;
|
|
||||||
Region_map &_rm;
|
|
||||||
|
|
||||||
Child_address_space(Pd_session &pd, Child_policy &policy)
|
|
||||||
:
|
|
||||||
_rm_client(pd.address_space()),
|
|
||||||
_rm(policy.address_space(pd) ? *policy.address_space(pd) : _rm_client)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Region_map ®ion_map() { return _rm; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Child::_try_construct_env_dependent_members()
|
void Child::_try_construct_env_dependent_members()
|
||||||
{
|
{
|
||||||
/* check if the environment sessions are complete */
|
/* check if the environment sessions are complete */
|
||||||
@ -788,10 +764,9 @@ void Child::_try_construct_env_dependent_members()
|
|||||||
? Process::TYPE_FORKED : Process::TYPE_LOADED;
|
? Process::TYPE_FORKED : Process::TYPE_LOADED;
|
||||||
try {
|
try {
|
||||||
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
|
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
|
||||||
|
_policy.with_address_space(_pd.session(), [&] (Region_map &address_space) {
|
||||||
_process.construct(type, _linker_dataspace(), _pd.session(),
|
_process.construct(type, _linker_dataspace(), _pd.session(),
|
||||||
*_initial_thread, _local_rm,
|
*_initial_thread, _local_rm, address_space, cap()); });
|
||||||
Child_address_space(_pd.session(), _policy).region_map(),
|
|
||||||
cap());
|
|
||||||
}
|
}
|
||||||
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
|
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
|
||||||
catch (Out_of_caps) { _error("out of caps during ELF loading"); }
|
catch (Out_of_caps) { _error("out of caps during ELF loading"); }
|
||||||
|
Loading…
Reference in New Issue
Block a user