mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-19 19:26:29 +00:00
parent
27a5edaf78
commit
47e95d4e18
@ -281,6 +281,11 @@ namespace Genode {
|
|||||||
/* RM session representing the address space of the child */
|
/* RM session representing the address space of the child */
|
||||||
Rm_session_capability _rm;
|
Rm_session_capability _rm;
|
||||||
|
|
||||||
|
/* Services where the RAM, CPU, and RM resources come from */
|
||||||
|
Service &_ram_service;
|
||||||
|
Service &_cpu_service;
|
||||||
|
Service &_rm_service;
|
||||||
|
|
||||||
/* heap for child-specific allocations using the child's quota */
|
/* heap for child-specific allocations using the child's quota */
|
||||||
Heap _heap;
|
Heap _heap;
|
||||||
|
|
||||||
@ -349,6 +354,20 @@ namespace Genode {
|
|||||||
destroy(heap(), s);
|
destroy(heap(), s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return service interface targetting the parent
|
||||||
|
*
|
||||||
|
* The service returned by this function is used as default
|
||||||
|
* provider for the RAM, CPU, and RM resources of the child. It is
|
||||||
|
* solely used for targeting resource donations during
|
||||||
|
* 'Parent::upgrade_quota()' calls.
|
||||||
|
*/
|
||||||
|
static Service *_parent_service()
|
||||||
|
{
|
||||||
|
static Parent_service parent_service("");
|
||||||
|
return &parent_service;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -357,23 +376,38 @@ namespace Genode {
|
|||||||
* \param elf_ds dataspace containing the binary
|
* \param elf_ds dataspace containing the binary
|
||||||
* \param ram RAM session with the child's quota
|
* \param ram RAM session with the child's quota
|
||||||
* \param cpu CPU session with the child's quota
|
* \param cpu CPU session with the child's quota
|
||||||
|
* \param rm RM session representing the address space
|
||||||
|
* of the child
|
||||||
* \param entrypoint server entrypoint to serve the parent interface
|
* \param entrypoint server entrypoint to serve the parent interface
|
||||||
* \param policy child policy
|
* \param policy child policy
|
||||||
|
* \param ram_service provider of the 'ram' session
|
||||||
|
* \param cpu_service provider of the 'cpu' session
|
||||||
|
* \param rm_service provider of the 'rm' session
|
||||||
*
|
*
|
||||||
* If assigning a separate entry point to each child, the host of
|
* If assigning a separate entry point to each child, the host of
|
||||||
* multiple children is able to handle a blocking invocation of
|
* multiple children is able to handle a blocking invocation of
|
||||||
* the parent interface of one child while still maintaining the
|
* the parent interface of one child while still maintaining the
|
||||||
* service to other children, each having an independent entry
|
* service to other children, each having an independent entry
|
||||||
* point.
|
* point.
|
||||||
|
*
|
||||||
|
* The 'ram_service', 'cpu_service', and 'rm_service' arguments are
|
||||||
|
* needed to direct quota upgrades referring to the resources of
|
||||||
|
* the child environment. By default, we expect that these
|
||||||
|
* resources are provided by the parent.
|
||||||
*/
|
*/
|
||||||
Child(Dataspace_capability elf_ds,
|
Child(Dataspace_capability elf_ds,
|
||||||
Ram_session_capability ram,
|
Ram_session_capability ram,
|
||||||
Cpu_session_capability cpu,
|
Cpu_session_capability cpu,
|
||||||
Rm_session_capability rm,
|
Rm_session_capability rm,
|
||||||
Rpc_entrypoint *entrypoint,
|
Rpc_entrypoint *entrypoint,
|
||||||
Child_policy *policy)
|
Child_policy *policy,
|
||||||
|
Service &ram_service = *_parent_service(),
|
||||||
|
Service &cpu_service = *_parent_service(),
|
||||||
|
Service &rm_service = *_parent_service())
|
||||||
:
|
:
|
||||||
_ram(ram), _ram_session_client(ram), _cpu(cpu), _rm(rm),
|
_ram(ram), _ram_session_client(ram), _cpu(cpu), _rm(rm),
|
||||||
|
_ram_service(ram_service), _cpu_service(cpu_service),
|
||||||
|
_rm_service(rm_service),
|
||||||
_heap(&_ram_session_client, env()->rm_session()),
|
_heap(&_ram_session_client, env()->rm_session()),
|
||||||
_entrypoint(entrypoint),
|
_entrypoint(entrypoint),
|
||||||
_parent_cap(_entrypoint->manage(this)),
|
_parent_cap(_entrypoint->manage(this)),
|
||||||
@ -493,10 +527,23 @@ namespace Genode {
|
|||||||
|
|
||||||
void upgrade(Session_capability to_session, Upgrade_args const &args)
|
void upgrade(Session_capability to_session, Upgrade_args const &args)
|
||||||
{
|
{
|
||||||
Session *s = _session_pool.obj_by_cap(to_session);
|
Service *targeted_service = 0;
|
||||||
|
|
||||||
if (!s) {
|
/* check of upgrade refers to an Env:: resource */
|
||||||
PWRN("no session structure found - nothing to be done\n");
|
if (to_session.local_name() == _ram.local_name())
|
||||||
|
targeted_service = &_ram_service;
|
||||||
|
if (to_session.local_name() == _cpu.local_name())
|
||||||
|
targeted_service = &_cpu_service;
|
||||||
|
if (to_session.local_name() == _rm.local_name())
|
||||||
|
targeted_service = &_rm_service;
|
||||||
|
|
||||||
|
/* check if upgrade refers to server */
|
||||||
|
Session * const session = _session_pool.obj_by_cap(to_session);
|
||||||
|
if (session)
|
||||||
|
targeted_service = session->service();
|
||||||
|
|
||||||
|
if (!targeted_service) {
|
||||||
|
PWRN("could not lookup service for session upgrade");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +552,8 @@ namespace Genode {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ram_quota = Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0);
|
size_t const ram_quota =
|
||||||
|
Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0);
|
||||||
|
|
||||||
/* transfer quota from client to ourself */
|
/* transfer quota from client to ourself */
|
||||||
Transfer donation_from_child(ram_quota, _ram,
|
Transfer donation_from_child(ram_quota, _ram,
|
||||||
@ -513,13 +561,14 @@ namespace Genode {
|
|||||||
|
|
||||||
/* transfer session quota from ourself to the service provider */
|
/* transfer session quota from ourself to the service provider */
|
||||||
Transfer donation_to_service(ram_quota, env()->ram_session_cap(),
|
Transfer donation_to_service(ram_quota, env()->ram_session_cap(),
|
||||||
s->service()->ram_session_cap());
|
targeted_service->ram_session_cap());
|
||||||
|
|
||||||
try { s->service()->upgrade(to_session, args.string()); }
|
try { targeted_service->upgrade(to_session, args.string()); }
|
||||||
catch (Service::Quota_exceeded) { throw Quota_exceeded(); }
|
catch (Service::Quota_exceeded) { throw Quota_exceeded(); }
|
||||||
|
|
||||||
/* remember new amount attached to the session */
|
/* remember new amount attached to the session */
|
||||||
s->upgrade_ram_quota(ram_quota);
|
if (session)
|
||||||
|
session->upgrade_ram_quota(ram_quota);
|
||||||
|
|
||||||
/* finish transaction */
|
/* finish transaction */
|
||||||
donation_from_child.acknowledge();
|
donation_from_child.acknowledge();
|
||||||
|
Loading…
Reference in New Issue
Block a user