diff --git a/repos/base-fiasco/lib/mk/base.mk b/repos/base-fiasco/lib/mk/base.mk index 5d0f684c33..5e7bdf98c1 100644 --- a/repos/base-fiasco/lib/mk/base.mk +++ b/repos/base-fiasco/lib/mk/base.mk @@ -11,6 +11,7 @@ SRC_CC += cpu/cache.cc SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc SRC_CC += thread/thread_start.cc SRC_CC += irq/platform.cc +SRC_CC += server/rpc_cap_alloc.cc INC_DIR += $(BASE_DIR)/src/base/env diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index 72b747854e..210abfa6e2 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -2,9 +2,9 @@ TARGET = core GEN_CORE_DIR = $(BASE_DIR)/src/core -SRC_CC += cap_session_component.cc \ - context_area.cc \ +SRC_CC += context_area.cc \ core_printf.cc \ + core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ dataspace_component.cc \ @@ -19,6 +19,7 @@ SRC_CC += cap_session_component.cc \ pager_ep.cc \ pager_object.cc \ pd_session_component.cc \ + rpc_cap_factory.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ platform.cc \ @@ -50,6 +51,8 @@ vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-foc/include/foc_native_pd/client.h b/repos/base-foc/include/foc_native_pd/client.h new file mode 100644 index 0000000000..c4670d0727 --- /dev/null +++ b/repos/base-foc/include/foc_native_pd/client.h @@ -0,0 +1,32 @@ +/* + * \brief Client-side Fiasco.OC specific PD session interface + * \author Stefan Kalkowski + * \author Norman Feske + * \date 2011-04-14 + */ + +/* + * Copyright (C) 2011-2013 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 _INCLUDE__FOC_NATIVE_PD__CLIENT_H_ +#define _INCLUDE__FOC_NATIVE_PD__CLIENT_H_ + +#include +#include + +namespace Genode { struct Foc_native_pd_client; } + + +struct Genode::Foc_native_pd_client : Rpc_client +{ + explicit Foc_native_pd_client(Capability cap) + : Rpc_client(static_cap_cast(cap)) { } + + Native_capability task_cap() { return call(); } +}; + +#endif /* _INCLUDE__FOC_NATIVE_PD__CLIENT_H_ */ diff --git a/repos/base-foc/include/foc_native_pd/foc_native_pd.h b/repos/base-foc/include/foc_native_pd/foc_native_pd.h new file mode 100644 index 0000000000..e095b0e054 --- /dev/null +++ b/repos/base-foc/include/foc_native_pd/foc_native_pd.h @@ -0,0 +1,33 @@ +/* + * \brief Fiasco.OC-specific part of the PD session interface + * \author Stefan Kalkowski + * \author Norman Feske + * \date 2011-04-14 + */ + +/* + * Copyright (C) 2011-2016 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 _INCLUDE__FOC_NATIVE_PD__FOC_NATIVE_PD_H_ +#define _INCLUDE__FOC_NATIVE_PD__FOC_NATIVE_PD_H_ + +#include +#include +#include + +namespace Genode { struct Foc_native_pd; } + + +struct Genode::Foc_native_pd : Pd_session::Native_pd +{ + virtual Native_capability task_cap() = 0; + + GENODE_RPC(Rpc_task_cap, Native_capability, task_cap); + GENODE_RPC_INTERFACE(Rpc_task_cap); +}; + +#endif /* _INCLUDE__FOC_NATIVE_PD__FOC_NATIVE_PD_H_ */ diff --git a/repos/base-foc/include/foc_pd_session/client.h b/repos/base-foc/include/foc_pd_session/client.h deleted file mode 100644 index 62384d32a9..0000000000 --- a/repos/base-foc/include/foc_pd_session/client.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * \brief Client-side Fiasco.OC specific PD session interface - * \author Stefan Kalkowski - * \date 2011-04-14 - */ - -/* - * Copyright (C) 2011-2013 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 _INCLUDE__FOC_PD_SESSION__CLIENT_H_ -#define _INCLUDE__FOC_PD_SESSION__CLIENT_H_ - -#include -#include - -namespace Genode { - - struct Foc_pd_session_client : Rpc_client - { - explicit Foc_pd_session_client(Capability session) - : Rpc_client(session) { } - - int bind_thread(Thread_capability thread) { - return call(thread); } - - int assign_parent(Parent_capability parent) { - return call(parent); } - - Native_capability task_cap() { return call(); } - }; - -} - -#endif /* _INCLUDE__FOC_PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-foc/include/foc_pd_session/connection.h b/repos/base-foc/include/foc_pd_session/connection.h deleted file mode 100644 index 8ead46fcc5..0000000000 --- a/repos/base-foc/include/foc_pd_session/connection.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * \brief Connection to Fiasco.OC specific PD service - * \author Stefan Kalkowski - * \date 2011-04-14 - */ - -/* - * Copyright (C) 2011-2013 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 _INCLUDE__FOC_PD_SESSION__CONNECTION_H_ -#define _INCLUDE__FOC_PD_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { - - struct Foc_pd_connection : Connection, Foc_pd_session_client - { - /** - * Constructor - * - * \param args additional session arguments - */ - Foc_pd_connection(const char *args = 0) - : - Connection( - session("ram_quota=4K%s%s", - args ? ", " : "", - args ? args : "")), - Foc_pd_session_client(cap()) - { } - }; -} - -#endif /* _INCLUDE__FOC_PD_SESSION__CONNECTION_H_ */ diff --git a/repos/base-foc/include/foc_pd_session/foc_pd_session.h b/repos/base-foc/include/foc_pd_session/foc_pd_session.h deleted file mode 100644 index 1a6036d36e..0000000000 --- a/repos/base-foc/include/foc_pd_session/foc_pd_session.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * \brief Fiasco.OC specific PD session extension - * \author Stefan Kalkowski - * \date 2011-04-14 - */ - -/* - * Copyright (C) 2011-2013 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 _INCLUDE__FOC_PD_SESSION__FOC_PD_SESSION_H_ -#define _INCLUDE__FOC_PD_SESSION__FOC_PD_SESSION_H_ - -#include -#include -#include - -namespace Genode { - - struct Foc_pd_session : Pd_session - { - virtual ~Foc_pd_session() { } - - virtual Native_capability task_cap() = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_task_cap, Native_capability, task_cap); - - GENODE_RPC_INTERFACE_INHERIT(Pd_session, Rpc_task_cap); - }; -} - -#endif /* _INCLUDE__FOC_PD_SESSION__FOC_PD_SESSION_H_ */ diff --git a/repos/base-foc/lib/mk/base.mk b/repos/base-foc/lib/mk/base.mk index 451da5bcb4..459a00389b 100644 --- a/repos/base-foc/lib/mk/base.mk +++ b/repos/base-foc/lib/mk/base.mk @@ -12,6 +12,7 @@ SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc \ env/cap_map_remove.cc env/cap_alloc.cc SRC_CC += thread/thread_start.cc SRC_CC += irq/platform.cc +SRC_CC += server/rpc_cap_alloc.cc INC_DIR += $(BASE_DIR)/src/base/env diff --git a/repos/base-foc/src/base/server/server.cc b/repos/base-foc/src/base/server/server.cc index b4307b6d85..eff3039a9a 100644 --- a/repos/base-foc/src/base/server/server.cc +++ b/repos/base-foc/src/base/server/server.cc @@ -28,7 +28,7 @@ using namespace Genode; Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) { - Untyped_capability new_obj_cap = _cap_session->alloc(_cap); + Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap); /* add server object to object pool */ obj->cap(new_obj_cap); diff --git a/repos/base-foc/src/core/include/cap_index.h b/repos/base-foc/src/core/include/cap_index.h index cb5f3e4f37..f5340faf96 100644 --- a/repos/base-foc/src/core/include/cap_index.h +++ b/repos/base-foc/src/core/include/cap_index.h @@ -17,33 +17,32 @@ /* Genode includes */ #include -/* Core includes */ -#include - namespace Genode { class Platform_thread; + class Pd_session_component; + class Core_cap_index : public Cap_index { private: - Cap_session_component *_session; + Pd_session_component *_session; Platform_thread *_pt; Native_thread _gate; public: - Core_cap_index(Cap_session_component *session = 0, - Platform_thread *pt = 0, - Native_thread gate = Native_thread() ) + Core_cap_index(Pd_session_component *session = 0, + Platform_thread *pt = 0, + Native_thread gate = Native_thread() ) : _session(session), _pt(pt), _gate(gate) {} - Cap_session_component *session() { return _session; } - Platform_thread *pt() { return _pt; } - Native_thread gate() { return _gate; } + Pd_session_component *session() { return _session; } + Platform_thread *pt() { return _pt; } + Native_thread gate() { return _gate; } - void session(Cap_session_component* c) { _session = c; } - void pt(Platform_thread* t) { _pt = t; } + void session(Pd_session_component *c) { _session = c; } + void pt(Platform_thread *t) { _pt = t; } }; } diff --git a/repos/base-foc/src/core/include/cap_session_component.h b/repos/base-foc/src/core/include/cap_session_component.h deleted file mode 100644 index 0a23e52e45..0000000000 --- a/repos/base-foc/src/core/include/cap_session_component.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * \brief Capability session service - * \author Stefan Kalkowski - * \date 2011-01-13 - */ - -/* - * Copyright (C) 2011-2013 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 _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include - -namespace Genode { - - class Cap_session_component : public Rpc_object - { - private: - - struct Entry : Object_pool::Entry - { - Entry(Native_capability cap) : Object_pool::Entry(cap) {} - }; - - Object_pool _pool; - Allocator *_md_alloc; - - public: - - Cap_session_component(Allocator *md_alloc, const char *args) - : _md_alloc(md_alloc) {} - - ~Cap_session_component(); - - void upgrade_ram_quota(size_t ram_quota) { } - - Native_capability alloc(Native_capability ep); - - void free(Native_capability cap); - }; -} - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base-foc/src/core/include/native_pd_component.h b/repos/base-foc/src/core/include/native_pd_component.h new file mode 100644 index 0000000000..0fea6f1e97 --- /dev/null +++ b/repos/base-foc/src/core/include/native_pd_component.h @@ -0,0 +1,45 @@ +/* + * \brief Kernel-specific part of the PD-session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ +#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ + +/* Genode includes */ +#include + +/* core-local includes */ +#include + +namespace Genode { + + class Pd_session_component; + class Native_pd_component; +} + + +class Genode::Native_pd_component : public Rpc_object +{ + private: + + Pd_session_component &_pd_session; + + public: + + Native_capability task_cap() override; + + Native_pd_component(Pd_session_component &pd, char const *args); + + ~Native_pd_component(); +}; + +#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */ diff --git a/repos/base-foc/src/core/include/pd_session_component.h b/repos/base-foc/src/core/include/pd_session_component.h deleted file mode 100644 index 63c0d0b7c1..0000000000 --- a/repos/base-foc/src/core/include/pd_session_component.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * \brief Core-specific instance of the PD session interface - * \author Christian Helmuth - * \author Stefan Kalkowski - * \date 2006-07-17 - */ - -/* - * Copyright (C) 2006-2013 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 _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include - -/* core includes */ -#include -#include - -namespace Genode { class Pd_session_component; } - - -class Genode::Pd_session_component : public Rpc_object -{ - private: - - Allocator_guard _md_alloc; /* guarded meta-data allocator */ - Platform_pd _pd; - Capability _parent; - Rpc_entrypoint &_thread_ep; - Signal_broker _signal_broker; - - size_t _ram_quota(char const * args) { - return Arg_string::find_arg(args, "ram_quota").long_value(0); } - - public: - - Pd_session_component(Rpc_entrypoint &thread_ep, - Rpc_entrypoint &receiver_ep, - Rpc_entrypoint &context_ep, - Allocator &md_alloc, - char const *args) - : - _md_alloc(&md_alloc, _ram_quota(args)), - _thread_ep(thread_ep), - _signal_broker(_md_alloc, receiver_ep, context_ep) - { } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { - _md_alloc.upgrade(ram_quota); } - - - /************************** - ** PD session interface ** - **************************/ - - int bind_thread(Thread_capability) override; - - int assign_parent(Capability) override; - - bool assign_pci(addr_t, uint16_t) override - { - PWRN("not implemented"); return false; - }; - - Signal_source_capability alloc_signal_source() override { - return _signal_broker.alloc_signal_source(); } - - void free_signal_source(Signal_source_capability sig_rec_cap) override { - _signal_broker.free_signal_source(sig_rec_cap); } - - Signal_context_capability - alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override - { - try { - return _signal_broker.alloc_context(sig_rec_cap, imprint); } - catch (Genode::Allocator::Out_of_memory) { - throw Pd_session::Out_of_metadata(); } - } - - void free_context(Signal_context_capability cap) override { - _signal_broker.free_context(cap); } - - void submit(Signal_context_capability cap, unsigned n) override { - _signal_broker.submit(cap, n); } - - - /********************************** - ** Fiasco.OC specific functions ** - **********************************/ - - Native_capability task_cap(); -}; - -#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-foc/src/core/include/platform_pd.h b/repos/base-foc/src/core/include/platform_pd.h index 460b8411ca..d84a4d88a5 100644 --- a/repos/base-foc/src/core/include/platform_pd.h +++ b/repos/base-foc/src/core/include/platform_pd.h @@ -69,7 +69,7 @@ namespace Genode { /** * Constructor for all tasks except core. */ - Platform_pd(); + Platform_pd(Allocator *, char const *label); /** * Destructor diff --git a/repos/base-foc/src/core/include/platform_thread.h b/repos/base-foc/src/core/include/platform_thread.h index 62bce146bc..432d35bfb4 100644 --- a/repos/base-foc/src/core/include/platform_thread.h +++ b/repos/base-foc/src/core/include/platform_thread.h @@ -22,7 +22,6 @@ /* core includes */ #include #include -#include #include #include diff --git a/repos/base-foc/src/core/include/rpc_cap_factory.h b/repos/base-foc/src/core/include/rpc_cap_factory.h new file mode 100644 index 0000000000..46377ec772 --- /dev/null +++ b/repos/base-foc/src/core/include/rpc_cap_factory.h @@ -0,0 +1,47 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +/* Genode includes */ +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + struct Entry : Object_pool::Entry + { + Entry(Native_capability cap) : Object_pool::Entry(cap) {} + }; + + Object_pool _pool; + Allocator &_md_alloc; + + public: + + Rpc_cap_factory(Allocator &md_alloc) : _md_alloc(md_alloc) { } + + ~Rpc_cap_factory(); + + Native_capability alloc(Native_capability ep); + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-foc/src/core/native_pd_component.cc b/repos/base-foc/src/core/native_pd_component.cc new file mode 100644 index 0000000000..6edf90ff57 --- /dev/null +++ b/repos/base-foc/src/core/native_pd_component.cc @@ -0,0 +1,40 @@ +/* + * \brief Kernel-specific part of the PD-session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +#include +#include + +using namespace Genode; + + +Native_capability Native_pd_component::task_cap() +{ + return Native_capability(_pd_session._pd.native_task()); +} + + +Native_pd_component::Native_pd_component(Pd_session_component &pd_session, + char const *args) +: + _pd_session(pd_session) +{ + _pd_session._thread_ep.manage(this); +} + + +Native_pd_component::~Native_pd_component() +{ + _pd_session._thread_ep.dissolve(this); +} + + diff --git a/repos/base-foc/src/core/pager.cc b/repos/base-foc/src/core/pager.cc index 272d55d717..f8fa7951b1 100644 --- a/repos/base-foc/src/core/pager.cc +++ b/repos/base-foc/src/core/pager.cc @@ -138,7 +138,7 @@ void Pager_entrypoint::entry() void Pager_entrypoint::dissolve(Pager_object *obj) { /* cleanup at cap session */ - _cap_session->free(obj->Object_pool::Entry::cap()); + _cap_factory.free(obj->Object_pool::Entry::cap()); remove(obj); } @@ -148,7 +148,7 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj) { using namespace Fiasco; - Native_capability cap(_cap_session->alloc({Thread_base::_thread_cap})); + Native_capability cap(_cap_factory.alloc(Thread_base::_thread_cap)); /* add server object to object pool */ obj->cap(cap); diff --git a/repos/base-foc/src/core/pd_session_extension.cc b/repos/base-foc/src/core/pd_session_extension.cc deleted file mode 100644 index 84be0fdba5..0000000000 --- a/repos/base-foc/src/core/pd_session_extension.cc +++ /dev/null @@ -1,22 +0,0 @@ -/* - * \brief Core implementation of the PD session extension - * \author Stefan Kalkowski - * \date 2011-04-14 - */ - -/* - * Copyright (C) 2011-2013 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. - */ - -/* Genode includes */ -#include - -/* Core includes */ -#include - - -Genode::Native_capability Genode::Pd_session_component::task_cap() { - return Native_capability(_pd.native_task()); } diff --git a/repos/base-foc/src/core/platform_pd.cc b/repos/base-foc/src/core/platform_pd.cc index 23c433b5fc..dc4dc47fa6 100644 --- a/repos/base-foc/src/core/platform_pd.cc +++ b/repos/base-foc/src/core/platform_pd.cc @@ -111,7 +111,7 @@ Platform_pd::Platform_pd(Core_cap_index* i) } -Platform_pd::Platform_pd() +Platform_pd::Platform_pd(Allocator *, char const *) : _task(true, TASK_CAP) { for (unsigned i = 0; i < THREAD_MAX; i++) diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index 92d4a54027..eb1aa7927d 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -17,7 +17,6 @@ #include /* core includes */ -#include #include #include #include @@ -219,6 +218,13 @@ Affinity::Location Platform_thread::affinity() const } +static Rpc_cap_factory &thread_cap_factory() +{ + static Rpc_cap_factory inst(*platform()->core_mem_alloc()); + return inst; +} + + void Platform_thread::_create_thread() { l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP, @@ -226,13 +232,8 @@ void Platform_thread::_create_thread() if (l4_msgtag_has_error(tag)) PERR("cannot create more thread kernel-objects!"); - /* for core threads we can't use core_env, it is to early */ - static Cap_session_component core_thread_cap_session(0,""); - Cap_session &csc = (_core_thread) - ? core_thread_cap_session : *core_env()->cap_session(); - /* create initial gate for thread */ - _gate.local = csc.alloc(_thread.local); + _gate.local = thread_cap_factory().alloc(_thread.local); } @@ -316,7 +317,7 @@ Platform_thread::Platform_thread(const char *name) Platform_thread::~Platform_thread() { - core_env()->cap_session()->free(_gate.local); + thread_cap_factory().free(_gate.local); /* * We inform our protection domain about thread destruction, which will end up in diff --git a/repos/base-foc/src/core/cap_session_component.cc b/repos/base-foc/src/core/rpc_cap_factory.cc similarity index 90% rename from repos/base-foc/src/core/cap_session_component.cc rename to repos/base-foc/src/core/rpc_cap_factory.cc index e2a210044a..59ab721298 100644 --- a/repos/base-foc/src/core/cap_session_component.cc +++ b/repos/base-foc/src/core/rpc_cap_factory.cc @@ -1,11 +1,12 @@ /* - * \brief Fiasco.oc platform-specific capability allocation + * \brief Fiasco.OC-specific RPC capability factory * \author Stefan Kalkowski + * \author Norman Feske * \date 2011-01-13 */ /* - * Copyright (C) 2011-2013 Genode Labs GmbH + * Copyright (C) 2011-2016 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. @@ -17,7 +18,7 @@ #include /* core includes */ -#include +#include #include #include #include @@ -80,11 +81,11 @@ Cap_mapping::Cap_mapping(Native_capability cap, Native_thread_id r) : local(cap), remote(r) { } -/***************************** - ** Cap_session_component ** - *****************************/ +/*********************** + ** Rpc_cap_factory ** + ***********************/ -Native_capability Cap_session_component::alloc(Native_capability ep) +Native_capability Rpc_cap_factory::alloc(Native_capability ep) { Native_capability cap; @@ -124,7 +125,8 @@ Native_capability Cap_session_component::alloc(Native_capability ep) /* set debugger-name of ipc-gate to thread's name */ Fiasco::l4_debugger_set_object_name(idx->kcap(), ref->pt()->name()); - idx->session(this); + // XXX remove cast + idx->session((Pd_session_component *)this); idx->pt(ref->pt()); cap = Native_capability(idx); } catch (Cap_id_allocator::Out_of_ids) { @@ -138,20 +140,20 @@ Native_capability Cap_session_component::alloc(Native_capability ep) * doesn't have an allocator set. But this session gets never destroyed * so this is not an issue. */ - if (cap.valid() && _md_alloc) + if (cap.valid()) _pool.insert(new (_md_alloc) Entry(cap)); return cap; } -void Cap_session_component::free(Native_capability cap) +void Rpc_cap_factory::free(Native_capability cap) { using namespace Fiasco; if (!cap.valid()) return; /* proof whether the capability was created by this cap_session */ - if (static_cast(cap.idx())->session() != this) return; + if (static_cast(cap.idx())->session() != (Pd_session_component *)this) return; Entry * entry; _pool.apply(cap, [&] (Entry *e) { @@ -165,7 +167,7 @@ void Cap_session_component::free(Native_capability cap) } -Cap_session_component::~Cap_session_component() +Rpc_cap_factory::~Rpc_cap_factory() { _pool.remove_all([this] (Entry *e) { if (!e) return; diff --git a/repos/base-foc/src/core/target.inc b/repos/base-foc/src/core/target.inc index 89315c8406..1f4295f496 100644 --- a/repos/base-foc/src/core/target.inc +++ b/repos/base-foc/src/core/target.inc @@ -5,9 +5,9 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core LIBS += base-common -SRC_CC += cap_session_component.cc \ - context_area.cc \ +SRC_CC += context_area.cc \ core_printf.cc \ + core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_extension.cc \ dataspace_component.cc \ @@ -21,7 +21,10 @@ SRC_CC += cap_session_component.cc \ pager.cc \ pager_object.cc \ pd_session_component.cc \ - pd_session_extension.cc \ + pd_assign_pci.cc \ + pd_upgrade_ram_quota.cc \ + native_pd_component.cc \ + rpc_cap_factory.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ @@ -53,10 +56,13 @@ vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath main.cc $(GEN_CORE_DIR) vpath multiboot_info.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath pd_assign_pci.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath pager_object.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console vpath %.cc $(REP_DIR)/src/core diff --git a/repos/base-foc/src/core/thread_start.cc b/repos/base-foc/src/core/thread_start.cc index 664f53ef8b..bf751dd5a5 100644 --- a/repos/base-foc/src/core/thread_start.cc +++ b/repos/base-foc/src/core/thread_start.cc @@ -17,7 +17,6 @@ #include /* core includes */ -#include #include #include diff --git a/repos/base-hw/include/cap_session/connection.h b/repos/base-hw/include/cap_session/connection.h deleted file mode 100644 index 49e6c0965a..0000000000 --- a/repos/base-hw/include/cap_session/connection.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * \brief Connection to CAP service - * \author Stefan Kalkowski - * \author Norman Feske - * \date 2015-05-20 - * - * This is a shadow copy of the generic header in base, - * due to higher memory donation requirements in base-hw - */ - -/* - * Copyright (C) 2015 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 _INCLUDE__CAP_SESSION__CONNECTION_H_ -#define _INCLUDE__CAP_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { struct Cap_connection; } - - -struct Genode::Cap_connection : Connection, Cap_session_client -{ - Cap_connection() : Connection(session("ram_quota=8K")), - Cap_session_client(cap()) { } -}; - -#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */ diff --git a/repos/base-hw/include/pd_session/connection.h b/repos/base-hw/include/pd_session/connection.h index 297ab95217..9e4a51f65a 100644 --- a/repos/base-hw/include/pd_session/connection.h +++ b/repos/base-hw/include/pd_session/connection.h @@ -26,7 +26,7 @@ namespace Genode { struct Pd_connection; } struct Genode::Pd_connection : Connection, Pd_session_client { - enum { RAM_QUOTA = 28*1024 }; + enum { RAM_QUOTA = 36*1024 }; /** * Constructor diff --git a/repos/base-hw/lib/mk/base.mk b/repos/base-hw/lib/mk/base.mk index 1e30bbcb10..562d217dda 100644 --- a/repos/base-hw/lib/mk/base.mk +++ b/repos/base-hw/lib/mk/base.mk @@ -17,6 +17,7 @@ SRC_CC += thread/start.cc SRC_CC += irq/platform.cc SRC_CC += env.cc SRC_CC += capability.cc +SRC_CC += server/rpc_cap_alloc.cc # add include paths INC_DIR += $(REP_DIR)/src/base/lock diff --git a/repos/base-hw/lib/mk/core.inc b/repos/base-hw/lib/mk/core.inc index 9e9dd9880b..1b5989b916 100644 --- a/repos/base-hw/lib/mk/core.inc +++ b/repos/base-hw/lib/mk/core.inc @@ -23,6 +23,7 @@ SRC_CC += cpu_session_component.cc SRC_CC += cpu_session_support.cc SRC_CC += core_rm_session.cc SRC_CC += core_mem_alloc.cc +SRC_CC += core_rpc_cap_alloc.cc SRC_CC += dataspace_component.cc SRC_CC += dump_alloc.cc SRC_CC += io_mem_session_component.cc diff --git a/repos/base-hw/src/base/server/server.cc b/repos/base-hw/src/base/server/server.cc index 87b5ad9043..fcddad2a01 100644 --- a/repos/base-hw/src/base/server/server.cc +++ b/repos/base-hw/src/base/server/server.cc @@ -16,7 +16,6 @@ #include #include #include -#include using namespace Genode; @@ -27,15 +26,7 @@ using namespace Genode; Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) { - Untyped_capability new_obj_cap = - retry( - [&] () { return _cap_session->alloc(_cap); }, - [&] () { - Cap_session_client *client = - dynamic_cast(_cap_session); - if (client) - env()->parent()->upgrade(*client, "ram_quota=16K"); - }); + Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap); /* add server object to object pool */ obj->cap(new_obj_cap); diff --git a/repos/base-hw/src/core/include/cap_session_component.h b/repos/base-hw/src/core/include/cap_session_component.h deleted file mode 100644 index a712696bdb..0000000000 --- a/repos/base-hw/src/core/include/cap_session_component.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * \brief Capability allocation service - * \author Stefan Kalkowski - * \date 2015-03-05 - */ - -/* - * Copyright (C) 2015 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 _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ - -#include -#include -#include -#include -#include - -#include - -namespace Genode { class Cap_session_component; } - - -class Genode::Cap_session_component : public Rpc_object -{ - private: - - /** - * Kernel object placeholder hold in a list - */ - struct Kobject : List::Element - { - using Identity = Kernel::Core_object_identity; - - Native_capability cap; - - uint8_t data[sizeof(Identity)] - __attribute__((aligned(sizeof(addr_t)))); - }; - - using Slab = Tslab; - - Allocator_guard _guard; - uint8_t _initial_sb[get_page_size()]; /* initial slab block */ - Slab _slab; - List _list; - Lock _lock; - - /** - * Returns the right meta-data allocator, - * for core it returns a non-guarded one, otherwise a guard - */ - Allocator * _md_alloc(Allocator *md_alloc) - { - Allocator * core_mem_alloc = - static_cast(platform()->core_mem_alloc()); - return (md_alloc == core_mem_alloc) ? core_mem_alloc : &_guard; - } - - public: - - Cap_session_component(Allocator *md_alloc, const char *args) - : _guard(md_alloc, - Arg_string::find_arg(args, "ram_quota").long_value(0)), - _slab(_md_alloc(md_alloc), (Slab_block*)&_initial_sb) { } - - ~Cap_session_component() - { - Lock::Guard guard(_lock); - - while (Kobject * obj = _list.first()) { - Kernel::delete_obj(obj->data); - _list.remove(obj); - destroy(&_slab, obj); - } - } - - void upgrade_ram_quota(size_t ram_quota) { _guard.upgrade(ram_quota); } - - Native_capability alloc(Native_capability ep) - { - Lock::Guard guard(_lock); - - /* allocate kernel object */ - Kobject * obj; - if (!_slab.alloc(sizeof(Kobject), (void**)&obj)) - throw Out_of_metadata(); - construct_at(obj); - - /* create kernel object via syscall */ - obj->cap = Kernel::new_obj(obj->data, ep.dst()); - if (!obj->cap.valid()) { - PWRN("Invalid entrypoint %u for allocating a capability!", - ep.dst()); - destroy(&_slab, obj); - return Native_capability(); - } - - /* store it in the list and return result */ - _list.insert(obj); - return obj->cap; - } - - void free(Native_capability cap) - { - Lock::Guard guard(_lock); - - for (Kobject * obj = _list.first(); obj; obj = obj->next()) - if (obj->cap.dst() == cap.dst()) { - Kernel::delete_obj(obj->data); - _list.remove(obj); - destroy(&_slab, obj); - return; - } - } -}; - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base-hw/src/core/include/pager.h b/repos/base-hw/src/core/include/pager.h index 9bf06cb02e..c48fc7fc1a 100644 --- a/repos/base-hw/src/core/include/pager.h +++ b/repos/base-hw/src/core/include/pager.h @@ -20,12 +20,14 @@ #include #include #include + +/* core-local includes */ #include #include +#include namespace Genode { - class Cap_session; /** * Translation of a virtual page frame @@ -199,10 +201,8 @@ class Genode::Pager_entrypoint : public Object_pool, /** * Constructor - * - * \param a activation that shall handle the objects of the entrypoint */ - Pager_entrypoint(Cap_session * cap_session); + Pager_entrypoint(Rpc_cap_factory &); /** * Associate pager object 'obj' with entry point diff --git a/repos/base-hw/src/core/include/rpc_cap_factory.h b/repos/base-hw/src/core/include/rpc_cap_factory.h new file mode 100644 index 0000000000..03522f9a0a --- /dev/null +++ b/repos/base-hw/src/core/include/rpc_cap_factory.h @@ -0,0 +1,117 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include + +/* core-local includes */ +#include +#include + +namespace Genode { class Rpc_cap_factory; } + + +class Genode::Rpc_cap_factory +{ + private: + + /** + * Kernel object placeholder held in a list + */ + struct Kobject : List::Element + { + using Identity = Kernel::Core_object_identity; + + Native_capability cap; + + uint8_t data[sizeof(Identity)] + __attribute__((aligned(sizeof(addr_t)))); + }; + + using Slab = Tslab; + + uint8_t _initial_slab_block[get_page_size()]; + Slab _slab; + List _list; + Lock _lock; + + public: + + Rpc_cap_factory(Allocator &md_alloc) + : + _slab(&md_alloc, (Slab_block*)&_initial_slab_block) + { } + + ~Rpc_cap_factory() + { + Lock::Guard guard(_lock); + + while (Kobject * obj = _list.first()) { + Kernel::delete_obj(obj->data); + _list.remove(obj); + destroy(&_slab, obj); + } + } + + /** + * Allocate RPC capability + * + * \throw Allocator::Out_of_memory + */ + Native_capability alloc(Native_capability ep) + { + Lock::Guard guard(_lock); + + /* allocate kernel object */ + Kobject * obj; + if (!_slab.alloc(sizeof(Kobject), (void**)&obj)) + throw Allocator::Out_of_memory(); + construct_at(obj); + + /* create kernel object via syscall */ + obj->cap = Kernel::new_obj(obj->data, ep.dst()); + if (!obj->cap.valid()) { + PWRN("Invalid entrypoint %u for allocating a capability!", + ep.dst()); + destroy(&_slab, obj); + return Native_capability(); + } + + /* store it in the list and return result */ + _list.insert(obj); + return obj->cap; + } + + void free(Native_capability cap) + { + Lock::Guard guard(_lock); + + for (Kobject * obj = _list.first(); obj; obj = obj->next()) { + if (obj->cap.dst() == cap.dst()) { + Kernel::delete_obj(obj->data); + _list.remove(obj); + destroy(&_slab, obj); + return; + } + } + } +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-hw/src/core/pager.cc b/repos/base-hw/src/core/pager.cc index b14a0c2114..9d283a4fb1 100644 --- a/repos/base-hw/src/core/pager.cc +++ b/repos/base-hw/src/core/pager.cc @@ -108,7 +108,7 @@ void Pager_entrypoint::dissolve(Pager_object * const o) } -Pager_entrypoint::Pager_entrypoint(Cap_session *) +Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &) : Thread("pager_ep"), Kernel_object(true) { start(); } diff --git a/repos/base-linux/include/linux_native_pd/client.h b/repos/base-linux/include/linux_native_pd/client.h new file mode 100644 index 0000000000..87490685ca --- /dev/null +++ b/repos/base-linux/include/linux_native_pd/client.h @@ -0,0 +1,31 @@ +/* + * \brief Client-side of the Linux-specific PD session interface + * \author Norman Feske + * \date 2012-08-15 + */ + +/* + * Copyright (C) 2012-2013 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 _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ +#define _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ + +#include +#include + +namespace Genode { struct Linux_native_pd_client; } + +struct Genode::Linux_native_pd_client : Rpc_client +{ + explicit Linux_native_pd_client(Capability cap) + : Rpc_client(static_cap_cast(cap)) { } + + void start(Capability binary) { + call(binary); } +}; + +#endif /* _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-linux/include/linux_native_pd/linux_native_pd.h b/repos/base-linux/include/linux_native_pd/linux_native_pd.h new file mode 100644 index 0000000000..1a574ff14d --- /dev/null +++ b/repos/base-linux/include/linux_native_pd/linux_native_pd.h @@ -0,0 +1,31 @@ +/* + * \brief Linux-specific extension of the PD session interface + * \author Norman Feske + * \date 2012-08-15 + */ + +/* + * Copyright (C) 2012-2016 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 _INCLUDE__LINUX_NATIVE_PD__LINUX_NATIVE_PD_ +#define _INCLUDE__LINUX_NATIVE_PD__LINUX_NATIVE_PD_ + +#include +#include + +namespace Genode { struct Linux_native_pd; } + + +struct Genode::Linux_native_pd : Pd_session::Native_pd +{ + void start(Capability binary); + + GENODE_RPC(Rpc_start, void, start, Capability); + GENODE_RPC_INTERFACE(Rpc_start); +}; + +#endif /* _INCLUDE__LINUX_NATIVE_PD__LINUX_NATIVE_PD_ */ diff --git a/repos/base-linux/include/linux_pd_session/client.h b/repos/base-linux/include/linux_pd_session/client.h deleted file mode 100644 index 07302706d5..0000000000 --- a/repos/base-linux/include/linux_pd_session/client.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * \brief Client-side PD session interface - * \author Norman Feske - * \date 2012-08-15 - */ - -/* - * Copyright (C) 2012-2013 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 _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ -#define _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ - -#include -#include - -namespace Genode { struct Linux_pd_session_client; } - -struct Genode::Linux_pd_session_client : Rpc_client -{ - explicit Linux_pd_session_client(Capability session) - : Rpc_client(session) { } - - int bind_thread(Thread_capability thread) override { - return call(thread); } - - int assign_parent(Capability parent) override { - return call(parent); } - - bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override { - return call(pci_config_memory_address, bdf); } - - Signal_source_capability alloc_signal_source() override { - return call(); } - - void free_signal_source(Signal_source_capability cap) override { - call(cap); } - - Signal_context_capability alloc_context(Signal_source_capability source, - unsigned long imprint) override { - return call(source, imprint); } - - void free_context(Signal_context_capability cap) override { - call(cap); } - - void submit(Signal_context_capability receiver, unsigned cnt = 1) override { - call(receiver, cnt); } - - - /***************************** - * Linux-specific extension ** - *****************************/ - - void start(Capability binary) { - call(binary); } -}; - -#endif /* _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-linux/include/linux_pd_session/linux_pd_session.h b/repos/base-linux/include/linux_pd_session/linux_pd_session.h deleted file mode 100644 index 472f8305ad..0000000000 --- a/repos/base-linux/include/linux_pd_session/linux_pd_session.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * \brief Linux-specific extension of the PD session interface - * \author Norman Feske - * \date 2012-08-15 - */ - -/* - * Copyright (C) 2012-2013 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 _INCLUDE__LINUX_PD_SESSION__LINUX_PD_SESSION_H_ -#define _INCLUDE__LINUX_PD_SESSION__LINUX_PD_SESSION_H_ - -#include -#include - -namespace Genode { - - struct Linux_pd_session : Pd_session - { - void start(Capability binary); - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_start, void, start, Capability); - GENODE_RPC_INTERFACE_INHERIT(Pd_session, Rpc_start); - }; -} - -#endif /* _INCLUDE__LINUX_PD_SESSION__LINUX_PD_SESSION_H_ */ diff --git a/repos/base-linux/include/pd_session/connection.h b/repos/base-linux/include/pd_session/connection.h index 8038bdf7d4..cf4bf7c731 100644 --- a/repos/base-linux/include/pd_session/connection.h +++ b/repos/base-linux/include/pd_session/connection.h @@ -90,7 +90,7 @@ namespace Genode { Pd_connection(char const *label = "", Native_pd_args const *pd_args = 0) : Connection( - session("ram_quota=4K, label=\"%s\"%s%s%s", label, + session("ram_quota=36K, label=\"%s\"%s%s%s", label, Root_arg(pd_args).string, Uid_arg(pd_args).string, Gid_arg(pd_args).string)), diff --git a/repos/base-linux/lib/mk/base.inc b/repos/base-linux/lib/mk/base.inc index 0959490c56..dcc8d55a0e 100644 --- a/repos/base-linux/lib/mk/base.inc +++ b/repos/base-linux/lib/mk/base.inc @@ -11,6 +11,7 @@ LIBS += base-common syscall cxx SRC_CC += console/log_console.cc SRC_CC += env/env.cc env/platform_env.cc env/context_area.cc +SRC_CC += server/rpc_cap_alloc.cc INC_DIR += $(REP_DIR)/src/base/env $(BASE_DIR)/src/base/env diff --git a/repos/base-linux/lib/mk/base.mk b/repos/base-linux/lib/mk/base.mk index e5df321130..d0094b62f3 100644 --- a/repos/base-linux/lib/mk/base.mk +++ b/repos/base-linux/lib/mk/base.mk @@ -6,6 +6,7 @@ LIBS += startup cxx SRC_CC += thread/thread.cc thread/myself.cc thread/thread_linux.cc +SRC_CC += server/rpc_cap_alloc.cc vpath %.cc $(REP_DIR)/src/base vpath %.cc $(BASE_DIR)/src/base diff --git a/repos/base-linux/src/base/env/platform_env.h b/repos/base-linux/src/base/env/platform_env.h index b8b33d1c9c..85ec614c46 100644 --- a/repos/base-linux/src/base/env/platform_env.h +++ b/repos/base-linux/src/base/env/platform_env.h @@ -454,8 +454,8 @@ namespace Genode { ** Env interface ** *******************/ - Parent *parent() override { return &_parent(); } - Heap *heap() override { return &_heap; } + Parent *parent() override { return &_parent(); } + Heap *heap() override { return &_heap; } }; } diff --git a/repos/base-linux/src/base/process/process.cc b/repos/base-linux/src/base/process/process.cc index aaadff4422..ab885c797d 100644 --- a/repos/base-linux/src/base/process/process.cc +++ b/repos/base-linux/src/base/process/process.cc @@ -16,7 +16,7 @@ #include #include #include -#include +#include /* framework-internal includes */ #include @@ -84,10 +84,10 @@ Process::Process(Dataspace_capability elf_data_ds_cap, enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT }; _thread0_cap = _cpu_session_client.create_thread(WEIGHT, name); - Linux_pd_session_client - lx_pd(static_cap_cast(pd_session_cap)); + Linux_native_pd_client + lx_pd(static_cap_cast(_pd_session_client.native_pd())); - lx_pd.assign_parent(parent_cap); + _pd_session_client.assign_parent(parent_cap); lx_pd.start(elf_data_ds_cap); } diff --git a/repos/base-linux/src/core/include/cap_session_component.h b/repos/base-linux/src/core/include/cap_session_component.h deleted file mode 100644 index c033e640ec..0000000000 --- a/repos/base-linux/src/core/include/cap_session_component.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * \brief Capability allocation service - * \author Norman Feske - * \date 2006-06-26 - */ - -/* - * Copyright (C) 2006-2013 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 _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_ - -#include -#include -#include -#include - -namespace Genode { - - class Cap_session_component : public Rpc_object - { - private: - - static long _unique_id_cnt; - static Lock &_lock() - { - static Lock static_lock; - return static_lock; - } - - public: - - Cap_session_component(Allocator *md_alloc, const char *args) {} - - void upgrade_ram_quota(size_t ram_quota) { } - - Native_capability alloc(Native_capability ep) - { - Lock::Guard lock_guard(_lock()); - - return Native_capability(ep.dst(), ++_unique_id_cnt); - } - - void free(Native_capability cap) { } - }; -} - -#endif /* _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/include/core_env.h b/repos/base-linux/src/core/include/core_env.h index 67bcb6a0dc..e95aed2e8d 100644 --- a/repos/base-linux/src/core/include/core_env.h +++ b/repos/base-linux/src/core/include/core_env.h @@ -21,7 +21,7 @@ /* core includes */ #include #include -#include +#include #include #include @@ -127,9 +127,9 @@ namespace Genode { { enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) }; - Entrypoint(Cap_session *cap_session) + Entrypoint() : - Rpc_entrypoint(cap_session, STACK_SIZE, "entrypoint") + Rpc_entrypoint(nullptr, STACK_SIZE, "entrypoint") { } }; @@ -138,7 +138,6 @@ namespace Genode { typedef Synchronized_ram_session Core_ram_session; Core_parent _core_parent; - Cap_session_component _cap_session; Entrypoint _entrypoint; Core_ram_session _ram_session; @@ -165,8 +164,6 @@ namespace Genode { Platform_env_base(Ram_session_capability(), Cpu_session_capability(), Pd_session_capability()), - _cap_session(platform()->core_mem_alloc(), "ram_quota=4K"), - _entrypoint(&_cap_session), _ram_session(&_entrypoint, &_entrypoint, platform()->ram_alloc(), platform()->core_mem_alloc(), "ram_quota=4M", platform()->ram_alloc()->avail()), @@ -186,7 +183,6 @@ namespace Genode { ** Core-specific accessor functions ** **************************************/ - Cap_session *cap_session() { return &_cap_session; } Entrypoint *entrypoint() { return &_entrypoint; } @@ -194,13 +190,14 @@ namespace Genode { ** Env interface ** *******************/ - Parent *parent() { return &_core_parent; } - Ram_session *ram_session() { return &_ram_session; } - Ram_session_capability ram_session_cap() { return _ram_session_cap; } - Pd_session *pd_session() { return &_pd_session_client; } - Allocator *heap() { return &_heap; } + Parent *parent() override { return &_core_parent; } + Ram_session *ram_session() override { return &_ram_session; } + Ram_session_capability ram_session_cap() override { return _ram_session_cap; } + Pd_session *pd_session() override { return &_pd_session_client; } + Allocator *heap() override { return &_heap; } - Cpu_session_capability cpu_session_cap() { + Cpu_session_capability cpu_session_cap() + { PWRN("%s:%u not implemented", __FILE__, __LINE__); return Cpu_session_capability(); } diff --git a/repos/base-linux/src/core/include/native_pd_component.h b/repos/base-linux/src/core/include/native_pd_component.h new file mode 100644 index 0000000000..d182eac6b0 --- /dev/null +++ b/repos/base-linux/src/core/include/native_pd_component.h @@ -0,0 +1,53 @@ +/* + * \brief Kernel-specific part of the PD-session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ +#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ + +/* Genode includes */ +#include + +namespace Genode { + + class Dataspace_component; + class Pd_session_component; + class Native_pd_component; +} + + +class Genode::Native_pd_component : public Rpc_object +{ + private: + + enum { LABEL_MAX_LEN = 1024 }; + enum { ROOT_PATH_MAX_LEN = 512 }; + + Pd_session_component &_pd_session; + char _root[ROOT_PATH_MAX_LEN]; + unsigned long _pid = 0; + unsigned _uid = 0; + unsigned _gid = 0; + + void _start(Dataspace_component &ds); + + public: + + Native_pd_component(Pd_session_component &pd, char const *args); + + ~Native_pd_component(); + + void start(Capability binary); +}; + +#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/include/pager.h b/repos/base-linux/src/core/include/pager.h index dcf1f99bdd..ed56e0c2f8 100644 --- a/repos/base-linux/src/core/include/pager.h +++ b/repos/base-linux/src/core/include/pager.h @@ -17,11 +17,15 @@ #ifndef _CORE__INCLUDE__PAGER_H_ #define _CORE__INCLUDE__PAGER_H_ +/* Genode includes */ #include #include #include #include +/* core-local includes */ +#include + namespace Genode { struct Pager_object @@ -44,7 +48,7 @@ namespace Genode { struct Pager_entrypoint { - Pager_entrypoint(Cap_session *) { } + Pager_entrypoint(Rpc_cap_factory &) { } template auto apply(Pager_capability, FUNC f) -> decltype(f(nullptr)) { diff --git a/repos/base-linux/src/core/include/pd_session_component.h b/repos/base-linux/src/core/include/pd_session_component.h deleted file mode 100644 index e4e0623b57..0000000000 --- a/repos/base-linux/src/core/include/pd_session_component.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * \brief Linux-specific PD session - * \author Norman Feske - * \date 2012-08-15 - */ - -/* - * Copyright (C) 2012-2013 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 _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include - -/* core includes */ -#include -#include - -namespace Genode { - - class Dataspace_component; - class Pd_session_component; - class Parent; -} - - -class Genode::Pd_session_component : public Rpc_object -{ - private: - - enum { LABEL_MAX_LEN = 1024 }; - enum { ROOT_PATH_MAX_LEN = 512 }; - - unsigned long _pid; - char _label[LABEL_MAX_LEN]; - char _root[ROOT_PATH_MAX_LEN]; - unsigned _uid; - unsigned _gid; - Capability _parent; - Rpc_entrypoint &_ds_ep; - Signal_broker _signal_broker; - - void _start(Dataspace_component *ds); - - public: - - /** - * Constructor - * - * \param ds_ep entrypoint where the dataspaces are managed - * \param receiver_ep entrypoint holding signal-receiver component - * objects - * \param context_ep global pool of all signal contexts - * \param md_alloc meta-data allocator - * \param args additional session arguments - */ - Pd_session_component(Rpc_entrypoint &ds_ep, - Rpc_entrypoint &receiver_ep, - Rpc_entrypoint &context_ep, - Allocator &md_alloc, - const char *args); - - ~Pd_session_component(); - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { } - - - /************************** - ** PD session interface ** - **************************/ - - int bind_thread(Thread_capability); - int assign_parent(Capability); - bool assign_pci(addr_t, uint16_t) { return false; } - - Signal_source_capability alloc_signal_source() override { - return _signal_broker.alloc_signal_source(); } - - void free_signal_source(Signal_source_capability cap) override { - _signal_broker.free_signal_source(cap); } - - Signal_context_capability - alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override - { - return _signal_broker.alloc_context(sig_rec_cap, imprint); - } - - void free_context(Signal_context_capability cap) override { - _signal_broker.free_context(cap); } - - void submit(Signal_context_capability cap, unsigned n) override { - _signal_broker.submit(cap, n); } - - - /****************************** - ** Linux-specific extension ** - ******************************/ - - void start(Capability binary); -}; - -#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/include/platform_pd.h b/repos/base-linux/src/core/include/platform_pd.h index 9dfb68d2fa..8415b3dbec 100644 --- a/repos/base-linux/src/core/include/platform_pd.h +++ b/repos/base-linux/src/core/include/platform_pd.h @@ -16,10 +16,10 @@ #ifndef _CORE__INCLUDE__LINUX__PLATFORM_PD_H_ #define _CORE__INCLUDE__LINUX__PLATFORM_PD_H_ -namespace Genode { +#include - class Platform_pd - { }; -} +namespace Genode { struct Platform_pd; } + +struct Genode::Platform_pd { Platform_pd(Allocator *, char const *) { } }; #endif /* _CORE__INCLUDE__LINUX__PLATFORM_PD_H_ */ diff --git a/repos/base-linux/src/core/native_pd_component.cc b/repos/base-linux/src/core/native_pd_component.cc new file mode 100644 index 0000000000..f10bc4350a --- /dev/null +++ b/repos/base-linux/src/core/native_pd_component.cc @@ -0,0 +1,454 @@ +/* + * \brief Core implementation of the PD session interface + * \author Norman Feske + * \date 2012-08-15 + */ + +/* + * Copyright (C) 2012-2013 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. + */ + +/* Genode includes */ +#include +#include +#include + +/* core-local includes */ +#include +#include + +/* Linux includes */ +#include + +using namespace Genode; + + +/*********************************** + ** Utilities for chroot handling ** + ***********************************/ + +enum { MAX_PATH_LEN = 256 }; + + +/** + * Return true if specified path is an existing directory + */ +static bool is_directory(char const *path) +{ + struct stat64 s; + if (lx_stat(path, &s) != 0) + return false; + + if (!(s.st_mode & S_IFDIR)) + return false; + + return true; +} + + +static bool is_path_delimiter(char c) { return c == '/'; } + + +static bool has_trailing_path_delimiter(char const *path) +{ + char last_char = 0; + for (; *path; path++) + last_char = *path; + + return is_path_delimiter(last_char); +} + + +/** + * Return number of path elements of given path + */ +static Genode::size_t num_path_elements(char const *path) +{ + Genode::size_t count = 0; + + /* + * If path starts with non-slash, the first characters belongs to a path + * element. + */ + if (*path && !is_path_delimiter(*path)) + count = 1; + + /* count slashes */ + for (; *path; path++) + if (is_path_delimiter(*path)) + count++; + + return count; +} + + +static bool leading_path_elements(char const *path, unsigned num, + char *dst, Genode::size_t dst_len) +{ + /* counter of path delimiters */ + unsigned count = 0; + unsigned i = 0; + + if (is_path_delimiter(path[0])) + num++; + + for (; path[i] && (count < num) && (i < dst_len); i++) + { + if (is_path_delimiter(path[i])) + count++; + + if (count == num) + break; + + dst[i] = path[i]; + } + + if (i + 1 < dst_len) { + dst[i] = 0; + return true; + } + + /* string is cut, append null termination anyway */ + dst[dst_len - 1] = 0; + return false; +} + + +static void mirror_path_to_chroot(char const *chroot_path, char const *path) +{ + char target_path[MAX_PATH_LEN]; + Genode::snprintf(target_path, sizeof(target_path), "%s%s", + chroot_path, path); + + /* + * Create directory hierarchy pointing to the target path except for the + * last element. The last element will be bind-mounted to refer to the + * original 'path'. + */ + for (unsigned i = 1; i <= num_path_elements(target_path); i++) + { + char buf[MAX_PATH_LEN]; + leading_path_elements(target_path, i, buf, sizeof(buf)); + + /* skip existing directories */ + if (is_directory(buf)) + continue; + + /* create new directory */ + lx_mkdir(buf, 0777); + } + + lx_umount(target_path); + + int ret = 0; + if ((ret = lx_bindmount(path, target_path))) + PERR("bind mount failed (errno=%d)", ret); +} + + +/** + * Setup content of chroot environment as prerequisite to 'execve' new + * processes within the environment. I.e., the current working directory + * containing the ROM modules must be mounted at the same location within the + * chroot environment. + */ +static bool setup_chroot_environment(char const *chroot_path) +{ + using namespace Genode; + + static char cwd_path[MAX_PATH_LEN]; + + lx_getcwd(cwd_path, sizeof(cwd_path)); + + /* + * Validate chroot path + */ + if (!is_directory(chroot_path)) { + PERR("chroot path does not point to valid directory"); + return false; + } + + if (has_trailing_path_delimiter(chroot_path)) { + PERR("chroot path has trailing slash"); + return false; + } + + /* + * Hardlink directories needed for running Genode within the chroot + * environment. + */ + mirror_path_to_chroot(chroot_path, cwd_path); + + return true; +} + + +/*************** + ** Utilities ** + ***************/ + +/** + * Argument frame for passing 'execve' paremeters through 'clone' + */ +struct Execve_args +{ + char const *filename; + char const *root; + char * const *argv; + char * const *envp; + unsigned int const uid; + unsigned int const gid; + int const parent_sd; + + Execve_args(char const *filename, + char const *root, + char * const *argv, + char * const *envp, + unsigned int uid, + unsigned int gid, + int parent_sd) + : + filename(filename), root(root), argv(argv), envp(envp), + uid(uid), gid(gid), parent_sd(parent_sd) + { } +}; + + +/** + * Startup code of the new child process + */ +static int _exec_child(Execve_args *arg) +{ + lx_dup2(arg->parent_sd, PARENT_SOCKET_HANDLE); + + /* change to chroot environment */ + if (arg->root && arg->root[0]) { + char cwd[1024]; + + PDBG("arg->root='%s'", arg->root); + + if (setup_chroot_environment(arg->root) == false) { + PERR("Could not setup chroot environment"); + return -1; + } + + if (!lx_getcwd(cwd, sizeof(cwd))) { + PERR("Failed to getcwd"); + return -1; + } + + PLOG("changing root of %s (PID %d) to %s", + arg->filename, lx_getpid(), arg->root); + + int ret = lx_chroot(arg->root); + if (ret < 0) { + PERR("Syscall chroot failed (errno %d)", ret); + return -1; + } + + ret = lx_chdir(cwd); + if (ret < 0) { + PERR("chdir to new chroot failed"); + return -1; + } + } + + /* + * Set UID and GID + * + * We must set the GID prior setting the UID because setting the GID won't + * be possible anymore once we set the UID to non-root. + */ + if (arg->gid) { + int const ret = lx_setgid(arg->gid); + if (ret) + PWRN("Could not set PID %d (%s) to GID %u (error %d)", + lx_getpid(), arg->filename, arg->gid, ret); + } + if (arg->uid) { + int const ret = lx_setuid(arg->uid); + if (ret) + PWRN("Could not set PID %d (%s) to UID %u (error %d)", + lx_getpid(), arg->filename, arg->uid, ret); + } + + return lx_execve(arg->filename, arg->argv, arg->envp); +} + + +/** + * List of Unix environment variables, initialized by the startup code + */ +extern char **lx_environ; + + +/** + * Read environment variable as string + * + * If no matching key exists, return an empty string. + */ +static const char *get_env(const char *key) +{ + Genode::size_t key_len = Genode::strlen(key); + for (char **curr = lx_environ; curr && *curr; curr++) + if ((Genode::strcmp(*curr, key, key_len) == 0) && (*curr)[key_len] == '=') + return (const char *)(*curr + key_len + 1); + + return ""; +} + + +/************************** + ** PD session interface ** + **************************/ + +void Native_pd_component::_start(Dataspace_component &ds) +{ + const char *tmp_filename = "temporary_executable_elf_dataspace_file_for_execve"; + + /* we need 's' on stack to make it an lvalue with an lvalue member we use the pointer to */ + Linux_dataspace::Filename s = ds.fname(); + const char *filename = s.buf; + + /* + * In order to be executable via 'execve', a program must be represented as + * a file on the Linux file system. However, this is not the case for a + * plain RAM dataspace that contains an ELF image. In this case, we copy + * the dataspace content into a temporary file whose path is passed to + * 'execve()'. + */ + if (strcmp(filename, "") == 0) { + + filename = tmp_filename; + + int tmp_binary_fd = lx_open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRWXU); + if (tmp_binary_fd < 0) { + PERR("Could not create file '%s'", filename); + return; /* XXX reflect error to client */ + } + + char buf[4096]; + int num_bytes = 0; + while ((num_bytes = lx_read(ds.fd().dst().socket, buf, sizeof(buf))) != 0) + lx_write(tmp_binary_fd, buf, num_bytes); + + lx_close(tmp_binary_fd); + } + + /* pass parent capability as environment variable to the child */ + enum { ENV_STR_LEN = 256 }; + static char envbuf[5][ENV_STR_LEN]; + Genode::snprintf(envbuf[1], ENV_STR_LEN, "parent_local_name=%lu", + _pd_session._parent.local_name()); + Genode::snprintf(envbuf[2], ENV_STR_LEN, "DISPLAY=%s", + get_env("DISPLAY")); + Genode::snprintf(envbuf[3], ENV_STR_LEN, "HOME=%s", + get_env("HOME")); + Genode::snprintf(envbuf[4], ENV_STR_LEN, "LD_LIBRARY_PATH=%s", + get_env("LD_LIBRARY_PATH")); + + char *env[] = { &envbuf[0][0], &envbuf[1][0], &envbuf[2][0], + &envbuf[3][0], &envbuf[4][0], 0 }; + + /* prefix name of Linux program (helps killing some zombies) */ + char const *prefix = "[Genode] "; + char pname_buf[sizeof(_pd_session._label) + sizeof(prefix)]; + snprintf(pname_buf, sizeof(pname_buf), "%s%s", prefix, _pd_session._label.string); + char *argv_buf[2]; + argv_buf[0] = pname_buf; + argv_buf[1] = 0; + + /* + * We cannot create the new process via 'fork()' because all our used + * memory including stack memory is backed by dataspaces, which had been + * mapped with the 'MAP_SHARED' flag. Therefore, after being created, the + * new process starts using the stack with the same physical memory pages + * as used by parent process. This would ultimately lead to stack + * corruption. To prevent both processes from concurrently accessing the + * same stack, we pause the execution of the parent until the child calls + * 'execve'. From then on, the child has its private memory layout. The + * desired behaviour is normally provided by 'vfork' but we use the more + * modern 'clone' call for this purpose. + */ + enum { STACK_SIZE = 4096 }; + static char stack[STACK_SIZE]; /* initial stack used by the child until + calling 'execve' */ + + /* + * Argument frame as passed to 'clone'. Because, we can only pass a single + * pointer, all arguments are embedded within the 'execve_args' struct. + */ + Execve_args arg(filename, _root, argv_buf, env, _uid, _gid, + _pd_session._parent.dst().socket); + + _pid = lx_create_process((int (*)(void *))_exec_child, + stack + STACK_SIZE - sizeof(umword_t), &arg); + + if (strcmp(filename, tmp_filename) == 0) + lx_unlink(filename); +} + + +Native_pd_component::Native_pd_component(Pd_session_component &pd_session, + const char *args) +: + _pd_session(pd_session) +{ + _pd_session._thread_ep.manage(this); + + /* + * Read Linux-specific session arguments + */ + Arg_string::find_arg(args, "root").string(_root, sizeof(_root), ""); + + _uid = Arg_string::find_arg(args, "uid").ulong_value(0); + _gid = Arg_string::find_arg(args, "gid").ulong_value(0); + + bool const is_chroot = (Genode::strcmp(_root, "") != 0); + + /* + * If a UID is specified but no GID, we use the UID as GID. This way, a + * configuration error where the UID is defined but the GID is left + * undefined won't result in the execution of the new process with the + * root user's GID. + */ + if (_gid == 0) + _gid = _uid; + + /* + * Print Linux-specific session arguments if specified + * + * This output used for the automated 'lx_pd_args' test. + */ + if (is_chroot || _uid || _gid) + printf("PD session for '%s'\n", _pd_session._label.string); + + if (is_chroot) printf(" root: %s\n", _root); + if (_uid) printf(" uid: %u\n", _uid); + if (_gid) printf(" gid: %u\n", _gid); +} + + +Native_pd_component::~Native_pd_component() +{ + if (_pid) + lx_kill(_pid, 9); + + _pd_session._thread_ep.dissolve(this); +} + + +void Native_pd_component::start(Capability binary) +{ + /* lookup binary dataspace */ + _pd_session._thread_ep.apply(binary, [&] (Dataspace_component *ds) { + + if (ds) + _start(*ds); + else + PERR("failed to lookup binary to start"); + }); +}; diff --git a/repos/base-linux/src/core/pd_session_component.cc b/repos/base-linux/src/core/pd_session_component.cc index 3f2548275c..a661453732 100644 --- a/repos/base-linux/src/core/pd_session_component.cc +++ b/repos/base-linux/src/core/pd_session_component.cc @@ -11,444 +11,12 @@ * under the terms of the GNU General Public License version 2. */ -/* Genode includes */ -#include -#include -#include - /* core-local includes */ #include -#include - -/* Linux includes */ -#include using namespace Genode; -/*********************************** - ** Utilities for chroot handling ** - ***********************************/ - -enum { MAX_PATH_LEN = 256 }; - - -/** - * Return true if specified path is an existing directory - */ -static bool is_directory(char const *path) -{ - struct stat64 s; - if (lx_stat(path, &s) != 0) - return false; - - if (!(s.st_mode & S_IFDIR)) - return false; - - return true; -} - - -static bool is_path_delimiter(char c) { return c == '/'; } - - -static bool has_trailing_path_delimiter(char const *path) -{ - char last_char = 0; - for (; *path; path++) - last_char = *path; - - return is_path_delimiter(last_char); -} - - -/** - * Return number of path elements of given path - */ -static Genode::size_t num_path_elements(char const *path) -{ - Genode::size_t count = 0; - - /* - * If path starts with non-slash, the first characters belongs to a path - * element. - */ - if (*path && !is_path_delimiter(*path)) - count = 1; - - /* count slashes */ - for (; *path; path++) - if (is_path_delimiter(*path)) - count++; - - return count; -} - - -static bool leading_path_elements(char const *path, unsigned num, - char *dst, Genode::size_t dst_len) -{ - /* counter of path delimiters */ - unsigned count = 0; - unsigned i = 0; - - if (is_path_delimiter(path[0])) - num++; - - for (; path[i] && (count < num) && (i < dst_len); i++) - { - if (is_path_delimiter(path[i])) - count++; - - if (count == num) - break; - - dst[i] = path[i]; - } - - if (i + 1 < dst_len) { - dst[i] = 0; - return true; - } - - /* string is cut, append null termination anyway */ - dst[dst_len - 1] = 0; - return false; -} - - -static void mirror_path_to_chroot(char const *chroot_path, char const *path) -{ - char target_path[MAX_PATH_LEN]; - Genode::snprintf(target_path, sizeof(target_path), "%s%s", - chroot_path, path); - - /* - * Create directory hierarchy pointing to the target path except for the - * last element. The last element will be bind-mounted to refer to the - * original 'path'. - */ - for (unsigned i = 1; i <= num_path_elements(target_path); i++) - { - char buf[MAX_PATH_LEN]; - leading_path_elements(target_path, i, buf, sizeof(buf)); - - /* skip existing directories */ - if (is_directory(buf)) - continue; - - /* create new directory */ - lx_mkdir(buf, 0777); - } - - lx_umount(target_path); - - int ret = 0; - if ((ret = lx_bindmount(path, target_path))) - PERR("bind mount failed (errno=%d)", ret); -} - - -/** - * Setup content of chroot environment as prerequisite to 'execve' new - * processes within the environment. I.e., the current working directory - * containing the ROM modules must be mounted at the same location within the - * chroot environment. - */ -static bool setup_chroot_environment(char const *chroot_path) -{ - using namespace Genode; - - static char cwd_path[MAX_PATH_LEN]; - - lx_getcwd(cwd_path, sizeof(cwd_path)); - - /* - * Validate chroot path - */ - if (!is_directory(chroot_path)) { - PERR("chroot path does not point to valid directory"); - return false; - } - - if (has_trailing_path_delimiter(chroot_path)) { - PERR("chroot path has trailing slash"); - return false; - } - - /* - * Hardlink directories needed for running Genode within the chroot - * environment. - */ - mirror_path_to_chroot(chroot_path, cwd_path); - - return true; -} - - -/*************** - ** Utilities ** - ***************/ - -/** - * Argument frame for passing 'execve' paremeters through 'clone' - */ -struct Execve_args -{ - char const *filename; - char const *root; - char * const *argv; - char * const *envp; - unsigned int const uid; - unsigned int const gid; - int const parent_sd; - - Execve_args(char const *filename, - char const *root, - char * const *argv, - char * const *envp, - unsigned int uid, - unsigned int gid, - int parent_sd) - : - filename(filename), root(root), argv(argv), envp(envp), - uid(uid), gid(gid), parent_sd(parent_sd) - { } -}; - - -/** - * Startup code of the new child process - */ -static int _exec_child(Execve_args *arg) -{ - lx_dup2(arg->parent_sd, PARENT_SOCKET_HANDLE); - - /* change to chroot environment */ - if (arg->root && arg->root[0]) { - char cwd[1024]; - - PDBG("arg->root='%s'", arg->root); - - if (setup_chroot_environment(arg->root) == false) { - PERR("Could not setup chroot environment"); - return -1; - } - - if (!lx_getcwd(cwd, sizeof(cwd))) { - PERR("Failed to getcwd"); - return -1; - } - - PLOG("changing root of %s (PID %d) to %s", - arg->filename, lx_getpid(), arg->root); - - int ret = lx_chroot(arg->root); - if (ret < 0) { - PERR("Syscall chroot failed (errno %d)", ret); - return -1; - } - - ret = lx_chdir(cwd); - if (ret < 0) { - PERR("chdir to new chroot failed"); - return -1; - } - } - - /* - * Set UID and GID - * - * We must set the GID prior setting the UID because setting the GID won't - * be possible anymore once we set the UID to non-root. - */ - if (arg->gid) { - int const ret = lx_setgid(arg->gid); - if (ret) - PWRN("Could not set PID %d (%s) to GID %u (error %d)", - lx_getpid(), arg->filename, arg->gid, ret); - } - if (arg->uid) { - int const ret = lx_setuid(arg->uid); - if (ret) - PWRN("Could not set PID %d (%s) to UID %u (error %d)", - lx_getpid(), arg->filename, arg->uid, ret); - } - - return lx_execve(arg->filename, arg->argv, arg->envp); -} - - -/** - * List of Unix environment variables, initialized by the startup code - */ -extern char **lx_environ; - - -/** - * Read environment variable as string - * - * If no matching key exists, return an empty string. - */ -static const char *get_env(const char *key) -{ - Genode::size_t key_len = Genode::strlen(key); - for (char **curr = lx_environ; curr && *curr; curr++) - if ((Genode::strcmp(*curr, key, key_len) == 0) && (*curr)[key_len] == '=') - return (const char *)(*curr + key_len + 1); - - return ""; -} - - -/************************** - ** PD session interface ** - **************************/ - -void Pd_session_component::_start(Dataspace_component *ds) -{ - const char *tmp_filename = "temporary_executable_elf_dataspace_file_for_execve"; - - if (!ds) { - PERR("could not lookup binary, aborted PD startup"); - return; /* XXX reflect error to client */ - } - - /* we need 's' on stack to make it an lvalue with an lvalue member we use the pointer to */ - Linux_dataspace::Filename s = ds->fname(); - const char *filename = s.buf; - - /* - * In order to be executable via 'execve', a program must be represented as - * a file on the Linux file system. However, this is not the case for a - * plain RAM dataspace that contains an ELF image. In this case, we copy - * the dataspace content into a temporary file whose path is passed to - * 'execve()'. - */ - if (strcmp(filename, "") == 0) { - - filename = tmp_filename; - - int tmp_binary_fd = lx_open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRWXU); - if (tmp_binary_fd < 0) { - PERR("Could not create file '%s'", filename); - return; /* XXX reflect error to client */ - } - - char buf[4096]; - int num_bytes = 0; - while ((num_bytes = lx_read(ds->fd().dst().socket, buf, sizeof(buf))) != 0) - lx_write(tmp_binary_fd, buf, num_bytes); - - lx_close(tmp_binary_fd); - } - - /* pass parent capability as environment variable to the child */ - enum { ENV_STR_LEN = 256 }; - static char envbuf[5][ENV_STR_LEN]; - Genode::snprintf(envbuf[1], ENV_STR_LEN, "parent_local_name=%lu", - _parent.local_name()); - Genode::snprintf(envbuf[2], ENV_STR_LEN, "DISPLAY=%s", - get_env("DISPLAY")); - Genode::snprintf(envbuf[3], ENV_STR_LEN, "HOME=%s", - get_env("HOME")); - Genode::snprintf(envbuf[4], ENV_STR_LEN, "LD_LIBRARY_PATH=%s", - get_env("LD_LIBRARY_PATH")); - - char *env[] = { &envbuf[0][0], &envbuf[1][0], &envbuf[2][0], - &envbuf[3][0], &envbuf[4][0], 0 }; - - /* prefix name of Linux program (helps killing some zombies) */ - char const *prefix = "[Genode] "; - char pname_buf[sizeof(_label) + sizeof(prefix)]; - snprintf(pname_buf, sizeof(pname_buf), "%s%s", prefix, _label); - char *argv_buf[2]; - argv_buf[0] = pname_buf; - argv_buf[1] = 0; - - /* - * We cannot create the new process via 'fork()' because all our used - * memory including stack memory is backed by dataspaces, which had been - * mapped with the 'MAP_SHARED' flag. Therefore, after being created, the - * new process starts using the stack with the same physical memory pages - * as used by parent process. This would ultimately lead to stack - * corruption. To prevent both processes from concurrently accessing the - * same stack, we pause the execution of the parent until the child calls - * 'execve'. From then on, the child has its private memory layout. The - * desired behaviour is normally provided by 'vfork' but we use the more - * modern 'clone' call for this purpose. - */ - enum { STACK_SIZE = 4096 }; - static char stack[STACK_SIZE]; /* initial stack used by the child until - calling 'execve' */ - - /* - * Argument frame as passed to 'clone'. Because, we can only pass a single - * pointer, all arguments are embedded within the 'execve_args' struct. - */ - Execve_args arg(filename, _root, argv_buf, env, _uid, _gid, - _parent.dst().socket); - - _pid = lx_create_process((int (*)(void *))_exec_child, - stack + STACK_SIZE - sizeof(umword_t), &arg); - - if (strcmp(filename, tmp_filename) == 0) - lx_unlink(filename); -} - - -Pd_session_component::Pd_session_component(Rpc_entrypoint &ds_ep, - Rpc_entrypoint &receiver_ep, - Rpc_entrypoint &context_ep, - Allocator &md_alloc, - const char *args) -: - _pid(0), _uid(0), _gid(0), _ds_ep(ds_ep), - _signal_broker(md_alloc, receiver_ep, context_ep) -{ - Arg_string::find_arg(args, "label").string(_label, sizeof(_label), - ""); - - /* - * Read Linux-specific session arguments - */ - Arg_string::find_arg(args, "root").string(_root, sizeof(_root), ""); - - _uid = Arg_string::find_arg(args, "uid").ulong_value(0); - _gid = Arg_string::find_arg(args, "gid").ulong_value(0); - - bool const is_chroot = (Genode::strcmp(_root, "") != 0); - - /* - * If a UID is specified but no GID, we use the UID as GID. This way, a - * configuration error where the UID is defined but the GID is left - * undefined won't result in the execution of the new process with the - * root user's GID. - */ - if (_gid == 0) - _gid = _uid; - - /* - * Print Linux-specific session arguments if specified - * - * This output used for the automated 'lx_pd_args' test. - */ - if (is_chroot || _uid || _gid) - printf("PD session for '%s'\n", _label); - - if (is_chroot) printf(" root: %s\n", _root); - if (_uid) printf(" uid: %u\n", _uid); - if (_gid) printf(" gid: %u\n", _gid); -} - - -Pd_session_component::~Pd_session_component() -{ - if (_pid) - lx_kill(_pid, 9); -} - - int Pd_session_component::bind_thread(Thread_capability) { return -1; } @@ -459,9 +27,5 @@ int Pd_session_component::assign_parent(Capability parent) } -void Pd_session_component::start(Capability binary) -{ - /* lookup binary dataspace */ - _ds_ep.apply(binary, [&] (Dataspace_component *ds) { - _start(ds); }); -}; +bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; } + diff --git a/repos/base-linux/src/core/target.mk b/repos/base-linux/src/core/target.mk index 428a5d9e56..a3851c3030 100644 --- a/repos/base-linux/src/core/target.mk +++ b/repos/base-linux/src/core/target.mk @@ -11,12 +11,15 @@ SRC_CC = main.cc \ ram_session_component.cc \ ram_session_support.cc \ rom_session_component.cc \ - cap_session_component.cc \ cpu_session_component.cc \ cpu_session_extension.cc \ cpu_session_support.cc \ - dataspace_component.cc \ pd_session_component.cc \ + pd_upgrade_ram_quota.cc \ + dataspace_component.cc \ + native_pd_component.cc \ + rpc_cap_factory.cc \ + core_rpc_cap_alloc.cc \ io_mem_session_component.cc \ signal_source_component.cc \ trace_session_component.cc \ @@ -40,11 +43,13 @@ include $(GEN_CORE_DIR)/version.inc vpath main.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) -vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console vpath thread.cc $(BASE_DIR)/src/base/thread vpath myself.cc $(BASE_DIR)/src/base/thread diff --git a/repos/base-nova/include/cap_session/cap_session.h b/repos/base-nova/include/cap_session/cap_session.h deleted file mode 100644 index c9f8e89aff..0000000000 --- a/repos/base-nova/include/cap_session/cap_session.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * \brief CAP-session interface - * \author Norman Feske - * \date 2006-06-23 - * - * A 'Cap_session' is an allocator of user-level capabilities. - * User-level capabilities are used to reference server objects - * across address spaces. - */ - -/* - * Copyright (C) 2006-2013 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 _INCLUDE__CAP_SESSION__CAP_SESSION_H_ -#define _INCLUDE__CAP_SESSION__CAP_SESSION_H_ - -#include -#include - -namespace Genode { - - struct Cap_session : Session - { - static const char *service_name() { return "CAP"; } - - virtual ~Cap_session() { } - - /** - * Allocate new unique userland capability - * - * \param ep entry point that will use this capability - * - * \return new userland capability - */ - virtual Native_capability alloc(Native_capability ep, - addr_t entry = 0, - addr_t flags = 0) = 0; - - /** - * Free userland capability - * - * \param cap userland capability to free - */ - virtual void free(Native_capability cap) = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_alloc, Native_capability, alloc, - Native_capability, addr_t, addr_t); - GENODE_RPC(Rpc_free, void, free, Native_capability); - GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free); - }; -} - -#endif /* _INCLUDE__CAP_SESSION__CAP_SESSION_H_ */ diff --git a/repos/base-nova/include/cap_session/client.h b/repos/base-nova/include/cap_session/client.h deleted file mode 100644 index 8604d84887..0000000000 --- a/repos/base-nova/include/cap_session/client.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * \brief Client-side CAP session interface - * \author Norman Feske - * \author Alexander Boettcher - * \date 2006-07-10 - */ - -/* - * Copyright (C) 2006-2015 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 _INCLUDE__CAP_SESSION__CLIENT_H_ -#define _INCLUDE__CAP_SESSION__CLIENT_H_ - -#include -#include -#include - -namespace Genode { - - struct Cap_session_client : Rpc_client - { - explicit Cap_session_client(Cap_session_capability session) - : Rpc_client(session) { } - - Native_capability alloc(Native_capability ep, addr_t entry = 0, - addr_t flags = 0) - { - return call(ep, entry, flags); - } - - void free(Native_capability cap) { call(cap); } - }; -} - -#endif /* _INCLUDE__CAP_SESSION__CLIENT_H_ */ diff --git a/repos/base-nova/include/nova_native_pd/client.h b/repos/base-nova/include/nova_native_pd/client.h new file mode 100644 index 0000000000..01ad4dc532 --- /dev/null +++ b/repos/base-nova/include/nova_native_pd/client.h @@ -0,0 +1,40 @@ +/* + * \brief Client-side stub for the NOVA-specific PD session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _INCLUDE__NOVA_NATIVE_PD__CLIENT_H_ +#define _INCLUDE__NOVA_NATIVE_PD__CLIENT_H_ + +#include +#include + +namespace Genode { struct Nova_native_pd_client; } + + +struct Genode::Nova_native_pd_client : Rpc_client +{ + explicit Nova_native_pd_client(Capability cap) + : Rpc_client(static_cap_cast(cap)) { } + + Native_capability alloc_rpc_cap(Native_capability ep, + addr_t entry, addr_t mtd) override + { + return call(ep, entry, mtd); + } + + void imprint_rpc_cap(Native_capability cap, unsigned long badge) override + { + call(cap, badge); + } +}; + +#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-nova/include/nova_native_pd/nova_native_pd.h b/repos/base-nova/include/nova_native_pd/nova_native_pd.h new file mode 100644 index 0000000000..e18a05997d --- /dev/null +++ b/repos/base-nova/include/nova_native_pd/nova_native_pd.h @@ -0,0 +1,51 @@ +/* + * \brief NOVA-specific part of the PD session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _INCLUDE__NOVA_NATIVE_PD__NOVA_NATIVE_PD_H_ +#define _INCLUDE__NOVA_NATIVE_PD__NOVA_NATIVE_PD_H_ + +#include +#include + +namespace Genode { struct Nova_native_pd; } + +struct Genode::Nova_native_pd : Pd_session::Native_pd +{ + /** + * Allocate RPC object capability + * + * \param ep entry point that will use this capability + * \param entry server-side instruction pointer of the RPC handler + * \param mtd NOVA message transfer descriptor + * + * \throw Pd_session::Out_of_metadata + * + * \return new RPC object capability + */ + virtual Native_capability alloc_rpc_cap(Native_capability ep, + addr_t entry, addr_t mtd) = 0; + + /** + * Imprint badge into the portal of the specified RPC capability + */ + virtual void imprint_rpc_cap(Native_capability cap, unsigned long badge) = 0; + + GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap, + GENODE_TYPE_LIST(Pd_session::Out_of_metadata), + Native_capability, addr_t, addr_t); + GENODE_RPC(Rpc_imprint_rpc_cap, void, imprint_rpc_cap, + Native_capability, unsigned long); + GENODE_RPC_INTERFACE(Rpc_alloc_rpc_cap, Rpc_imprint_rpc_cap); +}; + +#endif /* _INCLUDE__NOVA_NATIVE_PD__NOVA_NATIVE_PD_H_ */ diff --git a/repos/base-nova/include/pd_session/client.h b/repos/base-nova/include/pd_session/client.h deleted file mode 100644 index f874badb2c..0000000000 --- a/repos/base-nova/include/pd_session/client.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * \brief Client-side pd session interface - * \author Christian Helmuth - * \date 2006-07-12 - */ - -/* - * Copyright (C) 2006-2013 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 _INCLUDE__PD_SESSION__CLIENT_H_ -#define _INCLUDE__PD_SESSION__CLIENT_H_ - -#include -#include - -namespace Genode { struct Pd_session_client; } - - -/* - * This implementation overrides the corresponding header in base/include - * to tweak the way the parent capability is passed to core. - */ -struct Genode::Pd_session_client : Rpc_client -{ - explicit Pd_session_client(Pd_session_capability session) - : Rpc_client(session) { } - - int bind_thread(Thread_capability thread) override { - return call(thread); } - - int assign_parent(Capability parent) override - { - /* - * NOVA-specific implementation - * - * We need to prevent NOVA from creating a new branch in the mapping - * tree. Instead, we need core to re-associate the supplied PD cap with - * the core-known PD session component of the parent. - */ - parent.solely_map(); - return call(parent); - } - - bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override { - return call(pci_config_memory_address, bdf); } - - Signal_source_capability alloc_signal_source() override { - return call(); } - - void free_signal_source(Signal_source_capability cap) override { - call(cap); } - - Signal_context_capability alloc_context(Signal_source_capability source, - unsigned long imprint) override { - return call(source, imprint); } - - void free_context(Signal_context_capability cap) override { - call(cap); } - - void submit(Signal_context_capability receiver, unsigned cnt = 1) override { - call(receiver, cnt); } -}; - -#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-nova/lib/mk/base.mk b/repos/base-nova/lib/mk/base.mk index a471e689ad..1b4231ce47 100644 --- a/repos/base-nova/lib/mk/base.mk +++ b/repos/base-nova/lib/mk/base.mk @@ -11,6 +11,7 @@ SRC_CC += cpu/cache.cc SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc SRC_CC += thread/thread_nova.cc SRC_CC += irq/platform.cc +SRC_CC += server/rpc_cap_alloc.cc INC_DIR += $(BASE_DIR)/src/base/env diff --git a/repos/base-nova/lib/mk/spec/x86_32/core.mk b/repos/base-nova/lib/mk/spec/x86_32/core.mk index dc7caecfd0..0b0fe232ab 100644 --- a/repos/base-nova/lib/mk/spec/x86_32/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_32/core.mk @@ -1,5 +1,6 @@ SRC_CC += pager.cc -INC_DIR = $(REP_DIR)/src/core/include +INC_DIR = $(REP_DIR)/src/core/include \ + $(BASE_DIR)/src/core/include vpath %.cc $(REP_DIR)/src/core/spec/x86_32 diff --git a/repos/base-nova/src/base/server/rpc_cap_alloc.cc b/repos/base-nova/src/base/server/rpc_cap_alloc.cc new file mode 100644 index 0000000000..b5ec4816b1 --- /dev/null +++ b/repos/base-nova/src/base/server/rpc_cap_alloc.cc @@ -0,0 +1,56 @@ +/* + * \brief Core-specific back end of the RPC entrypoint + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* Genode includes */ +#include +#include +#include +#include + +/* NOVA-specific part of the PD session interface */ +#include + +using namespace Genode; + + +Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &pd, Native_capability ep, + addr_t entry) +{ + if (!_native_pd_cap.valid()) + _native_pd_cap = pd.native_pd(); + + Nova_native_pd_client native_pd(_native_pd_cap); + + Untyped_capability new_obj_cap = + retry( + [&] () { + return native_pd.alloc_rpc_cap(ep, entry, 0); + }, + [&] () { + Pd_session_client *client = + dynamic_cast(&pd); + + if (client) + env()->parent()->upgrade(*client, "ram_quota=16K"); + }); + + native_pd.imprint_rpc_cap(new_obj_cap, new_obj_cap.local_name()); + + return new_obj_cap; +} + + +void Rpc_entrypoint::_free_rpc_cap(Pd_session &pd, Native_capability cap) +{ + return pd.free_rpc_cap(cap); +} diff --git a/repos/base-nova/src/base/server/server.cc b/repos/base-nova/src/base/server/server.cc index 3282734293..9c350e4676 100644 --- a/repos/base-nova/src/base/server/server.cc +++ b/repos/base-nova/src/base/server/server.cc @@ -25,32 +25,6 @@ using namespace Genode; -static Untyped_capability create_portal(Cap_session * cap_session, - Untyped_capability ec_cap, - addr_t entry) -{ - Untyped_capability obj_cap; - - obj_cap = cap_session->alloc(ec_cap, entry); - - if (!obj_cap.valid()) - return obj_cap; - - using namespace Nova; - - /* set local badge */ - if (pt_ctrl(obj_cap.local_name(), obj_cap.local_name()) != NOVA_OK) { - cap_session->free(obj_cap); - return Untyped_capability(); - } - - /* disable PT_CTRL permission - feature for security reasons now */ - revoke(Obj_crd(obj_cap.local_name(), 0, Obj_crd::RIGHT_PT_CTRL)); - - return obj_cap; -} - - /*********************** ** Server entrypoint ** ***********************/ @@ -59,7 +33,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) { using namespace Nova; - Untyped_capability ec_cap, obj_cap; + Untyped_capability ec_cap; /* _ec_sel is invalid until thread gets started */ if (tid().ec_sel != Native_thread::INVALID_INDEX) @@ -67,7 +41,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) else ec_cap = _thread_cap; - obj_cap = create_portal(_cap_session, ec_cap, (addr_t)_activation_entry); + Untyped_capability obj_cap = _alloc_rpc_cap(_pd_session, ec_cap, + (addr_t)&_activation_entry); if (!obj_cap.valid()) return obj_cap; @@ -83,7 +58,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) void Rpc_entrypoint::_dissolve(Rpc_object_base *obj) { /* de-announce object from cap_session */ - _cap_session->free(obj->cap()); + _free_rpc_cap(_pd_session, obj->cap()); /* avoid any incoming IPC */ Nova::revoke(Nova::Obj_crd(obj->cap().local_name(), 0), true); @@ -206,13 +181,13 @@ void Rpc_entrypoint::activate() } -Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, +Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, const char *name, bool start_on_construction, Affinity::Location location) : Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size), _delay_start(Lock::LOCKED), - _cap_session(cap_session) + _pd_session(*pd_session) { /* when not running in core set the affinity via cpu session */ if (_tid.ec_sel == Native_thread::INVALID_INDEX) { @@ -232,8 +207,8 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, Thread_base::start(); /* create cleanup portal */ - _cap = create_portal(cap_session, Native_capability(_tid.ec_sel), - (addr_t)_activation_entry); + _cap = _alloc_rpc_cap(_pd_session, Native_capability(_tid.ec_sel), + (addr_t)_activation_entry); if (!_cap.valid()) throw Cpu_session::Thread_creation_failed(); @@ -258,6 +233,5 @@ Rpc_entrypoint::~Rpc_entrypoint() if (!_cap.valid()) return; - /* de-announce object from cap_session */ - _cap_session->free(_cap); + _free_rpc_cap(_pd_session, _cap); } diff --git a/repos/base-nova/src/core/core_rpc_cap_alloc.cc b/repos/base-nova/src/core/core_rpc_cap_alloc.cc new file mode 100644 index 0000000000..05372f3cd8 --- /dev/null +++ b/repos/base-nova/src/core/core_rpc_cap_alloc.cc @@ -0,0 +1,44 @@ +/* + * \brief Core-specific back end of the RPC entrypoint + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* Genode includes */ +#include + +/* core-local includes */ +#include +#include +#include + +using namespace Genode; + + +static Rpc_cap_factory &rpc_cap_factory() +{ + static Rpc_cap_factory inst(*platform()->core_mem_alloc()); + return inst; +} + + +Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &, Native_capability ep, + addr_t entry) +{ + Native_capability cap = rpc_cap_factory().alloc(ep, entry, 0); + imprint_badge(cap.local_name(), cap.local_name()); + return cap; +} + + +void Rpc_entrypoint::_free_rpc_cap(Pd_session &, Native_capability cap) +{ + rpc_cap_factory().free(cap); +} diff --git a/repos/base-nova/src/core/include/cap_session_component.h b/repos/base-nova/src/core/include/cap_session_component.h deleted file mode 100644 index 62ed2201ca..0000000000 --- a/repos/base-nova/src/core/include/cap_session_component.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * \brief Capability allocation service - * \author Alexander Boettcher - * \date 2012-07-27 - */ - -/* - * Copyright (C) 2006-2013 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 _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ - -#include -#include -#include - -/* core includes */ -#include - -namespace Genode { - - class Cap_session_component : public Rpc_object - { - private: - - struct Cap_object : List::Element - { - Genode::addr_t _cap_sel; - - Cap_object(addr_t cap_sel) : _cap_sel(cap_sel) {} - }; - - Tslab _cap_slab; - List _cap_list; - Lock _cap_lock; - - public: - - /** - * Constructor - */ - Cap_session_component(Allocator *md_alloc, const char *args) - : _cap_slab(md_alloc) { } - - /** - * Destructor - */ - ~Cap_session_component() - { - Lock::Guard cap_lock(_cap_lock); - - for (Cap_object *obj; (obj = _cap_list.first()); ) { - Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); - cap_map()->remove(obj->_cap_sel, 0, false); - - _cap_list.remove(obj); - destroy(&_cap_slab, obj); - } - } - - void upgrade_ram_quota(size_t ram_quota) { } - - Native_capability alloc(Native_capability ep, addr_t entry, - addr_t mtd) - { - addr_t pt_sel = cap_map()->insert(); - addr_t pd_sel = Platform_pd::pd_core_sel(); - addr_t ec_sel = ep.local_name(); - - using namespace Nova; - - Lock::Guard cap_lock(_cap_lock); - - /* create cap object */ - Cap_object * pt_cap = new (&_cap_slab) Cap_object(pt_sel); - if (!pt_cap) - return Native_capability::invalid_cap(); - - _cap_list.insert(pt_cap); - - /* create portal */ - uint8_t res = create_pt(pt_sel, pd_sel, ec_sel, Mtd(mtd), - entry); - if (res == NOVA_OK) - return Native_capability(pt_sel); - - PERR("cap_session - cap=%lx:%lx" - " addr=%lx flags=%lx xpt=%lx res=%u", - ec_sel, ep.local_name(), - entry, mtd, pt_sel, res); - - _cap_list.remove(pt_cap); - destroy(&_cap_slab, pt_cap); - - /* cleanup unused selectors */ - cap_map()->remove(pt_sel, 0, false); - - return Native_capability::invalid_cap(); - } - - void free(Native_capability cap) - { - if (!cap.valid()) return; - - Lock::Guard cap_lock(_cap_lock); - - for (Cap_object *obj = _cap_list.first(); obj ; obj = obj->next()) { - if (cap.local_name() == obj->_cap_sel) { - Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); - cap_map()->remove(obj->_cap_sel, 0, false); - - _cap_list.remove(obj); - destroy(&_cap_slab, obj); - return; - } - } - PDBG("invalid cap object"); - } - }; -} - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/include/imprint_badge.h b/repos/base-nova/src/core/include/imprint_badge.h new file mode 100644 index 0000000000..f574c540a4 --- /dev/null +++ b/repos/base-nova/src/core/include/imprint_badge.h @@ -0,0 +1,30 @@ +/* + * \brief Utility to imprint a badge into a NOVA portal + * \author Norman Feske + * \date 2016-03-03 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__IMPRINT_BADGE_H_ +#define _CORE__INCLUDE__IMPRINT_BADGE_H_ + +static inline bool imprint_badge(unsigned long pt_sel, unsigned long badge) +{ + using namespace Nova; + + /* assign badge to portal */ + if (pt_ctrl(pt_sel, badge) != NOVA_OK) + return false; + + /* disable PT_CTRL permission to prevent subsequent imprint attempts */ + revoke(Obj_crd(pt_sel, 0, Obj_crd::RIGHT_PT_CTRL)); + return true; +} + +#endif /* _CORE__INCLUDE__IMPRINT_BADGE_H_ */ diff --git a/repos/base-nova/src/core/include/native_pd_component.h b/repos/base-nova/src/core/include/native_pd_component.h new file mode 100644 index 0000000000..e0892b7c7a --- /dev/null +++ b/repos/base-nova/src/core/include/native_pd_component.h @@ -0,0 +1,49 @@ +/* + * \brief Kernel-specific part of the PD-session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ +#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ + +/* Genode includes */ +#include + +/* core-local includes */ +#include + +namespace Genode { + + class Pd_session_component; + class Native_pd_component; +} + + +class Genode::Native_pd_component : public Rpc_object +{ + private: + + Pd_session_component &_pd_session; + + public: + + Native_pd_component(Pd_session_component &pd, char const *args); + + ~Native_pd_component(); + + /** + * Nova_native_pd interface + */ + Native_capability alloc_rpc_cap(Native_capability, addr_t, addr_t) override; + void imprint_rpc_cap(Native_capability, unsigned long) override; +}; + +#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/include/pager.h b/repos/base-nova/src/core/include/pager.h index c66305e881..6b83b0117c 100644 --- a/repos/base-nova/src/core/include/pager.h +++ b/repos/base-nova/src/core/include/pager.h @@ -21,8 +21,9 @@ #include #include -/* Core includes */ +/* core-local includes */ #include +#include namespace Genode { @@ -416,18 +417,18 @@ namespace Genode { private: Pager_activation_base *_activation; - Cap_session *_cap_session; + Rpc_cap_factory &_cap_factory; public: /** * Constructor * - * \param cap_session Cap_session for creating capabilities + * \param cap_factory factory for creating capabilities * for the pager objects managed by this * entry point */ - Pager_entrypoint(Cap_session *cap_session); + Pager_entrypoint(Rpc_cap_factory &cap_factory); /** * Associate Pager_object with the entry point diff --git a/repos/base-nova/src/core/include/rpc_cap_factory.h b/repos/base-nova/src/core/include/rpc_cap_factory.h new file mode 100644 index 0000000000..189c82fc31 --- /dev/null +++ b/repos/base-nova/src/core/include/rpc_cap_factory.h @@ -0,0 +1,66 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + + +class Genode::Rpc_cap_factory +{ + private: + + struct Cap_object : List::Element + { + Genode::addr_t _cap_sel; + + Cap_object(addr_t cap_sel) : _cap_sel(cap_sel) {} + }; + + Tslab _slab; + List _list; + Lock _lock; + + public: + + Rpc_cap_factory(Allocator &md_alloc); + + ~Rpc_cap_factory(); + + /** + * Allocate RPC capability + * + * \throw Allocator::Out_of_memory + * + * This function is invoked via Nova_native_pd::alloc_rpc_cap. + */ + Native_capability alloc(Native_capability ep, addr_t entry, addr_t mtd); + + Native_capability alloc(Native_capability) + { + PWRN("unexpected call to non-implemented Rpc_cap_factory::alloc"); + return Native_capability(); + } + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-nova/src/core/native_pd_component.cc b/repos/base-nova/src/core/native_pd_component.cc new file mode 100644 index 0000000000..6da8987b27 --- /dev/null +++ b/repos/base-nova/src/core/native_pd_component.cc @@ -0,0 +1,55 @@ +/* + * \brief Kernel-specific part of the PD-session interface + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +#include +#include + +/* core-local includes */ +#include + +using namespace Genode; + + +Native_capability Native_pd_component::alloc_rpc_cap(Native_capability ep, + addr_t entry, addr_t mtd) +{ + try { + return _pd_session._rpc_cap_factory.alloc(ep, entry, mtd); } + + catch (Allocator::Out_of_memory) { + throw Pd_session::Out_of_metadata(); } +} + + +void Native_pd_component::imprint_rpc_cap(Native_capability cap, unsigned long badge) +{ + if (cap.valid()) + imprint_badge(cap.local_name(), badge); +} + + +Native_pd_component::Native_pd_component(Pd_session_component &pd_session, + char const *args) +: + _pd_session(pd_session) +{ + _pd_session._thread_ep.manage(this); +} + + +Native_pd_component::~Native_pd_component() +{ + _pd_session._thread_ep.dissolve(this); +} + + diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index 36f76bb5d5..b1626b3602 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -18,8 +18,9 @@ #include #include -/* Core includes */ +/* core-local includes */ #include +#include /* NOVA includes */ #include @@ -832,8 +833,8 @@ void Pager_activation_base::entry() { } **********************/ -Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session) -: _cap_session(cap_session) +Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &cap_factory) +: _cap_factory(cap_factory) { /* sanity check space for pager threads */ if (kernel_hip()->cpu_max() > PAGER_CPUS) { @@ -869,10 +870,9 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj) /* request creation of portal bind to pager thread */ Native_capability cap_session = - _cap_session->alloc(pager_thread_cap, obj->handler_address()); + _cap_factory.alloc(pager_thread_cap, obj->handler_address(), 0); - if (NOVA_OK != pt_ctrl(cap_session.local_name(), reinterpret_cast(obj))) - nova_die(); + imprint_badge(cap_session.local_name(), reinterpret_cast(obj)); /* disable the feature for security reasons now */ revoke(Obj_crd(cap_session.local_name(), 0, Obj_crd::RIGHT_PT_CTRL)); @@ -890,12 +890,16 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj) void Pager_entrypoint::dissolve(Pager_object *obj) { Native_capability pager_obj = obj->Object_pool::Entry::cap(); - /* cleanup at cap session */ - _cap_session->free(pager_obj); + + /* cleanup at cap factory */ + _cap_factory.free(pager_obj); + /* revoke cap selector locally */ revoke(pager_obj.dst(), true); + /* remove object from pool */ remove(obj); + /* take care that no faults are in-flight */ obj->cleanup_call(); } diff --git a/repos/base-nova/src/core/rpc_cap_factory.cc b/repos/base-nova/src/core/rpc_cap_factory.cc new file mode 100644 index 0000000000..68727371c1 --- /dev/null +++ b/repos/base-nova/src/core/rpc_cap_factory.cc @@ -0,0 +1,90 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* core-local includes */ +#include +#include + +using namespace Genode; + + +Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, addr_t mtd) +{ + addr_t pt_sel = cap_map()->insert(); + addr_t pd_sel = Platform_pd::pd_core_sel(); + addr_t ec_sel = ep.local_name(); + + using namespace Nova; + + Lock::Guard guard(_lock); + + /* create cap object */ + Cap_object * pt_cap = new (&_slab) Cap_object(pt_sel); + if (!pt_cap) + return Native_capability::invalid_cap(); + + _list.insert(pt_cap); + + /* create portal */ + uint8_t const res = create_pt(pt_sel, pd_sel, ec_sel, Mtd(mtd), entry); + if (res == NOVA_OK) + return Native_capability(pt_sel); + + PERR("cap_session - cap=%lx:%lx addr=%lx mtd=%lx xpt=%lx res=%u", + ec_sel, ep.local_name(), entry, mtd, pt_sel, res); + + _list.remove(pt_cap); + destroy(&_slab, pt_cap); + + /* cleanup unused selectors */ + cap_map()->remove(pt_sel, 0, false); + + return Native_capability::invalid_cap(); +} + + +void Rpc_cap_factory::free(Native_capability cap) +{ + if (!cap.valid()) return; + + Lock::Guard guard(_lock); + + for (Cap_object *obj = _list.first(); obj ; obj = obj->next()) { + if (cap.local_name() == obj->_cap_sel) { + Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); + cap_map()->remove(obj->_cap_sel, 0, false); + + _list.remove(obj); + destroy(&_slab, obj); + return; + } + } + PDBG("invalid cap object"); +} + + +Rpc_cap_factory::Rpc_cap_factory(Allocator &md_alloc) : _slab(&md_alloc) { } + + +Rpc_cap_factory::~Rpc_cap_factory() +{ + Lock::Guard guard(_lock); + + for (Cap_object *obj; (obj = _list.first()); ) { + Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); + cap_map()->remove(obj->_cap_sel, 0, false); + + _list.remove(obj); + destroy(&_slab, obj); + } +} diff --git a/repos/base-nova/src/core/target.inc b/repos/base-nova/src/core/target.inc index 4cd6a29c55..61ff7c5ef7 100644 --- a/repos/base-nova/src/core/target.inc +++ b/repos/base-nova/src/core/target.inc @@ -7,6 +7,7 @@ SRC_CC = context_area.cc \ core_mem_alloc.cc \ core_printf.cc \ core_rm_session.cc \ + core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_extension.cc \ cpu_session_support.cc \ @@ -21,8 +22,10 @@ SRC_CC = context_area.cc \ main.cc \ pager.cc \ pd_session_component.cc \ + native_pd_component.cc \ pd_upgrade_ram_quota.cc \ pd_assign_pci.cc \ + rpc_cap_factory.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ diff --git a/repos/base-okl4/include/okl4_pd_session/client.h b/repos/base-okl4/include/okl4_pd_session/client.h deleted file mode 100644 index fe1639f4fb..0000000000 --- a/repos/base-okl4/include/okl4_pd_session/client.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * \brief Client-side OKL4 specific pd session interface - * \author Stefan Kalkowski - * \date 2009-06-03 - */ - -/* - * Copyright (C) 2009-2013 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 _INCLUDE__OKL4_PD_SESSION__CLIENT_H_ -#define _INCLUDE__OKL4_PD_SESSION__CLIENT_H_ - -#include -#include - -namespace Genode { - - struct Okl4_pd_session_client : Rpc_client - { - explicit Okl4_pd_session_client(Pd_session_capability cap) - : Rpc_client(static_cap_cast(cap)) { } - - int bind_thread(Thread_capability thread) { - return call(thread); } - - int assign_parent(Parent_capability parent) { - return call(parent); } - - Okl4::L4_SpaceId_t space_id() { - return call(); } - - void space_pager(Thread_capability thread) { - call(thread); } - }; -} - -#endif /* _INCLUDE__OKL4_PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-okl4/include/okl4_pd_session/connection.h b/repos/base-okl4/include/okl4_pd_session/connection.h deleted file mode 100644 index 8ef23081f8..0000000000 --- a/repos/base-okl4/include/okl4_pd_session/connection.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * \brief Connection to OKL4-specific PD service - * \author Stefan Kalkowski - * \date 2009-06-22 - */ - -/* - * Copyright (C) 2009-2013 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 _INCLUDE__OKL4_PD_SESSION__CONNECTION_H_ -#define _INCLUDE__OKL4_PD_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { - - struct Pd_connection : Connection, Okl4_pd_session_client - { - Pd_connection() - : - Connection(session("ram_quota=4K")), - Okl4_pd_session_client(cap()) - { } - }; -} - -#endif /* _INCLUDE__OKL4_PD_SESSION__CONNECTION_H_ */ diff --git a/repos/base-okl4/include/okl4_pd_session/okl4_pd_session.h b/repos/base-okl4/include/okl4_pd_session/okl4_pd_session.h deleted file mode 100644 index 7c4d6bbf00..0000000000 --- a/repos/base-okl4/include/okl4_pd_session/okl4_pd_session.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * \brief OKL4 specific extension of the PD session interface - * \author Stefan Kalkowski - * \date 2009-06-03 - */ - -/* - * Copyright (C) 2009-2013 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 _INCLUDE__OKL4_PD_SESSION__OKL4_PD_SESSION_H_ -#define _INCLUDE__OKL4_PD_SESSION__OKL4_PD_SESSION_H_ - -/* OKL4 includes */ -namespace Okl4 { extern "C" { -#include -} } - -/* Genode includes */ -#include - -namespace Genode { - - struct Okl4_pd_session : Pd_session - { - virtual ~Okl4_pd_session() { } - - /** - * Get the OKL4 specific space ID of the PD - * - * Should be used only by OKLinux, as it will be removed - * in the future! - * - * \return the space ID - */ - virtual Okl4::L4_SpaceId_t space_id() = 0; - - /** - * Set the thread/space allowed to page the PD - * - * (have a look at SpaceControl in OKL4) - * Should be used only by OKLinux, as it will be removed - * in the future! - */ - virtual void space_pager(Thread_capability) = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_space_id, Okl4::L4_SpaceId_t, space_id); - GENODE_RPC(Rpc_space_pager, void, space_pager, Thread_capability); - - GENODE_RPC_INTERFACE_INHERIT(Pd_session, Rpc_space_id, Rpc_space_pager); - }; -} - -#endif /* _INCLUDE__OKL4_PD_SESSION__OKL4_PD_SESSION_H_ */ diff --git a/repos/base-okl4/lib/mk/base.mk b/repos/base-okl4/lib/mk/base.mk index 007e2e20ff..90b0c746ba 100644 --- a/repos/base-okl4/lib/mk/base.mk +++ b/repos/base-okl4/lib/mk/base.mk @@ -3,6 +3,7 @@ SRC_CC += cpu/cache.cc SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc SRC_CC += thread/thread_start.cc SRC_CC += irq/platform.cc +SRC_CC += server/rpc_cap_alloc.cc vpath %.cc $(REP_DIR)/src/base vpath %.cc $(BASE_DIR)/src/base diff --git a/repos/base-okl4/src/core/include/pd_session_component.h b/repos/base-okl4/src/core/include/pd_session_component.h deleted file mode 100644 index 2bb4d3b958..0000000000 --- a/repos/base-okl4/src/core/include/pd_session_component.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * \brief Core-specific instance of the PD session interface for OKL4 - * \author Christian Helmuth - * \author Stefan Kalkowski - * \date 2006-07-17 - */ - -/* - * Copyright (C) 2006-2013 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 _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include - -/* core includes */ -#include -#include - -namespace Genode { class Pd_session_component; } - - -class Genode::Pd_session_component : public Rpc_object -{ - private: - - Platform_pd _pd; - Rpc_entrypoint &_thread_ep; - Signal_broker _signal_broker; - - public: - - Pd_session_component(Rpc_entrypoint &thread_ep, - Rpc_entrypoint &receiver_ep, - Rpc_entrypoint &context_ep, - Allocator &md_alloc, const char *args) - : - _thread_ep(thread_ep), - _signal_broker(md_alloc, receiver_ep, context_ep) - { } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { } - - - /************************** - ** Pd session interface ** - **************************/ - - int bind_thread(Thread_capability); - int assign_parent(Capability); - bool assign_pci(addr_t, uint16_t) { return false; } - - Signal_source_capability alloc_signal_source() override { - return _signal_broker.alloc_signal_source(); } - - void free_signal_source(Signal_source_capability cap) override { - _signal_broker.free_signal_source(cap); } - - Signal_context_capability - alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override - { - return _signal_broker.alloc_context(sig_rec_cap, imprint); - } - - void free_context(Signal_context_capability cap) override { - _signal_broker.free_context(cap); } - - void submit(Signal_context_capability cap, unsigned n) override { - _signal_broker.submit(cap, n); } - - - /***************************** - ** OKL4-specific additions ** - *****************************/ - - void space_pager(Thread_capability thread); - - Okl4::L4_SpaceId_t space_id() { - return Okl4::L4_SpaceId(_pd.pd_id()); } -}; - -#endif /* _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-okl4/src/core/include/platform_pd.h b/repos/base-okl4/src/core/include/platform_pd.h index 9e78266140..dca8ca952d 100644 --- a/repos/base-okl4/src/core/include/platform_pd.h +++ b/repos/base-okl4/src/core/include/platform_pd.h @@ -14,6 +14,9 @@ #ifndef _CORE__INCLUDE__PLATFORM_PD_H_ #define _CORE__INCLUDE__PLATFORM_PD_H_ +/* Genode includes */ +#include + /* core includes */ #include #include @@ -121,11 +124,8 @@ namespace Genode { /** * Protection domain allocation - * - * Find free L4 task and use it. We need the special case for Core - * startup. */ - int _alloc_pd(signed pd_id); + int _alloc_pd(); /** * Protection domain deallocation @@ -153,7 +153,7 @@ namespace Genode { * Constructors */ Platform_pd(bool core); - Platform_pd(signed pd_id = PD_INVALID, bool create = true); + Platform_pd(Allocator *, char const *); /** * Destructor diff --git a/repos/base-okl4/src/core/okl4_pd_session_component.cc b/repos/base-okl4/src/core/okl4_pd_session_component.cc deleted file mode 100644 index 7a8e8a7c8b..0000000000 --- a/repos/base-okl4/src/core/okl4_pd_session_component.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* - * \brief Core implementation of the PD session interface extension - * \author Stefan Kalkowski - * \date 2009-06-21 - */ - -/* - * Copyright (C) 2009-2013 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. - */ - -/* core includes */ -#include -#include -#include - -using namespace Genode; - - -void Pd_session_component::space_pager(Thread_capability thread) -{ - _thread_ep.apply(thread, [this] (Cpu_thread_component *cpu_thread) - { - if (!cpu_thread) return; - _pd.space_pager(cpu_thread->platform_thread()); - }); -} diff --git a/repos/base-okl4/src/core/platform_pd.cc b/repos/base-okl4/src/core/platform_pd.cc index 067dd3ab82..4eaedf349c 100644 --- a/repos/base-okl4/src/core/platform_pd.cc +++ b/repos/base-okl4/src/core/platform_pd.cc @@ -91,29 +91,19 @@ void Platform_pd::_destroy_pd() } -int Platform_pd::_alloc_pd(signed pd_id) +int Platform_pd::_alloc_pd() { - if (pd_id == PD_INVALID) { - unsigned i; + unsigned i; - for (i = PD_FIRST; i <= PD_MAX; i++) - if (_pds()[i].free) break; + for (i = PD_FIRST; i <= PD_MAX; i++) + if (_pds()[i].free) break; - /* no free protection domains available */ - if (i > PD_MAX) return -1; + /* no free protection domains available */ + if (i > PD_MAX) return -1; - pd_id = i; + _pds()[i].free = 0; - } else { - if (!_pds()[pd_id].reserved || !_pds()[pd_id].free) - return -1; - } - - _pds()[pd_id].free = 0; - - _pd_id = pd_id; - - return pd_id; + return i; } @@ -329,26 +319,23 @@ Platform_pd::Platform_pd(bool core) _init_threads(); - _pd_id = _alloc_pd(PD_INVALID); + _pd_id = _alloc_pd(); _create_pd(false); } -Platform_pd::Platform_pd(signed pd_id, bool create) +Platform_pd::Platform_pd(Allocator *, char const *label) : _space_pager(0) { - if (!create) - panic("create must be true."); - _init_threads(); - _pd_id = _alloc_pd(pd_id); + _pd_id = _alloc_pd(); if (_pd_id > PD_MAX) PERR("pd alloc failed"); - _create_pd(create); + _create_pd(true); } diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc index 72d49c16d1..02f471dac5 100644 --- a/repos/base-okl4/src/core/target.inc +++ b/repos/base-okl4/src/core/target.inc @@ -4,11 +4,11 @@ LIBS += boot_info base-common GEN_CORE_DIR = $(BASE_DIR)/src/core -SRC_CC += cap_session_component.cc \ - context_area.cc \ +SRC_CC += context_area.cc \ core_mem_alloc.cc \ core_printf.cc \ core_rm_session.cc \ + core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ dataspace_component.cc \ @@ -17,11 +17,13 @@ SRC_CC += cap_session_component.cc \ io_mem_session_support.cc \ irq_session_component.cc \ main.cc \ - okl4_pd_session_component.cc \ pager.cc \ pager_ep.cc \ pager_object.cc \ pd_session_component.cc \ + pd_upgrade_ram_quota.cc \ + pd_assign_pci.cc \ + rpc_cap_factory.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ @@ -46,9 +48,11 @@ include $(GEN_CORE_DIR)/version.inc vpath main.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) -vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) +vpath pd_assign_pci.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) @@ -56,6 +60,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath core_mem_alloc.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR) vpath context_area.cc $(GEN_CORE_DIR) vpath pager_ep.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/lib/mk/base.mk b/repos/base-pistachio/lib/mk/base.mk index 5d0f684c33..5e7bdf98c1 100644 --- a/repos/base-pistachio/lib/mk/base.mk +++ b/repos/base-pistachio/lib/mk/base.mk @@ -11,6 +11,7 @@ SRC_CC += cpu/cache.cc SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc SRC_CC += thread/thread_start.cc SRC_CC += irq/platform.cc +SRC_CC += server/rpc_cap_alloc.cc INC_DIR += $(BASE_DIR)/src/base/env diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index febf051047..d6f018e3b5 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -4,9 +4,9 @@ LIBS = base-common GEN_CORE_DIR = $(BASE_DIR)/src/core -SRC_CC = cap_session_component.cc \ - context_area.cc \ +SRC_CC = context_area.cc \ core_printf.cc \ + core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_platform.cc \ dataspace_component.cc \ @@ -18,6 +18,7 @@ SRC_CC = cap_session_component.cc \ main.cc \ multiboot_info.cc \ pd_session_component.cc \ + rpc_cap_factory.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ pager.cc \ @@ -46,9 +47,9 @@ include $(GEN_CORE_DIR)/version.inc vpath main.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) -vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) @@ -58,6 +59,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath context_area.cc $(GEN_CORE_DIR) vpath pager_ep.cc $(GEN_CORE_DIR) vpath pager_object.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/lib/mk/base.mk b/repos/base-sel4/lib/mk/base.mk index 356289e352..9c2acb3a6e 100644 --- a/repos/base-sel4/lib/mk/base.mk +++ b/repos/base-sel4/lib/mk/base.mk @@ -11,6 +11,7 @@ SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc SRC_CC += env/capability_space.cc SRC_CC += thread/thread_start.cc thread/thread_init.cc SRC_CC += irq/platform.cc +SRC_CC += server/rpc_cap_alloc.cc INC_DIR += $(REP_DIR)/src/base INC_DIR += $(BASE_DIR)/src/base/env diff --git a/repos/base-sel4/lib/mk/core.mk b/repos/base-sel4/lib/mk/core.mk index 9726f6a38d..761c611537 100644 --- a/repos/base-sel4/lib/mk/core.mk +++ b/repos/base-sel4/lib/mk/core.mk @@ -7,10 +7,10 @@ SRC_CC += \ ram_session_component.cc \ ram_session_support.cc \ rom_session_component.cc \ - cap_session_component.cc \ cpu_session_component.cc \ cpu_session_support.cc \ pd_session_component.cc \ + rpc_cap_factory.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ io_mem_session_component.cc \ @@ -28,6 +28,7 @@ SRC_CC += \ trace_session_component.cc \ core_rm_session.cc \ core_mem_alloc.cc \ + core_rpc_cap_alloc.cc \ dump_alloc.cc \ context_area.cc \ capability_space.cc \ @@ -58,6 +59,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath core_mem_alloc.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR) vpath pager_ep.cc $(GEN_CORE_DIR) vpath %.cc $(REP_DIR)/src/core diff --git a/repos/base-sel4/src/base/server/server.cc b/repos/base-sel4/src/base/server/server.cc index 3fb2ed3785..26ffa031b3 100644 --- a/repos/base-sel4/src/base/server/server.cc +++ b/repos/base-sel4/src/base/server/server.cc @@ -29,7 +29,7 @@ using namespace Genode; Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) { - Untyped_capability new_obj_cap = _cap_session->alloc(_cap); + Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap); /* add server object to object pool */ obj->cap(new_obj_cap); diff --git a/repos/base-sel4/src/core/capability_space.cc b/repos/base-sel4/src/core/capability_space.cc index 1f2789658d..8595e39d3d 100644 --- a/repos/base-sel4/src/core/capability_space.cc +++ b/repos/base-sel4/src/core/capability_space.cc @@ -23,8 +23,6 @@ #include #include -namespace Genode { class Cap_session; } - /** * Core-specific supplement of the capability meta data @@ -33,20 +31,20 @@ class Genode::Native_capability::Data : public Capability_data { private: - Cap_session const *_cap_session = nullptr; + Pd_session const *_pd_session = nullptr; public: - Data(Cap_session const *cap_session, Rpc_obj_key key) + Data(Pd_session const *pd_session, Rpc_obj_key key) : - Capability_data(key), _cap_session(cap_session) + Capability_data(key), _pd_session(pd_session) { } Data() { } - bool belongs_to(Cap_session const *session) const + bool belongs_to(Pd_session const *session) const { - return _cap_session == session; + return _pd_session == session; } }; @@ -79,7 +77,7 @@ namespace { Native_capability Capability_space::create_rpc_obj_cap(Native_capability ep_cap, - Cap_session const *cap_session, + Pd_session const *pd_session, Rpc_obj_key rpc_obj_key) { /* allocate core-local selector for RPC object */ @@ -87,7 +85,7 @@ Capability_space::create_rpc_obj_cap(Native_capability ep_cap, /* create Genode capability */ Native_capability::Data &data = - local_capability_space().create_capability(rpc_obj_sel, cap_session, + local_capability_space().create_capability(rpc_obj_sel, pd_session, rpc_obj_key); ASSERT(ep_cap.valid()); @@ -128,11 +126,11 @@ Native_capability Capability_space::create_ep_cap(Thread_base &ep_thread) { Cap_sel const ep_sel(ep_thread.tid().ep_sel); - /* entrypoint capabilities are not allocated from a CAP session */ - Cap_session const *cap_session = nullptr; + /* entrypoint capabilities are not allocated from a PD session */ + Pd_session const *pd_session = nullptr; Native_capability::Data &data = - local_capability_space().create_capability(ep_sel, cap_session, + local_capability_space().create_capability(ep_sel, pd_session, Rpc_obj_key()); return Native_capability(data); @@ -185,11 +183,11 @@ void Capability_space::reset_sel(unsigned sel) Native_capability Capability_space::import(Ipc_cap_data ipc_cap_data) { - /* imported capabilities are not associated with a CAP session */ - Cap_session const *cap_session = nullptr; + /* imported capabilities are not associated with a PD session */ + Pd_session const *pd_session = nullptr; Native_capability::Data &data = - local_capability_space().create_capability(ipc_cap_data.sel, cap_session, + local_capability_space().create_capability(ipc_cap_data.sel, pd_session, ipc_cap_data.rpc_obj_key); return Native_capability(data); diff --git a/repos/base-sel4/src/core/include/cap_session_component.h b/repos/base-sel4/src/core/include/cap_session_component.h deleted file mode 100644 index 8e19697592..0000000000 --- a/repos/base-sel4/src/core/include/cap_session_component.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * \brief Capability session service - * \author Norman Feske - * \date 2015-05-08 - */ - -/* - * Copyright (C) 2015 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 _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include - -namespace Genode { class Cap_session_component; } - -struct Genode::Cap_session_component : Rpc_object -{ - Cap_session_component(Allocator *md_alloc, const char *args) {} - - void upgrade_ram_quota(size_t ram_quota) { } - - Native_capability alloc(Native_capability ep); - - void free(Native_capability cap); - - static Native_capability alloc(Cap_session_component *session, - Native_capability ep); -}; - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base-sel4/src/core/include/core_capability_space.h b/repos/base-sel4/src/core/include/core_capability_space.h index 886bf589ba..a630aa22a4 100644 --- a/repos/base-sel4/src/core/include/core_capability_space.h +++ b/repos/base-sel4/src/core/include/core_capability_space.h @@ -17,7 +17,7 @@ /* base-internal includes */ #include -namespace Genode { class Cap_session; } +namespace Genode { class Pd_session; } namespace Genode { namespace Capability_space { @@ -26,7 +26,7 @@ namespace Genode { namespace Capability_space { * Create new RPC object capability for the specified entrypoint */ Native_capability create_rpc_obj_cap(Native_capability ep_cap, - Cap_session const *, + Pd_session const *, Rpc_obj_key); } } diff --git a/repos/base-sel4/src/core/include/rpc_cap_factory.h b/repos/base-sel4/src/core/include/rpc_cap_factory.h new file mode 100644 index 0000000000..fd15145238 --- /dev/null +++ b/repos/base-sel4/src/core/include/rpc_cap_factory.h @@ -0,0 +1,39 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + static Native_capability _alloc(Rpc_cap_factory *owner, + Native_capability ep); + + public: + + Rpc_cap_factory(Allocator &md_alloc) { } + + Native_capability alloc(Native_capability ep); + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-sel4/src/core/cap_session_component.cc b/repos/base-sel4/src/core/rpc_cap_factory.cc similarity index 53% rename from repos/base-sel4/src/core/cap_session_component.cc rename to repos/base-sel4/src/core/rpc_cap_factory.cc index 8dc34b9fcb..7f0bc9c255 100644 --- a/repos/base-sel4/src/core/cap_session_component.cc +++ b/repos/base-sel4/src/core/rpc_cap_factory.cc @@ -1,14 +1,11 @@ /* - * \brief seL4-specific capability allocation + * \brief seL4-specific RPC capability factory * \author Norman Feske - * \author Stefan Kalkowski - * \date 2015-05-08 - * - * Based on base-foc/src/core/cap_session_component.cc + * \date 2016-01-19 */ /* - * Copyright (C) 2015 Genode Labs GmbH + * Copyright (C) 2016 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. @@ -19,7 +16,8 @@ #include /* core includes */ -#include +#include +#include #include /* base-internal include */ @@ -31,8 +29,8 @@ using namespace Genode; static unsigned unique_id_cnt; -Native_capability Cap_session_component::alloc(Cap_session_component *session, - Native_capability ep) +Native_capability Rpc_cap_factory::_alloc(Rpc_cap_factory *owner, + Native_capability ep) { if (!ep.valid()) { PWRN("Invalid entrypoint capability"); @@ -41,17 +39,18 @@ Native_capability Cap_session_component::alloc(Cap_session_component *session, Rpc_obj_key const rpc_obj_key(++unique_id_cnt); - return Capability_space::create_rpc_obj_cap(ep, session, rpc_obj_key); + // XXX remove cast + return Capability_space::create_rpc_obj_cap(ep, (Cap_session*)owner, rpc_obj_key); } -Native_capability Cap_session_component::alloc(Native_capability ep) +Native_capability Rpc_cap_factory::alloc(Native_capability ep) { - return Cap_session_component::alloc(this, ep); + return Rpc_cap_factory::_alloc(this, ep); } -void Cap_session_component::free(Native_capability cap) +void Rpc_cap_factory::free(Native_capability cap) { if (!cap.valid()) return; diff --git a/repos/base/include/base/rpc_server.h b/repos/base/include/base/rpc_server.h index 8db4b89691..90d8959eaf 100644 --- a/repos/base/include/base/rpc_server.h +++ b/repos/base/include/base/rpc_server.h @@ -278,10 +278,18 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool Lock _cap_valid; /* thread startup synchronization */ Lock _delay_start; /* delay start of request dispatching */ Lock _delay_exit; /* delay destructor until server settled */ - Cap_session *_cap_session; /* for creating capabilities */ + Pd_session &_pd_session; /* for creating capabilities */ Exit_handler _exit_handler; Capability _exit_cap; + /** + * Access to kernel-specific part of the PD session interface + * + * Some kernels like NOVA need a special interface for creating RPC + * object capabilities. + */ + Capability _native_pd_cap; + /** * Back end used to associate RPC object with the entry point * @@ -303,6 +311,24 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool */ void _block_until_cap_valid(); + /** + * Allocate new RPC object capability + * + * Regular servers allocate capabilities from their protection domain + * via the component's environment. This method allows core to have a + * special implementation that does not rely on a PD session. + * + * The 'entry' argument is used only on NOVA. It is the server-side + * instruction pointer to be associated with the RPC object capability. + */ + Native_capability _alloc_rpc_cap(Pd_session &, Native_capability ep, + addr_t entry = 0); + + /** + * Free RPC object capability + */ + void _free_rpc_cap(Pd_session &, Native_capability); + /** * Thread interface * @@ -322,7 +348,7 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool * \param name name of entrypoint thread * \param location CPU affinity */ - Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, + Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, char const *name, bool start_on_construction = true, Affinity::Location location = Affinity::Location()); diff --git a/repos/base/include/cap_session/cap_session.h b/repos/base/include/cap_session/cap_session.h index d79637222e..e9cbc73897 100644 --- a/repos/base/include/cap_session/cap_session.h +++ b/repos/base/include/cap_session/cap_session.h @@ -3,9 +3,9 @@ * \author Norman Feske * \date 2006-06-23 * - * A 'Cap_session' is an allocator of user-level capabilities. - * User-level capabilities are used to reference server objects - * across address spaces. + * \deprecated + * + * This header is scheduled for removal. It exists for API compatiblity only. */ /* @@ -18,48 +18,8 @@ #ifndef _INCLUDE__CAP_SESSION__CAP_SESSION_H_ #define _INCLUDE__CAP_SESSION__CAP_SESSION_H_ -#include -#include -#include +#include -namespace Genode { struct Cap_session; } - - -struct Genode::Cap_session : Session -{ - class Out_of_metadata : public Exception { }; - - static const char *service_name() { return "CAP"; } - - virtual ~Cap_session() { } - - /** - * Allocate new unique userland capability - * - * \param ep entry point that will use this capability - * - * \throw Out_of_metadata if meta-data backing store is exhausted - * - * \return new userland capability - */ - virtual Native_capability alloc(Native_capability ep) = 0; - - /** - * Free userland capability - * - * \param cap userland capability to free - */ - virtual void free(Native_capability cap) = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC_THROW(Rpc_alloc, Native_capability, alloc, - GENODE_TYPE_LIST(Out_of_metadata), Native_capability); - GENODE_RPC(Rpc_free, void, free, Native_capability); - GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free); -}; +namespace Genode { typedef Pd_session Cap_session; } #endif /* _INCLUDE__CAP_SESSION__CAP_SESSION_H_ */ diff --git a/repos/base/include/cap_session/capability.h b/repos/base/include/cap_session/capability.h deleted file mode 100644 index 7be38a38ad..0000000000 --- a/repos/base/include/cap_session/capability.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * \brief CAP-session capability type - * \author Norman Feske - * \date 2008-08-16 - */ - -/* - * Copyright (C) 2008-2013 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 _INCLUDE__CAP_SESSION__CAPABILITY_H_ -#define _INCLUDE__CAP_SESSION__CAPABILITY_H_ - -#include -#include - -namespace Genode { typedef Capability Cap_session_capability; } - -#endif /* _INCLUDE__CAP_SESSION__CAPABILITY_H_ */ diff --git a/repos/base/include/cap_session/client.h b/repos/base/include/cap_session/client.h deleted file mode 100644 index 5d4e466eef..0000000000 --- a/repos/base/include/cap_session/client.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * \brief Client-side CAP session interface - * \author Norman Feske - * \date 2006-07-10 - */ - -/* - * Copyright (C) 2006-2013 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 _INCLUDE__CAP_SESSION__CLIENT_H_ -#define _INCLUDE__CAP_SESSION__CLIENT_H_ - -#include -#include -#include - -namespace Genode { struct Cap_session_client; } - - -struct Genode::Cap_session_client : Rpc_client -{ - explicit Cap_session_client(Cap_session_capability session) - : Rpc_client(session) { } - - Native_capability alloc(Native_capability ep) override { - return call(ep); } - - void free(Native_capability cap) override { call(cap); } -}; - -#endif /* _INCLUDE__CAP_SESSION__CLIENT_H_ */ diff --git a/repos/base/include/cap_session/connection.h b/repos/base/include/cap_session/connection.h index b4304a60b6..0adf77eda3 100644 --- a/repos/base/include/cap_session/connection.h +++ b/repos/base/include/cap_session/connection.h @@ -2,6 +2,10 @@ * \brief Connection to CAP service * \author Norman Feske * \date 2008-08-22 + * + * \deprecated + * + * This header is scheduled for removal. It exists for API compatiblity only. */ /* @@ -14,19 +18,26 @@ #ifndef _INCLUDE__CAP_SESSION__CONNECTION_H_ #define _INCLUDE__CAP_SESSION__CONNECTION_H_ -#include -#include +#include +#include +#include namespace Genode { struct Cap_connection; } -struct Genode::Cap_connection : Connection, Cap_session_client +/* + * There are no CAP connections anymore. The only situation where CAP + * connections were created was inside old-fashioned servers that used + * to create an 'Rpc_entrypoint' manually. The 'Rpc_entrypoint' requires + * a CAP session as constructor argument. We accommodate this use case + * by allocating RPC capabilities from the server's protection domain. + * + * Modern components no longer create 'Rpc_entrypoint' objects directly + * but instead use the new 'Entrypoint' interface. + */ +struct Genode::Cap_connection : Pd_session_client { - Cap_connection() - : - Connection(session("ram_quota=4K")), - Cap_session_client(cap()) - { } + Cap_connection() : Pd_session_client(env()->pd_session_cap()) { } }; #endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */ diff --git a/repos/base/include/pd_session/client.h b/repos/base/include/pd_session/client.h index 7fbc4deae9..ff00be5daf 100644 --- a/repos/base/include/pd_session/client.h +++ b/repos/base/include/pd_session/client.h @@ -49,6 +49,14 @@ struct Genode::Pd_session_client : Rpc_client void submit(Signal_context_capability receiver, unsigned cnt = 1) override { call(receiver, cnt); } + + Native_capability alloc_rpc_cap(Native_capability ep) override { + return call(ep); } + + void free_rpc_cap(Native_capability cap) override { + call(cap); } + + Capability native_pd() override { return call(); } }; #endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */ diff --git a/repos/base/include/pd_session/pd_session.h b/repos/base/include/pd_session/pd_session.h index a342bbcf46..c1f6f26f76 100644 --- a/repos/base/include/pd_session/pd_session.h +++ b/repos/base/include/pd_session/pd_session.h @@ -138,6 +138,39 @@ struct Genode::Pd_session : Session ** Support for the RPC framework ** ***********************************/ + /** + * Allocate new RPC-object capability + * + * \param ep entry point that will use this capability + * + * \throw Out_of_metadata if meta-data backing store is exhausted + * + * \return new RPC capability + */ + virtual Native_capability alloc_rpc_cap(Native_capability ep) = 0; + + /** + * Free RPC-object capability + * + * \param cap capability to free + */ + virtual void free_rpc_cap(Native_capability cap) = 0; + + + /***************************************** + ** Access to kernel-specific interface ** + *****************************************/ + + /** + * Common base class of kernel-specific PD interfaces + */ + struct Native_pd { }; + + /** + * Return capability to kernel-specific PD operations + */ + virtual Capability native_pd() = 0; + /********************* ** RPC declaration ** @@ -161,10 +194,29 @@ struct Genode::Pd_session : Session GENODE_RPC(Rpc_submit, void, submit, Capability, unsigned); + GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap, + GENODE_TYPE_LIST(Out_of_metadata), Native_capability); - GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent, Rpc_assign_pci, - Rpc_alloc_signal_source, Rpc_free_signal_source, - Rpc_alloc_context, Rpc_free_context, Rpc_submit); + GENODE_RPC(Rpc_free_rpc_cap, void, free_rpc_cap, Native_capability); + + GENODE_RPC(Rpc_native_pd, Capability, native_pd); + + /* + * Manual definition of 'Rpc_functions', see the comment in cpu_session.h. + */ + typedef Meta::Type_tuple + > > > > > > > > > > Rpc_functions; }; #endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */ diff --git a/repos/base/src/base/env/platform_env.h b/repos/base/src/base/env/platform_env.h index f3ed2846b2..58192ffd5d 100644 --- a/repos/base/src/base/env/platform_env.h +++ b/repos/base/src/base/env/platform_env.h @@ -23,7 +23,7 @@ /* Genode includes */ #include #include -#include +#include /* local includes */ #include @@ -137,15 +137,15 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve ** Env interface ** *******************/ - Parent *parent() { return &_parent_client; } - Ram_session *ram_session() { return &_resources.ram; } - Ram_session_capability ram_session_cap() { return _resources.ram; } - Cpu_session *cpu_session() { return &_resources.cpu; } - Cpu_session_capability cpu_session_cap() { return _resources.cpu; } - Rm_session *rm_session() { return &_resources.rm; } - Pd_session *pd_session() { return &_resources.pd; } - Pd_session_capability pd_session_cap() { return _resources.pd; } - Allocator *heap() { return &_heap; } + Parent *parent() override { return &_parent_client; } + Ram_session *ram_session() override { return &_resources.ram; } + Ram_session_capability ram_session_cap() override { return _resources.ram; } + Cpu_session *cpu_session() override { return &_resources.cpu; } + Cpu_session_capability cpu_session_cap() override { return _resources.cpu; } + Rm_session *rm_session() override { return &_resources.rm; } + Pd_session *pd_session() override { return &_resources.pd; } + Pd_session_capability pd_session_cap() override { return _resources.pd; } + Allocator *heap() override { return &_heap; } }; #endif /* _PLATFORM_ENV_H_ */ diff --git a/repos/base/src/base/server/common.cc b/repos/base/src/base/server/common.cc index 9042ccd054..99971baa64 100644 --- a/repos/base/src/base/server/common.cc +++ b/repos/base/src/base/server/common.cc @@ -24,7 +24,7 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj) /* make sure nobody is able to find this object */ remove(obj); - _cap_session->free(obj->cap()); + _free_rpc_cap(_pd_session, obj->cap()); /* now the object may be safely destructed */ } @@ -79,7 +79,7 @@ bool Rpc_entrypoint::is_myself() const } -Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, +Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, char const *name, bool start_on_construction, Affinity::Location location) : @@ -87,7 +87,7 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, _cap(Untyped_capability()), _cap_valid(Lock::LOCKED), _delay_start(Lock::LOCKED), _delay_exit(Lock::LOCKED), - _cap_session(cap_session) + _pd_session(*pd_session) { /* set CPU affinity, if specified */ if (location.valid()) diff --git a/repos/base/src/base/server/rpc_cap_alloc.cc b/repos/base/src/base/server/rpc_cap_alloc.cc new file mode 100644 index 0000000000..b470cde185 --- /dev/null +++ b/repos/base/src/base/server/rpc_cap_alloc.cc @@ -0,0 +1,44 @@ +/* + * \brief Core-specific back end of the RPC entrypoint + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* Genode includes */ +#include +#include +#include +#include + +using namespace Genode; + + +Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &pd, + Native_capability ep, addr_t) +{ + Untyped_capability new_obj_cap = + retry( + [&] () { return pd.alloc_rpc_cap(_cap); }, + [&] () { + Pd_session_client *client = + dynamic_cast(&pd); + + if (client) + env()->parent()->upgrade(*client, "ram_quota=16K"); + }); + + return new_obj_cap; +} + + +void Rpc_entrypoint::_free_rpc_cap(Pd_session &pd, Native_capability cap) +{ + return pd.free_rpc_cap(cap); +} diff --git a/repos/base/src/base/server/server.cc b/repos/base/src/base/server/server.cc index 7aef8e3cf5..6a37457370 100644 --- a/repos/base/src/base/server/server.cc +++ b/repos/base/src/base/server/server.cc @@ -29,7 +29,7 @@ using namespace Genode; Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) { Untyped_capability ep_cap = Native_capability(_cap.dst(), 0); - Untyped_capability new_obj_cap = _cap_session->alloc(ep_cap); + Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, ep_cap); /* add server object to object pool */ obj->cap(new_obj_cap); diff --git a/repos/base/src/core/cap_session_component.cc b/repos/base/src/core/cap_session_component.cc deleted file mode 100644 index ce7a37e1af..0000000000 --- a/repos/base/src/core/cap_session_component.cc +++ /dev/null @@ -1,17 +0,0 @@ -/* - * \brief Core implementation of the Cap session interface - * \author Stefan Kalkowski - * \date 2015-03-10 - */ - -/* - * Copyright (C) 2015 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. - */ - -/* core includes */ -#include - -long Genode::Cap_session_component::_unique_id_cnt; diff --git a/repos/base/src/core/core_rpc_cap_alloc.cc b/repos/base/src/core/core_rpc_cap_alloc.cc new file mode 100644 index 0000000000..00a652391e --- /dev/null +++ b/repos/base/src/core/core_rpc_cap_alloc.cc @@ -0,0 +1,41 @@ +/* + * \brief Core-specific back end of the RPC entrypoint + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* Genode includes */ +#include + +/* core-local includes */ +#include +#include + +using namespace Genode; + + +static Rpc_cap_factory &rpc_cap_factory() +{ + static Rpc_cap_factory inst(*platform()->core_mem_alloc()); + return inst; +} + + +Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &, Native_capability ep, + addr_t) +{ + return rpc_cap_factory().alloc(ep); +} + + +void Rpc_entrypoint::_free_rpc_cap(Pd_session &, Native_capability cap) +{ + rpc_cap_factory().free(cap); +} diff --git a/repos/base/src/core/include/cap_root.h b/repos/base/src/core/include/cap_root.h deleted file mode 100644 index b9b30eb1da..0000000000 --- a/repos/base/src/core/include/cap_root.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * \brief CAP root interface - * \author Norman Feske - * \date 2006-07-06 - */ - -/* - * Copyright (C) 2006-2013 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 _CORE__INCLUDE__CAP_ROOT_H_ -#define _CORE__INCLUDE__CAP_ROOT_H_ - -/* Genode includes */ -#include - -/* core includes */ -#include - -namespace Genode { - - class Cap_root : public Root_component - { - private: - - Allocator *_md_alloc; - - protected: - - Cap_session_component *_create_session(const char *args) { - return new (md_alloc()) Cap_session_component(_md_alloc, args); } - - void _upgrade_session(Cap_session_component *c, const char *args) - { - size_t ram_quota = - Arg_string::find_arg(args, "ram_quota").ulong_value(0); - c->upgrade_ram_quota(ram_quota); - } - - public: - - /** - * Constructor - * - * \param session_ep entry point for managing session objects - * \param md_alloc meta-data allocator to be used by root component - */ - Cap_root(Rpc_entrypoint *session_ep, - Allocator *md_alloc) - : - Root_component(session_ep, md_alloc), - _md_alloc(md_alloc) - { } - }; -} - -#endif /* _CORE__INCLUDE__CAP_ROOT_H_ */ diff --git a/repos/base/src/core/include/cap_session_component.h b/repos/base/src/core/include/cap_session_component.h deleted file mode 100644 index cb518f3043..0000000000 --- a/repos/base/src/core/include/cap_session_component.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * \brief Capability allocation service - * \author Norman Feske - * \date 2006-06-26 - */ - -/* - * Copyright (C) 2006-2013 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 _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ - -#include -#include -#include - -namespace Genode { - - class Cap_session_component : public Rpc_object - { - private: - - static long _unique_id_cnt; - - static Lock &_lock() - { - static Lock static_lock; - return static_lock; - } - - public: - - Cap_session_component(Allocator *md_alloc, const char *args) {} - - void upgrade_ram_quota(size_t ram_quota) { } - - Native_capability alloc(Native_capability ep) - { - Lock::Guard lock_guard(_lock()); - - return Native_capability(ep.dst(), ++_unique_id_cnt); - } - - void free(Native_capability cap) { } - }; -} - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index 0a3cd1ab36..a5456a0b3a 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -30,7 +30,6 @@ #include #include #include -#include #include namespace Genode { @@ -115,8 +114,7 @@ namespace Genode { typedef Synchronized_ram_session Core_ram_session; - Core_parent _core_parent; - Cap_session_component _cap_session; + Core_parent _core_parent; enum { ENTRYPOINT_STACK_SIZE = 2048 * sizeof(Genode::addr_t) }; @@ -144,8 +142,7 @@ namespace Genode { */ Core_env() : - _cap_session(platform()->core_mem_alloc(), "ram_quota=4K"), - _entrypoint(&_cap_session, ENTRYPOINT_STACK_SIZE, "entrypoint"), + _entrypoint(nullptr, ENTRYPOINT_STACK_SIZE, "entrypoint"), _rm_session(&_entrypoint), _ram_session(&_entrypoint, &_entrypoint, platform()->ram_alloc(), platform()->core_mem_alloc(), @@ -162,7 +159,6 @@ namespace Genode { ~Core_env() { parent()->exit(0); } Rpc_entrypoint *entrypoint() { return &_entrypoint; } - Cap_session *cap_session() { return &_cap_session; } /******************* diff --git a/repos/base/src/core/include/core_pd_session.h b/repos/base/src/core/include/core_pd_session.h index 63b0a7befe..d738354cd4 100644 --- a/repos/base/src/core/include/core_pd_session.h +++ b/repos/base/src/core/include/core_pd_session.h @@ -97,6 +97,18 @@ class Genode::Core_pd_session_component : public Rpc_object context->source()->submit(context, cnt); }); } + + Native_capability alloc_rpc_cap(Native_capability) override + { + ASSERT_NEVER_CALLED; + } + + void free_rpc_cap(Native_capability) override + { + ASSERT_NEVER_CALLED; + } + + Capability native_pd() override { ASSERT_NEVER_CALLED; } }; #endif /* _CORE__INCLUDE__CORE_PD_SESSION_H_ */ diff --git a/repos/base/src/core/include/io_port_root.h b/repos/base/src/core/include/io_port_root.h index 21e2960b7d..a1478cfa36 100644 --- a/repos/base/src/core/include/io_port_root.h +++ b/repos/base/src/core/include/io_port_root.h @@ -29,8 +29,8 @@ namespace Genode { public: - Io_port_handler(Cap_session *cap_session) : - _ep(cap_session, STACK_SIZE, "ioport") + Io_port_handler(Pd_session *pd_session) : + _ep(pd_session, STACK_SIZE, "ioport") { } Rpc_entrypoint *entrypoint() { return &_ep; } @@ -58,11 +58,11 @@ namespace Genode { * \param io_port_alloc platform IO_PORT allocator * \param md_alloc meta-data allocator to be used by root component */ - Io_port_root(Cap_session *cap_session, + Io_port_root(Pd_session *pd_session, Range_allocator *io_port_alloc, Allocator *md_alloc) : - Io_port_handler(cap_session), + Io_port_handler(pd_session), Root_component(entrypoint(), md_alloc), _io_port_alloc(io_port_alloc) { } }; diff --git a/repos/base/src/core/include/native_pd_component.h b/repos/base/src/core/include/native_pd_component.h new file mode 100644 index 0000000000..c665ac7f3a --- /dev/null +++ b/repos/base/src/core/include/native_pd_component.h @@ -0,0 +1,42 @@ +/* + * \brief Kernel-specific part of the PD-session interface + * \author Norman Feske + * \date 2016-01-19 + * + * This definition is used on platforms with no kernel-specific PD functions + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__NATIVE_PD_H_ +#define _CORE__INCLUDE__NATIVE_PD_H_ + +/* Genode includes */ +#include + +/* core-local includes */ +#include + +namespace Genode { + + class Pd_session_component; + class Native_pd_component; +} + + +struct Genode::Native_pd_component +{ + Native_pd_component(Pd_session_component &, char const *) { } + + Capability cap() + { + return Capability(); + } +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base/src/core/include/pager.h b/repos/base/src/core/include/pager.h index 56ae2d4693..a25fb77052 100644 --- a/repos/base/src/core/include/pager.h +++ b/repos/base/src/core/include/pager.h @@ -16,12 +16,16 @@ #ifndef _CORE__INCLUDE__PAGER_H_ #define _CORE__INCLUDE__PAGER_H_ +/* Genode includes */ #include #include #include #include #include +/* core-local includes */ +#include + namespace Genode { /** @@ -131,8 +135,8 @@ class Genode::Pager_entrypoint : public Object_pool, { private: - Ipc_pager _pager; - Cap_session *_cap_session; + Ipc_pager _pager; + Rpc_cap_factory _cap_factory; Untyped_capability _pager_object_cap(unsigned long badge); @@ -141,13 +145,15 @@ class Genode::Pager_entrypoint : public Object_pool, /** * Constructor * - * \param cap_session Cap_session for creating capabilities + * \param cap_factory factory for creating capabilities * for the pager objects managed by this * entry point */ - Pager_entrypoint(Cap_session *cap_session) - : Thread("pager_ep"), - _cap_session(cap_session) { start(); } + Pager_entrypoint(Rpc_cap_factory &cap_factory) + : + Thread("pager_ep"), + _cap_factory(cap_factory) + { start(); } /** * Associate Pager_object with the entry point diff --git a/repos/base/src/core/include/pd_session_component.h b/repos/base/src/core/include/pd_session_component.h index f0b41ed32c..dd07a18587 100644 --- a/repos/base/src/core/include/pd_session_component.h +++ b/repos/base/src/core/include/pd_session_component.h @@ -25,6 +25,8 @@ /* core includes */ #include #include +#include +#include namespace Genode { class Pd_session_component; } @@ -48,16 +50,19 @@ class Genode::Pd_session_component : public Rpc_object } } const _label; - Allocator_guard _md_alloc; /* guarded meta-data allocator */ - Platform_pd _pd; - Capability _parent; - Rpc_entrypoint &_thread_ep; - - Signal_broker _signal_broker; + Allocator_guard _md_alloc; /* guarded meta-data allocator */ + Platform_pd _pd; + Capability _parent; + Rpc_entrypoint &_thread_ep; + Signal_broker _signal_broker; + Rpc_cap_factory _rpc_cap_factory; + Native_pd_component _native_pd; size_t _ram_quota(char const * args) { return Arg_string::find_arg(args, "ram_quota").long_value(0); } + friend class Native_pd_component; + public: /** @@ -86,7 +91,9 @@ class Genode::Pd_session_component : public Rpc_object _md_alloc(&md_alloc, _ram_quota(args)), _pd(&_md_alloc, _label.string), _thread_ep(thread_ep), - _signal_broker(_md_alloc, receiver_ep, context_ep) + _signal_broker(_md_alloc, receiver_ep, context_ep), + _rpc_cap_factory(_md_alloc), + _native_pd(*this, args) { } /** @@ -130,6 +137,19 @@ class Genode::Pd_session_component : public Rpc_object void submit(Signal_context_capability cap, unsigned n) override { _signal_broker.submit(cap, n); } + + Native_capability alloc_rpc_cap(Native_capability ep) override + { + try { + return _rpc_cap_factory.alloc(ep); } + catch (Genode::Allocator::Out_of_memory) { + throw Pd_session::Out_of_metadata(); } + } + + void free_rpc_cap(Native_capability cap) override { + _rpc_cap_factory.free(cap); } + + Capability native_pd() { return _native_pd.cap(); } }; #endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base/src/core/include/rm_root.h b/repos/base/src/core/include/rm_root.h index 445d6fc348..4e5affa5a9 100644 --- a/repos/base/src/core/include/rm_root.h +++ b/repos/base/src/core/include/rm_root.h @@ -17,8 +17,9 @@ /* Genode */ #include -/* Core */ +/* core-local includes */ #include +#include namespace Genode { @@ -88,21 +89,21 @@ namespace Genode { * \param ds_ep entry point for managing dataspaces * \param thread_ep entry point for managing threads * \param md_alloc meta data allocator to be used by root component - * \param cap_session allocator for pager-object capabilities + * \param cap_factory for allocating pager-object capabilities * \param vm_start begin of virtual memory (default value) * \param vm_size size of virtual memory (default value) */ - Rm_root(Rpc_entrypoint *session_ep, - Rpc_entrypoint *ds_ep, - Rpc_entrypoint *thread_ep, - Allocator *md_alloc, - Cap_session *cap_session, - addr_t vm_start, - size_t vm_size) + Rm_root(Rpc_entrypoint *session_ep, + Rpc_entrypoint *ds_ep, + Rpc_entrypoint *thread_ep, + Allocator *md_alloc, + Rpc_cap_factory &cap_factory, + addr_t vm_start, + size_t vm_size) : Root_component(session_ep, md_alloc), _ds_ep(ds_ep), _thread_ep(thread_ep), _md_alloc(md_alloc), - _pager_ep(cap_session), _vm_start(vm_start), _vm_size(vm_size) + _pager_ep(cap_factory), _vm_start(vm_start), _vm_size(vm_size) { } /** diff --git a/repos/base/src/core/include/rpc_cap_factory.h b/repos/base/src/core/include/rpc_cap_factory.h new file mode 100644 index 0000000000..4bde1ae612 --- /dev/null +++ b/repos/base/src/core/include/rpc_cap_factory.h @@ -0,0 +1,44 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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 _CORE__INCLUDE__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + static long _unique_id_cnt; + static Lock &_lock(); + + public: + + Rpc_cap_factory(Allocator &) { } + + Native_capability alloc(Native_capability ep) + { + Lock::Guard lock_guard(_lock()); + + return Native_capability(ep.dst(), ++_unique_id_cnt); + } + + void free(Native_capability) { } +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index ae20608663..2d49c37d57 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -120,11 +119,11 @@ class Core_child : public Child_policy * Constructor */ Core_child(Dataspace_capability elf_ds, Pd_session_capability pd, - Cap_session *cap_session, Ram_session_capability ram, + Ram_session_capability ram, Cpu_session_capability cpu, Rm_session_capability rm, Service_registry &services) : - _entrypoint(cap_session, STACK_SIZE, "init", false), + _entrypoint(nullptr, STACK_SIZE, "init", false), _local_services(services), _child(elf_ds, pd, ram, cpu, rm, &_entrypoint, this, *_local_services.find(Pd_session::service_name()), @@ -212,10 +211,14 @@ int main() */ static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); - static Cap_root cap_root (e, &sliced_heap); + /* + * Factory for creating RPC capabilities within core + */ + static Rpc_cap_factory rpc_cap_factory(sliced_heap); + static Ram_root ram_root (e, e, platform()->ram_alloc(), &sliced_heap); static Rom_root rom_root (e, e, platform()->rom_fs(), &sliced_heap); - static Rm_root rm_root (e, e, e, &sliced_heap, core_env()->cap_session(), + static Rm_root rm_root (e, e, e, &sliced_heap, rpc_cap_factory, platform()->vm_start(), platform()->vm_size()); static Cpu_root cpu_root (e, e, rm_root.pager_ep(), &sliced_heap, Trace::sources()); @@ -223,7 +226,7 @@ int main() static Log_root log_root (e, &sliced_heap); static Io_mem_root io_mem_root (e, e, platform()->io_mem_alloc(), platform()->ram_alloc(), &sliced_heap); - static Irq_root irq_root (core_env()->cap_session(), + static Irq_root irq_root (core_env()->pd_session(), platform()->irq_alloc(), &sliced_heap); static Trace::Root trace_root (e, &sliced_heap, Trace::sources(), trace_policies); @@ -234,7 +237,6 @@ int main() static Local_service ls[] = { Local_service(Rom_session::service_name(), &rom_root), Local_service(Ram_session::service_name(), &ram_root), - Local_service(Cap_session::service_name(), &cap_root), Local_service(Rm_session::service_name(), &rm_root), Local_service(Cpu_session::service_name(), &cpu_root), Local_service(Pd_session::service_name(), &pd_root), @@ -287,8 +289,8 @@ int main() Pd_connection init_pd("init"); Core_child *init = new (env()->heap()) Core_child(Rom_session_client(init_rom_session_cap).dataspace(), - init_pd, core_env()->cap_session(), init_ram_session_cap, - init_cpu.cap(), init_rm.cap(), local_services); + init_pd, init_ram_session_cap, init_cpu.cap(), init_rm.cap(), + local_services); PDBG("--- init created, waiting for exit condition ---"); platform()->wait_for_exit(); diff --git a/repos/base/src/core/rpc_cap_factory.cc b/repos/base/src/core/rpc_cap_factory.cc new file mode 100644 index 0000000000..46f7a01d4e --- /dev/null +++ b/repos/base/src/core/rpc_cap_factory.cc @@ -0,0 +1,23 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * Copyright (C) 2016 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. + */ + +/* core-local includes */ +#include + +long Genode::Rpc_cap_factory::_unique_id_cnt; + +Genode::Lock &Genode::Rpc_cap_factory::_lock() +{ + static Lock static_lock; + return static_lock; +} diff --git a/repos/base/src/core/spec/x86/platform_services.cc b/repos/base/src/core/spec/x86/platform_services.cc index d8af762b49..af266aff93 100644 --- a/repos/base/src/core/spec/x86/platform_services.cc +++ b/repos/base/src/core/spec/x86/platform_services.cc @@ -28,7 +28,7 @@ void Genode::platform_add_local_services(Rpc_entrypoint*, Sliced_heap *sliced_heap, Service_registry *local_services) { - static Io_port_root io_port_root(core_env()->cap_session(), + static Io_port_root io_port_root(core_env()->pd_session(), platform()->io_port_alloc(), sliced_heap); static Local_service io_port_ls(Io_port_session::service_name(), &io_port_root); diff --git a/repos/ports-foc/src/lib/l4lx/include/task.h b/repos/ports-foc/src/lib/l4lx/include/task.h index b49ca1e328..a86d813822 100644 --- a/repos/ports-foc/src/lib/l4lx/include/task.h +++ b/repos/ports-foc/src/lib/l4lx/include/task.h @@ -15,7 +15,8 @@ #define _L4LX__TASK_H_ /* Genode includes */ -#include +#include +#include #include namespace Fiasco { @@ -30,9 +31,10 @@ namespace L4lx { { private: - Fiasco::l4_cap_idx_t _ref; - Genode::Foc_pd_connection _pd; - Genode::Native_capability _cap; + Fiasco::l4_cap_idx_t _ref; + Genode::Pd_connection _pd; + Genode::Foc_native_pd_client _native_pd { _pd.native_pd() }; + Genode::Native_capability _cap; public: @@ -40,7 +42,9 @@ namespace L4lx { ** Constructor ** *****************/ - Task(Fiasco::l4_cap_idx_t ref) : _ref(ref), _cap(_pd.task_cap()) + Task(Fiasco::l4_cap_idx_t ref) + : + _ref(ref), _cap(_native_pd.task_cap()) { using namespace Fiasco; diff --git a/repos/ports-foc/src/lib/l4lx/startup.cc b/repos/ports-foc/src/lib/l4lx/startup.cc index 6555322f6a..f7f72ff505 100644 --- a/repos/ports-foc/src/lib/l4lx/startup.cc +++ b/repos/ports-foc/src/lib/l4lx/startup.cc @@ -105,7 +105,7 @@ static void prepare_l4re_env() Genode::Foc_cpu_session_client cpu(Genode::env()->cpu_session_cap()); - Genode::Thread_capability main_thread = Genode::env()->parent()->main_thread_cap(); + Genode::Thread_capability main_thread = Genode::Thread_base::myself()->cap(); static Genode::Native_capability main_thread_cap = cpu.native_cap(main_thread); l4re_env_t *env = l4re_env(); diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index d3dbf0b5b5..427eb92c15 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -14,6 +14,10 @@ #ifndef _INCLUDE__VMM__VCPU_DISPATCHER_H_ #define _INCLUDE__VMM__VCPU_DISPATCHER_H_ +/* Genode includes */ +#include +#include + namespace Vmm { using namespace Genode; @@ -33,7 +37,8 @@ class Vmm::Vcpu_dispatcher : public T enum { WEIGHT = Genode::Cpu_session::DEFAULT_WEIGHT }; - Cap_connection &_cap; + Pd_session &_pd; + Nova_native_pd_client _native_pd { _pd.native_pd() }; /** * Portal entry point entered on virtualization events @@ -63,12 +68,11 @@ class Vmm::Vcpu_dispatcher : public T unsigned int exit_reason = 0; - Vcpu_dispatcher(size_t stack_size, Cap_connection &cap, + Vcpu_dispatcher(size_t stack_size, Pd_session &pd, Cpu_session * cpu_session, Genode::Affinity::Location location) : - T(WEIGHT, "vCPU dispatcher", stack_size), - _cap(cap) + T(WEIGHT, "vCPU dispatcher", stack_size), _pd(pd) { using namespace Genode; @@ -82,12 +86,12 @@ class Vmm::Vcpu_dispatcher : public T } template - Vcpu_dispatcher(size_t stack_size, Cap_connection &cap, + Vcpu_dispatcher(size_t stack_size, Pd_session &pd, Cpu_session * cpu_session, Genode::Affinity::Location location, X attr, void *(*start_routine) (void *), void *arg) : T(attr, start_routine, arg, stack_size, "vCPU dispatcher", nullptr), - _cap(cap) + _pd(pd) { using namespace Genode; @@ -111,11 +115,23 @@ class Vmm::Vcpu_dispatcher : public T void (*entry)() = &_portal_entry; /* Create the portal at the desired selector index */ - _cap.rcv_window(exc_base + EV); + _native_pd.rcv_window(exc_base + EV); Native_capability thread_cap(T::tid().ec_sel); - Native_capability handler = - _cap.alloc(thread_cap, (Nova::mword_t)entry, mtd.value()); + + Untyped_capability handler = + retry( + [&] () { + return _native_pd.alloc_rpc_cap(thread_cap, (addr_t)entry, + mtd.value()); + }, + [&] () { + Pd_session_client *client = + dynamic_cast(&_pd); + + if (client) + env()->parent()->upgrade(*client, "ram_quota=16K"); + }); return handler.valid() && (exc_base + EV == handler.local_name()); }