From 88b358c5efde4754f7e2db898b0b459b3201c97e Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 15 Jun 2016 15:04:54 +0200 Subject: [PATCH] Unification of native_capability.h This patch establishes the sole use of generic headers across all kernels. The common 'native_capability.h' is based on the version of base-sel4. All traditional L4 kernels and Linux use the same implementation of the capability-lifetime management. On base-hw, NOVA, Fiasco.OC, and seL4, custom implementations (based on their original mechanisms) are used, with the potential to unify them further in the future. This change achieves binary compatibility of dynamically linked programs across all kernels. Furthermore, the patch introduces a Native_capability::print method, which allows the easy output of the kernel-specific capability representation using the base/log.h API. Issue #1993 --- .../include/base/native_capability.h | 42 ---- repos/base-fiasco/lib/mk/base-common.mk | 4 +- repos/base-fiasco/lib/mk/base.mk | 1 + .../src/core/include/rpc_cap_factory.h | 39 ++++ repos/base-fiasco/src/core/pager.cc | 3 +- repos/base-fiasco/src/core/pager_object.cc | 5 +- repos/base-fiasco/src/core/platform.cc | 5 +- repos/base-fiasco/src/core/platform_thread.cc | 7 +- repos/base-fiasco/src/core/target.inc | 6 +- .../src/include/base/internal/parent_cap.h | 40 ++++ .../include/base/internal/rpc_destination.h | 38 ++++ .../src/lib/base/capability_raw.cc | 28 +++ repos/base-fiasco/src/lib/base/ipc.cc | 51 ++++- .../base-foc/include/base/native_capability.h | 114 ---------- repos/base-foc/include/base/thread_state.h | 5 + repos/base-foc/include/foc/capability_space.h | 42 ++++ repos/base-foc/include/foc/receive_window.h | 19 +- repos/base-foc/include/signal_source/client.h | 99 +++----- repos/base-foc/lib/mk/base-common.inc | 2 + repos/base-foc/src/core/include/cap_index.h | 54 ++--- .../src/core/include/platform_thread.h | 12 +- repos/base-foc/src/core/ipc_pager.cc | 7 +- .../src/core/irq_session_component.cc | 2 +- .../base-foc/src/core/native_cpu_component.cc | 4 +- repos/base-foc/src/core/pager_object.cc | 5 +- repos/base-foc/src/core/platform.cc | 6 +- repos/base-foc/src/core/platform_pd.cc | 8 +- repos/base-foc/src/core/platform_thread.cc | 55 ++--- repos/base-foc/src/core/rpc_cap_factory.cc | 15 +- .../src/core/signal_source_component.cc | 6 +- repos/base-foc/src/core/thread_start.cc | 2 +- .../src/include/base/internal/cap_alloc.h | 9 +- .../include/base/internal}/cap_map.h | 48 +--- .../include/base/internal/capability_data.h | 63 ++++++ .../src/include/base/internal/parent_cap.h | 3 +- repos/base-foc/src/lib/base/cap_map.cc | 37 ++- repos/base-foc/src/lib/base/cap_map_remove.cc | 2 +- repos/base-foc/src/lib/base/capability.cc | 72 ++++++ repos/base-foc/src/lib/base/ipc.cc | 46 +++- .../src/lib/base/signal_source_client.cc | 77 +++++++ repos/base-foc/src/lib/base/spin_lock.cc | 4 +- .../base-foc/src/lib/base/thread_bootstrap.cc | 1 + repos/base-foc/src/lib/base/thread_start.cc | 1 + repos/base-foc/src/test/cap_integrity/main.cc | 9 +- .../base-foc/src/test/cap_integrity/target.mk | 1 + .../base-hw/include/base/native_capability.h | 91 -------- repos/base-hw/src/core/capability.cc | 27 ++- .../src/core/include/kernel/configuration.h | 2 + repos/base-hw/src/core/include/object.h | 24 +- repos/base-hw/src/core/include/platform_pd.h | 8 +- .../src/core/include/rpc_cap_factory.h | 13 +- .../spec/x86_64/muen/vm_session_component.h | 2 +- repos/base-hw/src/core/include/util.h | 3 + .../base-hw/src/core/irq_session_component.cc | 6 +- repos/base-hw/src/core/pager.cc | 5 +- repos/base-hw/src/core/platform_pd.cc | 11 +- repos/base-hw/src/core/platform_thread.cc | 10 +- repos/base-hw/src/core/region_map_support.cc | 4 +- .../arm_v7/trustzone/vm_session_component.cc | 4 +- .../virtualization/vm_session_component.cc | 2 +- repos/base-hw/src/core/thread_start.cc | 2 +- .../include/base/internal/capability_space.h | 40 ++++ .../src/include/base/internal/lock_helper.h | 11 +- repos/base-hw/src/lib/base/capability.cc | 51 ++++- repos/base-hw/src/lib/base/ipc.cc | 10 +- repos/base-hw/src/lib/base/signal.cc | 12 +- .../base-hw/src/lib/base/thread_bootstrap.cc | 20 +- .../include/base/native_capability.h | 45 ---- repos/base-linux/lib/mk/base-common.mk | 1 + repos/base-linux/lib/mk/base.mk | 1 + repos/base-linux/lib/mk/lx_hybrid.mk | 2 +- repos/base-linux/src/core/include/core_env.h | 2 - .../src/core/include/dataspace_component.h | 10 +- .../src/core/include/rpc_cap_factory.h | 39 ++++ .../src/core/native_cpu_component.cc | 15 +- .../src/core/native_pd_component.cc | 6 +- repos/base-linux/src/core/platform.cc | 6 +- .../src/core/ram_session_support.cc | 5 +- .../src/core/rom_session_component.cc | 5 +- repos/base-linux/src/core/target.mk | 6 +- .../include/base/internal/local_capability.h | 21 +- .../include/base/internal/rpc_destination.h | 41 ++++ .../base-linux/src/lib/base/capability_raw.cc | 31 +++ repos/base-linux/src/lib/base/ipc.cc | 59 +++-- repos/base-linux/src/lib/base/platform_env.cc | 28 ++- .../src/lib/base/region_map_mmap.cc | 2 +- .../include/base/native_capability.h | 168 -------------- .../include/{base => nova}/cap_map.h | 9 +- .../base-nova/include/nova/capability_space.h | 47 ++++ repos/base-nova/include/nova/native_thread.h | 18 +- repos/base-nova/include/nova/receive_window.h | 101 +-------- .../base-nova/include/signal_source/client.h | 5 +- repos/base-nova/lib/mk/base-common.mk | 1 + repos/base-nova/lib/mk/core.inc | 6 + repos/base-nova/lib/mk/spec/x86_32/core.mk | 6 +- repos/base-nova/lib/mk/spec/x86_64/core.mk | 5 +- .../src/core/include/imprint_badge.h | 3 + repos/base-nova/src/core/include/pager.h | 3 + .../src/core/include/signal_broker.h | 5 +- repos/base-nova/src/core/pager.cc | 9 +- repos/base-nova/src/core/platform_thread.cc | 3 +- repos/base-nova/src/core/rpc_cap_factory.cc | 11 +- .../base-nova/src/include/base/internal/ipc.h | 3 +- .../src/include/base/internal/parent_cap.h | 4 +- repos/base-nova/src/lib/base/cap_map.cc | 6 +- repos/base-nova/src/lib/base/capability.cc | 78 +++++++ repos/base-nova/src/lib/base/ipc.cc | 126 ++++++++++- .../base-nova/src/lib/base/rpc_entrypoint.cc | 12 +- repos/base-nova/src/lib/base/signal_submit.cc | 3 + repos/base-nova/src/lib/base/stack.cc | 4 +- repos/base-nova/src/lib/base/thread_start.cc | 5 +- repos/base-nova/src/test/platform/ipc.cc | 2 +- repos/base-nova/src/test/platform/main.cc | 30 +-- repos/base-nova/src/test/platform/server.h | 6 +- .../include/base/native_capability.h | 37 --- repos/base-okl4/include/base/thread_state.h | 33 --- repos/base-okl4/lib/mk/base-common.mk | 4 +- repos/base-okl4/lib/mk/base.mk | 1 + .../src/core/include/rpc_cap_factory.h | 39 ++++ repos/base-okl4/src/core/pager.cc | 3 +- repos/base-okl4/src/core/pager_object.cc | 5 +- repos/base-okl4/src/core/platform_thread.cc | 9 +- .../src/core/spec/x86/platform_thread_x86.cc | 1 - repos/base-okl4/src/core/target.inc | 6 +- .../src/include/base/internal/parent_cap.h | 40 ++++ .../include/base/internal/rpc_destination.h | 39 ++++ .../base-okl4/src/lib/base/capability_raw.cc | 28 +++ repos/base-okl4/src/lib/base/ipc.cc | 69 +++--- .../include/base/native_capability.h | 41 ---- repos/base-pistachio/lib/mk/base-common.mk | 4 +- repos/base-pistachio/lib/mk/base.mk | 1 + .../src/core/include/rpc_cap_factory.h | 39 ++++ repos/base-pistachio/src/core/pager.cc | 5 +- repos/base-pistachio/src/core/pager_object.cc | 5 +- repos/base-pistachio/src/core/platform.cc | 5 +- .../src/core/platform_thread.cc | 7 +- repos/base-pistachio/src/core/target.inc | 6 +- .../src/include/base/internal/parent_cap.h | 40 ++++ .../include/base/internal/rpc_destination.h | 39 ++++ .../src/lib/base/capability_raw.cc | 28 +++ repos/base-pistachio/src/lib/base/ipc.cc | 77 ++++--- .../include/base/native_capability.h | 102 --------- repos/base-sel4/lib/mk/base-common.inc | 2 +- .../base/internal/capability_space_sel4.h | 11 +- .../base-sel4/src/lib/base/capability_raw.cc | 25 ++ .../src/lib/base/capability_space.cc | 6 + repos/base/include/base/native_capability.h | 105 +++++++++ repos/base/include/base/output.h | 9 + repos/base/src/core/capability_space.cc | 100 ++++++++ .../src/core/include/core_capability_space.h | 0 repos/base/src/core/rpc_cap_factory_l4.cc | 53 +++++ .../include/base/internal/capability_data.h | 0 .../include/base/internal/capability_space.h | 11 +- .../base/internal/capability_space_tpl.h | 213 ++++++++++++++++++ .../src/include/base/internal/rpc_obj_key.h | 20 +- .../src/lib/base/capability.cc | 22 +- repos/base/src/lib/base/capability_space.cc | 100 ++++++++ .../drivers/timer/spec/hw/platform_timer.h | 17 +- repos/os/src/test/timer/main.cc | 2 +- repos/ports-foc/src/lib/l4lx/genode_block.cc | 7 +- repos/ports-foc/src/lib/l4lx/genode_net.cc | 6 +- .../ports-foc/src/lib/l4lx/genode_terminal.cc | 6 +- .../src/lib/l4lx/include/dataspace.h | 12 +- repos/ports-foc/src/lib/l4lx/include/task.h | 3 +- repos/ports-foc/src/lib/l4lx/include/vcpu.h | 1 - .../src/lib/l4lx/l4_re_c_util_cap.cc | 4 +- repos/ports-foc/src/lib/l4lx/l4lx_task.cc | 7 +- repos/ports-foc/src/lib/l4lx/l4lx_thread.cc | 3 +- repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc | 5 +- repos/ports-foc/src/lib/l4lx/startup.cc | 2 +- repos/ports/include/vmm/vcpu_dispatcher.h | 16 +- repos/ports/include/vmm/vcpu_thread.h | 2 +- repos/ports/src/noux/main.cc | 3 +- 173 files changed, 2614 insertions(+), 1333 deletions(-) delete mode 100644 repos/base-fiasco/include/base/native_capability.h create mode 100644 repos/base-fiasco/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-fiasco/src/include/base/internal/parent_cap.h create mode 100644 repos/base-fiasco/src/include/base/internal/rpc_destination.h create mode 100644 repos/base-fiasco/src/lib/base/capability_raw.cc delete mode 100644 repos/base-foc/include/base/native_capability.h create mode 100644 repos/base-foc/include/foc/capability_space.h rename repos/base-foc/{include/base => src/include/base/internal}/cap_map.h (82%) create mode 100644 repos/base-foc/src/include/base/internal/capability_data.h create mode 100644 repos/base-foc/src/lib/base/capability.cc create mode 100644 repos/base-foc/src/lib/base/signal_source_client.cc delete mode 100644 repos/base-hw/include/base/native_capability.h create mode 100644 repos/base-hw/src/include/base/internal/capability_space.h delete mode 100644 repos/base-linux/include/base/native_capability.h create mode 100644 repos/base-linux/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-linux/src/include/base/internal/rpc_destination.h create mode 100644 repos/base-linux/src/lib/base/capability_raw.cc delete mode 100644 repos/base-nova/include/base/native_capability.h rename repos/base-nova/include/{base => nova}/cap_map.h (89%) create mode 100644 repos/base-nova/include/nova/capability_space.h create mode 100644 repos/base-nova/lib/mk/core.inc create mode 100644 repos/base-nova/src/lib/base/capability.cc delete mode 100644 repos/base-okl4/include/base/native_capability.h delete mode 100644 repos/base-okl4/include/base/thread_state.h create mode 100644 repos/base-okl4/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-okl4/src/include/base/internal/parent_cap.h create mode 100644 repos/base-okl4/src/include/base/internal/rpc_destination.h create mode 100644 repos/base-okl4/src/lib/base/capability_raw.cc delete mode 100644 repos/base-pistachio/include/base/native_capability.h create mode 100644 repos/base-pistachio/src/core/include/rpc_cap_factory.h create mode 100644 repos/base-pistachio/src/include/base/internal/parent_cap.h create mode 100644 repos/base-pistachio/src/include/base/internal/rpc_destination.h create mode 100644 repos/base-pistachio/src/lib/base/capability_raw.cc delete mode 100644 repos/base-sel4/include/base/native_capability.h create mode 100644 repos/base-sel4/src/lib/base/capability_raw.cc create mode 100644 repos/base/include/base/native_capability.h create mode 100644 repos/base/src/core/capability_space.cc rename repos/{base-sel4 => base}/src/core/include/core_capability_space.h (100%) create mode 100644 repos/base/src/core/rpc_cap_factory_l4.cc rename repos/{base-sel4 => base}/src/include/base/internal/capability_data.h (100%) rename repos/{base-sel4 => base}/src/include/base/internal/capability_space.h (80%) create mode 100644 repos/base/src/include/base/internal/capability_space_tpl.h rename repos/{base-sel4 => base}/src/include/base/internal/rpc_obj_key.h (54%) rename repos/{base-sel4 => base}/src/lib/base/capability.cc (71%) create mode 100644 repos/base/src/lib/base/capability_space.cc diff --git a/repos/base-fiasco/include/base/native_capability.h b/repos/base-fiasco/include/base/native_capability.h deleted file mode 100644 index ef9537d60..000000000 --- a/repos/base-fiasco/include/base/native_capability.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * \brief Native capability type on L4/Fiasco - * \author Norman Feske - * \date 2008-07-26 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -/* Genode includes */ -#include -#include - -namespace Fiasco { -#include -} - -namespace Genode { - - struct Cap_dst_policy - { - typedef Fiasco::l4_threadid_t Dst; - static bool valid(Dst id) { return !Fiasco::l4_is_invalid_id(id); } - static Dst invalid() - { - using namespace Fiasco; - return L4_INVALID_ID; - } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-fiasco/lib/mk/base-common.mk b/repos/base-fiasco/lib/mk/base-common.mk index 256326a15..9d03d7f92 100644 --- a/repos/base-fiasco/lib/mk/base-common.mk +++ b/repos/base-fiasco/lib/mk/base-common.mk @@ -8,9 +8,7 @@ include $(BASE_DIR)/lib/mk/base-common.inc LIBS += startup -SRC_CC += cap_copy.cc +SRC_CC += capability.cc capability_raw.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc - -vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-fiasco/lib/mk/base.mk b/repos/base-fiasco/lib/mk/base.mk index a32c7ebd7..eec5dc939 100644 --- a/repos/base-fiasco/lib/mk/base.mk +++ b/repos/base-fiasco/lib/mk/base.mk @@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc SRC_CC += thread_start.cc SRC_CC += cache.cc +SRC_CC += capability_space.cc diff --git a/repos/base-fiasco/src/core/include/rpc_cap_factory.h b/repos/base-fiasco/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-fiasco/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-fiasco/src/core/pager.cc b/repos/base-fiasco/src/core/pager.cc index 6ba162810..8aa7655f3 100644 --- a/repos/base-fiasco/src/core/pager.cc +++ b/repos/base-fiasco/src/core/pager.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include namespace Fiasco { #include @@ -83,5 +84,5 @@ void Ipc_pager::acknowledge_wakeup() Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge) { - return Untyped_capability(native_thread().l4id, badge); + return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge)); } diff --git a/repos/base-fiasco/src/core/pager_object.cc b/repos/base-fiasco/src/core/pager_object.cc index f04c0cc96..a5d626766 100644 --- a/repos/base-fiasco/src/core/pager_object.cc +++ b/repos/base-fiasco/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco includes */ namespace Fiasco { #include @@ -37,7 +40,7 @@ void Pager_object::wake_up() l4_msgdope_t ipc_result; l4_umword_t dummy = 0; - l4_ipc_call(cap().dst(), L4_IPC_SHORT_MSG, + l4_ipc_call(Capability_space::ipc_cap_data(cap()).dst, L4_IPC_SHORT_MSG, 0, /* fault address */ (l4_umword_t)this, /* instruction pointer */ &rcv_header, &dummy, &dummy, L4_IPC_NEVER, &ipc_result); diff --git a/repos/base-fiasco/src/core/platform.cc b/repos/base-fiasco/src/core/platform.cc index 49c110e19..96c2636bd 100644 --- a/repos/base-fiasco/src/core/platform.cc +++ b/repos/base-fiasco/src/core/platform.cc @@ -21,6 +21,7 @@ #include #include #include +#include /* core includes */ #include @@ -137,7 +138,7 @@ Platform::Sigma0::Sigma0() : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { - cap(reinterpret_cap_cast(Native_capability(Fiasco::sigma0_threadid, 0))); + cap(Capability_space::import(Fiasco::sigma0_threadid, Rpc_obj_key())); } @@ -156,7 +157,7 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd) Platform_thread::pager(sigma0()); core_pd->bind_thread(this); - cap(Native_capability(native_thread_id(), 0)); + cap(Capability_space::import(native_thread_id(), Rpc_obj_key())); /* pager needs to know core's pd ID */ _core_pager_arg = core_pd->pd_id(); diff --git a/repos/base-fiasco/src/core/platform_thread.cc b/repos/base-fiasco/src/core/platform_thread.cc index 18e7e7b81..e1eeed7a5 100644 --- a/repos/base-fiasco/src/core/platform_thread.cc +++ b/repos/base-fiasco/src/core/platform_thread.cc @@ -22,6 +22,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco includes */ namespace Fiasco { #include @@ -38,7 +41,9 @@ int Platform_thread::start(void *ip, void *sp) { l4_umword_t dummy, old_eflags; l4_threadid_t thread = _l4_thread_id; - l4_threadid_t pager = _pager ? _pager->cap().dst() : L4_INVALID_ID; + l4_threadid_t pager = _pager + ? Capability_space::ipc_cap_data(_pager->cap()).dst + : L4_INVALID_ID; l4_threadid_t preempter = L4_INVALID_ID; l4_threadid_t cap_handler = L4_INVALID_ID; diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index 5fbc8dc0d..5009ac58b 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -9,6 +9,7 @@ SRC_CC += stack_area.cc \ cpu_session_component.cc \ cpu_thread_component.cc \ cpu_session_support.cc \ + capability_space.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -22,7 +23,7 @@ SRC_CC += stack_area.cc \ pager_ep.cc \ pager_object.cc \ pd_session_component.cc \ - rpc_cap_factory.cc \ + rpc_cap_factory_l4.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ platform.cc \ @@ -56,7 +57,8 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_region_map.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) diff --git a/repos/base-fiasco/src/include/base/internal/parent_cap.h b/repos/base-fiasco/src/include/base/internal/parent_cap.h new file mode 100644 index 000000000..9896bfbff --- /dev/null +++ b/repos/base-fiasco/src/include/base/internal/parent_cap.h @@ -0,0 +1,40 @@ +/* + * \brief Interface to obtain the parent capability for the component + * \author Norman Feske + * \date 2015-05-12 + */ + +/* + * Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_ +#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include +#include + + +namespace Genode { + + static inline Parent_capability parent_cap() + { + Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap; + + Fiasco::l4_threadid_t tid; + tid.raw = raw.v[0]; + + Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1])); + + return reinterpret_cap_cast(cap); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */ diff --git a/repos/base-fiasco/src/include/base/internal/rpc_destination.h b/repos/base-fiasco/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..2dae9af38 --- /dev/null +++ b/repos/base-fiasco/src/include/base/internal/rpc_destination.h @@ -0,0 +1,38 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +namespace Genode { + + typedef Fiasco::l4_threadid_t Rpc_destination; + + static inline Rpc_destination invalid_rpc_destination() + { + using namespace Fiasco; + return L4_INVALID_ID; + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "thread=", dst.id.task, ".", dst.id.lthread); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-fiasco/src/lib/base/capability_raw.cc b/repos/base-fiasco/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..90222e4dc --- /dev/null +++ b/repos/base-fiasco/src/lib/base/capability_raw.cc @@ -0,0 +1,28 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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 + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(*this); + + return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } }; +} diff --git a/repos/base-fiasco/src/lib/base/ipc.cc b/repos/base-fiasco/src/lib/base/ipc.cc index 40e5ba069..6d5719b85 100644 --- a/repos/base-fiasco/src/lib/base/ipc.cc +++ b/repos/base-fiasco/src/lib/base/ipc.cc @@ -13,17 +13,18 @@ /* Genode includes */ #include +#include #include #include /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { #include #include -#include } using namespace Genode; @@ -93,8 +94,14 @@ class Msg_header for (unsigned i = 0; i < num_caps; i++) { Native_capability const &cap = snd_msg.cap(i); - _cap_tid[i] = cap.dst(); - _cap_local_name[i] = cap.local_name(); + + if (cap.valid()) { + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(snd_msg.cap(i)); + + _cap_tid[i] = cap_data.dst; + _cap_local_name[i] = cap_data.rpc_obj_key.value(); + } } } @@ -115,9 +122,20 @@ class Msg_header */ void extract_caps(Msgbuf_base &rcv_msg) const { - for (unsigned i = 0; i < min((unsigned)MAX_CAPS_PER_MSG, num_caps); i++) - rcv_msg.insert(Native_capability(_cap_tid[i], - _cap_local_name[i])); + for (unsigned i = 0; i < min((unsigned)MAX_CAPS_PER_MSG, num_caps); i++) { + + Rpc_obj_key const rpc_obj_key(_cap_local_name[i]); + bool const cap_valid = !Fiasco::l4_is_invalid_id(_cap_tid[i]); + + Native_capability cap; + if (cap_valid) { + cap = Capability_space::lookup(rpc_obj_key); + if (!cap.valid()) + cap = Capability_space::import(_cap_tid[i], rpc_obj_key); + } + + rcv_msg.insert(cap); + } } }; @@ -132,14 +150,17 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, { using namespace Fiasco; + Capability_space::Ipc_cap_data const dst_data = + Capability_space::ipc_cap_data(dst); + Msg_header &snd_header = snd_msg.header(); - snd_header.prepare_snd_msg(dst.local_name(), snd_msg); + snd_header.prepare_snd_msg(dst_data.rpc_obj_key.value(), snd_msg); Msg_header &rcv_header = rcv_msg.header(); rcv_header.prepare_rcv_msg(rcv_msg); l4_msgdope_t ipc_result; - l4_ipc_call(dst.dst(), + l4_ipc_call(dst_data.dst, snd_header.msg_start(), snd_header.protocol_word, snd_header.num_caps, @@ -176,7 +197,8 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, snd_header.prepare_snd_msg(exc.value, snd_msg); l4_msgdope_t result; - l4_ipc_send(caller.dst(), snd_header.msg_start(), + l4_ipc_send(Capability_space::ipc_cap_data(caller).dst, + snd_header.msg_start(), snd_header.protocol_word, snd_header.num_caps, L4_IPC_SEND_TIMEOUT_0, &result); @@ -212,7 +234,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, * Use short IPC for reply if possible. This is the common case of * returning an integer as RPC result. */ - l4_ipc_reply_and_wait(last_caller.dst(), snd_header.msg_start(), + l4_ipc_reply_and_wait(Capability_space::ipc_cap_data(last_caller).dst, + snd_header.msg_start(), snd_header.protocol_word, snd_header.num_caps, &caller, rcv_header.msg_start(), @@ -250,11 +273,15 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, rcv_header.extract_caps(request_msg); - return Rpc_request(Native_capability(caller, 0), rcv_header.protocol_word); + return Rpc_request(Capability_space::import(caller, Rpc_obj_key()), + rcv_header.protocol_word); } -Ipc_server::Ipc_server() : Native_capability(Fiasco::l4_myself(), 0) { } +Ipc_server::Ipc_server() +: + Native_capability(Capability_space::import(Fiasco::l4_myself(), Rpc_obj_key())) +{ } Ipc_server::~Ipc_server() { } diff --git a/repos/base-foc/include/base/native_capability.h b/repos/base-foc/include/base/native_capability.h deleted file mode 100644 index cf0c8ecd4..000000000 --- a/repos/base-foc/include/base/native_capability.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * \brief Platform-specific capability type - * \author Norman Feske - * \date 2009-10-02 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -/* Fiasco includes */ -namespace Fiasco { -#include -} - -/* Genode includes */ -#include - -namespace Genode { - - /** - * Native_capability in Fiasco.OC is just a reference to a Cap_index. - * - * As Cap_index objects cannot be copied around, but Native_capability - * have to, we have to use this indirection. - */ - class Native_capability - { - public: - - typedef Fiasco::l4_cap_idx_t Dst; - - struct Raw - { - long local_name; - }; - - private: - - Cap_index* _idx; - - protected: - - inline void _inc() - { - if (_idx) - _idx->inc(); - } - - inline void _dec() - { - if (_idx && !_idx->dec()) { - cap_map()->remove(_idx); - } - } - - public: - - /** - * Default constructor creates an invalid capability - */ - Native_capability() : _idx(0) { } - - /** - * Construct capability manually - */ - Native_capability(Cap_index* idx) - : _idx(idx) { _inc(); } - - Native_capability(const Native_capability &o) - : _idx(o._idx) { _inc(); } - - ~Native_capability() { _dec(); } - - /** - * Return Cap_index object referenced by this object - */ - Cap_index* idx() const { return _idx; } - - /** - * Overloaded comparision operator - */ - bool operator==(const Native_capability &o) const { - return _idx == o._idx; } - - Native_capability& operator=(const Native_capability &o){ - if (this == &o) - return *this; - - _dec(); - _idx = o._idx; - _inc(); - return *this; - } - - /******************************************* - ** Interface provided by all platforms ** - *******************************************/ - - long local_name() const { return _idx ? _idx->id() : 0; } - Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); } - bool valid() const { return (_idx != 0) && _idx->valid(); } - - Raw raw() const { return { local_name() }; } - }; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-foc/include/base/thread_state.h b/repos/base-foc/include/base/thread_state.h index c12c398a4..2bcb9c68d 100644 --- a/repos/base-foc/include/base/thread_state.h +++ b/repos/base-foc/include/base/thread_state.h @@ -20,6 +20,11 @@ #include #include +/* Fiasco includes */ +namespace Fiasco { +#include +} + namespace Genode { struct Thread_state : Thread_state_base diff --git a/repos/base-foc/include/foc/capability_space.h b/repos/base-foc/include/foc/capability_space.h new file mode 100644 index 000000000..2c6100dde --- /dev/null +++ b/repos/base-foc/include/foc/capability_space.h @@ -0,0 +1,42 @@ +/* + * \brief Utilities for direct capability-space manipulation + * \author Norman Feske + * \date 2016-07-08 + * + * This interface is needed by L4Linux. + */ + +/* + * 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__FOC__CAPABILITY_SPACE_H_ +#define _INCLUDE__FOC__CAPABILITY_SPACE_H_ + +#include +#include + +namespace Genode { namespace Capability_space { + + /** + * Allocate kernel capability selector without associating it with a + * Genode capability + */ + Fiasco::l4_cap_idx_t alloc_kcap(); + + /** + * Release kernel capability selector + */ + void free_kcap(Fiasco::l4_cap_idx_t); + + /** + * Request kernel capability selector associated with Genode capability + */ + Fiasco::l4_cap_idx_t kcap(Native_capability); + +} } + +#endif /* _INCLUDE__FOC__CAPABILITY_SPACE_H_ */ diff --git a/repos/base-foc/include/foc/receive_window.h b/repos/base-foc/include/foc/receive_window.h index 587eae26d..77c0bb1af 100644 --- a/repos/base-foc/include/foc/receive_window.h +++ b/repos/base-foc/include/foc/receive_window.h @@ -17,7 +17,6 @@ /* Genode includes */ #include #include -#include namespace Genode { struct Receive_window; } @@ -29,7 +28,7 @@ class Genode::Receive_window /** * Base of capability receive window. */ - Cap_index* _rcv_idx_base = nullptr; + Native_capability::Data * _rcv_idx_base = nullptr; enum { MAX_CAPS_PER_MSG = Msgbuf_base::MAX_CAPS_PER_MSG }; @@ -37,29 +36,21 @@ class Genode::Receive_window Receive_window() { } - ~Receive_window() - { - if (_rcv_idx_base) - cap_idx_alloc()->free(_rcv_idx_base, MAX_CAPS_PER_MSG); - } + ~Receive_window(); - void init() - { - _rcv_idx_base = cap_idx_alloc()->alloc_range(MAX_CAPS_PER_MSG); - } + void init(); /** * Return address of capability receive window */ - addr_t rcv_cap_sel_base() { return _rcv_idx_base->kcap(); } + addr_t rcv_cap_sel_base(); /** * Return received selector with index i * * \return capability selector, or 0 if index is invalid */ - addr_t rcv_cap_sel(unsigned i) { - return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE; } + addr_t rcv_cap_sel(unsigned i); }; #endif /* _INCLUDE__FOC__RECEIVE_WINDOW_H_ */ diff --git a/repos/base-foc/include/signal_source/client.h b/repos/base-foc/include/signal_source/client.h index 286be602e..bc43d5a61 100644 --- a/repos/base-foc/include/signal_source/client.h +++ b/repos/base-foc/include/signal_source/client.h @@ -27,87 +27,40 @@ #include #include -/* base-internal includes */ -#include +namespace Genode { class Signal_source_client; } -namespace Fiasco { -#include -} -namespace Genode { +class Genode::Signal_source_client : public Rpc_client +{ + private: - class Signal_source_client : public Rpc_client - { - private: + /** + * Capability with 'dst' referring to a Fiasco.OC IRQ object + */ + Native_capability _sem; - /** - * Capability with 'dst' referring to a Fiasco.OC IRQ object - */ - Native_capability _sem; + public: - /** - * Request Fiasco.OC IRQ object from signal-source server - */ - void _init_sem() - { - using namespace Fiasco; + /** + * Constructor + */ + Signal_source_client(Capability cap); - /* request mapping of semaphore capability selector */ - _sem = call(); + /** + * Destructor + */ + ~Signal_source_client(); - l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0, - Thread::myself()->native_thread().kcap); - if (l4_error(tag)) - PERR("l4_irq_attach failed with %ld!", l4_error(tag)); - } - public: + /***************************** + ** Signal source interface ** + *****************************/ - /** - * Constructor - */ - Signal_source_client(Capability cap) - : Rpc_client(static_cap_cast(cap)) - { _init_sem(); } - - /** - * Destructor - */ - ~Signal_source_client() - { - Fiasco::l4_irq_detach(_sem.dst()); - } - - /***************************** - ** Signal source interface ** - *****************************/ - - /* Build with frame pointer to make GDB backtraces work. See issue #1061. */ - __attribute__((optimize("-fno-omit-frame-pointer"))) - __attribute__((noinline)) - Signal wait_for_signal() - { - using namespace Fiasco; - - Signal signal; - do { - - /* block on semaphore until signal context was submitted */ - l4_irq_receive(_sem.dst(), L4_IPC_NEVER); - - /* - * The following request will return immediately and either - * return a valid or a null signal. The latter may happen in - * the case a submitted signal context was destroyed (by the - * submitter) before we have a chance to raise our request. - */ - signal = call(); - - } while (!signal.imprint()); - - return signal; - } - }; -} + /* + * Build with frame pointer to make GDB backtraces work. See issue #1061. + */ + __attribute__((optimize("-fno-omit-frame-pointer"))) + Signal wait_for_signal(); +}; #endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */ diff --git a/repos/base-foc/lib/mk/base-common.inc b/repos/base-foc/lib/mk/base-common.inc index 2cabb463b..bc07de1c6 100644 --- a/repos/base-foc/lib/mk/base-common.inc +++ b/repos/base-foc/lib/mk/base-common.inc @@ -12,3 +12,5 @@ SRC_CC += spin_lock.cc cap_map.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc utcb.cc +SRC_CC += capability.cc +SRC_CC += signal_source_client.cc diff --git a/repos/base-foc/src/core/include/cap_index.h b/repos/base-foc/src/core/include/cap_index.h index a9d149ec3..3c42e1e7e 100644 --- a/repos/base-foc/src/core/include/cap_index.h +++ b/repos/base-foc/src/core/include/cap_index.h @@ -1,5 +1,5 @@ /* - * \brief Core-specific capability index. + * \brief Core-specific capability index * \author Stefan Kalkowski * \date 2012-02-22 */ @@ -14,39 +14,39 @@ #ifndef _CORE__INCLUDE__CAP_INDEX_H_ #define _CORE__INCLUDE__CAP_INDEX_H_ -/* Genode includes */ -#include - /* base-internal includes */ #include +#include namespace Genode { class Platform_thread; class Pd_session_component; - - class Core_cap_index : public Cap_index - { - private: - - Pd_session_component *_session; - Platform_thread *_pt; - Native_thread _gate; - - public: - - Core_cap_index(Pd_session_component *session = 0, - Platform_thread *pt = 0, - Native_thread gate = Native_thread() ) - : _session(session), _pt(pt), _gate(gate) {} - - Pd_session_component *session() { return _session; } - Platform_thread *pt() { return _pt; } - Native_thread gate() { return _gate; } - - void session(Pd_session_component *c) { _session = c; } - void pt(Platform_thread *t) { _pt = t; } - }; + class Core_cap_index; } + +class Genode::Core_cap_index : public Native_capability::Data +{ + private: + + Pd_session_component *_session; + Platform_thread const *_pt; + Native_thread _gate; + + public: + + Core_cap_index(Pd_session_component *session = 0, + Platform_thread *pt = 0, + Native_thread gate = Native_thread() ) + : _session(session), _pt(pt), _gate(gate) {} + + Pd_session_component const *session() const { return _session; } + Platform_thread const *pt() const { return _pt; } + Native_thread gate() const { return _gate; } + + void session(Pd_session_component *c) { _session = c; } + void pt(Platform_thread const *t) { _pt = t; } +}; + #endif /* _CORE__INCLUDE__CAP_INDEX_H_ */ diff --git a/repos/base-foc/src/core/include/platform_thread.h b/repos/base-foc/src/core/include/platform_thread.h index 570781074..4c7ff52aa 100644 --- a/repos/base-foc/src/core/include/platform_thread.h +++ b/repos/base-foc/src/core/include/platform_thread.h @@ -170,7 +170,7 @@ namespace Genode { * Return identification of thread when faulting */ unsigned long pager_object_badge() { - return (unsigned long) _thread.local.dst(); } + return (unsigned long) _thread.local.data()->kcap(); } /** * Set CPU quota of the thread to 'quota' @@ -187,11 +187,11 @@ namespace Genode { ** Fiasco-specific Accessors ** *******************************/ - Cap_mapping& thread() { return _thread; } - Cap_mapping& gate() { return _gate; } - const char *name() const { return _name; } - bool core_thread() const { return _core_thread; } - addr_t utcb() const { return _utcb; } + Cap_mapping const & thread() const { return _thread; } + Cap_mapping & gate() { return _gate; } + const char *name() const { return _name; } + bool core_thread() const { return _core_thread; } + addr_t utcb() const { return _utcb; } }; } diff --git a/repos/base-foc/src/core/ipc_pager.cc b/repos/base-foc/src/core/ipc_pager.cc index 32797cc18..3f2abc5fa 100644 --- a/repos/base-foc/src/core/ipc_pager.cc +++ b/repos/base-foc/src/core/ipc_pager.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { @@ -139,6 +140,8 @@ void Ipc_pager::acknowledge_exception() Ipc_pager::Ipc_pager() -: Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]), - _badge(0) { } +: + Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]), + _badge(0) +{ } diff --git a/repos/base-foc/src/core/irq_session_component.cc b/repos/base-foc/src/core/irq_session_component.cc index dfb54cf32..9e2903b46 100644 --- a/repos/base-foc/src/core/irq_session_component.cc +++ b/repos/base-foc/src/core/irq_session_component.cc @@ -56,7 +56,7 @@ class Genode::Interrupt_handler : public Thread_deprecated<2048*sizeof(long)> static Fiasco::l4_cap_idx_t handler_cap() { static Interrupt_handler handler; - return handler._thread_cap.dst(); + return handler._thread_cap.data()->kcap(); } }; diff --git a/repos/base-foc/src/core/native_cpu_component.cc b/repos/base-foc/src/core/native_cpu_component.cc index fafa5c540..7aaac41a6 100644 --- a/repos/base-foc/src/core/native_cpu_component.cc +++ b/repos/base-foc/src/core/native_cpu_component.cc @@ -38,7 +38,7 @@ void Genode::Native_cpu_component::enable_vcpu(Genode::Thread_capability thread_ auto lambda = [&] (Cpu_thread_component *thread) { if (!thread) return; - l4_cap_idx_t tid = thread->platform_thread().thread().local.dst(); + l4_cap_idx_t tid = thread->platform_thread().thread().local.data()->kcap(); l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state); if (l4_msgtag_has_error(tag)) @@ -86,7 +86,7 @@ Genode::Native_capability Genode::Native_cpu_component::alloc_irq() } /* construct cap and hold a reference in the irq container object */ - Genode::Native_capability cap(i); + Genode::Native_capability cap(*i); return (node->add(cap)) ? cap : Genode::Native_capability(); } diff --git a/repos/base-foc/src/core/pager_object.cc b/repos/base-foc/src/core/pager_object.cc index 4eb500117..ee2e03e69 100644 --- a/repos/base-foc/src/core/pager_object.cc +++ b/repos/base-foc/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco.OC includes */ namespace Fiasco { #include @@ -32,7 +35,7 @@ void Pager_object::wake_up() l4_utcb_mr()->mr[0] = 0; /* fault address */ l4_utcb_mr()->mr[1] = (l4_umword_t)this; /* instruction pointer */ - l4_ipc_call(cap().dst(), l4_utcb(), l4_msgtag(0, 2, 0, 0), L4_IPC_NEVER); + l4_ipc_call(cap().data()->kcap(), l4_utcb(), l4_msgtag(0, 2, 0, 0), L4_IPC_NEVER); } diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc index de66f41bc..1dbac6c97 100644 --- a/repos/base-foc/src/core/platform.cc +++ b/repos/base-foc/src/core/platform.cc @@ -137,7 +137,7 @@ Platform::Sigma0::Sigma0(Cap_index* i) * We use the Pager_object here in a slightly different manner, * just to tunnel the pager cap to the Platform_thread::start method. */ - cap(i); + cap(*i); } @@ -158,8 +158,8 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd, Sigma0 *sigma0) using namespace Fiasco; l4_thread_control_start(); - l4_thread_control_pager(thread().local.dst()); - l4_thread_control_exc_handler(thread().local.dst()); + l4_thread_control_pager(thread().local.data()->kcap()); + l4_thread_control_exc_handler(thread().local.data()->kcap()); l4_msgtag_t tag = l4_thread_control_commit(L4_BASE_THREAD_CAP); if (l4_msgtag_has_error(tag)) PWRN("l4_thread_control_commit failed!"); diff --git a/repos/base-foc/src/core/platform_pd.cc b/repos/base-foc/src/core/platform_pd.cc index 3ee2bf20a..c80b80961 100644 --- a/repos/base-foc/src/core/platform_pd.cc +++ b/repos/base-foc/src/core/platform_pd.cc @@ -70,7 +70,7 @@ bool Platform_pd::bind_thread(Platform_thread *thread) /* if it's no core-thread we have to map parent and pager gate cap */ if (!thread->core_thread()) - _task.map(_task.local.dst()); + _task.map(_task.local.data()->kcap()); /* inform thread about binding */ thread->bind(this); @@ -100,13 +100,13 @@ void Platform_pd::assign_parent(Native_capability parent) if (_parent.remote == Fiasco::L4_INVALID_CAP && parent.valid()) { _parent.local = parent; _parent.remote = PARENT_CAP; - _parent.map(_task.local.dst()); + _parent.map(_task.local.data()->kcap()); } } Platform_pd::Platform_pd(Core_cap_index* i) -: _task(Native_capability(i), TASK_CAP) +: _task(Native_capability(*i), TASK_CAP) { for (unsigned i = 0; i < THREAD_MAX; i++) _threads[i] = (Platform_thread*) 0; @@ -122,7 +122,7 @@ Platform_pd::Platform_pd(Allocator *, char const *) l4_fpage_t utcb_area = l4_fpage(utcb_area_start(), log2(UTCB_AREA_SIZE), 0); l4_msgtag_t tag = l4_factory_create_task(L4_BASE_FACTORY_CAP, - _task.local.dst(), utcb_area); + _task.local.data()->kcap(), utcb_area); if (l4_msgtag_has_error(tag)) PERR("pd creation failed"); } diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index ec65c3e68..aea50d2b2 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -39,24 +39,24 @@ int Platform_thread::start(void *ip, void *sp) { /* map the pager cap */ if (_platform_pd) - _pager.map(_platform_pd->native_task().dst()); + _pager.map(_platform_pd->native_task().data()->kcap()); /* reserve utcb area and associate thread with this task */ l4_thread_control_start(); l4_thread_control_pager(_pager.remote); l4_thread_control_exc_handler(_pager.remote); - l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().dst()); - l4_msgtag_t tag = l4_thread_control_commit(_thread.local.dst()); + l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().data()->kcap()); + l4_msgtag_t tag = l4_thread_control_commit(_thread.local.data()->kcap()); if (l4_msgtag_has_error(tag)) { PWRN("l4_thread_control_commit for %lx failed!", - (unsigned long) _thread.local.dst()); + (unsigned long) _thread.local.data()->kcap()); return -1; } _state = RUNNING; /* set ip and sp and run the thread */ - tag = l4_thread_ex_regs(_thread.local.dst(), (l4_addr_t) ip, + tag = l4_thread_ex_regs(_thread.local.data()->kcap(), (l4_addr_t) ip, (l4_addr_t) sp, 0); if (l4_msgtag_has_error(tag)) { PWRN("l4_thread_ex_regs failed!"); @@ -92,7 +92,7 @@ void Platform_thread::pause() * The pager thread, which also acts as exception handler, will * leave the thread in exception state until, it gets woken again */ - l4_thread_ex_regs_ret(_thread.local.dst(), &_pager_obj->state.ip, + l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &_pager_obj->state.ip, &_pager_obj->state.sp, &flags); /* @@ -111,14 +111,14 @@ void Platform_thread::pause() * the requested thread, and stored its thread state */ while (exc == _pager_obj->state.exceptions && !_pager_obj->state.in_exception) - l4_thread_switch(_thread.local.dst()); + l4_thread_switch(_thread.local.data()->kcap()); } } void Platform_thread::single_step(bool enabled) { - Fiasco::l4_cap_idx_t const tid = thread().local.dst(); + Fiasco::l4_cap_idx_t const tid = thread().local.data()->kcap(); enum { THREAD_SINGLE_STEP = 0x40000 }; int const flags = enabled ? THREAD_SINGLE_STEP : 0; @@ -148,8 +148,8 @@ void Platform_thread::resume() void Platform_thread::bind(Platform_pd *pd) { _platform_pd = pd; - _gate.map(pd->native_task().dst()); - _irq.map(pd->native_task().dst()); + _gate.map(pd->native_task().data()->kcap()); + _irq.map(pd->native_task().data()->kcap()); } @@ -160,12 +160,12 @@ void Platform_thread::unbind() l4_thread_control_start(); l4_thread_control_pager(_gate.remote); l4_thread_control_exc_handler(_gate.remote); - if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.dst()))) + if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.data()->kcap()))) PWRN("l4_thread_control_commit for %lx failed!", - (unsigned long) _thread.local.dst()); + (unsigned long) _thread.local.data()->kcap()); /* now force it into a pagefault */ - l4_thread_ex_regs(_thread.local.dst(), 0, 0, L4_THREAD_EX_REGS_CANCEL); + l4_thread_ex_regs(_thread.local.data()->kcap(), 0, 0, L4_THREAD_EX_REGS_CANCEL); } _platform_pd = (Platform_pd*) 0; @@ -204,7 +204,7 @@ Thread_state Platform_thread::state() void Platform_thread::cancel_blocking() { - l4_irq_trigger(_irq.local.dst()); + l4_irq_trigger(_irq.local.data()->kcap()); } @@ -217,9 +217,9 @@ void Platform_thread::affinity(Affinity::Location location) l4_sched_param_t params = l4_sched_param(_prio); params.affinity = l4_sched_cpu_set(cpu, 0, 1); l4_msgtag_t tag = l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, - _thread.local.dst(), ¶ms); + _thread.local.data()->kcap(), ¶ms); if (l4_error(tag)) - PWRN("setting affinity of %lx to %d failed!", _thread.local.dst(), cpu); + PWRN("setting affinity of %lx to %d failed!", _thread.local.data()->kcap(), cpu); } @@ -239,7 +239,7 @@ static Rpc_cap_factory &thread_cap_factory() void Platform_thread::_create_thread() { l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP, - _thread.local.dst()); + _thread.local.data()->kcap()); if (l4_msgtag_has_error(tag)) PERR("cannot create more thread kernel-objects!"); @@ -252,22 +252,22 @@ void Platform_thread::_finalize_construction(const char *name) { /* create irq for new thread */ l4_msgtag_t tag = l4_factory_create_irq(L4_BASE_FACTORY_CAP, - _irq.local.dst()); + _irq.local.data()->kcap()); if (l4_msgtag_has_error(tag)) PWRN("creating thread's irq failed"); /* attach thread to irq */ - tag = l4_irq_attach(_irq.local.dst(), 0, _thread.local.dst()); + tag = l4_irq_attach(_irq.local.data()->kcap(), 0, _thread.local.data()->kcap()); if (l4_msgtag_has_error(tag)) PWRN("attaching thread's irq failed"); /* set human readable name in kernel debugger */ strncpy(_name, name, sizeof(_name)); - Fiasco::l4_debugger_set_object_name(_thread.local.dst(), name); + Fiasco::l4_debugger_set_object_name(_thread.local.data()->kcap(), name); /* set priority of thread */ l4_sched_param_t params = l4_sched_param(_prio); - l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local.dst(), + l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local.data()->kcap(), ¶ms); } @@ -289,7 +289,8 @@ Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, _pager_obj(0), _prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, prio)) { - ((Core_cap_index*)_thread.local.idx())->pt(this); + /* XXX remove const cast */ + ((Core_cap_index *)_thread.local.data())->pt(this); _create_thread(); _finalize_construction(name); affinity(location); @@ -300,14 +301,15 @@ Platform_thread::Platform_thread(Core_cap_index* thread, Core_cap_index* irq, const char *name) : _state(RUNNING), _core_thread(true), - _thread(Native_capability(thread), L4_BASE_THREAD_CAP), - _irq(Native_capability(irq)), + _thread(Native_capability(*thread), L4_BASE_THREAD_CAP), + _irq(Native_capability(*irq)), _utcb(0), _platform_pd(0), _pager_obj(0), _prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0)) { - reinterpret_cast(_thread.local.idx())->pt(this); + /* XXX remove const cast */ + ((Core_cap_index *)_thread.local.data())->pt(this); _finalize_construction(name); } @@ -322,7 +324,8 @@ Platform_thread::Platform_thread(const char *name) _pager_obj(0), _prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0)) { - ((Core_cap_index*)_thread.local.idx())->pt(this); + /* XXX remove const cast */ + ((Core_cap_index *)_thread.local.data())->pt(this); _create_thread(); _finalize_construction(name); } diff --git a/repos/base-foc/src/core/rpc_cap_factory.cc b/repos/base-foc/src/core/rpc_cap_factory.cc index 84346bddc..8672f2072 100644 --- a/repos/base-foc/src/core/rpc_cap_factory.cc +++ b/repos/base-foc/src/core/rpc_cap_factory.cc @@ -69,7 +69,7 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task) return; l4_msgtag_t tag = l4_task_map(task, L4_BASE_TASK_CAP, - l4_obj_fpage(local.dst(), 0, L4_FPAGE_RWX), + l4_obj_fpage(local.data()->kcap(), 0, L4_FPAGE_RWX), ((l4_cap_idx_t)remote) | L4_ITEM_MAP); if (l4_msgtag_has_error(tag)) PERR("mapping cap failed"); @@ -77,7 +77,7 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task) Cap_mapping::Cap_mapping(bool alloc, Fiasco::l4_cap_idx_t r) -: local(alloc ? _get_cap() : 0), remote(r) { } +: local(alloc ? *_get_cap() : *(Native_capability::Data *)nullptr), remote(r) { } Cap_mapping::Cap_mapping(Native_capability cap, Fiasco::l4_cap_idx_t r) @@ -100,7 +100,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep) try { using namespace Fiasco; - Core_cap_index* ref = static_cast(ep.idx()); + Core_cap_index const * ref = static_cast(ep.data()); ASSERT(ref && ref->pt(), "No valid platform_thread"); @@ -118,7 +118,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep) l4_msgtag_t tag = l4_factory_create_gate(L4_BASE_FACTORY_CAP, idx->kcap(), - ref->pt()->thread().local.dst(), id); + ref->pt()->thread().local.data()->kcap(), id); if (l4_msgtag_has_error(tag)) { PERR("l4_factory_create_gate failed!"); cap_map()->remove(idx); @@ -131,7 +131,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep) // XXX remove cast idx->session((Pd_session_component *)this); idx->pt(ref->pt()); - cap = Native_capability(idx); + cap = Native_capability(*idx); } catch (Cap_id_allocator::Out_of_ids) { PERR("Out of capability ids"); } @@ -155,8 +155,9 @@ void Rpc_cap_factory::free(Native_capability cap) if (!cap.valid()) return; - /* proof whether the capability was created by this cap_session */ - if (static_cast(cap.idx())->session() != (Pd_session_component *)this) return; + /* check whether the capability was created by this cap_session */ + if (static_cast(cap.data())->session() != (Pd_session_component *)this) + return; Entry * entry; _pool.apply(cap, [&] (Entry *e) { diff --git a/repos/base-foc/src/core/signal_source_component.cc b/repos/base-foc/src/core/signal_source_component.cc index 309f5f25e..8ec92bd49 100644 --- a/repos/base-foc/src/core/signal_source_component.cc +++ b/repos/base-foc/src/core/signal_source_component.cc @@ -48,7 +48,7 @@ void Signal_source_component::submit(Signal_context_component *context, _signal_queue.enqueue(context); /* wake up client */ - Fiasco::l4_irq_trigger(_blocking_semaphore.dst()); + Fiasco::l4_irq_trigger(_blocking_semaphore.data()->kcap()); } } @@ -70,14 +70,14 @@ Signal_source::Signal Signal_source_component::wait_for_signal() Signal_source_component::Signal_source_component(Rpc_entrypoint *ep) : - Signal_source_rpc_object(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())), + Signal_source_rpc_object(*cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())), _entrypoint(ep), _finalizer(*this), _finalizer_cap(_entrypoint->manage(&_finalizer)) { using namespace Fiasco; l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, - _blocking_semaphore.dst()); + _blocking_semaphore.data()->kcap()); if (l4_error(res)) PERR("Allocation of irq object failed!"); } diff --git a/repos/base-foc/src/core/thread_start.cc b/repos/base-foc/src/core/thread_start.cc index b0eaa8ba3..215e2e424 100644 --- a/repos/base-foc/src/core/thread_start.cc +++ b/repos/base-foc/src/core/thread_start.cc @@ -61,7 +61,7 @@ void Thread::start() pt->pager(platform_specific()->core_pager()); - l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx(); + l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.data(); l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this; pt->start((void *)_thread_start, stack_top()); diff --git a/repos/base-foc/src/include/base/internal/cap_alloc.h b/repos/base-foc/src/include/base/internal/cap_alloc.h index ec8d9f329..7b995af1a 100644 --- a/repos/base-foc/src/include/base/internal/cap_alloc.h +++ b/repos/base-foc/src/include/base/internal/cap_alloc.h @@ -14,12 +14,15 @@ #ifndef _INCLUDE__BASE__CAP_ALLOC_H_ #define _INCLUDE__BASE__CAP_ALLOC_H_ -#include +/* Genode includes */ #include #include #include #include +/* base-internal includes */ +#include + namespace Genode { /** @@ -117,8 +120,8 @@ namespace Genode { } } - addr_t idx_to_kcap(Cap_index *idx) { - return ((T*)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT; + addr_t idx_to_kcap(Cap_index const *idx) const { + return ((T const *)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT; } Cap_index* kcap_to_idx(addr_t kcap) { diff --git a/repos/base-foc/include/base/cap_map.h b/repos/base-foc/src/include/base/internal/cap_map.h similarity index 82% rename from repos/base-foc/include/base/cap_map.h rename to repos/base-foc/src/include/base/internal/cap_map.h index c6571e4d0..d8b2311de 100644 --- a/repos/base-foc/include/base/cap_map.h +++ b/repos/base-foc/src/include/base/internal/cap_map.h @@ -35,50 +35,12 @@ #include #include -namespace Genode -{ - /** - * A Cap_index represents a single mapping of the global capability id - * to the address in the local capability space. - * - * The address of the Cap_index determines the location in the - * (platform-specific) capability space of the process. Therefore it - * shouldn't be copied around, but only referenced by - * e.g. Native_capability. - */ - class Cap_index : public Avl_node, - Noncopyable - { - private: +/* base-internal includes */ +#include - enum { INVALID_ID = -1, UNUSED = 0 }; +namespace Genode { - uint8_t _ref_cnt; /* reference counter */ - uint16_t _id; /* global capability id */ - - public: - - Cap_index() : _ref_cnt(0), _id(INVALID_ID) { } - - bool valid() const { return _id != INVALID_ID; } - bool used() const { return _id != UNUSED; } - uint16_t id() const { return _id; } - void id(uint16_t id) { _id = id; } - uint8_t inc(); - uint8_t dec(); - addr_t kcap(); - - void* operator new (size_t size, Cap_index* idx) { return idx; } - void operator delete (void* idx) { memset(idx, 0, sizeof(Cap_index)); } - - - /************************ - ** Avl node interface ** - ************************/ - - bool higher(Cap_index *n); - Cap_index *find_by_id(uint16_t id); - }; + typedef Native_capability::Data Cap_index; /** @@ -129,7 +91,7 @@ namespace Genode * * \param idx pointer to the Cap_index object in question */ - virtual addr_t idx_to_kcap(Cap_index *idx) = 0; + virtual addr_t idx_to_kcap(Cap_index const *idx) const = 0; /** * Get the Cap_index object of a specific location diff --git a/repos/base-foc/src/include/base/internal/capability_data.h b/repos/base-foc/src/include/base/internal/capability_data.h new file mode 100644 index 000000000..c151cc3bf --- /dev/null +++ b/repos/base-foc/src/include/base/internal/capability_data.h @@ -0,0 +1,63 @@ +/* + * \brief Internal capability representation + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2016-06-22 + */ + +/* + * 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__BASE__INTERNAL__CAPABILITY_DATA_H_ +#define _INCLUDE__BASE__INTERNAL__CAPABILITY_DATA_H_ + +/* Genode includes */ +#include + +/** + * A Native_capability::Data object represents a single mapping of the global + * capability id to the address in the local capability space. + * + * The address of the data object determines the location in the + * (platform-specific) capability space of the component. Therefore it + * shouldn't be copied around, but only referenced by e.g. Native_capability. + */ +class Genode::Native_capability::Data : public Avl_node, Noncopyable +{ + private: + + enum { INVALID_ID = -1, UNUSED = 0 }; + + uint8_t _ref_cnt; /* reference counter */ + uint16_t _id; /* global capability id */ + + public: + + Data() : _ref_cnt(0), _id(INVALID_ID) { } + + bool valid() const { return _id != INVALID_ID; } + bool used() const { return _id != UNUSED; } + uint16_t id() const { return _id; } + void id(uint16_t id) { _id = id; } + uint8_t inc(); + uint8_t dec(); + addr_t kcap() const; + + void* operator new (size_t size, Data* idx) { return idx; } + void operator delete (void* idx) { memset(idx, 0, sizeof(Data)); } + + + /************************ + ** Avl node interface ** + ************************/ + + bool higher(Data *n); + Data *find_by_id(uint16_t id); +}; + +#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_DATA_H_ */ + diff --git a/repos/base-foc/src/include/base/internal/parent_cap.h b/repos/base-foc/src/include/base/internal/parent_cap.h index 9da1776fc..f7e53b582 100644 --- a/repos/base-foc/src/include/base/internal/parent_cap.h +++ b/repos/base-foc/src/include/base/internal/parent_cap.h @@ -24,6 +24,7 @@ /* base-internal includes */ #include +#include namespace Genode { @@ -43,7 +44,7 @@ namespace Genode { i = cap_map()->insert(local_name, Fiasco::PARENT_CAP); } - return reinterpret_cap_cast(Native_capability(i)); + return reinterpret_cap_cast(Native_capability(*i)); } } diff --git a/repos/base-foc/src/lib/base/cap_map.cc b/repos/base-foc/src/lib/base/cap_map.cc index d1f823269..47974fb8c 100644 --- a/repos/base-foc/src/lib/base/cap_map.cc +++ b/repos/base-foc/src/lib/base/cap_map.cc @@ -14,19 +14,15 @@ */ /* Genode includes */ -#include -#include - #include +#include /* base-internal includes */ #include +#include /* kernel includes */ -namespace Fiasco { -#include -#include -} +#include /*********************** @@ -50,7 +46,7 @@ Genode::Cap_index* Genode::Cap_index::find_by_id(Genode::uint16_t id) } -Genode::addr_t Genode::Cap_index::kcap() { +Genode::addr_t Genode::Cap_index::kcap() const { return cap_idx_alloc()->idx_to_kcap(this); } @@ -181,3 +177,28 @@ Genode::Capability_map* Genode::cap_map() static Genode::Capability_map map; return ↦ } + + +/********************** + ** Capability_space ** + **********************/ + +Fiasco::l4_cap_idx_t Genode::Capability_space::alloc_kcap() +{ + return cap_idx_alloc()->alloc_range(1)->kcap(); +} + + +void Genode::Capability_space::free_kcap(Fiasco::l4_cap_idx_t kcap) +{ + Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(kcap); + Genode::cap_idx_alloc()->free(idx, 1); +} + + +Fiasco::l4_cap_idx_t Genode::Capability_space::kcap(Native_capability cap) +{ + if (cap.data() == nullptr) + Genode::raw("Native_capability data is NULL!"); + return cap.data()->kcap(); +} diff --git a/repos/base-foc/src/lib/base/cap_map_remove.cc b/repos/base-foc/src/lib/base/cap_map_remove.cc index 90edcbf30..34599adba 100644 --- a/repos/base-foc/src/lib/base/cap_map_remove.cc +++ b/repos/base-foc/src/lib/base/cap_map_remove.cc @@ -13,7 +13,7 @@ * under the terms of the GNU General Public License version 2. */ -#include +#include void Genode::Capability_map::remove(Genode::Cap_index* i) { diff --git a/repos/base-foc/src/lib/base/capability.cc b/repos/base-foc/src/lib/base/capability.cc new file mode 100644 index 000000000..2daec69f8 --- /dev/null +++ b/repos/base-foc/src/lib/base/capability.cc @@ -0,0 +1,72 @@ +/* + * \brief Capability lifetime management + * \author Norman Feske + * \date 2015-05-06 + */ + +/* + * 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. + */ + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +/* base-internal includes */ +#include +#include + +using namespace Genode; + + +Native_capability::Native_capability() { } + + +void Native_capability::_inc() +{ + if (_data) + _data->inc(); +} + + +void Native_capability::_dec() +{ + if (_data && !_data->dec()) + cap_map()->remove(_data); +} + + +long Native_capability::local_name() const +{ + return _data ? _data->id() : 0; +} + + +bool Native_capability::valid() const +{ + return (_data != 0) && _data->valid(); +} + + +Native_capability::Raw Native_capability::raw() const +{ + return { (unsigned long)local_name(), 0, 0, 0 }; +} + + +void Native_capability::print(Genode::Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + print(out, "kcap=", Hex(_data->kcap()), ",key=", (unsigned)_data->id()); + } else { + print(out, "invalid"); + } + print(out, ">"); +} diff --git a/repos/base-foc/src/lib/base/ipc.cc b/repos/base-foc/src/lib/base/ipc.cc index 242a9c121..8abe4dcbc 100644 --- a/repos/base-foc/src/lib/base/ipc.cc +++ b/repos/base-foc/src/lib/base/ipc.cc @@ -32,6 +32,7 @@ #include /* for 'thread_get_my_native_id()' */ #include #include +#include /* Fiasco.OC includes */ namespace Fiasco { @@ -168,8 +169,8 @@ static unsigned long extract_msg_from_utcb(l4_msgtag_t tag, */ for (unsigned i = 0; i < num_caps; i++) { if (caps[i].valid) { - rcv_msg.insert(Native_capability(cap_map()->insert_map(caps[i].badge, - caps[i].sel))); + rcv_msg.insert(Native_capability(*cap_map()->insert_map(caps[i].badge, + caps[i].sel))); } else { rcv_msg.insert(Native_capability()); } @@ -200,7 +201,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg, if (!cap.valid()) continue; - if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) + if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.data()->kcap()))) cap = Native_capability(); } @@ -217,7 +218,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg, if (cap.valid()) { caps[i].valid = true; caps[i].badge = cap.local_name(); - caps[i].sel = cap.dst(); + caps[i].sel = cap.data()->kcap(); } } @@ -285,8 +286,11 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, rcv_cap_sel += L4_CAP_SIZE; } + if (!dst.valid()) + throw Genode::Ipc_error(); + l4_msgtag_t const reply_tag = - l4_ipc_call(dst.dst(), l4_utcb(), call_tag, L4_IPC_NEVER); + l4_ipc_call(dst.data()->kcap(), l4_utcb(), call_tag, L4_IPC_NEVER); if (l4_ipc_error(reply_tag, l4_utcb()) == L4_IPC_RECANCELED) throw Genode::Blocking_canceled(); @@ -370,10 +374,40 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, Ipc_server::Ipc_server() : - Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]) + Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]) { Thread::myself()->native_thread().rcv_window.init(); } Ipc_server::~Ipc_server() { } + + +/******************** + ** Receive_window ** + ********************/ + +Receive_window::~Receive_window() +{ + if (_rcv_idx_base) + cap_idx_alloc()->free(_rcv_idx_base, MAX_CAPS_PER_MSG); +} + + +void Receive_window::init() +{ + _rcv_idx_base = cap_idx_alloc()->alloc_range(MAX_CAPS_PER_MSG); +} + + +addr_t Receive_window::rcv_cap_sel_base() +{ + return _rcv_idx_base->kcap(); +} + + +addr_t Receive_window::rcv_cap_sel(unsigned i) +{ + return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE; +} + diff --git a/repos/base-foc/src/lib/base/signal_source_client.cc b/repos/base-foc/src/lib/base/signal_source_client.cc new file mode 100644 index 000000000..060c19e2c --- /dev/null +++ b/repos/base-foc/src/lib/base/signal_source_client.cc @@ -0,0 +1,77 @@ +/* + * \brief Fiasco.OC-specific signal-source client interface + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2010-02-03 + */ + +/* + * 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 +#include +#include + +/* base-internal includes */ +#include +#include + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +using namespace Genode; + + +Signal_source_client::Signal_source_client(Capability cap) +: + Rpc_client(static_cap_cast(cap)) +{ + using namespace Fiasco; + + /* request mapping of semaphore capability selector */ + _sem = call(); + + l4_msgtag_t tag = l4_irq_attach(_sem.data()->kcap(), 0, + Thread::myself()->native_thread().kcap); + if (l4_error(tag)) + Genode::raw("l4_irq_attach failed with ", l4_error(tag)); +} + + +Signal_source_client::~Signal_source_client() +{ + Fiasco::l4_irq_detach(_sem.data()->kcap()); +} + + +__attribute__((optimize("-fno-omit-frame-pointer"))) +__attribute__((noinline)) +Signal_source_client::Signal Signal_source_client::wait_for_signal() +{ + using namespace Fiasco; + + Signal signal; + do { + + /* block on semaphore until signal context was submitted */ + l4_irq_receive(_sem.data()->kcap(), L4_IPC_NEVER); + + /* + * The following request will return immediately and either + * return a valid or a null signal. The latter may happen in + * the case a submitted signal context was destroyed (by the + * submitter) before we have a chance to raise our request. + */ + signal = call(); + + } while (!signal.imprint()); + + return signal; +} diff --git a/repos/base-foc/src/lib/base/spin_lock.cc b/repos/base-foc/src/lib/base/spin_lock.cc index eacb70f41..36eec1252 100644 --- a/repos/base-foc/src/lib/base/spin_lock.cc +++ b/repos/base-foc/src/lib/base/spin_lock.cc @@ -13,10 +13,8 @@ * under the terms of the GNU General Public License version 2. */ -/* Genode includes */ -#include - /* base-internal includes */ +#include #include diff --git a/repos/base-foc/src/lib/base/thread_bootstrap.cc b/repos/base-foc/src/lib/base/thread_bootstrap.cc index 14fa7c38e..2f6cca2bc 100644 --- a/repos/base-foc/src/lib/base/thread_bootstrap.cc +++ b/repos/base-foc/src/lib/base/thread_bootstrap.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include /***************************** diff --git a/repos/base-foc/src/lib/base/thread_start.cc b/repos/base-foc/src/lib/base/thread_start.cc index 271831830..1a8170cb9 100644 --- a/repos/base-foc/src/lib/base/thread_start.cc +++ b/repos/base-foc/src/lib/base/thread_start.cc @@ -23,6 +23,7 @@ /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { diff --git a/repos/base-foc/src/test/cap_integrity/main.cc b/repos/base-foc/src/test/cap_integrity/main.cc index e1e23d2df..761a23ad3 100644 --- a/repos/base-foc/src/test/cap_integrity/main.cc +++ b/repos/base-foc/src/test/cap_integrity/main.cc @@ -13,8 +13,13 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include +#include + +/* base-internal includes */ +#include /* cap_idx_alloc */ using namespace Genode; using namespace Fiasco; @@ -26,7 +31,7 @@ int main(int argc, char **argv) enum { COUNT = 1000 }; Cap_index* idx = cap_idx_alloc()->alloc_range(COUNT); - Fiasco::l4_cap_idx_t tid = env()->ram_session_cap().dst(); + Fiasco::l4_cap_idx_t tid = Capability_space::kcap(env()->ram_session_cap()); /* try the first 1000 local name IDs */ for (int local_name = 0; local_name < COUNT; local_name++, idx++) { @@ -36,7 +41,7 @@ int main(int argc, char **argv) idx->kcap() | L4_ITEM_MAP); Log_session_capability log_session_cap = - reinterpret_cap_cast(Native_capability(idx)); + reinterpret_cap_cast(Native_capability(*idx)); Log_session_client log_session_client(log_session_cap); try { log_session_client.write("test message"); diff --git a/repos/base-foc/src/test/cap_integrity/target.mk b/repos/base-foc/src/test/cap_integrity/target.mk index 403543f96..8b836382e 100644 --- a/repos/base-foc/src/test/cap_integrity/target.mk +++ b/repos/base-foc/src/test/cap_integrity/target.mk @@ -1,4 +1,5 @@ REQUIRES = foc TARGET = test-cap_integrity SRC_CC = main.cc +INC_DIR += $(REP_DIR)/src/include LIBS = base diff --git a/repos/base-hw/include/base/native_capability.h b/repos/base-hw/include/base/native_capability.h deleted file mode 100644 index c21d298c4..000000000 --- a/repos/base-hw/include/base/native_capability.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * \brief Native capability of base-hw - * \author Stefan Kalkowski - * \date 2015-05-15 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -/* Genode includes */ -#include -#include - -namespace Genode { class Native_capability; } - - -class Genode::Native_capability -{ - public: - - using Dst = Kernel::capid_t; - - private: - - Dst _dst; - - void _inc() const; - void _dec() const; - - public: - - struct Raw { }; - - /** - * Create an invalid capability - */ - Native_capability() : _dst(Kernel::cap_id_invalid()) { } - - /** - * Create a capability out of a kernel's capability id - */ - Native_capability(Kernel::capid_t dst) : _dst(dst) { _inc(); } - - /** - * Create a capability from another one - */ - Native_capability(const Native_capability &o) : _dst(o._dst) { _inc(); } - - ~Native_capability() { _dec(); } - - /** - * Returns true if it is a valid capability otherwise false - */ - bool valid() const { return (_dst != Kernel::cap_id_invalid()); } - - - /***************** - ** Accessors ** - *****************/ - - addr_t local_name() const { return _dst; } - Dst dst() const { return _dst; } - - - /************************** - ** Operator overloads ** - **************************/ - - bool operator==(const Native_capability &o) const { - return _dst == _dst; } - - Native_capability& operator=(const Native_capability &o) - { - if (this == &o) return *this; - _dec(); - _dst = o._dst; - _inc(); - return *this; - } - - Raw raw() const { return Raw(); } -}; - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-hw/src/core/capability.cc b/repos/base-hw/src/core/capability.cc index 6165eee90..71bad5dca 100644 --- a/repos/base-hw/src/core/capability.cc +++ b/repos/base-hw/src/core/capability.cc @@ -10,8 +10,29 @@ * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ -#include -void Genode::Native_capability::_inc() const { } +#include -void Genode::Native_capability::_dec() const { } +using namespace Genode; + + +Native_capability::Native_capability() { } + + +void Native_capability::_inc() { } +void Native_capability::_dec() { } + + +long Native_capability::local_name() const +{ + return (long)_data; +} + + +bool Native_capability::valid() const +{ + return (addr_t)_data != Kernel::cap_id_invalid(); +} + + +Native_capability::Raw Native_capability::raw() const { return { 0, 0, 0, 0 }; } diff --git a/repos/base-hw/src/core/include/kernel/configuration.h b/repos/base-hw/src/core/include/kernel/configuration.h index 8400e650a..74efdaae1 100644 --- a/repos/base-hw/src/core/include/kernel/configuration.h +++ b/repos/base-hw/src/core/include/kernel/configuration.h @@ -14,6 +14,8 @@ #ifndef _CORE__INCLUDE__KERNEL__CONFIGURATION_H_ #define _CORE__INCLUDE__KERNEL__CONFIGURATION_H_ +#include + namespace Kernel { enum { diff --git a/repos/base-hw/src/core/include/object.h b/repos/base-hw/src/core/include/object.h index 69560fd2b..f5398cc11 100644 --- a/repos/base-hw/src/core/include/object.h +++ b/repos/base-hw/src/core/include/object.h @@ -14,13 +14,17 @@ #ifndef _CORE__INCLUDE__OBJECT_H_ #define _CORE__INCLUDE__OBJECT_H_ -#include -#include -#include +/* Genode includes */ #include -namespace Genode -{ +/* base-internal includes */ +#include + +/* base-hw includes */ +#include +#include + +namespace Genode { /** * Represents a kernel object in core * @@ -51,9 +55,11 @@ class Genode::Kernel_object */ template Kernel_object(bool syscall, ARGS &&... args) - : _cap(syscall ? T::syscall_create(&_data, args...) - : Kernel::cap_id_invalid()) { - if (!syscall) construct_at(&_data, args...); } + : _cap(Capability_space::import(syscall ? T::syscall_create(&_data, args...) + : Kernel::cap_id_invalid())) + { + if (!syscall) construct_at(&_data, args...); + } ~Kernel_object() { T::syscall_destroy(kernel_object()); } @@ -66,7 +72,7 @@ class Genode::Kernel_object bool create(ARGS &&... args) { if (_cap.valid()) return false; - _cap = T::syscall_create(&_data, args...); + _cap = Capability_space::import(T::syscall_create(&_data, args...)); return _cap.valid(); } }; diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index 9b1e69f71..3b5695f38 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -40,7 +40,7 @@ namespace Genode { class Platform_thread; /* forward declaration */ - class Capability_space; + class Cap_space; /** * Platform specific part of a Genode protection domain @@ -128,7 +128,7 @@ class Hw::Address_space : public Genode::Address_space }; -class Genode::Capability_space +class Genode::Cap_space { private: @@ -142,7 +142,7 @@ class Genode::Capability_space public: - Capability_space(); + Cap_space(); Cap_slab & capability_slab() { return _slab; } @@ -151,7 +151,7 @@ class Genode::Capability_space class Genode::Platform_pd : public Hw::Address_space, - public Genode::Capability_space, + public Genode::Cap_space, public Kernel_object { private: diff --git a/repos/base-hw/src/core/include/rpc_cap_factory.h b/repos/base-hw/src/core/include/rpc_cap_factory.h index 4db2f2b67..552e1e87d 100644 --- a/repos/base-hw/src/core/include/rpc_cap_factory.h +++ b/repos/base-hw/src/core/include/rpc_cap_factory.h @@ -20,11 +20,15 @@ #include #include #include +#include /* core-local includes */ #include #include +/* base-internal includes */ +#include + namespace Genode { class Rpc_cap_factory; } @@ -86,10 +90,11 @@ class Genode::Rpc_cap_factory construct_at(obj); /* create kernel object via syscall */ - obj->cap = Kernel::new_obj(obj->data, ep.dst()); + Kernel::capid_t capid = Kernel::new_obj(obj->data, Capability_space::capid(ep)); + obj->cap = Capability_space::import(capid); if (!obj->cap.valid()) { - PWRN("Invalid entrypoint %u for allocating a capability!", - ep.dst()); + raw("Invalid entrypoint ", (addr_t)Capability_space::capid(ep), + " for allocating a capability!"); destroy(&_slab, obj); return Native_capability(); } @@ -104,7 +109,7 @@ class Genode::Rpc_cap_factory Lock::Guard guard(_lock); for (Kobject * obj = _list.first(); obj; obj = obj->next()) { - if (obj->cap.dst() == cap.dst()) { + if (obj->cap.data() == cap.data()) { Kernel::delete_obj(obj->data); _list.remove(obj); destroy(&_slab, obj); diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h b/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h index cf74c2581..b019d6b70 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h @@ -50,7 +50,7 @@ class Genode::Vm_session_component void exception_handler(Signal_context_capability handler) { - if (!create(&_state, handler.dst(), nullptr)) + if (!create(&_state, Capability_space::capid(handler), nullptr)) PWRN("Cannot instantiate vm kernel object, " "invalid signal context?"); } diff --git a/repos/base-hw/src/core/include/util.h b/repos/base-hw/src/core/include/util.h index 9704d862c..3a39eec79 100644 --- a/repos/base-hw/src/core/include/util.h +++ b/repos/base-hw/src/core/include/util.h @@ -21,6 +21,9 @@ /* base-internal includes */ #include +/* base-hw includes */ +#include + namespace Genode { struct Native_region diff --git a/repos/base-hw/src/core/irq_session_component.cc b/repos/base-hw/src/core/irq_session_component.cc index 670859492..8794af7b8 100644 --- a/repos/base-hw/src/core/irq_session_component.cc +++ b/repos/base-hw/src/core/irq_session_component.cc @@ -20,6 +20,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -47,7 +50,8 @@ void Irq_session_component::sigh(Signal_context_capability cap) _sig_cap = cap; - if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number, _sig_cap.dst())) + if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number, + Capability_space::capid(_sig_cap))) PWRN("invalid signal handler for IRQ %u", _irq_number); } diff --git a/repos/base-hw/src/core/pager.cc b/repos/base-hw/src/core/pager.cc index 837563a47..b108be7b3 100644 --- a/repos/base-hw/src/core/pager.cc +++ b/repos/base-hw/src/core/pager.cc @@ -19,6 +19,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -65,7 +68,7 @@ void Ipc_pager::set_reply_mapping(Mapping m) { _mapping = m; } void Pager_object::wake_up() { using Object = Kernel_object; - Kernel::ack_signal(Object::_cap.dst()); + Kernel::ack_signal(Capability_space::capid(Object::_cap)); } void Pager_object::start_paging(Kernel::Signal_receiver * receiver) diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index bd6c2b9f9..c2c473d8c 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -103,15 +103,14 @@ Hw::Address_space::~Address_space() } -/************************************* - ** Capability_space implementation ** - *************************************/ +/****************************** + ** Cap_space implementation ** + ******************************/ -Capability_space::Capability_space() -: _slab(nullptr, &_initial_sb) { } +Cap_space::Cap_space() : _slab(nullptr, &_initial_sb) { } -void Capability_space::upgrade_slab(Allocator &alloc) +void Cap_space::upgrade_slab(Allocator &alloc) { for (;;) { void *block = nullptr; diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 3e1af2bd3..78e5a99c1 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include +#include /* kernel includes */ #include @@ -171,10 +172,10 @@ int Platform_thread::start(void * const ip, void * const sp) /* reset capability counter */ utcb->cap_cnt(0); - utcb->cap_add(_cap.dst()); + utcb->cap_add(Capability_space::capid(_cap)); if (_main_thread) { - utcb->cap_add(_pd->parent().dst()); - utcb->cap_add(_utcb.dst()); + utcb->cap_add(Capability_space::capid(_pd->parent())); + utcb->cap_add(Capability_space::capid(_utcb)); } Kernel::start_thread(kernel_object(), cpu, _pd->kernel_pd(), _utcb_core_addr); @@ -187,7 +188,8 @@ void Platform_thread::pager(Pager_object * const pager) using namespace Kernel; if (route_thread_event(kernel_object(), Thread_event_id::FAULT, - pager ? pager->cap().dst() : cap_id_invalid())) + pager ? Capability_space::capid(pager->cap()) + : cap_id_invalid())) PERR("failed to set pager object for thread %s", label()); _pager = pager; diff --git a/repos/base-hw/src/core/region_map_support.cc b/repos/base-hw/src/core/region_map_support.cc index 29997b5f8..e370f7ea6 100644 --- a/repos/base-hw/src/core/region_map_support.cc +++ b/repos/base-hw/src/core/region_map_support.cc @@ -20,6 +20,8 @@ #include #include +/* base-internal includes */ + using namespace Genode; @@ -45,7 +47,7 @@ void Pager_entrypoint::entry() while (1) { /* receive fault */ - if (Kernel::await_signal(_cap.dst())) continue; + if (Kernel::await_signal(Capability_space::capid(_cap))) continue; Untyped_capability cap = (*(Pager_object**)Thread::myself()->utcb()->data())->cap(); diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc index a4377e4cf..4ffb813ee 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc @@ -20,7 +20,9 @@ using namespace Genode; void Vm_session_component::exception_handler(Signal_context_capability handler) { - if (!create((void*)_ds.core_local_addr(), handler.dst(), nullptr)) { + if (!create((void*)_ds.core_local_addr(), Capability_space::capid(handler), + nullptr)) + { PWRN("Cannot instantiate vm kernel object twice," "or invalid signal context?"); } diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc index 4dcbf5b5a..22b5013c5 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc @@ -28,7 +28,7 @@ void Vm_session_component::exception_handler(Signal_context_capability handler) Core_mem_allocator * cma = static_cast(platform()->core_mem_alloc()); - if (!create((void*)_ds.core_local_addr(), handler.dst(), + if (!create((void*)_ds.core_local_addr(), Capability_space::capid(handler), cma->phys_addr(_table))) PWRN("Cannot instantiate vm kernel object, invalid signal context?"); } diff --git a/repos/base-hw/src/core/thread_start.cc b/repos/base-hw/src/core/thread_start.cc index 1a297936e..ade5500fe 100644 --- a/repos/base-hw/src/core/thread_start.cc +++ b/repos/base-hw/src/core/thread_start.cc @@ -69,5 +69,5 @@ void Thread::_init_platform_thread(size_t, Type type) max(sizeof(Native_utcb) / get_page_size(), (size_t)1)); /* adjust initial object state in case of a main thread */ - native_thread().cap = Hw::_main_thread_cap.dst(); + native_thread().cap = Hw::_main_thread_cap; } diff --git a/repos/base-hw/src/include/base/internal/capability_space.h b/repos/base-hw/src/include/base/internal/capability_space.h new file mode 100644 index 000000000..d981428bc --- /dev/null +++ b/repos/base-hw/src/include/base/internal/capability_space.h @@ -0,0 +1,40 @@ +/* + * \brief Capability helper + * \author Norman Feske + * \date 2016-06-22 + */ + +/* + * 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__BASE__INTERNAL__CAPABILITY_SPACE_H_ +#define _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ + +/* Genode includes */ +#include + +/* base-hw includes */ +#include + +namespace Genode { namespace Capability_space { + + /** + * Return kernel capability selector of Genode capability + */ + static inline Kernel::capid_t capid(Native_capability const &cap) + { + addr_t const index = (addr_t)cap.data(); + return index; + } + + static inline Native_capability import(Kernel::capid_t capid) + { + return Native_capability(*(Native_capability::Data *)(addr_t)capid); + } +} } + +#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ */ diff --git a/repos/base-hw/src/include/base/internal/lock_helper.h b/repos/base-hw/src/include/base/internal/lock_helper.h index 44e49a684..79bf69cb5 100644 --- a/repos/base-hw/src/include/base/internal/lock_helper.h +++ b/repos/base-hw/src/include/base/internal/lock_helper.h @@ -17,9 +17,11 @@ /* Genode includes */ #include -namespace Hw { - extern Genode::Untyped_capability _main_thread_cap; -} +/* base-internal includes */ +#include + +namespace Hw { extern Genode::Untyped_capability _main_thread_cap; } + /** * Yield execution time-slice of current thread @@ -34,7 +36,8 @@ static inline void thread_yield() { static inline Kernel::capid_t native_thread_id(Genode::Thread * const t) { - return t ? t->native_thread().cap.dst() : Hw::_main_thread_cap.dst(); + using Genode::Capability_space::capid; + return t ? capid(t->native_thread().cap) : capid(Hw::_main_thread_cap); } diff --git a/repos/base-hw/src/lib/base/capability.cc b/repos/base-hw/src/lib/base/capability.cc index 02d664a97..ba9e16980 100644 --- a/repos/base-hw/src/lib/base/capability.cc +++ b/repos/base-hw/src/lib/base/capability.cc @@ -17,24 +17,63 @@ /* base-internal includes */ #include -static volatile int spinlock = SPINLOCK_UNLOCKED; -static Genode::uint8_t ref_counter[1 << (sizeof(Kernel::capid_t)*8)]; +/* kernel includes */ +#include -void Genode::Native_capability::_inc() const +using namespace Genode; + +static volatile int spinlock = SPINLOCK_UNLOCKED; + +static uint8_t ref_counter[1 << (sizeof(Kernel::capid_t)*8)]; + + +Native_capability::Native_capability() { } + + +void Native_capability::_inc() { if (!valid()) return; spinlock_lock(&spinlock); - ref_counter[_dst]++; + ref_counter[(addr_t)_data]++; spinlock_unlock(&spinlock); } -void Genode::Native_capability::_dec() const +void Native_capability::_dec() { if (!valid()) return; spinlock_lock(&spinlock); - if (!--ref_counter[_dst]) { Kernel::delete_cap(_dst); } + if (!--ref_counter[(addr_t)_data]) { Kernel::delete_cap((addr_t)_data); } spinlock_unlock(&spinlock); } + + +long Native_capability::local_name() const +{ + return (long)_data; +} + + +bool Native_capability::valid() const +{ + return (addr_t)_data != Kernel::cap_id_invalid(); +} + + +Native_capability::Raw Native_capability::raw() const { return { 0, 0, 0, 0 }; } + + +void Native_capability::print(Genode::Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + print(out, (addr_t)_data); + } else { + print(out, "invalid"); + } + print(out, ">"); +} diff --git a/repos/base-hw/src/lib/base/ipc.cc b/repos/base-hw/src/lib/base/ipc.cc index 33c622695..8603d6469 100644 --- a/repos/base-hw/src/lib/base/ipc.cc +++ b/repos/base-hw/src/lib/base/ipc.cc @@ -25,6 +25,7 @@ #include #include #include +#include /* base-hw includes */ #include @@ -44,7 +45,7 @@ static inline void copy_msg_to_utcb(Msgbuf_base const &snd_msg, Native_utcb &utc snd_msg.used_caps()); for (unsigned i = 0; i < num_caps; i++) - utcb.cap_set(i, snd_msg.cap(i).dst()); + utcb.cap_set(i, Capability_space::capid(snd_msg.cap(i))); utcb.cap_cnt(num_caps); @@ -68,9 +69,9 @@ static inline void copy_utcb_to_msg(Native_utcb const &utcb, Msgbuf_base &rcv_ms utcb.cap_cnt()); for (unsigned i = 0; i < num_caps; i++) { - rcv_msg.cap(i) = utcb.cap_get(i); + rcv_msg.cap(i) = Capability_space::import(utcb.cap_get(i)); if (rcv_msg.cap(i).valid()) - Kernel::ack_cap(rcv_msg.cap(i).dst()); + Kernel::ack_cap(Capability_space::capid(rcv_msg.cap(i))); } rcv_msg.used_caps(num_caps); @@ -100,8 +101,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, copy_msg_to_utcb(snd_msg, *Thread::myself()->utcb()); - switch (Kernel::send_request_msg(dst.dst(), - rcv_caps)) { + switch (Kernel::send_request_msg(Capability_space::capid(dst), rcv_caps)) { case -1: throw Blocking_canceled(); case -2: throw Allocator::Out_of_memory(); default: diff --git a/repos/base-hw/src/lib/base/signal.cc b/repos/base-hw/src/lib/base/signal.cc index e47b5e128..6d058fb86 100644 --- a/repos/base-hw/src/lib/base/signal.cc +++ b/repos/base-hw/src/lib/base/signal.cc @@ -20,9 +20,7 @@ /* base-internal includes */ #include - -/* base-hw includes */ -#include +#include using namespace Genode; @@ -54,7 +52,7 @@ void Signal_transmitter::submit(unsigned cnt) { Trace::Signal_submit trace_event(cnt); } - Kernel::submit_signal(_context.dst(), cnt); + Kernel::submit_signal(Capability_space::capid(_context), cnt); } @@ -85,7 +83,7 @@ void Signal_receiver::_platform_destructor() void Signal_receiver::_platform_begin_dissolve(Signal_context * const c) { - Kernel::kill_signal_context(c->_cap.dst()); + Kernel::kill_signal_context(Capability_space::capid(c->_cap)); } void Signal_receiver::_platform_finish_dissolve(Signal_context *) { } @@ -119,7 +117,7 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c) void Signal_receiver::block_for_signal() { /* wait for a signal */ - if (Kernel::await_signal(_cap.dst())) { + if (Kernel::await_signal(Capability_space::capid(_cap))) { PERR("failed to receive signal"); return; } @@ -135,7 +133,7 @@ void Signal_receiver::block_for_signal() context->_curr_signal = Signal::Data(context, num); } /* end kernel-aided life-time management */ - Kernel::ack_signal(data->context->_cap.dst()); + Kernel::ack_signal(Capability_space::capid(data->context->_cap)); } diff --git a/repos/base-hw/src/lib/base/thread_bootstrap.cc b/repos/base-hw/src/lib/base/thread_bootstrap.cc index df683f1d9..a308e5118 100644 --- a/repos/base-hw/src/lib/base/thread_bootstrap.cc +++ b/repos/base-hw/src/lib/base/thread_bootstrap.cc @@ -20,9 +20,7 @@ /* base-internal includes */ #include #include - -/* base-hw includes */ -#include +#include using namespace Genode; @@ -47,10 +45,13 @@ void prepare_init_main_thread() * before the UTCB gets polluted by the following function calls. */ Native_utcb * utcb = Thread::myself()->utcb(); - _parent_cap = utcb->cap_get(Native_utcb::PARENT); - Untyped_capability ds_cap(utcb->cap_get(Native_utcb::UTCB_DATASPACE)); + _parent_cap = Capability_space::import(utcb->cap_get(Native_utcb::PARENT)); + + Untyped_capability ds_cap = + Capability_space::import(utcb->cap_get(Native_utcb::UTCB_DATASPACE)); _main_thread_utcb_ds = reinterpret_cap_cast(ds_cap); - _main_thread_cap = utcb->cap_get(Native_utcb::THREAD_MYSELF); + + _main_thread_cap = Capability_space::import(utcb->cap_get(Native_utcb::THREAD_MYSELF)); } @@ -76,5 +77,8 @@ void Thread::_thread_start() Genode::sleep_forever(); } -void Thread::_thread_bootstrap() { - native_thread().cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); } +void Thread::_thread_bootstrap() +{ + Kernel::capid_t capid = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); + native_thread().cap = Capability_space::import(capid); +} diff --git a/repos/base-linux/include/base/native_capability.h b/repos/base-linux/include/base/native_capability.h deleted file mode 100644 index 512d15788..000000000 --- a/repos/base-linux/include/base/native_capability.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * \brief Native capability type - * \author Norman Feske - * \date 2007-10-15 - */ - -/* - * Copyright (C) 2007-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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include -#include -#include - -namespace Genode { - - struct Cap_dst_policy - { - struct Dst - { - int socket; - - /** - * Default constructor creates invalid destination - */ - Dst() : socket(-1) { } - - explicit Dst(int socket) : socket(socket) { } - }; - - static bool valid(Dst id) { return id.socket != -1; } - static Dst invalid() { return Dst(); } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-linux/lib/mk/base-common.mk b/repos/base-linux/lib/mk/base-common.mk index 2fa17ca2d..c45aaddcf 100644 --- a/repos/base-linux/lib/mk/base-common.mk +++ b/repos/base-linux/lib/mk/base-common.mk @@ -12,3 +12,4 @@ SRC_CC += region_map_mmap.cc debug.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread_env.cc +SRC_CC += capability.cc diff --git a/repos/base-linux/lib/mk/base.mk b/repos/base-linux/lib/mk/base.mk index 372407127..fa6bb32e2 100644 --- a/repos/base-linux/lib/mk/base.mk +++ b/repos/base-linux/lib/mk/base.mk @@ -8,4 +8,5 @@ include $(REP_DIR)/lib/mk/base.inc LIBS += startup SRC_CC += thread.cc thread_myself.cc thread_linux.cc +SRC_CC += capability_space.cc capability_raw.cc diff --git a/repos/base-linux/lib/mk/lx_hybrid.mk b/repos/base-linux/lib/mk/lx_hybrid.mk index 36183ac68..7a598d992 100644 --- a/repos/base-linux/lib/mk/lx_hybrid.mk +++ b/repos/base-linux/lib/mk/lx_hybrid.mk @@ -1,4 +1,4 @@ -SRC_CC += lx_hybrid.cc new_delete.cc +SRC_CC += lx_hybrid.cc new_delete.cc capability_space.cc vpath new_delete.cc $(BASE_DIR)/src/lib/cxx vpath lx_hybrid.cc $(REP_DIR)/src/lib/lx_hybrid diff --git a/repos/base-linux/src/core/include/core_env.h b/repos/base-linux/src/core/include/core_env.h index b656d187e..e5bf0b090 100644 --- a/repos/base-linux/src/core/include/core_env.h +++ b/repos/base-linux/src/core/include/core_env.h @@ -210,8 +210,6 @@ namespace Genode { PWRN("%s:%u not implemented", __FILE__, __LINE__); return Cpu_session_capability(); } - - void reload_parent_cap(Capability::Dst, long) { } }; diff --git a/repos/base-linux/src/core/include/dataspace_component.h b/repos/base-linux/src/core/include/dataspace_component.h index c0c26c448..3ca5e4b39 100644 --- a/repos/base-linux/src/core/include/dataspace_component.h +++ b/repos/base-linux/src/core/include/dataspace_component.h @@ -25,6 +25,9 @@ #include #include +/* base-internal includes */ +#include + namespace Genode { /** @@ -122,9 +125,10 @@ namespace Genode { Untyped_capability fd() { - typedef Untyped_capability::Dst Dst; - enum { DUMMY_LOCAL_NAME = 0 }; - return Untyped_capability(Dst(_fd), DUMMY_LOCAL_NAME); + Untyped_capability fd_cap = + Capability_space::import(Rpc_destination(_fd), Rpc_obj_key()); + + return fd_cap; } }; } diff --git a/repos/base-linux/src/core/include/rpc_cap_factory.h b/repos/base-linux/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-linux/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-linux/src/core/native_cpu_component.cc b/repos/base-linux/src/core/native_cpu_component.cc index f4e905d35..b19c00560 100644 --- a/repos/base-linux/src/core/native_cpu_component.cc +++ b/repos/base-linux/src/core/native_cpu_component.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -30,10 +33,8 @@ Untyped_capability Native_cpu_component::server_sd(Thread_capability thread_cap) auto lambda = [] (Cpu_thread_component *thread) { if (!thread) return Untyped_capability(); - enum { DUMMY_LOCAL_NAME = 0 }; - typedef Native_capability::Dst Dst; - return Untyped_capability(Dst(thread->platform_thread().server_sd()), - DUMMY_LOCAL_NAME); + return Capability_space::import(Rpc_destination(thread->platform_thread().server_sd()), + Rpc_obj_key()); }; return _thread_ep.apply(thread_cap, lambda); } @@ -44,10 +45,8 @@ Untyped_capability Native_cpu_component::client_sd(Thread_capability thread_cap) auto lambda = [] (Cpu_thread_component *thread) { if (!thread) return Untyped_capability(); - enum { DUMMY_LOCAL_NAME = 0 }; - typedef Native_capability::Dst Dst; - return Untyped_capability(Dst(thread->platform_thread().client_sd()), - DUMMY_LOCAL_NAME); + return Capability_space::import(Rpc_destination(thread->platform_thread().client_sd()), + Rpc_obj_key()); }; return _thread_ep.apply(thread_cap, lambda); } diff --git a/repos/base-linux/src/core/native_pd_component.cc b/repos/base-linux/src/core/native_pd_component.cc index b2f3e84e5..b46f0fd76 100644 --- a/repos/base-linux/src/core/native_pd_component.cc +++ b/repos/base-linux/src/core/native_pd_component.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include +#include /* Linux includes */ #include @@ -117,7 +118,8 @@ void Native_pd_component::_start(Dataspace_component &ds) char buf[4096]; int num_bytes = 0; - while ((num_bytes = lx_read(ds.fd().dst().socket, buf, sizeof(buf))) != 0) + int const fd_socket = Capability_space::ipc_cap_data(ds.fd()).dst.socket; + while ((num_bytes = lx_read(fd_socket, buf, sizeof(buf))) != 0) lx_write(tmp_binary_fd, buf, num_bytes); lx_close(tmp_binary_fd); @@ -167,7 +169,7 @@ void Native_pd_component::_start(Dataspace_component &ds) * pointer, all arguments are embedded within the 'execve_args' struct. */ Execve_args arg(filename, argv_buf, env, - _pd_session._parent.dst().socket); + Capability_space::ipc_cap_data(_pd_session._parent).dst.socket); _pid = lx_create_process((int (*)(void *))_exec_child, stack + STACK_SIZE - sizeof(umword_t), &arg); diff --git a/repos/base-linux/src/core/platform.cc b/repos/base-linux/src/core/platform.cc index 41496cc11..9ba8ae68d 100644 --- a/repos/base-linux/src/core/platform.cc +++ b/repos/base-linux/src/core/platform.cc @@ -18,6 +18,7 @@ /* base-internal includes */ #include #include +#include /* local includes */ #include "platform.h" @@ -206,7 +207,8 @@ int Region_map_mmap::_dataspace_fd(Capability ds_cap) if (!core_env()->entrypoint()->is_myself()) { /* release Region_map_mmap::_lock during RPC */ _lock.unlock(); - int socket = Linux_dataspace_client(ds_cap).fd().dst().socket; + Untyped_capability fd_cap = Linux_dataspace_client(ds_cap).fd(); + int socket = Capability_space::ipc_cap_data(fd_cap).dst.socket; _lock.lock(); return socket; } @@ -223,7 +225,7 @@ int Region_map_mmap::_dataspace_fd(Capability ds_cap) * dataspace, the descriptor would unexpectedly be closed again. */ return core_env()->entrypoint()->apply(lx_ds_cap, [] (Linux_dataspace *ds) { - return ds ? lx_dup(ds->fd().dst().socket) : -1; }); + return ds ? lx_dup(Capability_space::ipc_cap_data(ds->fd()).dst.socket) : -1; }); } diff --git a/repos/base-linux/src/core/ram_session_support.cc b/repos/base-linux/src/core/ram_session_support.cc index a77452cae..98058b6e6 100644 --- a/repos/base-linux/src/core/ram_session_support.cc +++ b/repos/base-linux/src/core/ram_session_support.cc @@ -21,6 +21,9 @@ #include #include +/* base-internal includes */ +#include + /* Linux syscall bindings */ #include @@ -55,7 +58,7 @@ void Ram_session_component::_export_ram_ds(Dataspace_component *ds) void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { - int const fd = ds->fd().dst().socket; + int const fd = Capability_space::ipc_cap_data(ds->fd()).dst.socket; if (fd != -1) lx_close(fd); } diff --git a/repos/base-linux/src/core/rom_session_component.cc b/repos/base-linux/src/core/rom_session_component.cc index 47ec3ec76..f5fe3e0cc 100644 --- a/repos/base-linux/src/core/rom_session_component.cc +++ b/repos/base-linux/src/core/rom_session_component.cc @@ -24,6 +24,9 @@ #include #include +/* base-internal includes */ +#include + /* local includes */ #include "rom_session_component.h" @@ -44,7 +47,7 @@ Rom_session_component::~Rom_session_component() { _ds_ep->dissolve(&_ds); - int const fd = _ds.fd().dst().socket; + int const fd = Capability_space::ipc_cap_data(_ds.fd()).dst.socket; if (fd != -1) lx_close(fd); } diff --git a/repos/base-linux/src/core/target.mk b/repos/base-linux/src/core/target.mk index 12e4d0bbc..a36f6d821 100644 --- a/repos/base-linux/src/core/target.mk +++ b/repos/base-linux/src/core/target.mk @@ -19,7 +19,8 @@ SRC_CC = main.cc \ dataspace_component.cc \ native_pd_component.cc \ native_cpu_component.cc \ - rpc_cap_factory.cc \ + capability_space.cc \ + rpc_cap_factory_l4.cc \ core_rpc_cap_alloc.cc \ io_mem_session_component.cc \ signal_source_component.cc \ @@ -47,7 +48,8 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.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) diff --git a/repos/base-linux/src/include/base/internal/local_capability.h b/repos/base-linux/src/include/base/internal/local_capability.h index 9fa5b63d5..158b201c8 100644 --- a/repos/base-linux/src/include/base/internal/local_capability.h +++ b/repos/base-linux/src/include/base/internal/local_capability.h @@ -14,15 +14,24 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__BASE__LOCAL_CAPABILITY_H_ -#define _INCLUDE__BASE__LOCAL_CAPABILITY_H_ +#ifndef _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ +#define _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ -#include +#include namespace Genode { template class Local_capability; + + /** + * Return true if argument is a local capability + */ + static inline bool local(Untyped_capability const &cap) + { + return Capability_space::ipc_cap_data(cap).dst.socket == -1; + } } + /** * Local capability referring to a specific RPC interface * @@ -44,7 +53,9 @@ class Genode::Local_capability * \return a capability that represents the local object. */ static Capability local_cap(RPC_INTERFACE* ptr) { - Untyped_capability cap(Cap_dst_policy::Dst(), (long)ptr); + Untyped_capability cap = + Capability_space::import(invalid_rpc_destination(), + Rpc_obj_key((long)ptr)); return reinterpret_cap_cast(cap); } /** @@ -57,4 +68,4 @@ class Genode::Local_capability return reinterpret_cast(c.local_name()); } }; -#endif /* _INCLUDE__BASE__LOCAL_CAPABILITY_H_ */ +#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ */ diff --git a/repos/base-linux/src/include/base/internal/rpc_destination.h b/repos/base-linux/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..7bf76ddb7 --- /dev/null +++ b/repos/base-linux/src/include/base/internal/rpc_destination.h @@ -0,0 +1,41 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +#include + +namespace Genode { + + struct Rpc_destination + { + int socket = -1; + + explicit Rpc_destination(int socket) : socket(socket) { } + + Rpc_destination() { } + }; + + static inline Rpc_destination invalid_rpc_destination() + { + return Rpc_destination(); + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "socket=", dst.socket); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-linux/src/lib/base/capability_raw.cc b/repos/base-linux/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..854a870ea --- /dev/null +++ b/repos/base-linux/src/lib/base/capability_raw.cc @@ -0,0 +1,31 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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 + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + /* + * On Linux, we don't pass information as a 'raw' representation to + * child components. So this function remains unused. We still need + * to provide it to prevent link errors of noux, which relies on this + * function for implementing 'fork' (not supported on base-linux). + */ + return { { 0, 0, 0, 0 } }; +} diff --git a/repos/base-linux/src/lib/base/ipc.cc b/repos/base-linux/src/lib/base/ipc.cc index d1fd3f102..6ef14bc04 100644 --- a/repos/base-linux/src/lib/base/ipc.cc +++ b/repos/base-linux/src/lib/base/ipc.cc @@ -24,6 +24,7 @@ #include #include #include +#include /* Linux includes */ #include @@ -33,6 +34,19 @@ using namespace Genode; +namespace { + + struct Pid + { + int value; + + Pid() : value(lx_getpid()) { } + + void print(Output &out) const { Genode::print(out, "[", value, "]"); } + }; +} + + /* * The request message layout is: * @@ -60,12 +74,21 @@ struct Protocol_header /* badges of the transferred capability arguments */ unsigned long badges[Msgbuf_base::MAX_CAPS_PER_MSG]; - enum { INVALID_BADGE = ~0UL }; + enum { INVALID_BADGE = ~1UL }; void *msg_start() { return &protocol_word; } }; +/* + * The INVALID_BADGE must be different from the representation of an + * invalid RPC object key because this key value is used by manually + * created NON-RPC-object capabilities (client_sd, server_sd, dataspace fd). + */ +static_assert((int)Protocol_header::INVALID_BADGE != (int)Rpc_obj_key::INVALID, + "ambigious INVALID_BADGE"); + + /****************************** ** File-descriptor registry ** ******************************/ @@ -242,8 +265,11 @@ static void insert_sds_into_message(Message &msg, Native_capability const &cap = snd_msgbuf.cap(i); if (cap.valid()) { - msg.marshal_socket(cap.dst().socket); - header.badges[i] = cap.local_name(); + Capability_space::Ipc_cap_data cap_data = + Capability_space::ipc_cap_data(cap); + + msg.marshal_socket(cap_data.dst.socket); + header.badges[i] = cap_data.rpc_obj_key.value(); } else { header.badges[i] = Protocol_header::INVALID_BADGE; } @@ -277,7 +303,8 @@ static void extract_sds_from_message(unsigned start_index, int const associated_sd = Genode::ep_sd_registry()->try_associate(sd, id); - buf.insert(Native_capability(Cap_dst_policy::Dst(associated_sd), badge)); + buf.insert(Capability_space::import(Rpc_destination(associated_sd), + Rpc_obj_key(badge))); if ((associated_sd >= 0) && (associated_sd != sd)) { @@ -374,10 +401,13 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, /* marshal capabilities contained in 'snd_msgbuf' */ insert_sds_into_message(snd_msg, snd_header, snd_msgbuf); - int const send_ret = lx_sendmsg(dst.dst().socket, snd_msg.msg(), 0); + int const dst_socket = Capability_space::ipc_cap_data(dst).dst.socket; + + int const send_ret = lx_sendmsg(dst_socket, snd_msg.msg(), 0); if (send_ret < 0) { - PRAW("[%d] lx_sendmsg to sd %d failed with %d in lx_call()", - lx_getpid(), dst.dst().socket, send_ret); + raw(Pid(), " lx_sendmsg to sd ", dst_socket, + " failed with ", send_ret, " in lx_call()"); + for (;;); throw Genode::Ipc_error(); } @@ -414,7 +444,9 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, Msgbuf_base &snd_msg) { - try { lx_reply(caller.dst().socket, exc, snd_msg); } catch (Ipc_error) { } + int const reply_socket = Capability_space::ipc_cap_data(caller).dst.socket; + + try { lx_reply(reply_socket, exc, snd_msg); } catch (Ipc_error) { } } @@ -425,7 +457,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, { /* when first called, there was no request yet */ if (last_caller.valid() && exc.value != Rpc_exception_code::INVALID_OBJECT) - lx_reply(last_caller.dst().socket, exc, reply_msg); + lx_reply(Capability_space::ipc_cap_data(last_caller).dst.socket, exc, reply_msg); /* * Block infinitely if called from the main thread. This may happen if the @@ -464,15 +496,15 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, /* start at offset 1 to skip the reply channel */ extract_sds_from_message(1, msg, header, request_msg); - typedef Native_capability::Dst Dst; - return Rpc_request(Native_capability(Dst(reply_socket), ~0UL), badge); + return Rpc_request(Capability_space::import(Rpc_destination(reply_socket), + Rpc_obj_key()), badge); } } Ipc_server::Ipc_server() : - Native_capability(Dst(-1), 0) + Native_capability(Capability_space::import(Rpc_destination(), Rpc_obj_key())) { /* * If 'thread' is 0, the constructor was called by the main thread. By @@ -498,7 +530,8 @@ Ipc_server::Ipc_server() /* override capability initialization */ *static_cast(this) = - Native_capability(Native_capability::Dst(socket_pair.client_sd), 0); + Capability_space::import(Rpc_destination(socket_pair.client_sd), + Rpc_obj_key()); } diff --git a/repos/base-linux/src/lib/base/platform_env.cc b/repos/base-linux/src/lib/base/platform_env.cc index ba0f3f2a5..7e5cbeaa7 100644 --- a/repos/base-linux/src/lib/base/platform_env.cc +++ b/repos/base-linux/src/lib/base/platform_env.cc @@ -22,6 +22,7 @@ #include #include #include +#include using namespace Genode; @@ -32,16 +33,18 @@ using namespace Genode; size_t Region_map_mmap::_dataspace_size(Dataspace_capability ds) { - if (ds.valid()) - return Dataspace_client(ds).size(); + if (local(ds)) + return Local_capability::deref(ds)->size(); + + return Dataspace_client(ds).size(); - return Local_capability::deref(ds)->size(); } int Region_map_mmap::_dataspace_fd(Dataspace_capability ds) { - return Linux_dataspace_client(ds).fd().dst().socket; + Untyped_capability fd_cap = Linux_dataspace_client(ds).fd(); + return Capability_space::ipc_cap_data(fd_cap).dst.socket; } @@ -126,12 +129,13 @@ static unsigned long get_env_ulong(const char *key) static Parent_capability obtain_parent_cap() { - long local_name = get_env_ulong("parent_local_name"); + long const local_name = get_env_ulong("parent_local_name"); - /* produce typed capability manually */ - typedef Native_capability::Dst Dst; - Dst const dst(PARENT_SOCKET_HANDLE); - return reinterpret_cap_cast(Native_capability(dst, local_name)); + Untyped_capability parent_cap = + Capability_space::import(Rpc_destination(PARENT_SOCKET_HANDLE), + Rpc_obj_key(local_name)); + + return reinterpret_cap_cast(parent_cap); } @@ -178,8 +182,10 @@ namespace Genode { Thread *thread = Thread::myself(); if (thread) { - socket_pair.server_sd = native_cpu.server_sd(thread->cap()).dst().socket; - socket_pair.client_sd = native_cpu.client_sd(thread->cap()).dst().socket; + Untyped_capability server_cap = native_cpu.server_sd(thread->cap()); + Untyped_capability client_cap = native_cpu.client_sd(thread->cap()); + socket_pair.server_sd = Capability_space::ipc_cap_data(server_cap).dst.socket; + socket_pair.client_sd = Capability_space::ipc_cap_data(client_cap).dst.socket; thread->native_thread().socket_pair = socket_pair; } return socket_pair; diff --git a/repos/base-linux/src/lib/base/region_map_mmap.cc b/repos/base-linux/src/lib/base/region_map_mmap.cc index a8aba7b74..11e83ddf4 100644 --- a/repos/base-linux/src/lib/base/region_map_mmap.cc +++ b/repos/base-linux/src/lib/base/region_map_mmap.cc @@ -53,7 +53,7 @@ using namespace Genode; static bool is_sub_rm_session(Dataspace_capability ds) { - if (ds.valid()) + if (ds.valid() && !local(ds)) return false; return Local_capability::deref(ds) != 0; diff --git a/repos/base-nova/include/base/native_capability.h b/repos/base-nova/include/base/native_capability.h deleted file mode 100644 index 182185401..000000000 --- a/repos/base-nova/include/base/native_capability.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * \brief Platform-specific capability type - * \author Norman Feske - * \author Alexander Boettcher - * \date 2009-10-02 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ - -/* Genode includes */ -#include -#include -#include - -/* NOVA includes */ -#include - -namespace Genode { - - class Native_capability - { - public: - - typedef Nova::Obj_crd Dst; - - struct Raw { }; - - private: - - struct _Raw - { - Dst dst; - - _Raw() : dst() { } - - _Raw(addr_t sel, unsigned rights) - : dst(sel, 0, rights) { } - } _cap; - - addr_t _rcv_window; - - enum { INVALID_INDEX = ~0UL }; - - protected: - - inline void _inc() const - { - Cap_index idx(cap_map()->find(local_name())); - idx.inc(); - } - - inline void _dec() const - { - Cap_index idx(cap_map()->find(local_name())); - idx.dec(); - } - - public: - - /** - * Constructors - */ - - Native_capability() - : _cap(), _rcv_window(INVALID_INDEX) {} - - explicit - Native_capability(addr_t sel, unsigned rights = 0x1f) - { - if (sel == INVALID_INDEX) - _cap = _Raw(); - else { - _cap = _Raw(sel, rights); - _inc(); - } - - _rcv_window = INVALID_INDEX; - } - - Native_capability(const Native_capability &o) - : _cap(o._cap), _rcv_window(o._rcv_window) - { if (valid()) _inc(); } - - ~Native_capability() { if (valid()) _dec(); } - - /** - * Overloaded comparison operator - */ - bool operator==(const Native_capability &o) const { - return local_name() == o.local_name(); } - - /** - * Copy constructor - */ - Native_capability& operator= - (const Native_capability &o) - { - if (this == &o) - return *this; - - if (valid()) _dec(); - - _cap = o._cap; - _rcv_window = o._rcv_window; - - if (valid()) _inc(); - - return *this; - } - - /** - * Check whether the selector of the Native_cap and - * the capability type is valid. - */ - bool valid() const { return !_cap.dst.is_null(); } - - Dst dst() const { return _cap.dst; } - - /** - * Return the local_name. On NOVA it is the same as the - * destination value. - */ - addr_t local_name() const - { - if (valid()) - return _cap.dst.base(); - else - return INVALID_INDEX; - } - - /** - * Set one specific cap selector index as receive - * window for the next IPC. This can be used to make - * sure that the to be received mapped capability will - * be placed at a specific index. - */ - void rcv_window(addr_t rcv) { _rcv_window = rcv; } - - /** - * Return the selector of the rcv_window. - */ - addr_t rcv_window() const { return _rcv_window; } - - /** - * Return an invalid Dst object - */ - static Dst invalid() { return Dst(); } - - /** - * Return a invalid Native_capability - */ - static Native_capability invalid_cap() - { - return Native_capability(); - } - - Raw raw() const { return Raw(); } - }; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-nova/include/base/cap_map.h b/repos/base-nova/include/nova/cap_map.h similarity index 89% rename from repos/base-nova/include/base/cap_map.h rename to repos/base-nova/include/nova/cap_map.h index 3b5231b0b..67e8444b6 100644 --- a/repos/base-nova/include/base/cap_map.h +++ b/repos/base-nova/include/nova/cap_map.h @@ -3,6 +3,9 @@ * \author Alexander Boettcher * \date 2013-08-26 * + * This header is public to allow user-level VMMs to manually allocate windows + * of consecutive selectors (for virtualization event portals) in the + * component's capability space. */ /* @@ -12,8 +15,8 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__BASE__CAP_MAP_H_ -#define _INCLUDE__BASE__CAP_MAP_H_ +#ifndef _INCLUDE__NOVA__CAP_MAP_H_ +#define _INCLUDE__NOVA__CAP_MAP_H_ /* Genode includes */ #include @@ -126,4 +129,4 @@ namespace Genode { Capability_map *cap_map(); } -#endif /* _INCLUDE__BASE__CAP_MAP_H_ */ +#endif /* _INCLUDE__NOVA__CAP_MAP_H_ */ diff --git a/repos/base-nova/include/nova/capability_space.h b/repos/base-nova/include/nova/capability_space.h new file mode 100644 index 000000000..d498b1ee5 --- /dev/null +++ b/repos/base-nova/include/nova/capability_space.h @@ -0,0 +1,47 @@ +/* + * \brief Capability helper + * \author Norman Feske + * \date 2016-06-27 + */ + +/* + * 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__CAPABILITY_SPACE_H_ +#define _INCLUDE__NOVA__CAPABILITY_SPACE_H_ + +/* Genode includes */ +#include + +/* NOVA includes */ +#include + +namespace Genode { namespace Capability_space { + + enum { INVALID_INDEX = ~0UL }; + + typedef Nova::Crd Ipc_cap_data; + + static inline Nova::Crd crd(Native_capability const &cap) + { + /* + * We store the 'Nova::Crd' value in place of the 'Data' pointer. + */ + addr_t value = (addr_t)cap.data(); + Nova::Crd crd = *(Nova::Crd *)&value; + return crd; + } + + static inline Native_capability import(addr_t sel, unsigned rights = 0x1f) + { + Nova::Obj_crd const crd = (sel == INVALID_INDEX) + ? Nova::Obj_crd() : Nova::Obj_crd(sel, 0, rights); + return Native_capability(*(Native_capability::Data *)crd.value()); + } +} } + +#endif /* _INCLUDE__NOVA__CAPABILITY_SPACE_H_ */ diff --git a/repos/base-nova/include/nova/native_thread.h b/repos/base-nova/include/nova/native_thread.h index 83bf68466..520c44727 100644 --- a/repos/base-nova/include/nova/native_thread.h +++ b/repos/base-nova/include/nova/native_thread.h @@ -34,7 +34,23 @@ struct Genode::Native_thread addr_t initial_ip; /* initial IP of local thread */ /* receive window for capability selectors received at the server side */ - Receive_window rcv_window; + Receive_window server_rcv_window; + + /* + * Designated selector to populate with the result of an IPC call + * + * By default, the client-side receive window for delegated selectors + * is automatically allocated within the component's selector space. + * However, in special cases such as during the initialization of a + * user-level VMM (ports/include/vmm/vcpu_dispatcher.h), the targeted + * selector is defined manually. The 'client_rcv_sel' provides the + * hook for such a manual allocation. If it contains a valid selector + * value, the value is used as the basis of the receive window of an + * 'ipc_call'. + */ + addr_t client_rcv_sel = INVALID_INDEX; + + void reset_client_rcv_sel() { client_rcv_sel = INVALID_INDEX; } Native_capability pager_cap; diff --git a/repos/base-nova/include/nova/receive_window.h b/repos/base-nova/include/nova/receive_window.h index 3ce750904..5206fbef3 100644 --- a/repos/base-nova/include/nova/receive_window.h +++ b/repos/base-nova/include/nova/receive_window.h @@ -126,24 +126,12 @@ struct Genode::Receive_window /** * Return received portal-capability selector */ - void rcv_pt_sel(Native_capability &cap) - { - if (_rcv_pt_sel_cnt >= _rcv_pt_sel_max) { - cap = Native_capability(); - return; - } - - /* return only received or translated caps */ - cap = Native_capability(_rcv_pt_sel[_rcv_pt_sel_cnt++].sel); - } + void rcv_pt_sel(Native_capability &cap); /** * Return true if receive window must be re-initialized */ - bool rcv_invalid() const - { - return _rcv_pt_base == INVALID_INDEX; - } + bool rcv_invalid() const; unsigned num_received_caps() const { return _rcv_pt_sel_max; } @@ -167,56 +155,7 @@ struct Genode::Receive_window * \result 'true' - receive window must be re-initialized * 'false' - portal selectors has been kept */ - bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS) - { - /* mark used mapped capabilities as used to prevent freeing */ - bool reinit = false; - for (unsigned i = 0; i < _rcv_pt_sel_cnt; i++) { - if (!_rcv_pt_sel[i].del) - continue; - - /* should never happen */ - if (_rcv_pt_sel[i].sel < _rcv_pt_base || - (_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS)) - nova_die(); - - _rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP; - - reinit = true; - } - - /* if old receive window was smaller, we need to re-init */ - for (unsigned i = 0; !reinit && i < new_max; i++) - if (_rcv_pt_cap_free[i] == FREE_INVALID) - reinit = true; - - _rcv_pt_sel_cnt = 0; - _rcv_pt_sel_max = 0; - - /* we can keep the cap selectors if none was used */ - if (keep && !reinit) { - for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { - /* revoke received caps which are unused */ - if (_rcv_pt_cap_free[i] == UNUSED_CAP) - Nova::revoke(Nova::Obj_crd(_rcv_pt_base + i, 0), true); - - /* free rest of indexes if new_max is smaller then last window */ - if (i >= new_max && _rcv_pt_cap_free[i] == FREE_SEL) - cap_map()->remove(_rcv_pt_base + i, 0, false); - } - - return false; - } - - /* decrease ref count if valid selector */ - for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { - if (_rcv_pt_cap_free[i] == FREE_INVALID) - continue; - cap_map()->remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL); - } - - return true; - } + bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS); /** * Initialize receive window for portal capability @@ -234,39 +173,7 @@ struct Genode::Receive_window * fresh receive window and clears 'rcv_invalid'. */ bool prepare_rcv_window(Nova::Utcb &utcb, - addr_t rcv_window = INVALID_INDEX) - { - /* open maximal translate window */ - utcb.crd_xlt = Nova::Obj_crd(0, ~0UL); - - /* use receive window if specified */ - if (rcv_window != INVALID_INDEX) { - /* cleanup if receive window already used */ - if (!rcv_invalid()) rcv_cleanup(false); - - _rcv_pt_base = rcv_window; - - /* open receive window */ - utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); - return true; - } - - /* allocate receive window if necessary, otherwise use old one */ - if (rcv_invalid() || rcv_cleanup(true, 1U << _rcv_wnd_log2)) - { - _rcv_pt_base = cap_map()->insert(_rcv_wnd_log2); - - if (_rcv_pt_base == INVALID_INDEX) { - /* no mappings can be received */ - utcb.crd_rcv = Nova::Obj_crd(); - return false; - } - } - - /* open receive window */ - utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); - return true; - } + addr_t rcv_window = INVALID_INDEX); /** * Post IPC processing. diff --git a/repos/base-nova/include/signal_source/client.h b/repos/base-nova/include/signal_source/client.h index 26ebbbcbe..2a2662a6b 100644 --- a/repos/base-nova/include/signal_source/client.h +++ b/repos/base-nova/include/signal_source/client.h @@ -31,6 +31,7 @@ /* NOVA includes */ #include #include +#include namespace Genode { @@ -53,9 +54,9 @@ namespace Genode { { /* request mapping of semaphore capability selector */ Thread * myself = Thread::myself(); - request_signal_sm_cap(Native_capability(myself->native_thread().ec_sel + 1), + request_signal_sm_cap(Capability_space::import(myself->native_thread().ec_sel + 1), myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); - _sem = Native_capability(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); + _sem = Capability_space::import(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); call(_sem); } diff --git a/repos/base-nova/lib/mk/base-common.mk b/repos/base-nova/lib/mk/base-common.mk index 66b1c3cc9..3656e3a9e 100644 --- a/repos/base-nova/lib/mk/base-common.mk +++ b/repos/base-nova/lib/mk/base-common.mk @@ -12,3 +12,4 @@ SRC_CC += signal_submit.cc SRC_CC += thread.cc thread_myself.cc SRC_CC += stack.cc SRC_CC += cap_map.cc +SRC_CC += capability.cc diff --git a/repos/base-nova/lib/mk/core.inc b/repos/base-nova/lib/mk/core.inc new file mode 100644 index 000000000..1067180d5 --- /dev/null +++ b/repos/base-nova/lib/mk/core.inc @@ -0,0 +1,6 @@ +SRC_CC += pager.cc + +INC_DIR = $(REP_DIR)/src/core/include \ + $(BASE_DIR)/src/core/include \ + $(REP_DIR)/src/include \ + $(BASE_DIR)/src/include 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 827c104a4..2f6dfad37 100644 --- a/repos/base-nova/lib/mk/spec/x86_32/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_32/core.mk @@ -1,7 +1,3 @@ -SRC_CC += pager.cc - -INC_DIR = $(REP_DIR)/src/core/include \ - $(BASE_DIR)/src/core/include \ - $(BASE_DIR)/src/include +include $(REP_DIR)/lib/mk/core.inc vpath %.cc $(REP_DIR)/src/core/spec/x86_32 diff --git a/repos/base-nova/lib/mk/spec/x86_64/core.mk b/repos/base-nova/lib/mk/spec/x86_64/core.mk index d6fc61fbb..b51370fb7 100644 --- a/repos/base-nova/lib/mk/spec/x86_64/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_64/core.mk @@ -1,6 +1,3 @@ -SRC_CC += pager.cc - -INC_DIR = $(REP_DIR)/src/core/include \ - $(BASE_DIR)/src/include +include $(REP_DIR)/lib/mk/core.inc vpath %.cc $(REP_DIR)/src/core/spec/x86_64 diff --git a/repos/base-nova/src/core/include/imprint_badge.h b/repos/base-nova/src/core/include/imprint_badge.h index f574c540a..af338bc18 100644 --- a/repos/base-nova/src/core/include/imprint_badge.h +++ b/repos/base-nova/src/core/include/imprint_badge.h @@ -14,6 +14,9 @@ #ifndef _CORE__INCLUDE__IMPRINT_BADGE_H_ #define _CORE__INCLUDE__IMPRINT_BADGE_H_ +/* NOVA includes */ +#include + static inline bool imprint_badge(unsigned long pt_sel, unsigned long badge) { using namespace Nova; diff --git a/repos/base-nova/src/core/include/pager.h b/repos/base-nova/src/core/include/pager.h index e2052743e..9e67e5f84 100644 --- a/repos/base-nova/src/core/include/pager.h +++ b/repos/base-nova/src/core/include/pager.h @@ -21,6 +21,9 @@ #include #include +/* NOVA includes */ +#include + /* core-local includes */ #include #include diff --git a/repos/base-nova/src/core/include/signal_broker.h b/repos/base-nova/src/core/include/signal_broker.h index 8b6d0ecd5..72fce06e7 100644 --- a/repos/base-nova/src/core/include/signal_broker.h +++ b/repos/base-nova/src/core/include/signal_broker.h @@ -17,6 +17,9 @@ /* Genode includes */ #include +/* NOVA includes */ +#include + /* core-local includes */ #include #include @@ -85,7 +88,7 @@ class Genode::Signal_broker return Signal_context_capability(); } - Native_capability si(cap_map()->insert()); + Native_capability si = Capability_space::import(cap_map()->insert()); Signal_context_capability cap = reinterpret_cap_cast(si); uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint, diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index ebbf6ab0e..65508bb4d 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -29,6 +29,7 @@ /* NOVA includes */ #include #include /* map_local */ +#include static bool verbose_oom = false; @@ -126,7 +127,8 @@ void Pager_object::_page_fault_handler(addr_t pager_obj) ret); Native_capability pager_cap = obj->Object_pool::Entry::cap(); - revoke(pager_cap.dst()); + + revoke(Capability_space::crd(pager_cap).base()); revoke(Obj_crd(obj->exc_pt_sel_client(), NUM_INITIAL_PT_LOG2)); @@ -917,7 +919,8 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj) PWRN("invalid CPU parameter used in pager object"); return Pager_capability(); } - Native_capability pager_thread_cap(pager_threads[use_cpu]->native_thread().ec_sel); + Native_capability pager_thread_cap = + Capability_space::import(pager_threads[use_cpu]->native_thread().ec_sel); /* request creation of portal bind to pager thread */ Native_capability cap_session = @@ -946,7 +949,7 @@ void Pager_entrypoint::dissolve(Pager_object *obj) _cap_factory.free(pager_obj); /* revoke cap selector locally */ - revoke(pager_obj.dst(), true); + revoke(Capability_space::crd(pager_obj), true); /* remove object from pool */ remove(obj); diff --git a/repos/base-nova/src/core/platform_thread.cc b/repos/base-nova/src/core/platform_thread.cc index b3e7a2d32..0981d5f93 100644 --- a/repos/base-nova/src/core/platform_thread.cc +++ b/repos/base-nova/src/core/platform_thread.cc @@ -114,7 +114,8 @@ int Platform_thread::start(void *ip, void *sp) if (!vcpu()) { pd_utcb = stack_area_virtual_base() + stack_virtual_size() - get_page_size(); - addr_t remap_src[] = { _pd->parent_pt_sel(), _pager->Object_pool::Entry::cap().local_name() }; + addr_t remap_src[] = { _pd->parent_pt_sel(), + (unsigned long)_pager->Object_pool::Entry::cap().local_name() }; addr_t remap_dst[] = { PT_SEL_PARENT, PT_SEL_MAIN_PAGER }; /* remap exception portals for first thread */ diff --git a/repos/base-nova/src/core/rpc_cap_factory.cc b/repos/base-nova/src/core/rpc_cap_factory.cc index 68727371c..bd6cb4eee 100644 --- a/repos/base-nova/src/core/rpc_cap_factory.cc +++ b/repos/base-nova/src/core/rpc_cap_factory.cc @@ -15,6 +15,9 @@ #include #include +/* NOVA includes */ +#include + using namespace Genode; @@ -31,14 +34,14 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, add /* create cap object */ Cap_object * pt_cap = new (&_slab) Cap_object(pt_sel); if (!pt_cap) - return Native_capability::invalid_cap(); + return Native_capability(); _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); + return Capability_space::import(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); @@ -49,7 +52,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, add /* cleanup unused selectors */ cap_map()->remove(pt_sel, 0, false); - return Native_capability::invalid_cap(); + return Native_capability(); } @@ -60,7 +63,7 @@ void Rpc_cap_factory::free(Native_capability cap) Lock::Guard guard(_lock); for (Cap_object *obj = _list.first(); obj ; obj = obj->next()) { - if (cap.local_name() == obj->_cap_sel) { + if (cap.local_name() == (long)obj->_cap_sel) { Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); cap_map()->remove(obj->_cap_sel, 0, false); diff --git a/repos/base-nova/src/include/base/internal/ipc.h b/repos/base-nova/src/include/base/internal/ipc.h index 3b046d92d..d152f49d2 100644 --- a/repos/base-nova/src/include/base/internal/ipc.h +++ b/repos/base-nova/src/include/base/internal/ipc.h @@ -17,6 +17,7 @@ /* NOVA includes */ #include #include +#include /** * Copy message registers from UTCB to destination message buffer @@ -108,7 +109,7 @@ static inline bool copy_msgbuf_to_utcb(Nova::Utcb &utcb, for (unsigned i = 0; i < snd_msg.used_caps(); i++) { Native_capability const &cap = snd_msg.cap(i); - Nova::Obj_crd crd(cap.local_name(), 0, cap.dst().rights()); + Nova::Crd const crd = Capability_space::crd(cap); if (crd.base() == ~0UL) continue; diff --git a/repos/base-nova/src/include/base/internal/parent_cap.h b/repos/base-nova/src/include/base/internal/parent_cap.h index 8629eaceb..1513e193c 100644 --- a/repos/base-nova/src/include/base/internal/parent_cap.h +++ b/repos/base-nova/src/include/base/internal/parent_cap.h @@ -22,7 +22,7 @@ #include /* NOVA includes */ -#include +#include namespace Genode { @@ -30,7 +30,7 @@ namespace Genode { static inline Parent_capability parent_cap() { return reinterpret_cap_cast( - Native_capability(Nova::PT_SEL_PARENT)); + Capability_space::import(Nova::PT_SEL_PARENT)); } } diff --git a/repos/base-nova/src/lib/base/cap_map.cc b/repos/base-nova/src/lib/base/cap_map.cc index 6217eb6e9..b46a7da87 100644 --- a/repos/base-nova/src/lib/base/cap_map.cc +++ b/repos/base-nova/src/lib/base/cap_map.cc @@ -11,12 +11,12 @@ * under the terms of the GNU General Public License version 2. */ -#include - +/* Genode includes */ #include -/* base-nova specific include */ +/* NOVA includes */ #include +#include using namespace Genode; diff --git a/repos/base-nova/src/lib/base/capability.cc b/repos/base-nova/src/lib/base/capability.cc new file mode 100644 index 000000000..ca776beb9 --- /dev/null +++ b/repos/base-nova/src/lib/base/capability.cc @@ -0,0 +1,78 @@ +/* + * \brief Capability lifetime management + * \author Norman Feske + * \date 2015-05-06 + */ + +/* + * 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. + */ + +#include + +/* base-internal includes */ +#include + +/* NOVA includes */ +#include +#include + +using namespace Genode; + + +Native_capability::Native_capability() +{ + *this = Capability_space::import(Capability_space::INVALID_INDEX); +} + + +void Native_capability::_inc() +{ + Cap_index idx(cap_map()->find(local_name())); + idx.inc(); +} + + +void Native_capability::_dec() +{ + Cap_index idx(cap_map()->find(local_name())); + idx.dec(); +} + + +long Native_capability::local_name() const +{ + if (valid()) + return Capability_space::crd(*this).base(); + else + return Capability_space::INVALID_INDEX; +} + + +bool Native_capability::valid() const +{ + return _data != nullptr; +} + + +Native_capability::Raw Native_capability::raw() const +{ + return { 0, 0, 0, 0 }; +} + + +void Native_capability::print(Genode::Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + print(out, local_name()); + } else { + print(out, "invalid"); + } + print(out, ">"); +} diff --git a/repos/base-nova/src/lib/base/ipc.cc b/repos/base-nova/src/lib/base/ipc.cc index 6e9da3e6d..fa4894ca7 100644 --- a/repos/base-nova/src/lib/base/ipc.cc +++ b/repos/base-nova/src/lib/base/ipc.cc @@ -19,6 +19,9 @@ /* base-internal includes */ #include +/* NOVA includes */ +#include + using namespace Genode; @@ -43,7 +46,8 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, rcv_window.rcv_wnd(log2_max); } - Nova::Utcb &utcb = *(Nova::Utcb *)Thread::myself()->utcb(); + Thread * const myself = Thread::myself(); + Nova::Utcb &utcb = *(Nova::Utcb *)myself->utcb(); /* the protocol value is unused as the badge is delivered by the kernel */ if (!copy_msgbuf_to_utcb(utcb, snd_msg, 0)) { @@ -51,8 +55,15 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, throw Ipc_error(); } + /* + * Determine manually defined selector for receiving the call result. + * See the comment in 'base-nova/include/nova/native_thread.h'. + */ + addr_t const manual_rcv_sel = myself ? myself->native_thread().client_rcv_sel + : Receive_window::INVALID_INDEX; + /* if we can't setup receive window, die in order to recognize the issue */ - if (!rcv_window.prepare_rcv_window(utcb, dst.rcv_window())) + if (!rcv_window.prepare_rcv_window(utcb, manual_rcv_sel)) /* printf doesn't work here since for IPC also rcv_prepare* is used */ nova_die(); @@ -64,7 +75,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, utcb.set_msg_word(0); /* track potentially received caps and invalidate unused caps slots */ - rcv_window.post_ipc(utcb, dst.rcv_window()); + rcv_window.post_ipc(utcb, manual_rcv_sel); if (res != Nova::NOVA_OK) return Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT); @@ -75,3 +86,112 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, return Rpc_exception_code(copy_utcb_to_msgbuf(utcb, rcv_window, rcv_msg)); } + + +/******************** + ** Receive_window ** + ********************/ + +void Receive_window::rcv_pt_sel(Native_capability &cap) +{ + if (_rcv_pt_sel_cnt >= _rcv_pt_sel_max) { + cap = Native_capability(); + return; + } + + /* return only received or translated caps */ + cap = Capability_space::import(_rcv_pt_sel[_rcv_pt_sel_cnt++].sel); +} + + +bool Receive_window::rcv_invalid() const +{ + return _rcv_pt_base == Capability_space::INVALID_INDEX; +} + + +bool Receive_window::rcv_cleanup(bool keep, unsigned short const new_max) +{ + /* mark used mapped capabilities as used to prevent freeing */ + bool reinit = false; + for (unsigned i = 0; i < _rcv_pt_sel_cnt; i++) { + if (!_rcv_pt_sel[i].del) + continue; + + /* should never happen */ + if (_rcv_pt_sel[i].sel < _rcv_pt_base || + (_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS)) + nova_die(); + + _rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP; + + reinit = true; + } + + /* if old receive window was smaller, we need to re-init */ + for (unsigned i = 0; !reinit && i < new_max; i++) + if (_rcv_pt_cap_free[i] == FREE_INVALID) + reinit = true; + + _rcv_pt_sel_cnt = 0; + _rcv_pt_sel_max = 0; + + /* we can keep the cap selectors if none was used */ + if (keep && !reinit) { + for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { + /* revoke received caps which are unused */ + if (_rcv_pt_cap_free[i] == UNUSED_CAP) + Nova::revoke(Nova::Obj_crd(_rcv_pt_base + i, 0), true); + + /* free rest of indexes if new_max is smaller then last window */ + if (i >= new_max && _rcv_pt_cap_free[i] == FREE_SEL) + cap_map()->remove(_rcv_pt_base + i, 0, false); + } + + return false; + } + + /* decrease ref count if valid selector */ + for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { + if (_rcv_pt_cap_free[i] == FREE_INVALID) + continue; + cap_map()->remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL); + } + + return true; +} + + +bool Receive_window::prepare_rcv_window(Nova::Utcb &utcb, addr_t rcv_window) +{ + /* open maximal translate window */ + utcb.crd_xlt = Nova::Obj_crd(0, ~0UL); + + /* use receive window if specified */ + if (rcv_window != INVALID_INDEX) { + /* cleanup if receive window already used */ + if (!rcv_invalid()) rcv_cleanup(false); + + _rcv_pt_base = rcv_window; + + /* open receive window */ + utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); + return true; + } + + /* allocate receive window if necessary, otherwise use old one */ + if (rcv_invalid() || rcv_cleanup(true, 1U << _rcv_wnd_log2)) + { + _rcv_pt_base = cap_map()->insert(_rcv_wnd_log2); + + if (_rcv_pt_base == INVALID_INDEX) { + /* no mappings can be received */ + utcb.crd_rcv = Nova::Obj_crd(); + return false; + } + } + + /* open receive window */ + utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); + return true; +} diff --git a/repos/base-nova/src/lib/base/rpc_entrypoint.cc b/repos/base-nova/src/lib/base/rpc_entrypoint.cc index 8c79254ac..3407f0d2b 100644 --- a/repos/base-nova/src/lib/base/rpc_entrypoint.cc +++ b/repos/base-nova/src/lib/base/rpc_entrypoint.cc @@ -23,7 +23,6 @@ #include /* NOVA includes */ -#include #include #include @@ -42,7 +41,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) /* _ec_sel is invalid until thread gets started */ if (native_thread().ec_sel != Native_thread::INVALID_INDEX) - ec_cap = Native_capability(native_thread().ec_sel); + ec_cap = Capability_space::import(native_thread().ec_sel); else ec_cap = _thread_cap; @@ -127,7 +126,7 @@ void Rpc_entrypoint::_activation_entry() Rpc_entrypoint &ep = *static_cast(Thread::myself()); Nova::Utcb &utcb = *(Nova::Utcb *)Thread::myself()->utcb(); - Receive_window &rcv_window = ep.native_thread().rcv_window; + Receive_window &rcv_window = ep.native_thread().server_rcv_window; rcv_window.post_ipc(utcb); /* handle ill-formed message */ @@ -146,7 +145,7 @@ void Rpc_entrypoint::_activation_entry() Rpc_exception_code exc = Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT); /* in case of a portal cleanup call we are done here - just reply */ - if (ep._cap.local_name() == id_pt) { + if (ep._cap.local_name() == (long)id_pt) { if (!rcv_window.prepare_rcv_window(utcb)) PWRN("out of capability selectors for handling server requests"); @@ -224,12 +223,13 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, Thread::start(); /* create cleanup portal */ - _cap = _alloc_rpc_cap(_pd_session, Native_capability(native_thread().ec_sel), + _cap = _alloc_rpc_cap(_pd_session, + Capability_space::import(native_thread().ec_sel), (addr_t)_activation_entry); if (!_cap.valid()) throw Cpu_session::Thread_creation_failed(); - Receive_window &rcv_window = Thread::native_thread().rcv_window; + Receive_window &rcv_window = Thread::native_thread().server_rcv_window; /* prepare portal receive window of new thread */ if (!rcv_window.prepare_rcv_window(*(Nova::Utcb *)&_stack->utcb())) diff --git a/repos/base-nova/src/lib/base/signal_submit.cc b/repos/base-nova/src/lib/base/signal_submit.cc index 668615ff0..3c2df933d 100644 --- a/repos/base-nova/src/lib/base/signal_submit.cc +++ b/repos/base-nova/src/lib/base/signal_submit.cc @@ -16,6 +16,9 @@ #include #include +/* NOVA includes */ +#include + using namespace Genode; diff --git a/repos/base-nova/src/lib/base/stack.cc b/repos/base-nova/src/lib/base/stack.cc index 9e549d321..a768ce6e0 100644 --- a/repos/base-nova/src/lib/base/stack.cc +++ b/repos/base-nova/src/lib/base/stack.cc @@ -26,8 +26,8 @@ #include #include -/* base-nova includes */ -#include +/* NOVA includes */ +#include using namespace Genode; diff --git a/repos/base-nova/src/lib/base/thread_start.cc b/repos/base-nova/src/lib/base/thread_start.cc index ffcb6de30..cee4bec8a 100644 --- a/repos/base-nova/src/lib/base/thread_start.cc +++ b/repos/base-nova/src/lib/base/thread_start.cc @@ -29,6 +29,8 @@ /* NOVA includes */ #include #include +#include +#include using namespace Genode; @@ -80,7 +82,8 @@ void Thread::_init_platform_thread(size_t weight, Type type) if (type == MAIN || type == REINITIALIZED_MAIN) { _thread_cap = env()->parent()->main_thread_cap(); - Genode::Native_capability pager_cap(Nova::PT_SEL_MAIN_PAGER); + Genode::Native_capability pager_cap = + Capability_space::import(Nova::PT_SEL_MAIN_PAGER); native_thread().exc_pt_sel = 0; native_thread().ec_sel = Nova::PT_SEL_MAIN_EC; diff --git a/repos/base-nova/src/test/platform/ipc.cc b/repos/base-nova/src/test/platform/ipc.cc index c3a819e49..eb4967c6a 100644 --- a/repos/base-nova/src/test/platform/ipc.cc +++ b/repos/base-nova/src/test/platform/ipc.cc @@ -44,7 +44,7 @@ long Test::cap_void_manual(Genode::Native_capability dst, if (!arg1.valid()) return Genode::Rpc_exception_code::INVALID_OBJECT; - Nova::Obj_crd crd(arg1.local_name(), 0, arg1.dst().rights()); + Nova::Crd crd = Genode::Capability_space::crd(arg1); if (!utcb->append_item(crd, 0, false, false, false)) return Genode::Rpc_exception_code::INVALID_OBJECT; diff --git a/repos/base-nova/src/test/platform/main.cc b/repos/base-nova/src/test/platform/main.cc index f911ab658..c6d6d2e41 100644 --- a/repos/base-nova/src/test/platform/main.cc +++ b/repos/base-nova/src/test/platform/main.cc @@ -49,8 +49,8 @@ void test_translate() long rpc = Test::cap_void_manual(session_cap, session_cap, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == session_cap.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)session_cap.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("%s: ipc call failed %lx", __func__, rpc); @@ -58,12 +58,12 @@ void test_translate() return; } - Genode::Native_capability copy1(local_name); + Genode::Native_capability copy1 = Capability_space::import(local_name); rpc = Test::cap_void_manual(session_cap, copy1, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == copy1.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)copy1.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("%s: ipc call failed %lx", __func__, rpc); @@ -71,7 +71,7 @@ void test_translate() return; } - Genode::Native_capability copy2(local_name); + Genode::Native_capability copy2 = Capability_space::import(local_name); PINF("delegation session_cap->copy1->copy2 0x%lx->0x%lx->0x%lx", session_cap.local_name(), copy1.local_name(), copy2.local_name()); @@ -144,8 +144,8 @@ void test_revoke() long rpc = Test::cap_void_manual(session_cap, session_cap, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == session_cap.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)session_cap.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("test_revoke ipc call failed %lx", rpc); @@ -153,12 +153,12 @@ void test_revoke() return; } - Genode::Native_capability copy_session_cap(local_name); + Genode::Native_capability copy_session_cap = Capability_space::import(local_name); rpc = Test::cap_void_manual(copy_session_cap, copy_session_cap, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == copy_session_cap.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)copy_session_cap.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("test_revoke ipc call failed %lx", rpc); @@ -178,8 +178,8 @@ void test_revoke() Nova::Obj_crd crd_ses(copy_session_cap.local_name(), 0); res = Nova::lookup(crd_ses); - if (res != Nova::NOVA_OK || crd_ses.base() != copy_session_cap.local_name() || crd_ses.type() != 3 || - crd_ses.order() != 0) { + if (res != Nova::NOVA_OK || crd_ses.base() != (addr_t)copy_session_cap.local_name() + || crd_ses.type() != 3 || crd_ses.order() != 0) { failed ++; PERR("%u - lookup call failed err=%x is_null=%u", __LINE__, res, crd_ses.is_null()); ep.dissolve(&component); @@ -222,13 +222,13 @@ void test_revoke() * as used before by copy_session_cap */ Genode::Thread * myself = Genode::Thread::myself(); - Genode::Native_capability pager_cap(myself->native_thread().ec_sel + 1); + Genode::Native_capability pager_cap = Capability_space::import(myself->native_thread().ec_sel + 1); request_event_portal(pager_cap, copy_session_cap.local_name(), 0, 0); /* check whether the requested cap before is valid and placed well */ crd_ses = Nova::Obj_crd(copy_session_cap.local_name(), 0); res = Nova::lookup(crd_ses); - if (res != Nova::NOVA_OK || crd_ses.base() != copy_session_cap.local_name() || + if (res != Nova::NOVA_OK || crd_ses.base() != (addr_t)copy_session_cap.local_name() || crd_ses.type() != 3 || crd_ses.order() != 0) { failed ++; PERR("%u - lookup call failed err=%x is_null=%u", __LINE__, res, crd_ses.is_null()); diff --git a/repos/base-nova/src/test/platform/server.h b/repos/base-nova/src/test/platform/server.h index dfd0c87a3..45e283fbc 100644 --- a/repos/base-nova/src/test/platform/server.h +++ b/repos/base-nova/src/test/platform/server.h @@ -21,6 +21,10 @@ #include #include +/* NOVA includes */ +#include +#include + namespace Test { struct Session; struct Client; @@ -115,4 +119,4 @@ inline Genode::addr_t Test::Component::leak_utcb_address() { return reinterpret_cast(Genode::Thread::myself()->utcb()); } inline Genode::Native_capability Test::Component::cap_cap(Genode::addr_t cap) { - return Genode::Native_capability(cap); } + return Genode::Capability_space::import(cap); } diff --git a/repos/base-okl4/include/base/native_capability.h b/repos/base-okl4/include/base/native_capability.h deleted file mode 100644 index faa839f38..000000000 --- a/repos/base-okl4/include/base/native_capability.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * \brief Native capability type - * \author Norman Feske - * \date 2008-07-26 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include -#include - -namespace Okl4 { extern "C" { -#include -} } - -namespace Genode { - - struct Cap_dst_policy - { - typedef Okl4::L4_ThreadId_t Dst; - static bool valid(Dst tid) { return !Okl4::L4_IsNilThread(tid); } - static Dst invalid() { return Okl4::L4_nilthread; } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-okl4/include/base/thread_state.h b/repos/base-okl4/include/base/thread_state.h deleted file mode 100644 index ecbe2c0e5..000000000 --- a/repos/base-okl4/include/base/thread_state.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * \brief Thread state - * \author Stefan Kalkowski - * \date 2007-07-30 - * - * This file contains the OKL4 specific part of the thread state. - */ - -/* - * Copyright (C) 2007-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__BASE__THREAD_STATE_H_ -#define _INCLUDE__BASE__THREAD_STATE_H_ - -namespace Okl4 { extern "C" { -#include -} } - -#include - -namespace Genode { - - struct Thread_state : Thread_state_base - { - Okl4::L4_ThreadId_t tid; /* OKL4 specific thread id */ - }; -} - -#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */ diff --git a/repos/base-okl4/lib/mk/base-common.mk b/repos/base-okl4/lib/mk/base-common.mk index 256326a15..9d03d7f92 100644 --- a/repos/base-okl4/lib/mk/base-common.mk +++ b/repos/base-okl4/lib/mk/base-common.mk @@ -8,9 +8,7 @@ include $(BASE_DIR)/lib/mk/base-common.inc LIBS += startup -SRC_CC += cap_copy.cc +SRC_CC += capability.cc capability_raw.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc - -vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-okl4/lib/mk/base.mk b/repos/base-okl4/lib/mk/base.mk index a32c7ebd7..eec5dc939 100644 --- a/repos/base-okl4/lib/mk/base.mk +++ b/repos/base-okl4/lib/mk/base.mk @@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc SRC_CC += thread_start.cc SRC_CC += cache.cc +SRC_CC += capability_space.cc diff --git a/repos/base-okl4/src/core/include/rpc_cap_factory.h b/repos/base-okl4/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-okl4/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-okl4/src/core/pager.cc b/repos/base-okl4/src/core/pager.cc index 3df81be42..defdfef66 100644 --- a/repos/base-okl4/src/core/pager.cc +++ b/repos/base-okl4/src/core/pager.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include #include +#include namespace Okl4 { extern "C" { #include @@ -156,5 +157,5 @@ void Ipc_pager::acknowledge_wakeup() Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge) { - return Untyped_capability(native_thread().l4id, badge); + return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge)); } diff --git a/repos/base-okl4/src/core/pager_object.cc b/repos/base-okl4/src/core/pager_object.cc index bb3adab87..da81e6684 100644 --- a/repos/base-okl4/src/core/pager_object.cc +++ b/repos/base-okl4/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* OKL4 includes */ namespace Okl4 { extern "C" { #include @@ -40,7 +43,7 @@ void Pager_object::wake_up() L4_LoadMR(1, 0); /* fault address */ L4_LoadMR(2, (unsigned long)this); /* instruction pointer */ - L4_Call(cap().dst()); + L4_Call(Capability_space::ipc_cap_data(cap()).dst); } diff --git a/repos/base-okl4/src/core/platform_thread.cc b/repos/base-okl4/src/core/platform_thread.cc index 1a96061a3..a3168e01a 100644 --- a/repos/base-okl4/src/core/platform_thread.cc +++ b/repos/base-okl4/src/core/platform_thread.cc @@ -24,6 +24,9 @@ #include #include +/* base-internal includes */ +#include + /* OKL4 includes */ namespace Okl4 { extern "C" { #include @@ -50,7 +53,11 @@ int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no) _thread_id); L4_SpaceId_t space_id = L4_SpaceId(space_no); L4_ThreadId_t scheduler = L4_rootserver; - L4_ThreadId_t pager = _pager ? _pager->cap().dst() : L4_nilthread; + + L4_ThreadId_t pager = _pager + ? Capability_space::ipc_cap_data(_pager->cap()).dst + : L4_nilthread; + L4_ThreadId_t exception_handler = pager; L4_Word_t resources = 0; L4_Word_t utcb_size_per_task = L4_GetUtcbSize()*(1 << Thread_id_bits::THREAD); diff --git a/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc b/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc index 2bf59faed..fdcd6728b 100644 --- a/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc +++ b/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc @@ -26,7 +26,6 @@ using namespace Okl4; Thread_state Platform_thread::state() { Thread_state s; - s.tid = _l4_thread_id; L4_Copy_regs_to_mrs(_l4_thread_id); diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc index b1c4111e1..df81d3e48 100644 --- a/repos/base-okl4/src/core/target.inc +++ b/repos/base-okl4/src/core/target.inc @@ -12,6 +12,7 @@ SRC_CC += stack_area.cc \ cpu_session_component.cc \ cpu_session_support.cc \ cpu_thread_component.cc \ + capability_space.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -25,7 +26,7 @@ SRC_CC += stack_area.cc \ pd_session_component.cc \ pd_upgrade_ram_quota.cc \ pd_assign_pci.cc \ - rpc_cap_factory.cc \ + rpc_cap_factory_l4.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ @@ -50,10 +51,11 @@ vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.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 region_map_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) diff --git a/repos/base-okl4/src/include/base/internal/parent_cap.h b/repos/base-okl4/src/include/base/internal/parent_cap.h new file mode 100644 index 000000000..d8fa0a4f7 --- /dev/null +++ b/repos/base-okl4/src/include/base/internal/parent_cap.h @@ -0,0 +1,40 @@ +/* + * \brief Interface to obtain the parent capability for the component + * \author Norman Feske + * \date 2015-05-12 + */ + +/* + * Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_ +#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include +#include + + +namespace Genode { + + static inline Parent_capability parent_cap() + { + Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap; + + Okl4::L4_ThreadId_t tid; + tid.raw = raw.v[0]; + + Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1])); + + return reinterpret_cap_cast(cap); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */ diff --git a/repos/base-okl4/src/include/base/internal/rpc_destination.h b/repos/base-okl4/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..19a5be466 --- /dev/null +++ b/repos/base-okl4/src/include/base/internal/rpc_destination.h @@ -0,0 +1,39 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +/* OKL4 includes */ +namespace Okl4 { +#include +} + +namespace Genode { + + typedef Okl4::L4_ThreadId_t Rpc_destination; + + static inline Rpc_destination invalid_rpc_destination() + { + Okl4::L4_ThreadId_t tid; + tid.raw = 0; + return tid; + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "tid=", Hex(dst.raw)); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-okl4/src/lib/base/capability_raw.cc b/repos/base-okl4/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..90222e4dc --- /dev/null +++ b/repos/base-okl4/src/lib/base/capability_raw.cc @@ -0,0 +1,28 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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 + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(*this); + + return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } }; +} diff --git a/repos/base-okl4/src/lib/base/ipc.cc b/repos/base-okl4/src/lib/base/ipc.cc index a846afaa4..ba192dd78 100644 --- a/repos/base-okl4/src/lib/base/ipc.cc +++ b/repos/base-okl4/src/lib/base/ipc.cc @@ -13,40 +13,26 @@ /* Genode includes */ #include +#include #include #include /* base-internal includes */ #include #include +#include /* OKL4 includes */ namespace Okl4 { extern "C" { #include #include #include -#include } } using namespace Genode; using namespace Okl4; -/*************** - ** Utilities ** - ***************/ - -/** - * Print string, bypassing Genode's LOG mechanism - * - * This function is used in conditions where Genode's base mechanisms may fail. - */ -static void kdb_emergency_print(const char *s) -{ - for (; s && *s; s++) - Okl4::L4_KDB_PrintChar(*s); -} - /* * Message layout within the UTCB * @@ -85,7 +71,18 @@ static L4_Word_t extract_msg_from_utcb(L4_MsgTag_t rcv_tag, Msgbuf_base &rcv_msg L4_ThreadId_t tid; L4_StoreMR(3 + 2*i, &tid.raw); L4_StoreMR(3 + 2*i + 1, &local_name); - rcv_msg.insert(Native_capability(tid, local_name)); + + Rpc_obj_key const rpc_obj_key(local_name); + bool const cap_valid = tid.raw != 0UL; + + Native_capability cap; + if (cap_valid) { + cap = Capability_space::lookup(rpc_obj_key); + if (!cap.valid()) + cap = Capability_space::import(tid, rpc_obj_key); + } + + rcv_msg.insert(cap); } unsigned const data_start_idx = 3 + 2*num_caps; @@ -120,7 +117,7 @@ static void copy_msg_to_utcb(Msgbuf_base const &snd_msg, L4_Word_t local_name) unsigned const num_msg_words = num_data_words + num_header_words; if (num_msg_words >= L4_GetMessageRegisters()) { - kdb_emergency_print("Message does not fit into UTCB message registers\n"); + raw("Message does not fit into UTCB message registers"); L4_LoadMR(0, 0); return; } @@ -134,8 +131,19 @@ static void copy_msg_to_utcb(Msgbuf_base const &snd_msg, L4_Word_t local_name) L4_LoadMR(2, snd_msg.used_caps()); for (unsigned i = 0; i < snd_msg.used_caps(); i++) { - L4_LoadMR(3 + i*2, snd_msg.cap(i).dst().raw); - L4_LoadMR(3 + i*2 + 1, snd_msg.cap(i).local_name()); + + Native_capability cap = snd_msg.cap(i); + if (cap.valid()) { + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(snd_msg.cap(i)); + + L4_LoadMR(3 + i*2, (L4_Word_t)cap_data.dst.raw); + L4_LoadMR(3 + i*2 + 1, (L4_Word_t)cap_data.rpc_obj_key.value()); + } else { + L4_LoadMR(3 + i*2, (L4_Word_t)0UL); + L4_LoadMR(3 + i*2 + 1, (L4_Word_t)0UL); + } + } L4_LoadMRs(num_header_words, num_data_words, (L4_Word_t *)snd_msg.data()); @@ -150,12 +158,15 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, size_t) { + Capability_space::Ipc_cap_data const dst_data = + Capability_space::ipc_cap_data(dst); + /* copy call message to the UTCBs message registers */ - copy_msg_to_utcb(snd_msg, dst.local_name()); + copy_msg_to_utcb(snd_msg, dst_data.rpc_obj_key.value()); L4_Accept(L4_UntypedWordsAcceptor); - L4_MsgTag_t rcv_tag = L4_Call(dst.dst()); + L4_MsgTag_t rcv_tag = L4_Call(dst_data.dst); enum { ERROR_MASK = 0xe, ERROR_CANCELED = 3 << 1 }; if (L4_IpcFailed(rcv_tag) && @@ -163,7 +174,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, throw Genode::Blocking_canceled(); if (L4_IpcFailed(rcv_tag)) { - kdb_emergency_print("Ipc failed\n"); + raw("Ipc failed"); return Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT); } @@ -183,7 +194,7 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, copy_msg_to_utcb(snd_msg, exc.value); /* perform non-blocking IPC send operation */ - L4_MsgTag_t rcv_tag = L4_Reply(caller.dst()); + L4_MsgTag_t rcv_tag = L4_Reply(Capability_space::ipc_cap_data(caller).dst); if (L4_IpcFailed(rcv_tag)) PERR("ipc error in _reply - gets ignored"); @@ -204,7 +215,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, /* copy reply to the UTCBs message registers */ copy_msg_to_utcb(reply_msg, exc.value); - rcv_tag = L4_ReplyWait(last_caller.dst(), &caller); + rcv_tag = L4_ReplyWait(Capability_space::ipc_cap_data(last_caller).dst, + &caller); } else { rcv_tag = L4_Wait(&caller); } @@ -212,7 +224,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, /* copy request message from the UTCBs message registers */ unsigned long const badge = extract_msg_from_utcb(rcv_tag, request_msg); - return Rpc_request(Native_capability(caller, 0), badge); + return Rpc_request(Capability_space::import(caller, Rpc_obj_key()), badge); } @@ -231,7 +243,10 @@ static inline Okl4::L4_ThreadId_t thread_get_my_global_id() } -Ipc_server::Ipc_server() : Native_capability(thread_get_my_global_id(), 0) { } +Ipc_server::Ipc_server() +: + Native_capability(Capability_space::import(thread_get_my_global_id(), Rpc_obj_key())) +{ } Ipc_server::~Ipc_server() { } diff --git a/repos/base-pistachio/include/base/native_capability.h b/repos/base-pistachio/include/base/native_capability.h deleted file mode 100644 index 8bec3c24f..000000000 --- a/repos/base-pistachio/include/base/native_capability.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * \brief Native capability type on Pistachio - * \author Norman Feske - * \date 2008-07-26 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include -#include - -namespace Pistachio { -#include -} - -namespace Genode { - - struct Cap_dst_policy - { - typedef Pistachio::L4_ThreadId_t Dst; - static bool valid(Dst tid) { return !Pistachio::L4_IsNilThread(tid); } - static Dst invalid() - { - using namespace Pistachio; - return L4_nilthread; - } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-pistachio/lib/mk/base-common.mk b/repos/base-pistachio/lib/mk/base-common.mk index 6730a5da9..28a975ee3 100644 --- a/repos/base-pistachio/lib/mk/base-common.mk +++ b/repos/base-pistachio/lib/mk/base-common.mk @@ -8,12 +8,10 @@ include $(BASE_DIR)/lib/mk/base-common.inc LIBS += startup syscall -SRC_CC += cap_copy.cc +SRC_CC += capability.cc capability_raw.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc # suppress warning caused by Pistachio's 'l4/message.h' CC_WARN += -Wno-array-bounds - -vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-pistachio/lib/mk/base.mk b/repos/base-pistachio/lib/mk/base.mk index a32c7ebd7..eec5dc939 100644 --- a/repos/base-pistachio/lib/mk/base.mk +++ b/repos/base-pistachio/lib/mk/base.mk @@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc SRC_CC += thread_start.cc SRC_CC += cache.cc +SRC_CC += capability_space.cc diff --git a/repos/base-pistachio/src/core/include/rpc_cap_factory.h b/repos/base-pistachio/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-pistachio/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-pistachio/src/core/pager.cc b/repos/base-pistachio/src/core/pager.cc index cfeb6d204..ec0a810cb 100644 --- a/repos/base-pistachio/src/core/pager.cc +++ b/repos/base-pistachio/src/core/pager.cc @@ -17,8 +17,9 @@ /* base-internal includes */ #include +#include -/* Core includes */ +/* core includes */ #include #include @@ -142,5 +143,5 @@ void Ipc_pager::acknowledge_wakeup() Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge) { - return Untyped_capability(native_thread().l4id, badge); + return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge)); } diff --git a/repos/base-pistachio/src/core/pager_object.cc b/repos/base-pistachio/src/core/pager_object.cc index 0165684d5..b925a1588 100644 --- a/repos/base-pistachio/src/core/pager_object.cc +++ b/repos/base-pistachio/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Pistachio includes */ namespace Pistachio { #include @@ -40,7 +43,7 @@ void Pager_object::wake_up() L4_LoadMR(1, 0); /* fault address */ L4_LoadMR(2, (unsigned long)this); /* instruction pointer */ - L4_Call(cap().dst()); + L4_Call(Capability_space::ipc_cap_data(cap()).dst); } diff --git a/repos/base-pistachio/src/core/platform.cc b/repos/base-pistachio/src/core/platform.cc index b5ec20ea5..23cab3cfb 100644 --- a/repos/base-pistachio/src/core/platform.cc +++ b/repos/base-pistachio/src/core/platform.cc @@ -21,6 +21,7 @@ /* base-internal includes */ #include #include +#include /* core includes */ #include @@ -206,7 +207,7 @@ Platform::Sigma0::Sigma0() : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { - cap(Native_capability(Pistachio::get_sigma0(), 0)); + cap(Capability_space::import(Pistachio::get_sigma0(), Rpc_obj_key())); } @@ -225,7 +226,7 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd) Platform_thread::pager(sigma0()); core_pd->bind_thread(this); - cap(Native_capability(native_thread_id(), 0)); + cap(Capability_space::import(native_thread_id(), Rpc_obj_key())); /* stack begins at the top end of the '_core_pager_stack' array */ void *sp = (void *)&_core_pager_stack[PAGER_STACK_ELEMENTS - 1]; diff --git a/repos/base-pistachio/src/core/platform_thread.cc b/repos/base-pistachio/src/core/platform_thread.cc index d34bbc64a..084c4d462 100644 --- a/repos/base-pistachio/src/core/platform_thread.cc +++ b/repos/base-pistachio/src/core/platform_thread.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + /* core includes */ #include #include @@ -64,7 +67,9 @@ Affinity::Location Platform_thread::affinity() const int Platform_thread::start(void *ip, void *sp) { L4_ThreadId_t thread = _l4_thread_id; - L4_ThreadId_t pager = _pager ? _pager->cap().dst() : L4_nilthread; + L4_ThreadId_t pager = _pager + ? Capability_space::ipc_cap_data(_pager->cap()).dst + : L4_nilthread; /* XXX should always be the root task */ L4_ThreadId_t preempter = L4_Myself(); diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index ff81129f6..91bd4edc8 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -11,6 +11,7 @@ SRC_CC = stack_area.cc \ cpu_session_component.cc \ cpu_session_platform.cc \ cpu_thread_component.cc \ + capability_space.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -21,7 +22,7 @@ SRC_CC = stack_area.cc \ main.cc \ multiboot_info.cc \ pd_session_component.cc \ - rpc_cap_factory.cc \ + rpc_cap_factory_l4.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ pager.cc \ @@ -52,10 +53,11 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_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 region_map_component.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/src/include/base/internal/parent_cap.h b/repos/base-pistachio/src/include/base/internal/parent_cap.h new file mode 100644 index 000000000..913e3c6fb --- /dev/null +++ b/repos/base-pistachio/src/include/base/internal/parent_cap.h @@ -0,0 +1,40 @@ +/* + * \brief Interface to obtain the parent capability for the component + * \author Norman Feske + * \date 2015-05-12 + */ + +/* + * Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_ +#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include +#include + + +namespace Genode { + + static inline Parent_capability parent_cap() + { + Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap; + + Pistachio::L4_ThreadId_t tid; + tid.raw = raw.v[0]; + + Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1])); + + return reinterpret_cap_cast(cap); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */ diff --git a/repos/base-pistachio/src/include/base/internal/rpc_destination.h b/repos/base-pistachio/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..d69fa1601 --- /dev/null +++ b/repos/base-pistachio/src/include/base/internal/rpc_destination.h @@ -0,0 +1,39 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +/* Pistachio includes */ +namespace Pistachio { +#include +} + +namespace Genode { + + typedef Pistachio::L4_ThreadId_t Rpc_destination; + + static inline Rpc_destination invalid_rpc_destination() + { + Pistachio::L4_ThreadId_t tid; + tid.raw = 0; + return tid; + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "tid=", Hex(dst.raw)); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-pistachio/src/lib/base/capability_raw.cc b/repos/base-pistachio/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..90222e4dc --- /dev/null +++ b/repos/base-pistachio/src/lib/base/capability_raw.cc @@ -0,0 +1,28 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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 + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(*this); + + return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } }; +} diff --git a/repos/base-pistachio/src/lib/base/ipc.cc b/repos/base-pistachio/src/lib/base/ipc.cc index ae07e5c8b..414321ab7 100644 --- a/repos/base-pistachio/src/lib/base/ipc.cc +++ b/repos/base-pistachio/src/lib/base/ipc.cc @@ -13,39 +13,24 @@ */ /* Genode includes */ -#include +#include #include #include #include /* base-internal includes */ #include +#include /* Pistachio includes */ namespace Pistachio { #include #include -#include } using namespace Genode; using namespace Pistachio; -#define VERBOSE_IPC 0 -#if VERBOSE_IPC - -/* Just a printf wrapper for now. */ -#define IPCDEBUG(msg, ...) { \ - if (L4_Myself().raw == 0xf4001) { \ - (void)printf("IPC (thread = 0x%x) " msg, \ - L4_ThreadNo(Pistachio::L4_Myself()) \ - , ##__VA_ARGS__); \ - } else {} -} -#else -#define IPCDEBUG(...) -#endif - /** * Assert that we got 1 untyped word and 2 typed words @@ -64,13 +49,13 @@ static inline void check_ipc_result(L4_MsgTag_t result, L4_Word_t error_code) * Provide diagnostic information on unexpected conditions */ if (L4_IpcFailed(result)) { - PERR("Error in thread %08lx. IPC failed.", L4_Myself().raw); + raw("Error in thread ", Hex(L4_Myself().raw), ". IPC failed."); throw Genode::Ipc_error(); } if (L4_UntypedWords(result) < 2) { - PERR("Error in thread %08lx. Expected at leat two untyped words, but got %lu.\n", - L4_Myself().raw, L4_UntypedWords(result)); + raw("Error in thread ", Hex(L4_Myself().raw), ". " + "Expected at leat two untyped words, but got ", L4_UntypedWords(result), ".\n"); throw Genode::Ipc_error(); } } @@ -90,9 +75,21 @@ static void extract_caps(L4_Msg_t &msg, Msgbuf_base &rcv_msg) L4_ThreadId_t tid; tid.raw = L4_Get(&msg, 2 + i*2); - L4_Word_t const local_name = L4_Get(&msg, 2 + i*2 + 1); + Rpc_obj_key const rpc_obj_key(L4_Get(&msg, 2 + i*2 + 1)); - rcv_msg.insert(Native_capability(tid, local_name)); + bool const cap_valid = tid.raw != 0UL; + + Native_capability cap; + + if (cap_valid) { + + cap = Capability_space::lookup(rpc_obj_key); + + if (!cap.valid()) + cap = Capability_space::import(tid, rpc_obj_key); + } + + rcv_msg.insert(cap); } } @@ -109,8 +106,19 @@ static void prepare_send(L4_Word_t protocol_value, L4_Msg_t &msg, L4_Append(&msg, (L4_Word_t)snd_msg.used_caps()); for (unsigned i = 0; i < snd_msg.used_caps(); i++) { - L4_Append(&msg, (L4_Word_t)snd_msg.cap(i).dst().raw); - L4_Append(&msg, (L4_Word_t)snd_msg.cap(i).local_name()); + + Native_capability cap = snd_msg.cap(i); + + if (cap.valid()) { + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(snd_msg.cap(i)); + + L4_Append(&msg, (L4_Word_t)cap_data.dst.raw); + L4_Append(&msg, (L4_Word_t)cap_data.rpc_obj_key.value()); + } else { + L4_Append(&msg, (L4_Word_t)0UL); + L4_Append(&msg, (L4_Word_t)0UL); + } } L4_Append(&msg, L4_StringItem(snd_msg.data_size(), snd_msg.data())); @@ -139,11 +147,14 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, L4_MsgBuffer_t msgbuf; prepare_receive(msgbuf, rcv_msg); + Capability_space::Ipc_cap_data const dst_data = + Capability_space::ipc_cap_data(dst); + /* prepare sending parameters */ L4_Msg_t msg; - prepare_send(dst.local_name(), msg, snd_msg); + prepare_send(dst_data.rpc_obj_key.value(), msg, snd_msg); - L4_MsgTag_t result = L4_Call(dst.dst()); + L4_MsgTag_t result = L4_Call(dst_data.dst); L4_Clear(&msg); L4_Store(result, &msg); @@ -166,9 +177,9 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, L4_Msg_t msg; prepare_send(exc.value, msg, snd_msg); - L4_MsgTag_t result = L4_Reply(caller.dst()); + L4_MsgTag_t result = L4_Reply(Capability_space::ipc_cap_data(caller).dst); if (L4_IpcFailed(result)) - PERR("ipc error in _reply, ignored"); + raw("ipc error in _reply, ignored"); snd_msg.reset(); } @@ -198,7 +209,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, prepare_send(exc.value, reply_l4_msg, reply_msg); /* send reply and wait for new request message */ - request_tag = L4_Ipc(last_caller.dst(), L4_anythread, + request_tag = L4_Ipc(Capability_space::ipc_cap_data(last_caller).dst, + L4_anythread, L4_Timeouts(L4_ZeroTime, L4_Never), &caller); if (!L4_IpcFailed(request_tag)) @@ -221,11 +233,14 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, extract_caps(msg, request_msg); unsigned long const badge = L4_Get(&msg, 0); - return Rpc_request(Native_capability(caller, 0), badge); + return Rpc_request(Capability_space::import(caller, Rpc_obj_key()), badge); } -Ipc_server::Ipc_server() : Native_capability(Pistachio::L4_Myself(), 0) { } +Ipc_server::Ipc_server() +: + Native_capability(Capability_space::import(Pistachio::L4_Myself(), Rpc_obj_key())) +{ } Ipc_server::~Ipc_server() { } diff --git a/repos/base-sel4/include/base/native_capability.h b/repos/base-sel4/include/base/native_capability.h deleted file mode 100644 index 3b27cb70f..000000000 --- a/repos/base-sel4/include/base/native_capability.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * \brief Platform-specific capability type - * \author Norman Feske - * \date 2014-10-14 - */ - -/* - * Copyright (C) 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include - -namespace Genode { - - class Native_capability - { - public: - - /* - * Platform-specific raw information of the capability that is - * transferred as-is when the capability is delegated. - */ - struct Raw { long v[4]; }; - - /** - * Forward declaration of the platform-specific internal capability - * representation - */ - class Data; - - private: - - Data *_data = nullptr; - - protected: - - void _inc(); - void _dec(); - - public: - - /** - * Default constructor creates an invalid capability - */ - Native_capability() { } - - /** - * Copy constructor - */ - Native_capability(const Native_capability &other) - : _data(other._data) { _inc(); } - - /** - * Construct capability manually - * - * This constructor is used internally. - * - * \noapi - */ - Native_capability(Data &data) : _data(&data) { _inc(); } - - /** - * Destructor - */ - ~Native_capability() { _dec(); } - - Data const *data() const { return _data; } - - /** - * Overloaded comparision operator - */ - bool operator == (const Native_capability &o) const - { - return _data == o._data; - } - - Native_capability& operator = (const Native_capability &o) - { - if (this == &o) - return *this; - - _dec(); - _data = o._data; - _inc(); - return *this; - } - - long local_name() const; - - bool valid() const; - - Raw raw() const { return { { 0, 0, 0, 0 } }; } - }; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-sel4/lib/mk/base-common.inc b/repos/base-sel4/lib/mk/base-common.inc index 4a23a090c..3bf9e2a48 100644 --- a/repos/base-sel4/lib/mk/base-common.inc +++ b/repos/base-sel4/lib/mk/base-common.inc @@ -11,4 +11,4 @@ LIBS += startup syscall SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_myself.cc thread_bootstrap.cc -SRC_CC += capability.cc +SRC_CC += capability.cc capability_raw.cc diff --git a/repos/base-sel4/src/include/base/internal/capability_space_sel4.h b/repos/base-sel4/src/include/base/internal/capability_space_sel4.h index 83a59e88e..bad118067 100644 --- a/repos/base-sel4/src/include/base/internal/capability_space_sel4.h +++ b/repos/base-sel4/src/include/base/internal/capability_space_sel4.h @@ -37,6 +37,8 @@ namespace Genode { explicit Cap_sel(addr_t value) : _value(value) { } addr_t value() const { return _value; } + + void print(Output &out) const { Genode::print(out, "sel=", _value); } }; } @@ -56,6 +58,8 @@ namespace Genode { namespace Capability_space { Ipc_cap_data(Rpc_obj_key rpc_obj_key, unsigned sel) : rpc_obj_key(rpc_obj_key), sel(sel) { } + + void print(Output &out) const { Genode::print(out, sel, ",", rpc_obj_key); } }; /** @@ -111,7 +115,7 @@ namespace Genode * First, core must keep track of all capabilities of the system. Hence, its * capability space must be dimensioned larger. * - * Second, core has to maintain the information about the CAP session that + * Second, core has to maintain the information about the PD session that * was used to allocate the capability to prevent misbehaving clients from * freeing capabilities allocated from another component. This information * is part of the core-specific 'Native_capability::Data' structure. @@ -251,6 +255,11 @@ class Genode::Capability_space_sel4 return data.rpc_obj_key(); } + void print(Output &out, Data const &data) const + { + ipc_cap_data(data).print(out); + } + Capability_space::Ipc_cap_data ipc_cap_data(Data const &data) const { return { rpc_obj_key(data), sel(data) }; diff --git a/repos/base-sel4/src/lib/base/capability_raw.cc b/repos/base-sel4/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..4189764af --- /dev/null +++ b/repos/base-sel4/src/lib/base/capability_raw.cc @@ -0,0 +1,25 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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 + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + /* + * On seL4, there is no raw data representation of capabilities. + */ + return { { 0, 0, 0, 0 } }; +} diff --git a/repos/base-sel4/src/lib/base/capability_space.cc b/repos/base-sel4/src/lib/base/capability_space.cc index c2d3fe7a3..ee056fa47 100644 --- a/repos/base-sel4/src/lib/base/capability_space.cc +++ b/repos/base-sel4/src/lib/base/capability_space.cc @@ -122,6 +122,12 @@ Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data) } +void Capability_space::print(Output &out, Native_capability::Data const &data) +{ + return local_capability_space().print(out, data); +} + + Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap) { return local_capability_space().ipc_cap_data(*cap.data()); diff --git a/repos/base/include/base/native_capability.h b/repos/base/include/base/native_capability.h new file mode 100644 index 000000000..5e02a15e8 --- /dev/null +++ b/repos/base/include/base/native_capability.h @@ -0,0 +1,105 @@ +/* + * \brief Capability type + * \author Norman Feske + * \date 2016-07-15 + */ + +/* + * 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__BASE__NATIVE_CAPABILITY_H_ +#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ + +#include +#include + +namespace Genode { class Native_capability; } + + +class Genode::Native_capability +{ + public: + + /* + * Platform-specific raw information of the capability that is + * transferred as-is when the capability is delegated. + */ + struct Raw { unsigned long v[4]; }; + + /** + * Forward declaration of the platform-specific internal capability + * representation + */ + class Data; + + private: + + Data *_data = nullptr; + + protected: + + void _inc(); + void _dec(); + + public: + + /** + * Default constructor creates an invalid capability + */ + Native_capability(); + + /** + * Copy constructor + */ + Native_capability(const Native_capability &other) + : _data(other._data) { _inc(); } + + /** + * Construct capability manually + * + * This constructor is used internally. + * + * \noapi + */ + Native_capability(Data &data) : _data(&data) { _inc(); } + + /** + * Destructor + */ + ~Native_capability() { _dec(); } + + Data const *data() const { return _data; } + + /** + * Overloaded comparision operator + */ + bool operator == (const Native_capability &o) const + { + return _data == o._data; + } + + Native_capability& operator = (const Native_capability &o) + { + if (this == &o) + return *this; + + _dec(); + _data = o._data; + _inc(); + return *this; + } + + long local_name() const; + + bool valid() const; + + Raw raw() const; + + void print(Output &) const; +}; + +#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base/include/base/output.h b/repos/base/include/base/output.h index 0ef3158d5..5ab087ea6 100644 --- a/repos/base/include/base/output.h +++ b/repos/base/include/base/output.h @@ -173,6 +173,15 @@ namespace Genode { { obj.print(output); } + + /** + * Print a variable number of arguments + */ + template + static inline void print(Output &output, HEAD const &head, TAIL... tail) + { + Output::out_args(output, head, tail...); + } } #endif /* _INCLUDE__BASE__OUTPUT_H_ */ diff --git a/repos/base/src/core/capability_space.cc b/repos/base/src/core/capability_space.cc new file mode 100644 index 000000000..48c40cb02 --- /dev/null +++ b/repos/base/src/core/capability_space.cc @@ -0,0 +1,100 @@ +/* + * \brief Instance of the (Genode) capability space for non-core components + * \author Norman Feske + * \date 2015-05-11 + */ + +/* + * 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. + */ + +/* base includes */ +#include +#include + +/* base-internal includes */ +#include + + +/** + * Definition of capability meta data + */ +struct Genode::Native_capability::Data : Capability_data +{ + Rpc_destination dst = invalid_rpc_destination(); + + Data(Rpc_destination dst, Rpc_obj_key key) + : Capability_data(key), dst(dst) { } + + Data() { } +}; + + +using namespace Genode; + + +/** + * Singleton instance of component-local capability space + */ +namespace { + + struct Local_capability_space + : + Capability_space_tpl<64*1024, Native_capability::Data> + { }; + + static Local_capability_space &local_capability_space() + { + static Local_capability_space capability_space; + return capability_space; + } +} + + +/****************************************************** + ** Implementation of the Capability_space interface ** + ******************************************************/ + +void Capability_space::dec_ref(Native_capability::Data &data) +{ + local_capability_space().dec_ref(data); +} + + +void Capability_space::inc_ref(Native_capability::Data &data) +{ + local_capability_space().inc_ref(data); +} + + +Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data) +{ + return local_capability_space().rpc_obj_key(data); +} + + +Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap) +{ + return local_capability_space().ipc_cap_data(*cap.data()); +} + + +Native_capability Capability_space::lookup(Rpc_obj_key rpc_obj_key) +{ + return local_capability_space().lookup(rpc_obj_key); +} + + +Native_capability Capability_space::import(Rpc_destination dst, Rpc_obj_key key) +{ + return local_capability_space().import(dst, key); +} + + +void Capability_space::print(Output &out, Native_capability::Data const &data) +{ + local_capability_space().print(out, data); +} diff --git a/repos/base-sel4/src/core/include/core_capability_space.h b/repos/base/src/core/include/core_capability_space.h similarity index 100% rename from repos/base-sel4/src/core/include/core_capability_space.h rename to repos/base/src/core/include/core_capability_space.h diff --git a/repos/base/src/core/rpc_cap_factory_l4.cc b/repos/base/src/core/rpc_cap_factory_l4.cc new file mode 100644 index 000000000..b040c8e16 --- /dev/null +++ b/repos/base/src/core/rpc_cap_factory_l4.cc @@ -0,0 +1,53 @@ +/* + * \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 includes */ +#include +#include + +/* base-internal include */ +#include +#include + +using namespace Genode; + + +static unsigned unique_id_cnt; + + +Native_capability Rpc_cap_factory::_alloc(Rpc_cap_factory *owner, + Native_capability ep) +{ + if (!ep.valid()) { + PWRN("Invalid entrypoint capability"); + return Native_capability(); + } + + Rpc_obj_key const rpc_obj_key(++unique_id_cnt); + + /* combine thread ID of 'ep' with new unique ID */ + Capability_space::Ipc_cap_data cap_data = + Capability_space::ipc_cap_data(ep); + + return Capability_space::import(cap_data.dst, rpc_obj_key); +} + + +Native_capability Rpc_cap_factory::alloc(Native_capability ep) +{ + return Rpc_cap_factory::_alloc(this, ep); +} + + +void Rpc_cap_factory::free(Native_capability cap) { } + diff --git a/repos/base-sel4/src/include/base/internal/capability_data.h b/repos/base/src/include/base/internal/capability_data.h similarity index 100% rename from repos/base-sel4/src/include/base/internal/capability_data.h rename to repos/base/src/include/base/internal/capability_data.h diff --git a/repos/base-sel4/src/include/base/internal/capability_space.h b/repos/base/src/include/base/internal/capability_space.h similarity index 80% rename from repos/base-sel4/src/include/base/internal/capability_space.h rename to repos/base/src/include/base/internal/capability_space.h index dde982e6c..5b7165777 100644 --- a/repos/base-sel4/src/include/base/internal/capability_space.h +++ b/repos/base/src/include/base/internal/capability_space.h @@ -35,17 +35,22 @@ namespace Genode { namespace Capability_space { /** * Increment reference counter */ - void dec_ref(Native_capability::Data &data); + void dec_ref(Native_capability::Data &); /** * Decrement reference counter */ - void inc_ref(Native_capability::Data &data); + void inc_ref(Native_capability::Data &); /** * Obtain RPC object key */ - Rpc_obj_key rpc_obj_key(Native_capability::Data const &data); + Rpc_obj_key rpc_obj_key(Native_capability::Data const &); + + /** + * Print internal capability representation + */ + void print(Output &, Native_capability::Data const &); } } #endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ */ diff --git a/repos/base/src/include/base/internal/capability_space_tpl.h b/repos/base/src/include/base/internal/capability_space_tpl.h new file mode 100644 index 000000000..60087c770 --- /dev/null +++ b/repos/base/src/include/base/internal/capability_space_tpl.h @@ -0,0 +1,213 @@ +/* + * \brief Capability-space management for traditional L4 kernels and Linux + * \author Norman Feske + * \date 2016-06-15 + * + * On traditional L4 kernels, a capability is represented by the thread ID + * of the invoked entrypoint thread and a globally unique RPC object key. + * On Linux, a capability is represented by a socket descriptor and an RPC + * object key. The thread ID respectively socket descriptor refer to the + * recipient of an RPC call (RPC destination). + */ + +/* + * 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__BASE__INTERNAL__CAPABILITY_SPACE_TPL_H_ +#define _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_TPL_H_ + +/* base includes */ +#include +#include +#include +#include + +/* base-internal includes */ +#include +#include + +namespace Genode { template class Capability_space_tpl; } + + +/** + * Platform-specific supplement to the generic 'Capability_space' interface + */ +namespace Genode { namespace Capability_space { + + /** + * Information needed to transfer capability via the kernel's IPC mechanism + */ + struct Ipc_cap_data + { + Rpc_destination dst; + Rpc_obj_key rpc_obj_key; + + Ipc_cap_data(Rpc_destination dst, Rpc_obj_key rpc_obj_key) + : dst(dst), rpc_obj_key(rpc_obj_key) { } + + void print(Output &out) const { Genode::print(out, dst, ",", rpc_obj_key); } + }; + + /** + * Retrieve IPC data for given capability + */ + Ipc_cap_data ipc_cap_data(Native_capability const &cap); + + Native_capability lookup(Rpc_obj_key); + + Native_capability import(Rpc_destination, Rpc_obj_key); +} } + + +/** + * Capability space template + * + * The capability space of core and non-core components differ in two ways. + * + * First, core must keep track of all capabilities of the system. Hence, its + * capability space must be dimensioned larger. + * + * Second, core has to maintain the information about the PD session that + * was used to allocate the capability to prevent misbehaving clients from + * freeing capabilities allocated from another component. This information + * is part of the core-specific 'Native_capability::Data' structure. + */ +template +class Genode::Capability_space_tpl +{ + private: + + typedef CAP_DATA Data; + + /** + * Supplement Native_capability::Data with the meta data needed to + * manage it in an AVL tree + */ + struct Tree_managed_data : Data, Avl_node + { + template + Tree_managed_data(ARGS... args) : Data(args...) { } + + Tree_managed_data() { } + + bool higher(Tree_managed_data *data) + { + return data->rpc_obj_key().value() > rpc_obj_key().value(); + } + + Tree_managed_data *find_by_key(Rpc_obj_key key) + { + if (key.value() == rpc_obj_key().value()) return this; + + Tree_managed_data *data = + this->child(key.value() > rpc_obj_key().value()); + + return data ? data->find_by_key(key) : nullptr; + } + }; + + Tree_managed_data _caps_data[NUM_CAPS]; + Bit_allocator _alloc; + Avl_tree _tree; + Lock mutable _lock; + + /** + * Calculate index into _caps_data for capability data object + */ + unsigned _index(Data const &data) const + { + addr_t const offset = (addr_t)&data - (addr_t)_caps_data; + return offset / sizeof(_caps_data[0]); + } + + Data *_lookup(Rpc_obj_key key) const + { + Lock::Guard guard(_lock); + + if (!_tree.first()) + return nullptr; + + return _tree.first()->find_by_key(key); + } + + public: + + /** + * Create Genode capability + * + * The arguments are passed to the constructor of the + * 'Native_capability::Data' type. + */ + template + Native_capability::Data &create_capability(ARGS... args) + { + Lock::Guard guard(_lock); + + addr_t const index = _alloc.alloc(); + + _caps_data[index] = Tree_managed_data(args...); + + if (_caps_data[index].rpc_obj_key().valid()) + _tree.insert(&_caps_data[index]); + + return _caps_data[index]; + } + + void dec_ref(Data &data) + { + Lock::Guard guard(_lock); + + if (data.dec_ref() == 0) { + + if (data.rpc_obj_key().valid()) + _tree.remove(static_cast(&data)); + + _alloc.free(_index(data)); + data = Tree_managed_data(); + } + } + + void inc_ref(Data &data) + { + Lock::Guard guard(_lock); + + if (data.inc_ref() == 255) + PERR("cap ref count overflow"); + } + + Rpc_obj_key rpc_obj_key(Data const &data) const + { + return data.rpc_obj_key(); + } + + void print(Output &out, Data const &data) const + { + ipc_cap_data(data).print(out); + } + + Capability_space::Ipc_cap_data ipc_cap_data(Data const &data) const + { + if (&data == nullptr) { + raw("ipc_cap_data nullptr"); + for (;;); + } + return { data.dst, data.rpc_obj_key() }; + } + + Native_capability lookup(Rpc_obj_key rpc_obj_key) + { + Native_capability::Data *data = _lookup(rpc_obj_key); + return data ? Native_capability(*data) : Native_capability(); + } + + Native_capability import(Rpc_destination dst, Rpc_obj_key key) + { + return Native_capability(create_capability(dst, key)); + } +}; + +#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_TPL_H_ */ diff --git a/repos/base-sel4/src/include/base/internal/rpc_obj_key.h b/repos/base/src/include/base/internal/rpc_obj_key.h similarity index 54% rename from repos/base-sel4/src/include/base/internal/rpc_obj_key.h rename to repos/base/src/include/base/internal/rpc_obj_key.h index e1dfb22ac..9535230d6 100644 --- a/repos/base-sel4/src/include/base/internal/rpc_obj_key.h +++ b/repos/base/src/include/base/internal/rpc_obj_key.h @@ -16,6 +16,7 @@ /* base includes */ #include +#include namespace Genode { struct Rpc_obj_key; } @@ -28,16 +29,27 @@ class Genode::Rpc_obj_key private: - uint32_t _value = INVALID; + addr_t _value = INVALID; public: Rpc_obj_key() { } - explicit Rpc_obj_key(uint32_t value) : _value(value) { } + explicit Rpc_obj_key(addr_t value) : _value(value) { } - bool valid() const { return _value != INVALID; } - uint32_t value() const { return _value; } + bool valid() const { return _value != INVALID; } + addr_t value() const { return _value; } + + void print(Output &out) const + { + /* + * We print the value as signed long to make 'INVALID' or platform- + * specific low-level codes like 'Protocol_header::INVALID_BADGE' + * on Linux) easily recognizable. Such codes appear as negative + * numbers. + */ + Genode::print(out, "key=", (long)_value); + } }; #endif /* _INCLUDE__BASE__INTERNAL__RPC_OBJ_KEY_H_ */ diff --git a/repos/base-sel4/src/lib/base/capability.cc b/repos/base/src/lib/base/capability.cc similarity index 71% rename from repos/base-sel4/src/lib/base/capability.cc rename to repos/base/src/lib/base/capability.cc index f6197b1dc..200db63b6 100644 --- a/repos/base-sel4/src/lib/base/capability.cc +++ b/repos/base/src/lib/base/capability.cc @@ -11,15 +11,15 @@ * under the terms of the GNU General Public License version 2. */ -/* base includes */ -#include - /* base-internal includes */ #include using namespace Genode; +Native_capability::Native_capability() { } + + void Native_capability::_inc() { if (_data) @@ -42,6 +42,20 @@ long Native_capability::local_name() const bool Native_capability::valid() const { - return _data != 0; + return _data != nullptr; +} + + +void Native_capability::print(Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + Capability_space::print(out, *_data); + } else { + print(out, "invalid"); + } + print(out, ">"); } diff --git a/repos/base/src/lib/base/capability_space.cc b/repos/base/src/lib/base/capability_space.cc new file mode 100644 index 000000000..d7907f5a0 --- /dev/null +++ b/repos/base/src/lib/base/capability_space.cc @@ -0,0 +1,100 @@ +/* + * \brief Instance of the (Genode) capability space for non-core components + * \author Norman Feske + * \date 2015-05-11 + */ + +/* + * 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. + */ + +/* base includes */ +#include +#include + +/* base-internal includes */ +#include + + +/** + * Definition of capability meta data + */ +struct Genode::Native_capability::Data : Capability_data +{ + Rpc_destination dst = invalid_rpc_destination(); + + Data(Rpc_destination dst, Rpc_obj_key key) + : Capability_data(key), dst(dst) { } + + Data() { } +}; + + +using namespace Genode; + + +/** + * Singleton instance of component-local capability space + */ +namespace { + + struct Local_capability_space + : + Capability_space_tpl<4*1024, Native_capability::Data> + { }; + + static Local_capability_space &local_capability_space() + { + static Local_capability_space capability_space; + return capability_space; + } +} + + +/****************************************************** + ** Implementation of the Capability_space interface ** + ******************************************************/ + +void Capability_space::dec_ref(Native_capability::Data &data) +{ + local_capability_space().dec_ref(data); +} + + +void Capability_space::inc_ref(Native_capability::Data &data) +{ + local_capability_space().inc_ref(data); +} + + +Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data) +{ + return local_capability_space().rpc_obj_key(data); +} + + +Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap) +{ + return local_capability_space().ipc_cap_data(*cap.data()); +} + + +Native_capability Capability_space::lookup(Rpc_obj_key rpc_obj_key) +{ + return local_capability_space().lookup(rpc_obj_key); +} + + +Native_capability Capability_space::import(Rpc_destination dst, Rpc_obj_key key) +{ + return local_capability_space().import(dst, key); +} + + +void Capability_space::print(Output &out, Native_capability::Data const &data) +{ + local_capability_space().print(out, data); +} diff --git a/repos/os/src/drivers/timer/spec/hw/platform_timer.h b/repos/os/src/drivers/timer/spec/hw/platform_timer.h index d0aad7fa8..24957d38f 100644 --- a/repos/os/src/drivers/timer/spec/hw/platform_timer.h +++ b/repos/os/src/drivers/timer/spec/hw/platform_timer.h @@ -38,12 +38,25 @@ class Platform_timer unsigned long mutable _last_timeout_us; time_t const _max_timeout_us; + /** + * Return kernel capability selector of Genode capability + * + * This function is normally framework-internal and defined in + * 'base/internal/capability_space.h'. + */ + static inline Kernel::capid_t _capid(Genode::Native_capability const &cap) + { + Genode::addr_t const index = (Genode::addr_t)cap.data(); + return index; + } + public: Platform_timer() : - _sigid(_sigrec.manage(&_sigctx).dst()), _curr_time_us(0), - _last_timeout_us(0), _max_timeout_us(Kernel::timeout_max_us()) + _sigid(_capid(_sigrec.manage(&_sigctx))), + _curr_time_us(0), _last_timeout_us(0), + _max_timeout_us(Kernel::timeout_max_us()) { PINF("Maximum timeout %lu us", _max_timeout_us); if (max_timeout() < min_timeout()) { diff --git a/repos/os/src/test/timer/main.cc b/repos/os/src/test/timer/main.cc index a8c9d85e0..204fd5471 100644 --- a/repos/os/src/test/timer/main.cc +++ b/repos/os/src/test/timer/main.cc @@ -17,7 +17,7 @@ #include #include -enum { STACK_SIZE = 4096 }; +enum { STACK_SIZE = 1024*sizeof(long) }; class Timer_client : public Genode::List::Element, Timer::Connection, Genode::Thread_deprecated diff --git a/repos/ports-foc/src/lib/l4lx/genode_block.cc b/repos/ports-foc/src/lib/l4lx/genode_block.cc index f1dafb7ba..54cd3d81d 100644 --- a/repos/ports-foc/src/lib/l4lx/genode_block.cc +++ b/repos/ports-foc/src/lib/l4lx/genode_block.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -116,9 +117,13 @@ namespace { Genode::strncpy(_name, label, sizeof(_name)); } + Fiasco::l4_cap_idx_t irq_cap() + { + return Genode::Capability_space::kcap(_irq_cap); + } + Req_cache *cache() { return &_cache; } Block::Connection *session() { return &_session; } - Fiasco::l4_cap_idx_t irq_cap() { return _irq_cap.dst(); } Genode::Signal_context *context() { return &_tx; } Genode::size_t block_size() { return _blk_size; } Genode::size_t block_count() { return _blk_cnt; } diff --git a/repos/ports-foc/src/lib/l4lx/genode_net.cc b/repos/ports-foc/src/lib/l4lx/genode_net.cc index 48efac87e..375d137f8 100644 --- a/repos/ports-foc/src/lib/l4lx/genode_net.cc +++ b/repos/ports-foc/src/lib/l4lx/genode_net.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -153,9 +154,10 @@ extern "C" { native_cpu(L4lx::cpu_connection()->native_cpu()); static Genode::Native_capability cap = native_cpu.alloc_irq(); static Genode::Lock lock(Genode::Lock::LOCKED); - static Signal_thread th(cap.dst(), &lock); + static Fiasco::l4_cap_idx_t const kcap = Genode::Capability_space::kcap(cap); + static Signal_thread th(kcap, &lock); lock.lock(); - return cap.dst(); + return kcap; } diff --git a/repos/ports-foc/src/lib/l4lx/genode_terminal.cc b/repos/ports-foc/src/lib/l4lx/genode_terminal.cc index 45f2232d0..24f1e1e97 100644 --- a/repos/ports-foc/src/lib/l4lx/genode_terminal.cc +++ b/repos/ports-foc/src/lib/l4lx/genode_terminal.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -100,9 +101,10 @@ extern "C" { native_cpu(L4lx::cpu_connection()->native_cpu()); static Genode::Native_capability cap = native_cpu.alloc_irq(); + l4_cap_idx_t const kcap = Genode::Capability_space::kcap(cap); if (!signal_thread) - signal_thread = new (Genode::env()->heap()) Signal_thread(cap.dst()); - return cap.dst(); + signal_thread = new (Genode::env()->heap()) Signal_thread(kcap); + return kcap; } diff --git a/repos/ports-foc/src/lib/l4lx/include/dataspace.h b/repos/ports-foc/src/lib/l4lx/include/dataspace.h index 20b680308..e7c3d3a44 100644 --- a/repos/ports-foc/src/lib/l4lx/include/dataspace.h +++ b/repos/ports-foc/src/lib/l4lx/include/dataspace.h @@ -16,16 +16,12 @@ /* Genode includes */ #include -#include #include #include #include #include #include - -namespace Fiasco { -#include -} +#include namespace L4lx { @@ -86,10 +82,10 @@ namespace L4lx { public: Single_dataspace(const char* name, - Genode::size_t size, - Genode::Dataspace_capability ds, + Genode::size_t size, + Genode::Dataspace_capability ds, Fiasco::l4_cap_idx_t ref = - Genode::cap_idx_alloc()->alloc_range(1)->kcap()) + Genode::Capability_space::alloc_kcap()) : Dataspace(name, size, ref), _cap(ds) {} Genode::Dataspace_capability cap() { return _cap; } diff --git a/repos/ports-foc/src/lib/l4lx/include/task.h b/repos/ports-foc/src/lib/l4lx/include/task.h index 738658767..6eb46199a 100644 --- a/repos/ports-foc/src/lib/l4lx/include/task.h +++ b/repos/ports-foc/src/lib/l4lx/include/task.h @@ -51,7 +51,8 @@ namespace L4lx { /* remap task cap to given cap slot */ l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, - l4_obj_fpage(_cap.dst(), 0, L4_FPAGE_RWX), + l4_obj_fpage(Genode::Capability_space::kcap(_cap), + 0, L4_FPAGE_RWX), _ref | L4_ITEM_MAP); } diff --git a/repos/ports-foc/src/lib/l4lx/include/vcpu.h b/repos/ports-foc/src/lib/l4lx/include/vcpu.h index 8ac17beb6..102e87b39 100644 --- a/repos/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/repos/ports-foc/src/lib/l4lx/include/vcpu.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc b/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc index 704d8b5ce..5d7651d11 100644 --- a/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc +++ b/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc @@ -13,7 +13,7 @@ /* Genode includes */ #include -#include +#include namespace Fiasco { #include @@ -28,7 +28,7 @@ extern "C" { l4_cap_idx_t l4re_util_cap_alloc(void) { - l4_cap_idx_t ret = Genode::cap_idx_alloc()->alloc_range(1)->kcap(); + l4_cap_idx_t ret = Genode::Capability_space::alloc_kcap(); if (DEBUG) PDBG("ret=%lx", ret); diff --git a/repos/ports-foc/src/lib/l4lx/l4lx_task.cc b/repos/ports-foc/src/lib/l4lx/l4lx_task.cc index de4ee2fc7..d1326dba7 100644 --- a/repos/ports-foc/src/lib/l4lx/l4lx_task.cc +++ b/repos/ports-foc/src/lib/l4lx/l4lx_task.cc @@ -13,7 +13,7 @@ /* Genode includes */ #include -#include +#include #include #include @@ -67,8 +67,7 @@ int l4lx_task_number_free(l4_cap_idx_t task) { Linux::Irq_guard guard; - Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(task); - Genode::cap_idx_alloc()->free(idx, 1); + Genode::Capability_space::free_kcap(task); return 0; } @@ -89,7 +88,7 @@ int l4lx_task_get_new_task(l4_cap_idx_t parent_id, { Linux::Irq_guard guard; - *id = Genode::cap_idx_alloc()->alloc_range(1)->kcap(); + *id = Genode::Capability_space::alloc_kcap(); return 0; } diff --git a/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc b/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc index 62c098fa5..0ff0dd53b 100644 --- a/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc +++ b/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc @@ -106,7 +106,8 @@ void l4lx_thread_alloc_irq(l4_cap_idx_t c) Genode::Native_capability cap = native_cpu.alloc_irq(); l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, - l4_obj_fpage(cap.dst(), 0, L4_FPAGE_RWX), c | L4_ITEM_MAP); + l4_obj_fpage(Genode::Capability_space::kcap(cap), 0, L4_FPAGE_RWX), + c | L4_ITEM_MAP); } l4lx_thread_t l4lx_thread_create(L4_CV void (*thread_func)(void *data), diff --git a/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc b/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc index d9470b3df..504fd36f1 100644 --- a/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc +++ b/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc @@ -94,9 +94,10 @@ Fiasco::l4_cap_idx_t genode_balloon_irq_cap() static Genode::Foc_native_cpu_client native_cpu(L4lx::cpu_connection()->native_cpu()); static Genode::Native_capability cap = native_cpu.alloc_irq(); static Genode::Lock lock(Genode::Lock::LOCKED); - static Signal_thread th(cap.dst(), &lock); + static Fiasco::l4_cap_idx_t kcap = Genode::Capability_space::kcap(cap); + static Signal_thread th(kcap, &lock); lock.lock(); - return cap.dst(); + return kcap; } diff --git a/repos/ports-foc/src/lib/l4lx/startup.cc b/repos/ports-foc/src/lib/l4lx/startup.cc index e415c217c..bd2f3c966 100644 --- a/repos/ports-foc/src/lib/l4lx/startup.cc +++ b/repos/ports-foc/src/lib/l4lx/startup.cc @@ -120,7 +120,7 @@ static void prepare_l4re_env() env->scheduler = L4_BASE_SCHEDULER_CAP; env->mem_alloc = L4_INVALID_CAP; env->log = L4_INVALID_CAP; - env->main_thread = main_thread_cap.dst(); + env->main_thread = Genode::Capability_space::kcap(main_thread_cap); env->rm = Fiasco::THREAD_AREA_BASE + Fiasco::THREAD_PAGER_CAP; } diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index 37fdc5143..a82d4ee25 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -17,6 +17,7 @@ /* Genode includes */ #include #include +#include namespace Vmm { @@ -108,18 +109,20 @@ class Vmm::Vcpu_dispatcher : public T */ void (*entry)() = &_portal_entry; - /* Create the portal at the desired selector index */ - _native_pd.rcv_window(exc_base + EV); - - Native_capability thread_cap(T::native_thread().ec_sel); + /* create the portal at the desired selector index (EV) */ + Native_capability thread_cap = + Capability_space::import(T::native_thread().ec_sel); Untyped_capability handler = retry( [&] () { + /* manually define selector used for RPC result */ + Thread::myself()->native_thread().client_rcv_sel = exc_base + EV; return _native_pd.alloc_rpc_cap(thread_cap, (addr_t)entry, mtd.value()); }, [&] () { + Thread::myself()->native_thread().reset_client_rcv_sel(); Pd_session_client *client = dynamic_cast(&_pd); @@ -127,7 +130,10 @@ class Vmm::Vcpu_dispatcher : public T env()->parent()->upgrade(*client, "ram_quota=16K"); }); - return handler.valid() && (exc_base + EV == handler.local_name()); + /* revert selector allocation to automatic mode of operation */ + Thread::myself()->native_thread().reset_client_rcv_sel(); + + return handler.valid() && (exc_base + EV == (addr_t)handler.local_name()); } /** diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index 23d78d5db..149d3a11a 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -15,7 +15,6 @@ #define _INCLUDE__VMM__VCPU_THREAD_H_ /* Genode includes */ -#include #include #include #include @@ -26,6 +25,7 @@ /* NOVA includes */ #include +#include namespace Vmm { diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc index 46f229f04..3ff0c3c75 100644 --- a/repos/ports/src/noux/main.cc +++ b/repos/ports/src/noux/main.cc @@ -66,7 +66,8 @@ extern void init_network(); namespace Noux { using namespace Genode; - class Timeout_scheduler : Thread_deprecated<4096>, public Alarm_scheduler + class Timeout_scheduler : Thread_deprecated<1024*sizeof(long)>, + public Alarm_scheduler { private: Timer::Connection _timer;