From 62b1c55399d6dc1b59548e542b35751ff2a3f425 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 19 Jan 2016 20:24:22 +0100 Subject: [PATCH] Integrate CAP session into PD session This patch integrates the functionality of the former CAP session into the PD session and unifies the approch of supplementing the generic PD session with kernel-specific functionality. The latter is achieved by the new 'Native_pd' interface. The kernel-specific interface can be obtained via the Pd_session::native_pd accessor function. The kernel-specific interfaces are named Nova_native_pd, Foc_native_pd, and Linux_native_pd. The latter change allowed for to deduplication of the pd_session_component code among the various base platforms. To retain API compatibility, we keep the 'Cap_session' and 'Cap_connection' around. But those classes have become mere wrappers around the PD session interface. Issue #1841 --- repos/base-fiasco/lib/mk/base.mk | 1 + repos/base-fiasco/src/core/target.inc | 7 +- repos/base-foc/include/foc_native_pd/client.h | 32 ++ .../include/foc_native_pd/foc_native_pd.h | 33 ++ .../base-foc/include/foc_pd_session/client.h | 38 -- .../include/foc_pd_session/connection.h | 40 -- .../include/foc_pd_session/foc_pd_session.h | 40 -- repos/base-foc/lib/mk/base.mk | 1 + repos/base-foc/src/base/server/server.cc | 2 +- repos/base-foc/src/core/include/cap_index.h | 23 +- .../src/core/include/cap_session_component.h | 51 -- .../src/core/include/native_pd_component.h | 45 ++ .../src/core/include/pd_session_component.h | 105 ---- repos/base-foc/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 1 - .../src/core/include/rpc_cap_factory.h | 47 ++ .../base-foc/src/core/native_pd_component.cc | 40 ++ repos/base-foc/src/core/pager.cc | 4 +- .../base-foc/src/core/pd_session_extension.cc | 22 - repos/base-foc/src/core/platform_pd.cc | 2 +- repos/base-foc/src/core/platform_thread.cc | 17 +- ...ession_component.cc => rpc_cap_factory.cc} | 26 +- repos/base-foc/src/core/target.inc | 12 +- repos/base-foc/src/core/thread_start.cc | 1 - .../base-hw/include/cap_session/connection.h | 33 -- repos/base-hw/include/pd_session/connection.h | 2 +- repos/base-hw/lib/mk/base.mk | 1 + repos/base-hw/lib/mk/core.inc | 1 + repos/base-hw/src/base/server/server.cc | 11 +- .../src/core/include/cap_session_component.h | 122 ----- repos/base-hw/src/core/include/pager.h | 8 +- .../src/core/include/rpc_cap_factory.h | 117 +++++ repos/base-hw/src/core/pager.cc | 2 +- .../include/linux_native_pd/client.h | 31 ++ .../include/linux_native_pd/linux_native_pd.h | 31 ++ .../include/linux_pd_session/client.h | 61 --- .../linux_pd_session/linux_pd_session.h | 36 -- .../include/pd_session/connection.h | 2 +- repos/base-linux/lib/mk/base.inc | 1 + repos/base-linux/lib/mk/base.mk | 1 + repos/base-linux/src/base/env/platform_env.h | 4 +- repos/base-linux/src/base/process/process.cc | 8 +- .../src/core/include/cap_session_component.h | 52 -- repos/base-linux/src/core/include/core_env.h | 23 +- .../src/core/include/native_pd_component.h | 53 ++ repos/base-linux/src/core/include/pager.h | 6 +- .../src/core/include/pd_session_component.h | 112 ----- .../base-linux/src/core/include/platform_pd.h | 8 +- .../src/core/native_pd_component.cc | 454 ++++++++++++++++++ .../src/core/pd_session_component.cc | 440 +---------------- repos/base-linux/src/core/target.mk | 11 +- .../include/cap_session/cap_session.h | 62 --- repos/base-nova/include/cap_session/client.h | 39 -- .../base-nova/include/nova_native_pd/client.h | 40 ++ .../include/nova_native_pd/nova_native_pd.h | 51 ++ repos/base-nova/include/pd_session/client.h | 68 --- repos/base-nova/lib/mk/base.mk | 1 + repos/base-nova/lib/mk/spec/x86_32/core.mk | 3 +- .../src/base/server/rpc_cap_alloc.cc | 56 +++ repos/base-nova/src/base/server/server.cc | 44 +- .../base-nova/src/core/core_rpc_cap_alloc.cc | 44 ++ .../src/core/include/cap_session_component.h | 126 ----- .../src/core/include/imprint_badge.h | 30 ++ .../src/core/include/native_pd_component.h | 49 ++ repos/base-nova/src/core/include/pager.h | 9 +- .../src/core/include/rpc_cap_factory.h | 66 +++ .../base-nova/src/core/native_pd_component.cc | 55 +++ repos/base-nova/src/core/pager.cc | 20 +- repos/base-nova/src/core/rpc_cap_factory.cc | 90 ++++ repos/base-nova/src/core/target.inc | 3 + .../include/okl4_pd_session/client.h | 41 -- .../include/okl4_pd_session/connection.h | 32 -- .../include/okl4_pd_session/okl4_pd_session.h | 62 --- repos/base-okl4/lib/mk/base.mk | 1 + .../src/core/include/pd_session_component.h | 91 ---- .../base-okl4/src/core/include/platform_pd.h | 10 +- .../src/core/okl4_pd_session_component.cc | 29 -- repos/base-okl4/src/core/platform_pd.cc | 37 +- repos/base-okl4/src/core/target.inc | 13 +- repos/base-pistachio/lib/mk/base.mk | 1 + repos/base-pistachio/src/core/target.inc | 8 +- repos/base-sel4/lib/mk/base.mk | 1 + repos/base-sel4/lib/mk/core.mk | 4 +- repos/base-sel4/src/base/server/server.cc | 2 +- repos/base-sel4/src/core/capability_space.cc | 28 +- .../src/core/include/cap_session_component.h | 37 -- .../src/core/include/core_capability_space.h | 4 +- .../src/core/include/rpc_cap_factory.h | 39 ++ ...ession_component.cc => rpc_cap_factory.cc} | 25 +- repos/base/include/base/rpc_server.h | 30 +- repos/base/include/cap_session/cap_session.h | 50 +- repos/base/include/cap_session/capability.h | 22 - repos/base/include/cap_session/client.h | 35 -- repos/base/include/cap_session/connection.h | 27 +- repos/base/include/pd_session/client.h | 8 + repos/base/include/pd_session/pd_session.h | 58 ++- repos/base/src/base/env/platform_env.h | 20 +- repos/base/src/base/server/common.cc | 6 +- repos/base/src/base/server/rpc_cap_alloc.cc | 44 ++ repos/base/src/base/server/server.cc | 2 +- repos/base/src/core/cap_session_component.cc | 17 - repos/base/src/core/core_rpc_cap_alloc.cc | 41 ++ repos/base/src/core/include/cap_root.h | 60 --- .../src/core/include/cap_session_component.h | 52 -- repos/base/src/core/include/core_env.h | 8 +- repos/base/src/core/include/core_pd_session.h | 12 + repos/base/src/core/include/io_port_root.h | 8 +- .../src/core/include/native_pd_component.h | 42 ++ repos/base/src/core/include/pager.h | 18 +- .../src/core/include/pd_session_component.h | 34 +- repos/base/src/core/include/rm_root.h | 21 +- repos/base/src/core/include/rpc_cap_factory.h | 44 ++ repos/base/src/core/main.cc | 20 +- repos/base/src/core/rpc_cap_factory.cc | 23 + .../src/core/spec/x86/platform_services.cc | 2 +- repos/ports-foc/src/lib/l4lx/include/task.h | 14 +- repos/ports-foc/src/lib/l4lx/startup.cc | 2 +- repos/ports/include/vmm/vcpu_dispatcher.h | 34 +- 118 files changed, 2040 insertions(+), 2258 deletions(-) create mode 100644 repos/base-foc/include/foc_native_pd/client.h create mode 100644 repos/base-foc/include/foc_native_pd/foc_native_pd.h delete mode 100644 repos/base-foc/include/foc_pd_session/client.h delete mode 100644 repos/base-foc/include/foc_pd_session/connection.h delete mode 100644 repos/base-foc/include/foc_pd_session/foc_pd_session.h delete mode 100644 repos/base-foc/src/core/include/cap_session_component.h create mode 100644 repos/base-foc/src/core/include/native_pd_component.h delete mode 100644 repos/base-foc/src/core/include/pd_session_component.h create mode 100644 repos/base-foc/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-foc/src/core/native_pd_component.cc delete mode 100644 repos/base-foc/src/core/pd_session_extension.cc rename repos/base-foc/src/core/{cap_session_component.cc => rpc_cap_factory.cc} (90%) delete mode 100644 repos/base-hw/include/cap_session/connection.h delete mode 100644 repos/base-hw/src/core/include/cap_session_component.h create mode 100644 repos/base-hw/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-linux/include/linux_native_pd/client.h create mode 100644 repos/base-linux/include/linux_native_pd/linux_native_pd.h delete mode 100644 repos/base-linux/include/linux_pd_session/client.h delete mode 100644 repos/base-linux/include/linux_pd_session/linux_pd_session.h delete mode 100644 repos/base-linux/src/core/include/cap_session_component.h create mode 100644 repos/base-linux/src/core/include/native_pd_component.h delete mode 100644 repos/base-linux/src/core/include/pd_session_component.h create mode 100644 repos/base-linux/src/core/native_pd_component.cc delete mode 100644 repos/base-nova/include/cap_session/cap_session.h delete mode 100644 repos/base-nova/include/cap_session/client.h create mode 100644 repos/base-nova/include/nova_native_pd/client.h create mode 100644 repos/base-nova/include/nova_native_pd/nova_native_pd.h delete mode 100644 repos/base-nova/include/pd_session/client.h create mode 100644 repos/base-nova/src/base/server/rpc_cap_alloc.cc create mode 100644 repos/base-nova/src/core/core_rpc_cap_alloc.cc delete mode 100644 repos/base-nova/src/core/include/cap_session_component.h create mode 100644 repos/base-nova/src/core/include/imprint_badge.h create mode 100644 repos/base-nova/src/core/include/native_pd_component.h create mode 100644 repos/base-nova/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-nova/src/core/native_pd_component.cc create mode 100644 repos/base-nova/src/core/rpc_cap_factory.cc delete mode 100644 repos/base-okl4/include/okl4_pd_session/client.h delete mode 100644 repos/base-okl4/include/okl4_pd_session/connection.h delete mode 100644 repos/base-okl4/include/okl4_pd_session/okl4_pd_session.h delete mode 100644 repos/base-okl4/src/core/include/pd_session_component.h delete mode 100644 repos/base-okl4/src/core/okl4_pd_session_component.cc delete mode 100644 repos/base-sel4/src/core/include/cap_session_component.h create mode 100644 repos/base-sel4/src/core/include/rpc_cap_factory.h rename repos/base-sel4/src/core/{cap_session_component.cc => rpc_cap_factory.cc} (53%) delete mode 100644 repos/base/include/cap_session/capability.h delete mode 100644 repos/base/include/cap_session/client.h create mode 100644 repos/base/src/base/server/rpc_cap_alloc.cc delete mode 100644 repos/base/src/core/cap_session_component.cc create mode 100644 repos/base/src/core/core_rpc_cap_alloc.cc delete mode 100644 repos/base/src/core/include/cap_root.h delete mode 100644 repos/base/src/core/include/cap_session_component.h create mode 100644 repos/base/src/core/include/native_pd_component.h create mode 100644 repos/base/src/core/include/rpc_cap_factory.h create mode 100644 repos/base/src/core/rpc_cap_factory.cc diff --git a/repos/base-fiasco/lib/mk/base.mk b/repos/base-fiasco/lib/mk/base.mk index 5d0f684c3..5e7bdf98c 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 72b747854..210abfa6e 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 000000000..c4670d072 --- /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 000000000..e095b0e05 --- /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 62384d32a..000000000 --- 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 8ead46fcc..000000000 --- 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 1a6036d36..000000000 --- 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 451da5bcb..459a00389 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 b4307b6d8..eff3039a9 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 cb5f3e4f3..f5340faf9 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 0a23e52e4..000000000 --- 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 000000000..0fea6f1e9 --- /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 63c0d0b7c..000000000 --- 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 460b8411c..d84a4d88a 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 62bce146b..432d35bfb 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 000000000..46377ec77 --- /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 000000000..6edf90ff5 --- /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 272d55d71..f8fa7951b 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 84be0fdba..000000000 --- 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 23c433b5f..dc4dc47fa 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 92d4a5402..eb1aa7927 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 e2a210044..59ab72129 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 89315c840..1f4295f49 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 664f53ef8..bf751dd5a 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 49e6c0965..000000000 --- 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 297ab9521..9e4a51f65 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 1e30bbcb1..562d217dd 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 9e9dd9880..1b5989b91 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 87b5ad904..fcddad2a0 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 a712696bd..000000000 --- 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 9bf06cb02..c48fc7fc1 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 000000000..03522f9a0 --- /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 b14a0c211..9d283a4fb 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 000000000..87490685c --- /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 000000000..1a574ff14 --- /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 07302706d..000000000 --- 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 472f8305a..000000000 --- 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 8038bdf7d..cf4bf7c73 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 0959490c5..dcc8d55a0 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 e5df32113..d0094b62f 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 b8b33d1c9..85ec614c4 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 aaadff442..ab885c797 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 c033e640e..000000000 --- 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 67bcb6a0d..e95aed2e8 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 000000000..d182eac6b --- /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 dcf1f99bd..ed56e0c2f 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 e4e0623b5..000000000 --- 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 9dfb68d2f..8415b3dbe 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 000000000..f10bc4350 --- /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 3f2548275..a66145373 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 428a5d9e5..a3851c303 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 c9f8e89af..000000000 --- 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 8604d8488..000000000 --- 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 000000000..01ad4dc53 --- /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 000000000..e18a05997 --- /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 f874badb2..000000000 --- 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 a471e689a..1b4231ce4 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 dc7caecfd..0b0fe232a 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 000000000..b5ec4816b --- /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 328273429..9c350e467 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 000000000..05372f3cd --- /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 62ed2201c..000000000 --- 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 000000000..f574c540a --- /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 000000000..e0892b7c7 --- /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 c66305e88..6b83b0117 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 000000000..189c82fc3 --- /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 000000000..6da8987b2 --- /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 36f76bb5d..b1626b360 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 000000000..68727371c --- /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 4cd6a29c5..61ff7c5ef 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 fe1639f4f..000000000 --- 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 8ef23081f..000000000 --- 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 7c4d6bbf0..000000000 --- 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 007e2e20f..90b0c746b 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 2bb4d3b95..000000000 --- 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 9e7826614..dca8ca952 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 7a8e8a7c8..000000000 --- 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 067dd3ab8..4eaedf349 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 72d49c16d..02f471dac 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 5d0f684c3..5e7bdf98c 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 febf05104..d6f018e3b 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 356289e35..9c2acb3a6 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 9726f6a38..761c61153 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 3fb2ed378..26ffa031b 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 1f2789658..8595e39d3 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 8e1969759..000000000 --- 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 886bf589b..a630aa22a 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 000000000..fd1514523 --- /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 8dc34b9fc..7f0bc9c25 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 8db4b8969..90d8959ea 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 d79637222..e9cbc7389 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 7be38a38a..000000000 --- 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 5d4e466ee..000000000 --- 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 b4304a60b..0adf77eda 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 7fbc4deae..ff00be5da 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 a342bbcf4..c1f6f26f7 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 f3ed2846b..58192ffd5 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 9042ccd05..99971baa6 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 000000000..b470cde18 --- /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 7aef8e3cf..6a3745737 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 ce7a37e1a..000000000 --- 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 000000000..00a652391 --- /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 b9b30eb1d..000000000 --- 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 cb518f304..000000000 --- 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 0a3cd1ab3..a5456a0b3 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 63b0a7bef..d738354cd 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 21e2960b7..a1478cfa3 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 000000000..c665ac7f3 --- /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 56ae2d469..a25fb7705 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 f0b41ed32..dd07a1858 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 445d6fc34..4e5affa5a 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 000000000..4bde1ae61 --- /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 ae2060866..2d49c37d5 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 000000000..46f7a01d4 --- /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 d8af762b4..af266aff9 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 b49ca1e32..a86d81382 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 6555322f6..f7f72ff50 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 d3dbf0b5b..427eb92c1 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()); }