From 3ac3236a288f3ea2f9b58f7b06b7410c1d7a8a81 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Tue, 31 Jan 2017 18:03:11 +0100 Subject: [PATCH] Noux: 'empty' ROM service for initial ROMs The initial ROMs (program and linker) are already attached to the region map of a forked process and don't need to be obtained again from an external ROM service when the 'Child' class asks for them. For the program image, the local Noux ROM service already returned an invalid dataspace capability, but not for the linker. Instead of adding another 'magic' ROM name for the local ROM service, this commit implements an 'empty' ROM service, which returns an invalid dataspace for the initial ROMs. Fixes #2272 --- repos/ports/src/noux/child.h | 10 +-- repos/ports/src/noux/child_policy.h | 26 +++++--- repos/ports/src/noux/empty_rom_service.h | 61 +++++++++++++++++++ .../src/noux/empty_rom_session_component.h | 58 ++++++++++++++++++ repos/ports/src/noux/rom_session_component.h | 13 ---- 5 files changed, 141 insertions(+), 27 deletions(-) create mode 100644 repos/ports/src/noux/empty_rom_service.h create mode 100644 repos/ports/src/noux/empty_rom_session_component.h diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h index bffd9871fe..e63b020922 100644 --- a/repos/ports/src/noux/child.h +++ b/repos/ports/src/noux/child.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,8 @@ class Noux::Child : public Rpc_object, /* * Locally-provided ROM service */ + Empty_rom_factory _empty_rom_factory { _heap, _ep }; + Empty_rom_service _empty_rom_service { _empty_rom_factory }; Local_rom_factory _rom_factory { _heap, _env, _ep, _root_dir, _ds_registry }; Local_rom_service _rom_service { _rom_factory }; @@ -359,12 +362,11 @@ class Noux::Child : public Rpc_object, _args_ds_info(_ds_registry, _args.cap()), _sysio_env_ds_info(_ds_registry, _sysio_env.cap()), _config_ds_info(_ds_registry, _config.cap()), - _child_policy(name, - forked ? Rom_session_component::forked_magic_binary_name() - : name, + _child_policy(name, forked, _args.cap(), _sysio_env.cap(), _config.cap(), _ep, _pd_service, _ram_service, _cpu_service, - _noux_service, _rom_service, _parent_services, + _noux_service, _empty_rom_service, + _rom_service, _parent_services, *this, parent_exit, *this, _destruct_handler, ref_ram, ref_ram_cap, _verbose.enabled()), _child(_env.rm(), _ep, _child_policy) diff --git a/repos/ports/src/noux/child_policy.h b/repos/ports/src/noux/child_policy.h index 6f9f66603a..a87f79decd 100644 --- a/repos/ports/src/noux/child_policy.h +++ b/repos/ports/src/noux/child_policy.h @@ -21,6 +21,7 @@ #include #include #include +#include #include namespace Noux { @@ -42,7 +43,7 @@ class Noux::Child_policy : public Genode::Child_policy private: Name const _name; - Binary_name const _binary_name; + bool _forked; Init::Child_policy_provide_rom_file _args_policy; Init::Child_policy_provide_rom_file _env_policy; Init::Child_policy_provide_rom_file _config_policy; @@ -50,6 +51,7 @@ class Noux::Child_policy : public Genode::Child_policy Ram_service &_ram_service; Cpu_service &_cpu_service; Noux_service &_noux_service; + Empty_rom_service &_empty_rom_service; Local_rom_service &_rom_service; Parent_services &_parent_services; Family_member &_family_member; @@ -75,7 +77,7 @@ class Noux::Child_policy : public Genode::Child_policy public: Child_policy(Name const &name, - Binary_name const &binary_name, + bool forked, Dataspace_capability args_ds, Dataspace_capability env_ds, Dataspace_capability config_ds, @@ -84,6 +86,7 @@ class Noux::Child_policy : public Genode::Child_policy Ram_service &ram_service, Cpu_service &cpu_service, Noux_service &noux_service, + Empty_rom_service &empty_rom_service, Local_rom_service &rom_service, Parent_services &parent_services, Family_member &family_member, @@ -94,13 +97,13 @@ class Noux::Child_policy : public Genode::Child_policy Ram_session_capability ref_ram_cap, bool verbose) : - _name(name), - _binary_name(binary_name), + _name(name), _forked(forked), _args_policy( "args", args_ds, &entrypoint), _env_policy( "env", env_ds, &entrypoint), _config_policy("config", config_ds, &entrypoint), _pd_service(pd_service), _ram_service(ram_service), _cpu_service(cpu_service), _noux_service(noux_service), + _empty_rom_service(empty_rom_service), _rom_service(rom_service), _parent_services(parent_services), _family_member(family_member), _parent_exit(parent_exit), @@ -117,8 +120,7 @@ class Noux::Child_policy : public Genode::Child_policy ** Child policy interface ** ****************************/ - Name name() const override { return _name; } - Binary_name binary_name() const override { return _binary_name; } + Name name() const override { return _name; } Ram_session &ref_ram() override { return _ref_ram; } @@ -134,10 +136,14 @@ class Noux::Child_policy : public Genode::Child_policy { Session_label const label(Genode::label_from_args(args.string())); - /* route initial ROM requests (binary and linker) to the parent */ - if (service_name == Genode::Rom_session::service_name()) { - if (label.last_element() == binary_name()) return _rom_service; - if (label.last_element() == linker_name()) return _rom_service; + /* + * Route initial ROM requests (binary and linker) of a forked child + * to the empty ROM service, since the ROMs are already attached in + * the replayed region map. + */ + if (_forked && (service_name == Genode::Rom_session::service_name())) { + if (label.last_element() == name()) return _empty_rom_service; + if (label.last_element() == linker_name()) return _empty_rom_service; } Genode::Service *service = nullptr; diff --git a/repos/ports/src/noux/empty_rom_service.h b/repos/ports/src/noux/empty_rom_service.h new file mode 100644 index 0000000000..59ab74e966 --- /dev/null +++ b/repos/ports/src/noux/empty_rom_service.h @@ -0,0 +1,61 @@ +/* + * \brief ROM service provided to Noux processes for initial ROMs + * \author Christian Prochaska + * \date 2017-01-31 + * + * The initial ROMs (binary and linker) are already attached in a forked + * child and don't need a new ROM dataspace. + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _NOUX__EMPTY_ROM_SERVICE_H_ +#define _NOUX__EMPTY_ROM_SERVICE_H_ + +/* Genode includes */ +#include + +/* Noux includes */ +#include + +namespace Noux { + + typedef Local_service Empty_rom_service; + class Empty_rom_factory; +} + + +class Noux::Empty_rom_factory : public Empty_rom_service::Factory +{ + private: + + Allocator &_alloc; + Rpc_entrypoint &_ep; + + public: + + Empty_rom_factory(Allocator &alloc, Rpc_entrypoint &ep) + : _alloc(alloc), _ep(ep) { } + + Empty_rom_session_component &create(Args const &args, Affinity) override + { + try { + return *new (_alloc) Empty_rom_session_component(_ep); + } + catch (Rom_connection::Rom_connection_failed) { throw Denied(); } + } + + void upgrade(Empty_rom_session_component &, Args const &) override { } + + void destroy(Empty_rom_session_component &session) override + { + Genode::destroy(_alloc, &session); + } +}; + +#endif /* _NOUX__EMPTY_ROM_SERVICE_H_ */ diff --git a/repos/ports/src/noux/empty_rom_session_component.h b/repos/ports/src/noux/empty_rom_session_component.h new file mode 100644 index 0000000000..4f29089ea0 --- /dev/null +++ b/repos/ports/src/noux/empty_rom_session_component.h @@ -0,0 +1,58 @@ +/* + * \brief ROM session implementation used by Noux processes for initial ROMs + * \author Christian Prochaska + * \date 2017-01-31 + * + * The initial ROMs (binary and linker) are already attached in a forked + * child and don't need a new ROM dataspace. The invalid dataspace returned + * by this component is handled in 'Child::Process'. + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ +#define _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ + +/* Genode includes */ +#include + +namespace Noux { class Empty_rom_session_component; } + +class Noux::Empty_rom_session_component : public Rpc_object +{ + private: + + Rpc_entrypoint &_ep; + + public: + + Empty_rom_session_component(Rpc_entrypoint &ep) + : _ep(ep) + { + _ep.manage(this); + } + + ~Empty_rom_session_component() + { + _ep.dissolve(this); + } + + + /*************************** + ** ROM session interface ** + ***************************/ + + Rom_dataspace_capability dataspace() + { + return Rom_dataspace_capability(); + } + + void sigh(Signal_context_capability) { } +}; + +#endif /* _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/noux/rom_session_component.h b/repos/ports/src/noux/rom_session_component.h index 861cc1510f..492f8b69f6 100644 --- a/repos/ports/src/noux/rom_session_component.h +++ b/repos/ports/src/noux/rom_session_component.h @@ -62,16 +62,6 @@ class Noux::Rom_session_component : public Rpc_object typedef Child_policy::Name Name; - /** - * Label of ROM session requested for the binary of a forked process - * - * In this case, the loading of the binary must be omitted because the - * address space is replayed by the fork operation. Hence, requests for - * such ROM modules are answered by an invalid dataspace, which is - * handled in 'Child::Process'. - */ - static Name forked_magic_binary_name() { return "(forked)"; } - private: Allocator &_alloc; @@ -111,9 +101,6 @@ class Noux::Rom_session_component : public Rpc_object return _rom_from_vfs->ds; } - if (name == forked_magic_binary_name()) - return Dataspace_capability(); - _rom_from_parent.construct(env, name.string()); Dataspace_capability ds = _rom_from_parent->dataspace(); return ds;