mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-30 02:28:54 +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_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
|
||||
*
|
||||
@ -188,22 +193,38 @@ struct Genode::Child_policy
|
||||
*/
|
||||
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
|
||||
*
|
||||
* By default, the function returns a 'nullptr'. In this case, the 'Child'
|
||||
* interacts with the address space of the child's PD session via RPC calls
|
||||
* to the 'Pd_session::address_space'.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
* where the child's PD session interface is locally implemented - as is
|
||||
* the case for a debug monitor - the address space must be accessed by
|
||||
* component-local method calls instead.
|
||||
*/
|
||||
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
|
||||
@ -307,7 +328,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
Id_space<Client> _id_space { };
|
||||
|
||||
/* 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_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; }
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
/* check if the environment sessions are complete */
|
||||
@ -788,10 +764,9 @@ void Child::_try_construct_env_dependent_members()
|
||||
? Process::TYPE_FORKED : Process::TYPE_LOADED;
|
||||
try {
|
||||
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
|
||||
_process.construct(type, _linker_dataspace(), _pd.session(),
|
||||
*_initial_thread, _local_rm,
|
||||
Child_address_space(_pd.session(), _policy).region_map(),
|
||||
cap());
|
||||
_policy.with_address_space(_pd.session(), [&] (Region_map &address_space) {
|
||||
_process.construct(type, _linker_dataspace(), _pd.session(),
|
||||
*_initial_thread, _local_rm, address_space, cap()); });
|
||||
}
|
||||
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
|
||||
catch (Out_of_caps) { _error("out of caps during ELF loading"); }
|
||||
|
Loading…
Reference in New Issue
Block a user