From b49e588c1cabd11d0433fd686d79b7c8c3e5bbbf Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 20 Apr 2016 21:12:57 +0200 Subject: [PATCH] Assign threads to PD at its creation time This patch replaces the former 'Pd_session::bind_thread' function by a PD-capability argument of the 'Cpu_session::create_thread' function, and removes the ancient thread-start protocol via 'Rm_session::add_client' and 'Cpu_session::set_pager'. Threads are now bound to PDs at their creation time and implicitly paged according to the address space of the PD. Note the API change: This patch changes the signature of the 'Child' and 'Process' constructors. There is a new 'address_space' argument, which represents the region map representing the child's address space. It is supplied separately to the PD session capability (which principally can be invoked to obtain the PD's address space) to allow the population of the address space without relying on an 'Pd_session::address_space' RPC call. Furthermore, a new (optional) env_pd argument allows the explicit overriding of the PD capability handed out to the child as part of its environment. It can be used to intercept the interaction of the child with its PD session at core. This is used by Noux. Issue #1938 --- .../src/core/include/platform_pd.h | 4 +- .../src/core/include/platform_thread.h | 10 +- repos/base-fiasco/src/core/include/util.h | 3 +- repos/base-fiasco/src/core/platform.cc | 7 +- repos/base-fiasco/src/core/platform_pd.cc | 7 +- repos/base-fiasco/src/core/platform_thread.cc | 3 +- repos/base-fiasco/src/core/target.inc | 2 + .../base-foc/src/base/thread/thread_start.cc | 13 +- .../src/core/include/native_cpu_component.h | 2 - repos/base-foc/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 12 +- repos/base-foc/src/core/include/util.h | 5 +- repos/base-foc/src/core/platform.cc | 8 +- repos/base-foc/src/core/platform_pd.cc | 10 +- repos/base-foc/src/core/platform_thread.cc | 4 +- repos/base-foc/src/core/target.inc | 2 + repos/base-hw/src/base/thread/start.cc | 14 +- repos/base-hw/src/core/core_region_map.cc | 5 +- .../src/core/include/core_region_map.h | 57 ------ repos/base-hw/src/core/include/pager.h | 20 +- repos/base-hw/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 3 +- repos/base-hw/src/core/pager.cc | 13 +- repos/base-hw/src/core/platform_pd.cc | 3 +- repos/base-hw/src/core/platform_thread.cc | 2 + repos/base-linux/src/base/process/process.cc | 4 +- .../base-linux/src/base/region_map_client.cc | 8 - .../src/base/thread/thread_linux.cc | 3 +- repos/base-linux/src/core/include/pager.h | 4 + .../base-linux/src/core/include/platform_pd.h | 12 +- .../src/core/include/platform_thread.h | 10 +- .../src/core/include/region_map_component.h | 20 +- repos/base-linux/src/core/include/util.h | 6 +- .../src/core/pd_session_component.cc | 3 - repos/base-linux/src/core/platform_thread.cc | 3 +- repos/base-linux/src/core/stack_area.cc | 5 - .../src/include/base/internal/platform_env.h | 11 +- .../base-linux/src/lib/lx_hybrid/lx_hybrid.cc | 6 +- repos/base-nova/include/cpu_session/client.h | 45 +++-- repos/base-nova/include/nova/native_thread.h | 2 + .../include/nova_native_cpu/client.h | 32 ++++ .../include/nova_native_cpu/nova_native_cpu.h | 36 ++++ repos/base-nova/lib/mk/spec/x86_32/core.mk | 3 +- repos/base-nova/lib/mk/spec/x86_64/core.mk | 3 +- repos/base-nova/src/base/region_map_client.cc | 13 +- repos/base-nova/src/base/server/server.cc | 16 +- .../base-nova/src/base/thread/thread_nova.cc | 26 +-- repos/base-nova/src/core/core_region_map.cc | 2 +- .../src/core/cpu_session_extension.cc | 2 +- .../src/core/include/core_region_map.h | 56 ------ .../src/core/include/cpu_session_component.h | 176 +++++++++++++----- .../src/core/include/native_cpu_component.h | 44 +++++ repos/base-nova/src/core/include/pager.h | 23 ++- .../base-nova/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 10 +- repos/base-nova/src/core/include/util.h | 5 +- .../src/core/native_cpu_component.cc | 48 +++++ repos/base-nova/src/core/pager.cc | 15 +- repos/base-nova/src/core/platform_pd.cc | 3 +- repos/base-nova/src/core/platform_thread.cc | 12 +- repos/base-nova/src/core/target.inc | 1 + repos/base-nova/src/core/thread_start.cc | 6 +- repos/base-okl4/src/core/core_region_map.cc | 5 +- .../src/core/include/core_region_map.h | 56 ------ .../base-okl4/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 5 +- repos/base-okl4/src/core/include/util.h | 5 +- repos/base-okl4/src/core/platform_pd.cc | 5 +- repos/base-okl4/src/core/platform_thread.cc | 4 +- .../src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 10 +- repos/base-pistachio/src/core/include/util.h | 5 +- repos/base-pistachio/src/core/platform.cc | 7 +- repos/base-pistachio/src/core/platform_pd.cc | 5 +- .../src/core/platform_thread.cc | 2 +- repos/base-pistachio/src/core/target.inc | 2 + repos/base-sel4/src/core/core_region_map.cc | 5 +- .../src/core/include/core_region_map.h | 56 ------ .../base-sel4/src/core/include/platform_pd.h | 2 +- .../src/core/include/platform_thread.h | 11 +- repos/base-sel4/src/core/include/util.h | 5 +- repos/base-sel4/src/core/platform_pd.cc | 3 +- repos/base-sel4/src/core/platform_thread.cc | 2 +- repos/base-sel4/src/core/stack_area.cc | 15 +- repos/base/include/base/child.h | 21 ++- repos/base/include/base/process.h | 2 + repos/base/include/base/thread.h | 20 +- repos/base/include/cpu_session/client.h | 8 +- repos/base/include/cpu_session/cpu_session.h | 43 ++--- repos/base/include/pd_session/client.h | 3 - repos/base/include/pd_session/pd_session.h | 17 +- repos/base/include/region_map/client.h | 2 - repos/base/include/region_map/region_map.h | 30 +-- repos/base/src/base/child/child.cc | 10 +- repos/base/src/base/process/process.cc | 40 +--- repos/base/src/base/region_map_client.cc | 10 - repos/base/src/base/server/common.cc | 6 +- repos/base/src/base/thread/thread.cc | 11 +- repos/base/src/base/thread/thread_start.cc | 19 +- repos/base/src/core/core_region_map.cc | 39 ++++ repos/base/src/core/cpu_session_component.cc | 105 +++++------ repos/base/src/core/include/core_env.h | 2 +- repos/base/src/core/include/core_pd_session.h | 5 - repos/base/src/core/include/core_region_map.h | 29 +-- .../src/core/include/cpu_session_component.h | 158 ++++++++++++---- .../src/core/include/cpu_thread_allocator.h | 5 +- repos/base/src/core/include/pager.h | 24 ++- .../src/core/include/pd_session_component.h | 23 ++- .../src/core/include/region_map_component.h | 30 +-- repos/base/src/core/main.cc | 5 +- repos/base/src/core/pd_session_component.cc | 27 +-- repos/base/src/core/region_map_component.cc | 128 +++---------- repos/base/src/core/stack_area.cc | 32 ++-- .../src/include/base/internal/platform_env.h | 5 +- .../base/internal/platform_env_common.h | 21 +-- .../base/{ => src}/include/pager/capability.h | 0 repos/base/src/test/rm_fault/main.cc | 9 +- repos/demo/include/launchpad/launchpad.h | 5 +- repos/libports/src/lib/pthread/thread.h | 4 +- .../libports/src/lib/pthread/thread_create.cc | 3 +- repos/os/include/cli_monitor/child.h | 13 +- repos/os/include/init/child.h | 3 +- repos/os/include/os/slave.h | 7 +- repos/os/src/server/loader/child.h | 4 +- repos/os/src/test/bomb/main.cc | 4 +- repos/os/src/test/fault_detection/main.cc | 11 +- repos/ports-foc/src/lib/l4lx/include/vcpu.h | 6 +- repos/ports/include/vmm/vcpu_dispatcher.h | 10 +- repos/ports/include/vmm/vcpu_thread.h | 32 ++-- repos/ports/src/app/gdb_monitor/app_child.h | 4 +- .../app/gdb_monitor/cpu_session_component.cc | 12 +- .../app/gdb_monitor/cpu_session_component.h | 40 ++-- .../app/gdb_monitor/pd_session_component.h | 3 - .../app/gdb_monitor/region_map_component.cc | 18 -- .../app/gdb_monitor/region_map_component.h | 12 +- repos/ports/src/noux/child.h | 46 +++-- repos/ports/src/noux/cpu_session_component.h | 71 ++++--- repos/ports/src/noux/pd_session_component.h | 5 +- repos/ports/src/noux/region_map_component.h | 25 --- repos/ports/src/virtualbox/thread.cc | 3 +- 140 files changed, 1112 insertions(+), 1221 deletions(-) delete mode 100644 repos/base-hw/src/core/include/core_region_map.h create mode 100644 repos/base-nova/include/nova_native_cpu/client.h create mode 100644 repos/base-nova/include/nova_native_cpu/nova_native_cpu.h delete mode 100644 repos/base-nova/src/core/include/core_region_map.h create mode 100644 repos/base-nova/src/core/include/native_cpu_component.h create mode 100644 repos/base-nova/src/core/native_cpu_component.cc delete mode 100644 repos/base-okl4/src/core/include/core_region_map.h delete mode 100644 repos/base-sel4/src/core/include/core_region_map.h create mode 100644 repos/base/src/core/core_region_map.cc rename repos/base/{ => src}/include/pager/capability.h (100%) diff --git a/repos/base-fiasco/src/core/include/platform_pd.h b/repos/base-fiasco/src/core/include/platform_pd.h index a6ae468a1..a0f444887 100644 --- a/repos/base-fiasco/src/core/include/platform_pd.h +++ b/repos/base-fiasco/src/core/include/platform_pd.h @@ -163,8 +163,10 @@ namespace Genode { /** * Bind thread to protection domain + * + * \return true on success */ - void bind_thread(Platform_thread *thread); + bool bind_thread(Platform_thread *thread); /** * Unbind thread from protection domain diff --git a/repos/base-fiasco/src/core/include/platform_thread.h b/repos/base-fiasco/src/core/include/platform_thread.h index 4d157f152..02da9255c 100644 --- a/repos/base-fiasco/src/core/include/platform_thread.h +++ b/repos/base-fiasco/src/core/include/platform_thread.h @@ -54,6 +54,7 @@ namespace Genode { * Constructor */ Platform_thread(size_t, const char *name = 0, unsigned priority = 0, + Affinity::Location = Affinity::Location(), addr_t utcb = 0, int thread_id = THREAD_INVALID); /** @@ -107,15 +108,6 @@ namespace Genode { */ void unbind(); - /** - * Return pointer to the thread's PD - * - * Used to validate the success of the bind operation. - * - * XXX to be removed - */ - Platform_pd *pd() { return _platform_pd; } - /** * Override thread state with 's' * diff --git a/repos/base-fiasco/src/core/include/util.h b/repos/base-fiasco/src/core/include/util.h index 23c729025..92df7e796 100644 --- a/repos/base-fiasco/src/core/include/util.h +++ b/repos/base-fiasco/src/core/include/util.h @@ -24,6 +24,7 @@ /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { @@ -94,8 +95,6 @@ namespace Genode { return l4_round_superpage(addr); } - constexpr size_t get_page_size() { return L4_PAGESIZE; } - constexpr size_t get_page_size_log2() { return L4_LOG2_PAGESIZE; } constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; } constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } diff --git a/repos/base-fiasco/src/core/platform.cc b/repos/base-fiasco/src/core/platform.cc index fb98694df..49c110e19 100644 --- a/repos/base-fiasco/src/core/platform.cc +++ b/repos/base-fiasco/src/core/platform.cc @@ -133,7 +133,9 @@ static void _core_pager_loop() } -Platform::Sigma0::Sigma0() : Pager_object(0, Affinity::Location()) +Platform::Sigma0::Sigma0() +: + Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { cap(reinterpret_cap_cast(Native_capability(Fiasco::sigma0_threadid, 0))); } @@ -148,7 +150,8 @@ Platform::Sigma0 *Platform::sigma0() Platform::Core_pager::Core_pager(Platform_pd *core_pd) : - Platform_thread(0, "core.pager"), Pager_object(0, Affinity::Location()) + Platform_thread(0, "core.pager"), + Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { Platform_thread::pager(sigma0()); diff --git a/repos/base-fiasco/src/core/platform_pd.cc b/repos/base-fiasco/src/core/platform_pd.cc index fe727f6b9..25ef4901f 100644 --- a/repos/base-fiasco/src/core/platform_pd.cc +++ b/repos/base-fiasco/src/core/platform_pd.cc @@ -199,7 +199,7 @@ void Platform_pd::_free_thread(int thread_id) ** Public object members ** ***************************/ -void Platform_pd::bind_thread(Platform_thread *thread) +bool Platform_pd::bind_thread(Platform_thread *thread) { /* thread_id is THREAD_INVALID by default - only core is the special case */ int thread_id = thread->thread_id(); @@ -207,8 +207,8 @@ void Platform_pd::bind_thread(Platform_thread *thread) int t = _alloc_thread(thread_id, thread); if (t < 0) { - PERR("Thread alloc failed"); - return; + PERR("thread alloc failed"); + return false; } thread_id = t; @@ -219,6 +219,7 @@ void Platform_pd::bind_thread(Platform_thread *thread) thread->bind(thread_id, l4_thread_id, this); if (verbose) _debug_log_threads(); + return true; } diff --git a/repos/base-fiasco/src/core/platform_thread.cc b/repos/base-fiasco/src/core/platform_thread.cc index ba9b611c8..5bd183547 100644 --- a/repos/base-fiasco/src/core/platform_thread.cc +++ b/repos/base-fiasco/src/core/platform_thread.cc @@ -151,7 +151,8 @@ Weak_ptr Platform_thread::address_space() } -Platform_thread::Platform_thread(size_t, const char *name, unsigned, addr_t, +Platform_thread::Platform_thread(size_t, const char *name, unsigned, + Affinity::Location, addr_t, int thread_id) : _thread_id(thread_id), _l4_thread_id(L4_INVALID_ID), _pager(0) { diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index 85266de73..6468c6e85 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -4,6 +4,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core SRC_CC += stack_area.cc \ core_printf.cc \ + core_region_map.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ @@ -54,6 +55,7 @@ vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) +vpath core_region_map.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) diff --git a/repos/base-foc/src/base/thread/thread_start.cc b/repos/base-foc/src/base/thread/thread_start.cc index 8aee5ecc5..b4a3428c5 100644 --- a/repos/base-foc/src/base/thread/thread_start.cc +++ b/repos/base-foc/src/base/thread/thread_start.cc @@ -37,7 +37,6 @@ void Thread_base::_deinit_platform_thread() Cap_index *i = (Cap_index*)l4_utcb_tcr_u(utcb()->foc_utcb)->user[UTCB_TCR_BADGE]; cap_map()->remove(i); _cpu_session->kill_thread(_thread_cap); - env()->rm_session()->remove_client(_pager_cap); } } @@ -53,13 +52,13 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) /* create thread at core */ char buf[48]; name(buf, sizeof(buf)); - _thread_cap = _cpu_session->create_thread(weight, buf); + _thread_cap = _cpu_session->create_thread(env()->pd_session_cap(), + weight, buf); /* assign thread to protection domain */ if (!_thread_cap.valid()) throw Cpu_session::Thread_creation_failed(); - env()->pd_session()->bind_thread(_thread_cap); return; } /* adjust values whose computation differs for a main thread */ @@ -79,14 +78,6 @@ void Thread_base::start() { using namespace Fiasco; - /* create new pager object and assign it to the new thread */ - try { - _pager_cap = env()->rm_session()->add_client(_thread_cap); - } catch (Region_map::Unbound_thread) { - throw Cpu_session::Thread_creation_failed(); } - - _cpu_session->set_pager(_thread_cap, _pager_cap); - /* get gate-capability and badge of new thread */ Thread_state state; try { state = _cpu_session->state(_thread_cap); } diff --git a/repos/base-foc/src/core/include/native_cpu_component.h b/repos/base-foc/src/core/include/native_cpu_component.h index bf1fd037b..a64499f69 100644 --- a/repos/base-foc/src/core/include/native_cpu_component.h +++ b/repos/base-foc/src/core/include/native_cpu_component.h @@ -2,8 +2,6 @@ * \brief Kernel-specific part of the CPU-session interface * \author Norman Feske * \date 2016-01-19 - * - * This definition is used on platforms with no kernel-specific PD functions */ /* diff --git a/repos/base-foc/src/core/include/platform_pd.h b/repos/base-foc/src/core/include/platform_pd.h index b80343efe..2fbcce33a 100644 --- a/repos/base-foc/src/core/include/platform_pd.h +++ b/repos/base-foc/src/core/include/platform_pd.h @@ -82,7 +82,7 @@ namespace Genode { /** * Bind thread to protection domain */ - void bind_thread(Platform_thread *thread); + bool bind_thread(Platform_thread *thread); /** * Unbind thread from protection domain diff --git a/repos/base-foc/src/core/include/platform_thread.h b/repos/base-foc/src/core/include/platform_thread.h index 6564de489..9d9d2ec9f 100644 --- a/repos/base-foc/src/core/include/platform_thread.h +++ b/repos/base-foc/src/core/include/platform_thread.h @@ -64,7 +64,8 @@ namespace Genode { /** * Constructor for non-core threads */ - Platform_thread(size_t, const char *name, unsigned priority, addr_t); + Platform_thread(size_t, const char *name, unsigned priority, + Affinity::Location, addr_t); /** * Constructor for core main-thread @@ -125,15 +126,6 @@ namespace Genode { */ void unbind(); - /** - * Return pointer to the thread's PD - * - * Used to validate the success of the bind operation. - * - * XXX to be removed - */ - Platform_pd *pd() { return _platform_pd; } - /** * Override thread state with 's' * diff --git a/repos/base-foc/src/core/include/util.h b/repos/base-foc/src/core/include/util.h index 50a264b56..a94d51d77 100644 --- a/repos/base-foc/src/core/include/util.h +++ b/repos/base-foc/src/core/include/util.h @@ -23,6 +23,9 @@ #include #include +/* base-internal includes */ +#include + /* Fiasco includes */ namespace Fiasco { #include @@ -91,8 +94,6 @@ namespace Genode { return (addr + L4_SUPERPAGESIZE-1) & L4_SUPERPAGEMASK; } - constexpr size_t get_page_size() { return L4_PAGESIZE; } - constexpr size_t get_page_size_log2() { return L4_LOG2_PAGESIZE; } constexpr size_t get_super_page_size() { return L4_SUPERPAGESIZE; } constexpr size_t get_super_page_size_log2() { return L4_LOG2_SUPERPAGESIZE; } diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc index 17a87e6a4..de66f41bc 100644 --- a/repos/base-foc/src/core/platform.cc +++ b/repos/base-foc/src/core/platform.cc @@ -129,7 +129,9 @@ static void _core_pager_loop() } -Platform::Sigma0::Sigma0(Cap_index* i) : Pager_object(0, Affinity::Location()) +Platform::Sigma0::Sigma0(Cap_index* i) +: + Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { /* * We use the Pager_object here in a slightly different manner, @@ -140,7 +142,9 @@ Platform::Sigma0::Sigma0(Cap_index* i) : Pager_object(0, Affinity::Location()) Platform::Core_pager::Core_pager(Platform_pd *core_pd, Sigma0 *sigma0) -: Platform_thread("core.pager"), Pager_object(0, Affinity::Location()) +: + Platform_thread("core.pager"), + Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { Platform_thread::pager(sigma0); diff --git a/repos/base-foc/src/core/platform_pd.cc b/repos/base-foc/src/core/platform_pd.cc index 2cd026db5..a8bbbd452 100644 --- a/repos/base-foc/src/core/platform_pd.cc +++ b/repos/base-foc/src/core/platform_pd.cc @@ -41,7 +41,7 @@ static addr_t core_utcb_base() { ** Public object members ** ***************************/ -void Platform_pd::bind_thread(Platform_thread *thread) +bool Platform_pd::bind_thread(Platform_thread *thread) { /* * Fiasco.OC limits the UTCB area for roottask to 16K. Therefore, the @@ -69,17 +69,16 @@ void Platform_pd::bind_thread(Platform_thread *thread) thread->_irq.remote = cap_offset + THREAD_IRQ_CAP; /* if it's no core-thread we have to map parent and pager gate cap */ - if (!thread->core_thread()) { + if (!thread->core_thread()) _task.map(_task.local.dst()); - _parent.map(_task.local.dst()); - } /* inform thread about binding */ thread->bind(this); - return; + return true; } PERR("thread alloc failed"); + return false; } @@ -101,6 +100,7 @@ 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()); } } diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index daf630936..ec65c3e68 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -278,7 +278,8 @@ Weak_ptr Platform_thread::address_space() } -Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, addr_t) +Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, + Affinity::Location location, addr_t) : _state(DEAD), _core_thread(false), _thread(true), @@ -291,6 +292,7 @@ Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, addr_t ((Core_cap_index*)_thread.local.idx())->pt(this); _create_thread(); _finalize_construction(name); + affinity(location); } diff --git a/repos/base-foc/src/core/target.inc b/repos/base-foc/src/core/target.inc index 68fff8597..ca491cf30 100644 --- a/repos/base-foc/src/core/target.inc +++ b/repos/base-foc/src/core/target.inc @@ -7,6 +7,7 @@ LIBS += base-common SRC_CC += stack_area.cc \ core_printf.cc \ + core_region_map.cc \ core_rpc_cap_alloc.cc \ cpu_session_component.cc \ cpu_session_support.cc \ @@ -63,6 +64,7 @@ vpath region_map_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) +vpath core_region_map.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console vpath %.cc $(REP_DIR)/src/core vpath %.cc $(REP_DIR)/src/base/thread diff --git a/repos/base-hw/src/base/thread/start.cc b/repos/base-hw/src/base/thread/start.cc index 178ac5eb9..5831e0d4d 100644 --- a/repos/base-hw/src/base/thread/start.cc +++ b/repos/base-hw/src/base/thread/start.cc @@ -43,7 +43,8 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) char buf[48]; name(buf, sizeof(buf)); addr_t const utcb = (addr_t)&_stack->utcb(); - _thread_cap = _cpu_session->create_thread(weight, buf, utcb); + _thread_cap = _cpu_session->create_thread(env()->pd_session_cap(), + weight, buf, _affinity, utcb); return; } /* if we got reinitialized we have to get rid of the old UTCB */ @@ -78,22 +79,11 @@ void Thread_base::_deinit_platform_thread() addr_t utcb = Stack_allocator::addr_to_base(_stack) + stack_virtual_size() - size - stack_area_virtual_base(); env_stack_area_region_map->detach(utcb); - - if (_pager_cap.valid()) { - env()->rm_session()->remove_client(_pager_cap); - } } void Thread_base::start() { - /* assign thread to protection domain */ - env()->pd_session()->bind_thread(_thread_cap); - - /* create pager object and assign it to the thread */ - _pager_cap = env()->rm_session()->add_client(_thread_cap); - _cpu_session->set_pager(_thread_cap, _pager_cap); - /* attach userland stack */ try { Ram_dataspace_capability ds = _cpu_session->utcb(_thread_cap); diff --git a/repos/base-hw/src/core/core_region_map.cc b/repos/base-hw/src/core/core_region_map.cc index 1ad0c25f8..f84c74588 100644 --- a/repos/base-hw/src/core/core_region_map.cc +++ b/repos/base-hw/src/core/core_region_map.cc @@ -67,5 +67,8 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size, return virt_addr; }; - return _ds_ep->apply(ds_cap, lambda); + return _ep.apply(ds_cap, lambda); } + + +void Core_region_map::detach(Local_addr) { } diff --git a/repos/base-hw/src/core/include/core_region_map.h b/repos/base-hw/src/core/include/core_region_map.h deleted file mode 100644 index 176cf06d0..000000000 --- a/repos/base-hw/src/core/include/core_region_map.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * \brief Kernel-specific core-local region map - * \author Norman Feske - * \author Stefan Kalkowski - * \date 2009-04-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 _CORE__INCLUDE__CORE_REGION_MAP_H_ -#define _CORE__INCLUDE__CORE_REGION_MAP_H_ - -/* Genode includes */ -#include -#include - -/* core includes */ -#include - -namespace Genode { class Core_region_map; } - - -class Genode::Core_region_map : public Region_map -{ - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false); - - void detach(Local_addr) { } - - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - - void fault_handler(Signal_context_capability handler) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } -}; - -#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base-hw/src/core/include/pager.h b/repos/base-hw/src/core/include/pager.h index 4acbf38bb..cd6f466f9 100644 --- a/repos/base-hw/src/core/include/pager.h +++ b/repos/base-hw/src/core/include/pager.h @@ -121,16 +121,17 @@ class Genode::Ipc_pager void set_reply_mapping(Mapping m); }; -class Genode::Pager_object -: public Object_pool::Entry, - public Genode::Kernel_object + +class Genode::Pager_object : public Object_pool::Entry, + public Genode::Kernel_object { friend class Pager_entrypoint; private: - Thread_capability _thread_cap; - unsigned long const _badge; + unsigned long const _badge; + Cpu_session_capability _cpu_session_cap; + Thread_capability _thread_cap; public: @@ -139,7 +140,9 @@ class Genode::Pager_object * * \param badge user identifaction of pager object */ - Pager_object(unsigned const badge, Affinity::Location); + Pager_object(Cpu_session_capability cpu_session_cap, + Thread_capability thread_cap, unsigned const badge, + Affinity::Location); /** * User identification of pager object @@ -188,9 +191,8 @@ class Genode::Pager_object ** Accessors ** ***************/ - Thread_capability thread_cap() const; - - void thread_cap(Thread_capability const & c); + Cpu_session_capability cpu_session_cap() const { return _cpu_session_cap; } + Thread_capability thread_cap() const { return _thread_cap; } }; diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index b176dc9aa..9b1e69f71 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -188,7 +188,7 @@ class Genode::Platform_pd : public Hw::Address_space, /** * Bind thread 't' to protection domain */ - void bind_thread(Platform_thread * t); + bool bind_thread(Platform_thread * t); /** * Unbind thread 't' from protection domain diff --git a/repos/base-hw/src/core/include/platform_thread.h b/repos/base-hw/src/core/include/platform_thread.h index 89afced76..68dc4a826 100644 --- a/repos/base-hw/src/core/include/platform_thread.h +++ b/repos/base-hw/src/core/include/platform_thread.h @@ -101,7 +101,8 @@ namespace Genode { * \param utcb core local pointer to userland stack */ Platform_thread(size_t const quota, const char * const label, - unsigned const virt_prio, addr_t const utcb); + unsigned const virt_prio, Affinity::Location, + addr_t const utcb); /** * Destructor diff --git a/repos/base-hw/src/core/pager.cc b/repos/base-hw/src/core/pager.cc index 9d283a4fb..8981e04f9 100644 --- a/repos/base-hw/src/core/pager.cc +++ b/repos/base-hw/src/core/pager.cc @@ -62,10 +62,6 @@ void Ipc_pager::set_reply_mapping(Mapping m) { _mapping = m; } ** Pager_object ** ******************/ -Thread_capability Pager_object::thread_cap() const { return _thread_cap; } - -void Pager_object::thread_cap(Thread_capability const & c) { _thread_cap = c; } - void Pager_object::wake_up() { using Object = Kernel_object; @@ -92,9 +88,12 @@ void Pager_object::unresolved_page_fault_occurred() pt->kernel_object()->sp, pt->kernel_object()->fault_addr()); } -Pager_object::Pager_object(unsigned const badge, Affinity::Location) -: Object_pool::Entry(Kernel_object::_cap), - _badge(badge) +Pager_object::Pager_object(Cpu_session_capability cpu_session_cap, + Thread_capability thread_cap, unsigned const badge, + Affinity::Location) +: + Object_pool::Entry(Kernel_object::_cap), + _badge(badge), _cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap) { } diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index fc47bcdd9..0012dffad 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -131,12 +131,13 @@ void Capability_space::upgrade_slab(Allocator &alloc) ** Platform_pd implementation ** ********************************/ -void Platform_pd::bind_thread(Platform_thread * t) +bool Platform_pd::bind_thread(Platform_thread * t) { /* is this the first and therefore main thread in this PD? */ bool main_thread = !_thread_associated; _thread_associated = true; t->join_pd(this, main_thread, Address_space::weak_ptr()); + return true; } diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 91f59241d..ad5670493 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -79,6 +79,7 @@ Platform_thread::Platform_thread(const char * const label, Platform_thread::Platform_thread(size_t const quota, const char * const label, unsigned const virt_prio, + Affinity::Location location, addr_t const utcb) : Kernel_object(true, _priority(virt_prio), quota, _label), _pd(nullptr), @@ -96,6 +97,7 @@ Platform_thread::Platform_thread(size_t const quota, throw Cpu_session::Out_of_metadata(); } _utcb_core_addr = (Native_utcb *)core_env()->rm_session()->attach(_utcb); + affinity(location); } diff --git a/repos/base-linux/src/base/process/process.cc b/repos/base-linux/src/base/process/process.cc index 7515f6854..d5355dbeb 100644 --- a/repos/base-linux/src/base/process/process.cc +++ b/repos/base-linux/src/base/process/process.cc @@ -56,6 +56,7 @@ Process::Process(Dataspace_capability elf_data_ds_cap, Pd_session_capability pd_session_cap, Ram_session_capability ram_session_cap, Cpu_session_capability cpu_session_cap, + Region_map &, Parent_capability parent_cap, char const *name) : @@ -80,7 +81,8 @@ Process::Process(Dataspace_capability elf_data_ds_cap, * the 'Platform_env' of the new process. */ enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT }; - _thread0_cap = _cpu_session_client.create_thread(WEIGHT, name); + _thread0_cap = _cpu_session_client.create_thread(pd_session_cap, + WEIGHT, name); Linux_native_pd_client lx_pd(static_cap_cast(_pd_session_client.native_pd())); diff --git a/repos/base-linux/src/base/region_map_client.cc b/repos/base-linux/src/base/region_map_client.cc index e5ee05537..7f3364f43 100644 --- a/repos/base-linux/src/base/region_map_client.cc +++ b/repos/base-linux/src/base/region_map_client.cc @@ -50,14 +50,6 @@ void Region_map_client::detach(Local_addr local_addr) { return _local(*this)->detach(local_addr); } -Pager_capability Region_map_client::add_client(Thread_capability thread) { - return _local(*this)->add_client(thread); } - - -void Region_map_client::remove_client(Pager_capability pager) { - _local(*this)->remove_client(pager); } - - void Region_map_client::fault_handler(Signal_context_capability /*handler*/) { /* diff --git a/repos/base-linux/src/base/thread/thread_linux.cc b/repos/base-linux/src/base/thread/thread_linux.cc index 96bcd8194..71211911d 100644 --- a/repos/base-linux/src/base/thread/thread_linux.cc +++ b/repos/base-linux/src/base/thread/thread_linux.cc @@ -83,7 +83,8 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) /* for normal threads create an object at the CPU session */ if (type == NORMAL) { - _thread_cap = _cpu_session->create_thread(weight, _stack->name().string()); + _thread_cap = _cpu_session->create_thread(env()->pd_session_cap(), + weight, _stack->name().string()); return; } /* adjust initial object state for main threads */ diff --git a/repos/base-linux/src/core/include/pager.h b/repos/base-linux/src/core/include/pager.h index ed56e0c2f..7b736563a 100644 --- a/repos/base-linux/src/core/include/pager.h +++ b/repos/base-linux/src/core/include/pager.h @@ -53,6 +53,10 @@ namespace Genode { template auto apply(Pager_capability, FUNC f) -> decltype(f(nullptr)) { return f(nullptr); } + + Pager_capability manage(Pager_object *) { return Pager_capability(); } + + void dissolve(Pager_object *) { } }; } diff --git a/repos/base-linux/src/core/include/platform_pd.h b/repos/base-linux/src/core/include/platform_pd.h index 9a05be50e..7dcc2bc7b 100644 --- a/repos/base-linux/src/core/include/platform_pd.h +++ b/repos/base-linux/src/core/include/platform_pd.h @@ -18,8 +18,16 @@ #include -namespace Genode { struct Platform_pd; } +namespace Genode { + struct Platform_pd; + struct Platform_thread; +} -struct Genode::Platform_pd { Platform_pd(Allocator *, char const *) { } }; +struct Genode::Platform_pd +{ + Platform_pd(Allocator *, char const *) { } + + bool bind_thread(Platform_thread *) { return true; } +}; #endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */ diff --git a/repos/base-linux/src/core/include/platform_thread.h b/repos/base-linux/src/core/include/platform_thread.h index 84486d2b0..14c577717 100644 --- a/repos/base-linux/src/core/include/platform_thread.h +++ b/repos/base-linux/src/core/include/platform_thread.h @@ -19,6 +19,7 @@ /* Genode includes */ #include #include +#include /* base-internal includes */ #include @@ -30,6 +31,8 @@ namespace Genode { class Platform_thread; + class Address_space; + /* * We hold all Platform_thread objects in a list in order to be able to * reflect SIGCHLD as exception signals. When a SIGCHILD occurs, we @@ -81,7 +84,8 @@ namespace Genode { /** * Constructor */ - Platform_thread(size_t, const char *name, unsigned priority, addr_t); + Platform_thread(size_t, const char *name, unsigned priority, + Affinity::Location, addr_t); ~Platform_thread(); @@ -174,6 +178,10 @@ namespace Genode { * Return execution time consumed by the thread */ unsigned long long execution_time() const { return 0; } + + Weak_ptr address_space() { return Weak_ptr(); } + + unsigned long pager_object_badge() const { return 0; } }; } diff --git a/repos/base-linux/src/core/include/region_map_component.h b/repos/base-linux/src/core/include/region_map_component.h index 5942112c2..28f59b46a 100644 --- a/repos/base-linux/src/core/include/region_map_component.h +++ b/repos/base-linux/src/core/include/region_map_component.h @@ -22,8 +22,9 @@ #include #include -/* Core includes */ +/* core includes */ #include +#include namespace Genode { struct Rm_client; @@ -46,16 +47,14 @@ class Genode::Region_map_component : public Rpc_object, void upgrade_ram_quota(size_t ram_quota) { } + void add_client(Rm_client &) { } + void remove_client(Rm_client &) { } + Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) { return (addr_t)0; } void detach(Local_addr) { } - Pager_capability add_client(Thread_capability) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - void fault_handler(Signal_context_capability) { } State state() { return State(); } @@ -69,6 +68,13 @@ class Genode::Region_map_component : public Rpc_object, struct Genode::Rm_member { Region_map_component *member_rm() { return 0; } }; -struct Genode::Rm_client : Pager_object, Rm_member { }; +struct Genode::Rm_client : Pager_object, Rm_member +{ + Rm_client(Cpu_session_capability, Thread_capability, + Region_map_component *rm, unsigned long badge, + Weak_ptr &address_space, + Affinity::Location location) + { } +}; #endif /* _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/include/util.h b/repos/base-linux/src/core/include/util.h index 2ff35dc9c..9283e96b6 100644 --- a/repos/base-linux/src/core/include/util.h +++ b/repos/base-linux/src/core/include/util.h @@ -14,9 +14,7 @@ #ifndef _CORE__INCLUDE__UTIL_H_ #define _CORE__INCLUDE__UTIL_H_ -namespace Genode { - constexpr size_t get_page_size_log2() { return 12; } - constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } -} +/* base-internal includes */ +#include #endif /* _CORE__INCLUDE__UTIL_H_ */ diff --git a/repos/base-linux/src/core/pd_session_component.cc b/repos/base-linux/src/core/pd_session_component.cc index c512997a4..f0322bb2c 100644 --- a/repos/base-linux/src/core/pd_session_component.cc +++ b/repos/base-linux/src/core/pd_session_component.cc @@ -17,9 +17,6 @@ using namespace Genode; -void Pd_session_component::bind_thread(Thread_capability) { } - - void Pd_session_component::assign_parent(Capability parent) { _parent = parent; diff --git a/repos/base-linux/src/core/platform_thread.cc b/repos/base-linux/src/core/platform_thread.cc index f7fe433a3..77ce98bf0 100644 --- a/repos/base-linux/src/core/platform_thread.cc +++ b/repos/base-linux/src/core/platform_thread.cc @@ -74,7 +74,8 @@ Platform_thread::Registry *Platform_thread::_registry() ** Platform_thread ** *********************/ -Platform_thread::Platform_thread(size_t, const char *name, unsigned, addr_t) +Platform_thread::Platform_thread(size_t, const char *name, unsigned, + Affinity::Location, addr_t) : _tid(-1), _pid(-1) { strncpy(_name, name, min(sizeof(_name), strlen(name) + 1)); diff --git a/repos/base-linux/src/core/stack_area.cc b/repos/base-linux/src/core/stack_area.cc index ee830177f..5936177c5 100644 --- a/repos/base-linux/src/core/stack_area.cc +++ b/repos/base-linux/src/core/stack_area.cc @@ -67,11 +67,6 @@ class Stack_area_region_map : public Genode::Region_map void detach(Local_addr local_addr) { PWRN("stack area detach from 0x%p - not implemented", (void *)local_addr); } - Genode::Pager_capability add_client(Genode::Thread_capability) { - return Genode::Pager_capability(); } - - void remove_client(Genode::Pager_capability) { } - void fault_handler(Genode::Signal_context_capability) { } State state() { return State(); } diff --git a/repos/base-linux/src/include/base/internal/platform_env.h b/repos/base-linux/src/include/base/internal/platform_env.h index 70e4a8e17..a4660020f 100644 --- a/repos/base-linux/src/include/base/internal/platform_env.h +++ b/repos/base-linux/src/include/base/internal/platform_env.h @@ -45,10 +45,12 @@ struct Genode::Expanding_cpu_session_client Expanding_cpu_session_client(Genode::Capability cap) : Upgradeable_client(cap) { } - Thread_capability create_thread(size_t weight, Name const &name, addr_t utcb) + Thread_capability create_thread(Pd_session_capability pd, size_t weight, + Name const &name, Affinity::Location affinity, + addr_t utcb) { return retry( - [&] () { return Cpu_session_client::create_thread(weight, name, utcb); }, + [&] () { return Cpu_session_client::create_thread(pd, weight, name, affinity, utcb); }, [&] () { upgrade_ram(8*1024); }); } }; @@ -280,11 +282,6 @@ class Genode::Platform_env_base : public Env void detach(Local_addr local_addr); - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability pager) { } - void fault_handler(Signal_context_capability handler) { } State state() { return State(); } diff --git a/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc b/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc index 90e5c5204..9cc10e464 100644 --- a/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc +++ b/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc @@ -452,7 +452,7 @@ Native_thread &Thread_base::native_thread() { return *_native_thread; } Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, - Type type, Cpu_session * cpu_sess) + Type type, Cpu_session * cpu_sess, Affinity::Location) : _cpu_session(cpu_sess) { Native_thread::Meta_data *meta_data = @@ -470,7 +470,7 @@ Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, native_thread().meta_data->wait_for_construction(); - _thread_cap = _cpu_session->create_thread(weight, name); + _thread_cap = _cpu_session->create_thread(env()->pd_session_cap(), weight, name); Linux_native_cpu_client native_cpu(_cpu_session->native_cpu()); native_cpu.thread_id(_thread_cap, native_thread().pid, native_thread().tid); @@ -478,7 +478,7 @@ Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, - Type type) + Type type, Affinity::Location) : Thread_base(weight, name, stack_size, type, env()->cpu_session()) { } void Thread_base::cancel_blocking() diff --git a/repos/base-nova/include/cpu_session/client.h b/repos/base-nova/include/cpu_session/client.h index 1faa05628..ad1a735dd 100644 --- a/repos/base-nova/include/cpu_session/client.h +++ b/repos/base-nova/include/cpu_session/client.h @@ -28,22 +28,21 @@ namespace Genode { explicit Cpu_session_client(Cpu_session_capability session) : Rpc_client(static_cap_cast(session)) { } - Thread_capability create_thread(size_t weight, Name const &name, addr_t utcb = 0) { - return call(weight, name, utcb); } + Thread_capability + create_thread(Capability pd, size_t quota, Name const &name, + Affinity::Location affinity, addr_t utcb = 0) override { + return call(pd, quota, name, affinity, utcb); } - Ram_dataspace_capability utcb(Thread_capability thread) { + Ram_dataspace_capability utcb(Thread_capability thread) override { return call(thread); } - void kill_thread(Thread_capability thread) { + void kill_thread(Thread_capability thread) override { call(thread); } - int set_pager(Thread_capability thread, Pager_capability pager) { - return call(thread, pager); } - - int start(Thread_capability thread, addr_t ip, addr_t sp) { + int start(Thread_capability thread, addr_t ip, addr_t sp) override { return call(thread, ip, sp); } - void pause(Thread_capability thread) + void pause(Thread_capability thread) override { Native_capability block = call(thread); if (!block.valid()) @@ -52,22 +51,22 @@ namespace Genode { Nova::sm_ctrl(block.local_name(), Nova::SEMAPHORE_DOWN); } - void resume(Thread_capability thread) { + void resume(Thread_capability thread) override { call(thread); } - void cancel_blocking(Thread_capability thread) { + void cancel_blocking(Thread_capability thread) override { call(thread); } - Thread_state state(Thread_capability thread) { + Thread_state state(Thread_capability thread) override { return call(thread); } - void state(Thread_capability thread, Thread_state const &state) { + void state(Thread_capability thread, Thread_state const &state) override { call(thread, state); } - void exception_handler(Thread_capability thread, Signal_context_capability handler) { + void exception_handler(Thread_capability thread, Signal_context_capability handler) override { call(thread, handler); } - void single_step(Thread_capability thread, bool enable) + void single_step(Thread_capability thread, bool enable) override { Native_capability block = call(thread, enable); if (!block.valid()) @@ -76,28 +75,28 @@ namespace Genode { Nova::sm_ctrl(block.local_name(), Nova::SEMAPHORE_DOWN); } - Affinity::Space affinity_space() const { + Affinity::Space affinity_space() const override { return call(); } - void affinity(Thread_capability thread, Affinity::Location location) { + void affinity(Thread_capability thread, Affinity::Location location) override { call(thread, location); } - Dataspace_capability trace_control() { + Dataspace_capability trace_control() override { return call(); } - unsigned trace_control_index(Thread_capability thread) { + unsigned trace_control_index(Thread_capability thread) override { return call(thread); } - Dataspace_capability trace_buffer(Thread_capability thread) { + Dataspace_capability trace_buffer(Thread_capability thread) override { return call(thread); } - Dataspace_capability trace_policy(Thread_capability thread) { + Dataspace_capability trace_policy(Thread_capability thread) override { return call(thread); } - int ref_account(Cpu_session_capability session) { + int ref_account(Cpu_session_capability session) override { return call(session); } - int transfer_quota(Cpu_session_capability session, size_t amount) { + int transfer_quota(Cpu_session_capability session, size_t amount) override { return call(session, amount); } Quota quota() override { return call(); } diff --git a/repos/base-nova/include/nova/native_thread.h b/repos/base-nova/include/nova/native_thread.h index 32aec3fa9..aa8d34a69 100644 --- a/repos/base-nova/include/nova/native_thread.h +++ b/repos/base-nova/include/nova/native_thread.h @@ -35,6 +35,8 @@ struct Genode::Native_thread /* receive window for capability selectors received at the server side */ Receive_window rcv_window; + Native_capability pager_cap; + Native_thread() : ec_sel(INVALID_INDEX), exc_pt_sel(INVALID_INDEX), is_vcpu(false) { } }; diff --git a/repos/base-nova/include/nova_native_cpu/client.h b/repos/base-nova/include/nova_native_cpu/client.h new file mode 100644 index 000000000..252172ab5 --- /dev/null +++ b/repos/base-nova/include/nova_native_cpu/client.h @@ -0,0 +1,32 @@ +/* + * \brief Client-side NOVA-specific CPU session interface + * \author Norman Feske + * \date 2016-04-21 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_ +#define _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_ + +#include +#include + +namespace Genode { struct Nova_native_cpu_client; } + + +struct Genode::Nova_native_cpu_client : Rpc_client +{ + explicit Nova_native_cpu_client(Capability cap) + : Rpc_client(static_cap_cast(cap)) { } + + Native_capability pager_cap(Thread_capability cap) { + return call(cap); } +}; + +#endif /* _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_ */ diff --git a/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h b/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h new file mode 100644 index 000000000..582346002 --- /dev/null +++ b/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h @@ -0,0 +1,36 @@ +/* + * \brief NOVA-specific part of the CPU session interface + * \author Norman Feske + * \date 2016-04-21 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__NOVA_NATIVE_CPU__FOC_NATIVE_CPU_H_ +#define _INCLUDE__NOVA_NATIVE_CPU__FOC_NATIVE_CPU_H_ + +#include +#include + +namespace Genode { struct Nova_native_cpu; } + + +struct Genode::Nova_native_cpu : Cpu_session::Native_cpu +{ + virtual Native_capability pager_cap(Thread_capability) = 0; + + + /********************* + ** RPC declaration ** + *********************/ + + GENODE_RPC(Rpc_pager_cap, Native_capability, pager_cap, Thread_capability); + GENODE_RPC_INTERFACE(Rpc_pager_cap); +}; + +#endif /* _INCLUDE__NOVA_NATIVE_CPU__FOC_NATIVE_CPU_H_ */ 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 0b0fe232a..827c104a4 100644 --- a/repos/base-nova/lib/mk/spec/x86_32/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_32/core.mk @@ -1,6 +1,7 @@ SRC_CC += pager.cc INC_DIR = $(REP_DIR)/src/core/include \ - $(BASE_DIR)/src/core/include + $(BASE_DIR)/src/core/include \ + $(BASE_DIR)/src/include 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 6d7324c6c..d6fc61fbb 100644 --- a/repos/base-nova/lib/mk/spec/x86_64/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_64/core.mk @@ -1,5 +1,6 @@ SRC_CC += pager.cc -INC_DIR = $(REP_DIR)/src/core/include +INC_DIR = $(REP_DIR)/src/core/include \ + $(BASE_DIR)/src/include vpath %.cc $(REP_DIR)/src/core/spec/x86_64 diff --git a/repos/base-nova/src/base/region_map_client.cc b/repos/base-nova/src/base/region_map_client.cc index 5f252691c..e6463b3ba 100644 --- a/repos/base-nova/src/base/region_map_client.cc +++ b/repos/base-nova/src/base/region_map_client.cc @@ -20,6 +20,7 @@ using namespace Genode; Region_map_client::Region_map_client(Capability session) : Rpc_client(session) { } + Region_map::Local_addr Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset, bool use_local_addr, Local_addr local_addr, @@ -29,21 +30,17 @@ Region_map_client::attach(Dataspace_capability ds, size_t size, off_t offset, executable); } + void Region_map_client::detach(Local_addr local_addr) { call(local_addr); } -Pager_capability Region_map_client::add_client(Thread_capability thread) -{ - return call(thread); -} - -void Region_map_client::remove_client(Pager_capability pager) { - call(pager); } void Region_map_client::fault_handler(Signal_context_capability cap) { call(cap); } - Region_map::State Region_map_client::state() { return call(); } + +Region_map::State Region_map_client::state() { return call(); } + Dataspace_capability Region_map_client::dataspace() { diff --git a/repos/base-nova/src/base/server/server.cc b/repos/base-nova/src/base/server/server.cc index 0c9a76b6e..35ef27682 100644 --- a/repos/base-nova/src/base/server/server.cc +++ b/repos/base-nova/src/base/server/server.cc @@ -219,23 +219,13 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, const char *name, bool start_on_construction, Affinity::Location location) : - Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size), + Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size, location), _delay_start(Lock::LOCKED), _pd_session(*pd_session) { - /* when not running in core set the affinity via cpu session */ - if (native_thread().ec_sel == Native_thread::INVALID_INDEX) { - - /* place new thread on the specified CPU */ - if (location.valid()) - _cpu_session->affinity(_thread_cap, location); - - /* magic value evaluated by thread_nova.cc to start a local thread */ + /* set magic value evaluated by thread_nova.cc to start a local thread */ + if (native_thread().ec_sel == Native_thread::INVALID_INDEX) native_thread().ec_sel = Native_thread::INVALID_INDEX - 1; - } else { - /* tell affinity CPU in 'core' via stack */ - reinterpret_cast(stack_base())[0] = location; - } /* required to create a 'local' EC */ Thread_base::start(); diff --git a/repos/base-nova/src/base/thread/thread_nova.cc b/repos/base-nova/src/base/thread/thread_nova.cc index c08349a65..3bc9f9d1c 100644 --- a/repos/base-nova/src/base/thread/thread_nova.cc +++ b/repos/base-nova/src/base/thread/thread_nova.cc @@ -20,6 +20,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -82,12 +83,11 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) _thread_cap = env()->parent()->main_thread_cap(); Genode::Native_capability pager_cap(Nova::PT_SEL_MAIN_PAGER); - _pager_cap = reinterpret_cap_cast(pager_cap); native_thread().exc_pt_sel = 0; native_thread().ec_sel = Nova::PT_SEL_MAIN_EC; - request_native_ec_cap(_pager_cap, native_thread().ec_sel); + request_native_ec_cap(pager_cap, native_thread().ec_sel); return; } @@ -116,12 +116,9 @@ void Thread_base::_init_platform_thread(size_t weight, Type type) char buf[48]; name(buf, sizeof(buf)); - _thread_cap = _cpu_session->create_thread(weight, buf); + _thread_cap = _cpu_session->create_thread(env()->pd_session_cap(), weight, buf, _affinity); if (!_thread_cap.valid()) throw Cpu_session::Thread_creation_failed(); - - /* assign thread to protection domain */ - env()->pd_session()->bind_thread(_thread_cap); } @@ -139,9 +136,6 @@ void Thread_base::_deinit_platform_thread() _cpu_session->kill_thread(_thread_cap); cap_map()->remove(native_thread().exc_pt_sel, NUM_INITIAL_PT_LOG2); - - if (_pager_cap.valid()) - env()->rm_session()->remove_client(_pager_cap); } @@ -158,12 +152,12 @@ void Thread_base::start() using namespace Genode; - /* create new pager object and assign it to the new thread */ - _pager_cap = env()->rm_session()->add_client(_thread_cap); - if (!_pager_cap.valid()) - throw Cpu_session::Thread_creation_failed(); + /* obtain interface to NOVA-specific CPU session operations */ + Nova_native_cpu_client native_cpu(_cpu_session->native_cpu()); - if (_cpu_session->set_pager(_thread_cap, _pager_cap)) + /* create new pager object and assign it to the new thread */ + Native_capability pager_cap = native_cpu.pager_cap(_thread_cap); + if (!pager_cap.valid()) throw Cpu_session::Thread_creation_failed(); /* create EC at core */ @@ -187,13 +181,13 @@ void Thread_base::start() /* requested pager cap used by request_native_ec_cap in Signal_source_client */ enum { MAP_PAGER_CAP = 1 }; - request_native_ec_cap(_pager_cap, native_thread().ec_sel, MAP_PAGER_CAP); + request_native_ec_cap(pager_cap, native_thread().ec_sel, MAP_PAGER_CAP); using namespace Nova; /* request exception portals for normal threads */ if (!native_thread().is_vcpu) { - request_event_portal(_pager_cap, native_thread().exc_pt_sel, 0, NUM_INITIAL_PT_LOG2); + request_event_portal(pager_cap, native_thread().exc_pt_sel, 0, NUM_INITIAL_PT_LOG2); /* default: we don't accept any mappings or translations */ Utcb * utcb_obj = reinterpret_cast(utcb()); diff --git a/repos/base-nova/src/core/core_region_map.cc b/repos/base-nova/src/core/core_region_map.cc index 23b006ca2..f325da3d8 100644 --- a/repos/base-nova/src/core/core_region_map.cc +++ b/repos/base-nova/src/core/core_region_map.cc @@ -86,7 +86,7 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size, return virt_ptr; }; - return _ds_ep->apply(ds_cap, lambda); + return _ep.apply(ds_cap, lambda); } diff --git a/repos/base-nova/src/core/cpu_session_extension.cc b/repos/base-nova/src/core/cpu_session_extension.cc index 68269d2c5..4324f1924 100644 --- a/repos/base-nova/src/core/cpu_session_extension.cc +++ b/repos/base-nova/src/core/cpu_session_extension.cc @@ -14,7 +14,7 @@ /* Genode includes */ #include -/* Core includes */ +/* core-local includes */ #include using namespace Genode; diff --git a/repos/base-nova/src/core/include/core_region_map.h b/repos/base-nova/src/core/include/core_region_map.h deleted file mode 100644 index 9f995243c..000000000 --- a/repos/base-nova/src/core/include/core_region_map.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief Core-local region map - * \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 _CORE__INCLUDE__CORE_REGION_MAP_H_ -#define _CORE__INCLUDE__CORE_REGION_MAP_H_ - -/* Genode includes */ -#include - -/* core includes */ -#include - -namespace Genode { class Core_region_map; } - - -class Genode::Core_region_map : public Region_map -{ - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_region_map(Rpc_entrypoint *ds_ep) : _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false) override; - - void detach(Local_addr) override; - - Pager_capability add_client(Thread_capability thread) override { - return Pager_capability(); } - - void remove_client(Pager_capability) override { } - - void fault_handler(Signal_context_capability handler) override { } - - State state() override { return State(); } - - Dataspace_capability dataspace() override { - return Dataspace_capability(); } -}; - -#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base-nova/src/core/include/cpu_session_component.h b/repos/base-nova/src/core/include/cpu_session_component.h index 709b7b357..5fb3a1fc3 100644 --- a/repos/base-nova/src/core/include/cpu_session_component.h +++ b/repos/base-nova/src/core/include/cpu_session_component.h @@ -26,6 +26,8 @@ /* core includes */ #include +#include +#include #include #include #include @@ -57,31 +59,120 @@ namespace Genode { private: + Rpc_entrypoint &_ep; + Pager_entrypoint &_pager_ep; + Capability _pd; + Region_map_component &_address_space_region_map; + size_t const _weight; Session_label const _session_label; Thread_name const _name; Platform_thread _platform_thread; - bool _bound; /* pd binding flag */ + bool const _bound_to_pd; + + bool _bind_to_pd(Pd_session_component &pd) + { + if (!pd.bind_thread(_platform_thread)) + throw Cpu_session::Thread_creation_failed(); + return true; + } + Signal_context_capability _sigh; /* exception handler */ - unsigned const _trace_control_index; - Trace::Source _trace_source; + + struct Trace_control_slot + { + unsigned index = 0; + Trace::Control_area &trace_control_area; + + Trace_control_slot(Trace::Control_area &trace_control_area) + : trace_control_area(trace_control_area) + { + if (!trace_control_area.alloc(index)) + throw Cpu_session::Out_of_metadata(); + } + + ~Trace_control_slot() + { + trace_control_area.free(index); + } + + Trace::Control &control() + { + return *trace_control_area.at(index); + } + }; + + Trace_control_slot _trace_control_slot; + + Trace::Source _trace_source { *this, _trace_control_slot.control() }; + + Weak_ptr _address_space = _platform_thread.address_space(); + + Rm_client _rm_client; public: - Cpu_thread_component(size_t const weight, + /** + * Constructor + * + * \param ep entrypoint used for managing the thread RPC + * object + * \param pager_ep pager entrypoint used for handling the page + * faults of the thread + * \param pd PD session where the thread is executed + * \param weight weighting regarding the CPU session quota + * \param quota initial quota counter-value of the weight + * \param labal label of the threads session + * \param name name for the thread + * \param priority scheduling priority + * \param utcb user-local UTCB base + * \param sigh initial exception handler + */ + Cpu_thread_component(Cpu_session_capability cpu_session_cap, + Rpc_entrypoint &ep, + Pager_entrypoint &pager_ep, + Pd_session_component &pd, + Trace::Control_area &trace_control_area, + size_t const weight, size_t const quota, + Affinity::Location affinity, Session_label const &label, Thread_name const &name, unsigned priority, addr_t utcb, - Signal_context_capability sigh, - unsigned trace_control_index, - Trace::Control &trace_control) + Signal_context_capability sigh) : + _ep(ep), _pager_ep(pager_ep), _pd(pd.cap()), + _address_space_region_map(pd.address_space_region_map()), + _weight(weight), _session_label(label), _name(name), - _platform_thread(name.string(), priority, utcb), _bound(false), - _sigh(sigh), _trace_control_index(trace_control_index), - _trace_source(*this, trace_control) + _platform_thread(name.string(), priority, affinity, utcb), + _bound_to_pd(_bind_to_pd(pd)), + _sigh(sigh), + _trace_control_slot(trace_control_area), + _rm_client(cpu_session_cap, _ep.manage(this), + &_address_space_region_map, + _platform_thread.pager_object_badge(), + _address_space, _platform_thread.affinity()) { update_exception_sigh(); + + _address_space_region_map.add_client(_rm_client); + + /* acquaint thread with its pager object */ + _pager_ep.manage(&_rm_client); + _platform_thread.pager(&_rm_client); + } + + ~Cpu_thread_component() + { + _pager_ep.dissolve(&_rm_client); + _ep.dissolve(this); + + _address_space_region_map.remove_client(_rm_client); + } + + void affinity(Affinity::Location affinity) + { + _platform_thread.affinity(affinity); } @@ -102,8 +193,6 @@ namespace Genode { ************************/ Platform_thread *platform_thread() { return &_platform_thread; } - bool bound() const { return _bound; } - void bound(bool b) { _bound = b; } Trace::Source *trace_source() { return &_trace_source; } size_t weight() const { return Cpu_session::DEFAULT_WEIGHT; } @@ -122,7 +211,7 @@ namespace Genode { /** * Return index within the CPU-session's trace control area */ - unsigned trace_control_index() const { return _trace_control_index; } + unsigned trace_control_index() const { return _trace_control_slot.index; } }; @@ -134,12 +223,6 @@ namespace Genode { private: - /** - * Allocator used for managing the CPU threads associated with the - * CPU session - */ - typedef Tslab Cpu_thread_allocator; - Session_label _label; Rpc_entrypoint *_session_ep; Rpc_entrypoint *_thread_ep; @@ -167,7 +250,7 @@ namespace Genode { List _ref_members; Lock _ref_members_lock; - Native_cpu_component _native_cpu; + Native_cpu_component _native_cpu; friend class Native_cpu_component; @@ -201,6 +284,11 @@ namespace Genode { */ void _unsynchronized_kill_thread(Thread_capability cap); + /** + * Convert session-local affinity location to physical location + */ + Affinity::Location _thread_affinity(Affinity::Location) const; + public: /** @@ -229,37 +317,37 @@ namespace Genode { ** CPU session interface ** ***************************/ - Thread_capability create_thread(size_t, Name const &, addr_t); - Ram_dataspace_capability utcb(Thread_capability thread); - void kill_thread(Thread_capability); - int set_pager(Thread_capability, Pager_capability); - int start(Thread_capability, addr_t, addr_t); - void pause(Thread_capability thread_cap); - void resume(Thread_capability thread_cap); - void single_step(Thread_capability thread_cap, bool enable); - void cancel_blocking(Thread_capability); - int name(Thread_capability, char *, size_t); - Thread_state state(Thread_capability); - void state(Thread_capability, Thread_state const &); - void exception_handler(Thread_capability, Signal_context_capability); - Affinity::Space affinity_space() const; - void affinity(Thread_capability, Affinity::Location); - Dataspace_capability trace_control(); - unsigned trace_control_index(Thread_capability); - Dataspace_capability trace_buffer(Thread_capability); - Dataspace_capability trace_policy(Thread_capability); - int ref_account(Cpu_session_capability c); - int transfer_quota(Cpu_session_capability, size_t); + Thread_capability create_thread(Capability, size_t, Name const &, + Affinity::Location, addr_t) override; + Ram_dataspace_capability utcb(Thread_capability thread) override; + void kill_thread(Thread_capability) override; + int start(Thread_capability, addr_t, addr_t) override; + void pause(Thread_capability thread_cap) override; + void resume(Thread_capability thread_cap) override; + void single_step(Thread_capability thread_cap, bool enable) override; + void cancel_blocking(Thread_capability) override; + Thread_state state(Thread_capability) override; + void state(Thread_capability, Thread_state const &) override; + void exception_handler(Thread_capability, Signal_context_capability) override; + Affinity::Space affinity_space() const override; + void affinity(Thread_capability, Affinity::Location) override; + Dataspace_capability trace_control() override; + unsigned trace_control_index(Thread_capability) override; + Dataspace_capability trace_buffer(Thread_capability) override; + Dataspace_capability trace_policy(Thread_capability) override; + int ref_account(Cpu_session_capability c) override; + int transfer_quota(Cpu_session_capability, size_t) override; Quota quota() override; - Capability native_cpu() { return Capability(); } + + Capability native_cpu() { return _native_cpu.cap(); } /****************************** ** NOVA specific extensions ** ******************************/ - Native_capability pause_sync(Thread_capability); - Native_capability single_step_sync(Thread_capability, bool); + Native_capability pause_sync(Thread_capability) override; + Native_capability single_step_sync(Thread_capability, bool) override; }; } diff --git a/repos/base-nova/src/core/include/native_cpu_component.h b/repos/base-nova/src/core/include/native_cpu_component.h new file mode 100644 index 000000000..dd318bad8 --- /dev/null +++ b/repos/base-nova/src/core/include/native_cpu_component.h @@ -0,0 +1,44 @@ +/* + * \brief Kernel-specific part of the CPU-session interface + * \author Norman Feske + * \date 2016-04-21 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE__INCLUDE__NATIVE_CPU_COMPONENT_H_ +#define _CORE__INCLUDE__NATIVE_CPU_COMPONENT_H_ + +/* Genode includes */ +#include +#include + +namespace Genode { + + class Cpu_session_component; + class Native_cpu_component; +} + + +class Genode::Native_cpu_component : public Rpc_object +{ + private: + + Cpu_session_component &_cpu_session; + Rpc_entrypoint &_thread_ep; + + public: + + Native_cpu_component(Cpu_session_component &, char const *); + ~Native_cpu_component(); + + Native_capability pager_cap(Thread_capability) override; +}; + +#endif /* _CORE__INCLUDE__NATIVE_CPU_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/include/pager.h b/repos/base-nova/src/core/include/pager.h index 6b83b0117..364529fc4 100644 --- a/repos/base-nova/src/core/include/pager.h +++ b/repos/base-nova/src/core/include/pager.h @@ -118,8 +118,9 @@ namespace Genode { inline void skip_reset() { _status &= ~SKIP_EXCEPTION; } } _state; - Thread_capability _thread_cap; - Exception_handlers _exceptions; + Cpu_session_capability _cpu_session_cap; + Thread_capability _thread_cap; + Exception_handlers _exceptions; addr_t _pd; @@ -149,7 +150,9 @@ namespace Genode { const Affinity::Location location; - Pager_object(unsigned long badge, Affinity::Location location); + Pager_object(Cpu_session_capability cpu_session_cap, + Thread_capability thread_cap, + unsigned long badge, Affinity::Location location); virtual ~Pager_object(); @@ -283,11 +286,17 @@ namespace Genode { } /** - * Remember thread cap so that rm_session can tell thread that - * rm_client is gone. + * Return CPU session that was used to created the thread */ - Thread_capability thread_cap() { return _thread_cap; } const - void thread_cap(Thread_capability cap) { _thread_cap = cap; } + Cpu_session_capability cpu_session_cap() const { return _cpu_session_cap; } + + /** + * Return thread capability + * + * This function enables the destructor of the thread's + * address-space region map to kill the thread. + */ + Thread_capability thread_cap() const { return _thread_cap; } /** * Note in the thread state that an unresolved page diff --git a/repos/base-nova/src/core/include/platform_pd.h b/repos/base-nova/src/core/include/platform_pd.h index 168f4b54f..2cdc8e496 100644 --- a/repos/base-nova/src/core/include/platform_pd.h +++ b/repos/base-nova/src/core/include/platform_pd.h @@ -51,7 +51,7 @@ namespace Genode { /** * Bind thread to protection domain */ - void bind_thread(Platform_thread *thread); + bool bind_thread(Platform_thread *thread); /** * Unbind thread from protection domain diff --git a/repos/base-nova/src/core/include/platform_thread.h b/repos/base-nova/src/core/include/platform_thread.h index 899e3c90b..53b9cae12 100644 --- a/repos/base-nova/src/core/include/platform_thread.h +++ b/repos/base-nova/src/core/include/platform_thread.h @@ -70,6 +70,7 @@ namespace Genode { */ Platform_thread(const char *name = 0, unsigned priority = 0, + Affinity::Location affinity = Affinity::Location(), int thread_id = THREAD_INVALID); /** @@ -172,15 +173,6 @@ namespace Genode { if (main_thread) _features |= MAIN_THREAD; } - /** - * Return pointer to the thread's PD - * - * Used to validate the success of the bind operation. - * - * XXX to be removed - */ - Platform_pd *pd() { return _pd; } - Native_capability single_step_sync(bool on); /** diff --git a/repos/base-nova/src/core/include/util.h b/repos/base-nova/src/core/include/util.h index 7dbf9ea46..dc8dbca00 100644 --- a/repos/base-nova/src/core/include/util.h +++ b/repos/base-nova/src/core/include/util.h @@ -18,10 +18,11 @@ #include #include +/* base-internal includes */ +#include + namespace Genode { - constexpr size_t get_page_size_log2() { return 12; } - constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } constexpr size_t get_super_page_size_log2() { return 22; } constexpr size_t get_super_page_size() { return 1 << get_super_page_size_log2(); } inline addr_t trunc_page(addr_t addr) { return addr & _align_mask(get_page_size_log2()); } diff --git a/repos/base-nova/src/core/native_cpu_component.cc b/repos/base-nova/src/core/native_cpu_component.cc new file mode 100644 index 000000000..d8d6a3919 --- /dev/null +++ b/repos/base-nova/src/core/native_cpu_component.cc @@ -0,0 +1,48 @@ +/* + * \brief Core implementation of the CPU session interface extension + * \author Norman Feske + * \date 2016-04-21 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include + +/* core-local includes */ +#include +#include + +using namespace Genode; + + +Native_capability +Native_cpu_component::pager_cap(Thread_capability thread_cap) +{ + auto lambda = [] (Cpu_thread_component *thread) { + if (!thread) + return Native_capability(); + + return thread->platform_thread()->pager()->cap(); + }; + return _thread_ep.apply(thread_cap, lambda); +} + + +Native_cpu_component::Native_cpu_component(Cpu_session_component &cpu_session, char const *) +: + _cpu_session(cpu_session), _thread_ep(*_cpu_session._thread_ep) +{ + _thread_ep.manage(this); +} + + +Genode::Native_cpu_component::~Native_cpu_component() +{ + _thread_ep.dissolve(this); +} diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index 0e73d8eca..0a8d8cb62 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -399,6 +399,10 @@ void Pager_object::cleanup_call() { _state.mark_dissolved(); + /* revoke ec and sc cap of client before the sm cap */ + if (_state.sel_client_ec != Native_thread::INVALID_INDEX) + revoke(Obj_crd(_state.sel_client_ec, 2)); + /* revoke all portals handling the client. */ revoke(Obj_crd(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2)); @@ -502,12 +506,15 @@ Exception_handlers::Exception_handlers(Pager_object *obj) ******************/ -Pager_object::Pager_object(unsigned long badge, Affinity::Location location) +Pager_object::Pager_object(Cpu_session_capability cpu_session_cap, + Thread_capability thread_cap, unsigned long badge, + Affinity::Location location) : _badge(badge), _selectors(cap_map()->insert(2)), _client_exc_pt_sel(cap_map()->insert(NUM_INITIAL_PT_LOG2)), _client_exc_vcpu(Native_thread::INVALID_INDEX), + _cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap), _exceptions(this), location(location) { @@ -815,12 +822,10 @@ addr_t Pager_object::get_oom_portal() Pager_activation_base::Pager_activation_base(const char *name, size_t stack_size) : - Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size), + Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size, + Affinity::Location(which_cpu(this), 0)), _cap(Native_capability()), _ep(0), _cap_valid(Lock::LOCKED) { - /* tell thread starting code on which CPU to let run the pager */ - reinterpret_cast(stack_base())[0] = Affinity::Location(which_cpu(this), 0); - /* creates local EC */ Thread_base::start(); diff --git a/repos/base-nova/src/core/platform_pd.cc b/repos/base-nova/src/core/platform_pd.cc index b198a04a0..0ea4a4e44 100644 --- a/repos/base-nova/src/core/platform_pd.cc +++ b/repos/base-nova/src/core/platform_pd.cc @@ -25,10 +25,11 @@ using namespace Genode; ** Public object members ** ***************************/ -void Platform_pd::bind_thread(Platform_thread *thread) +bool Platform_pd::bind_thread(Platform_thread *thread) { thread->bind_to_pd(this, _thread_cnt == 0); _thread_cnt++; + return true; } diff --git a/repos/base-nova/src/core/platform_thread.cc b/repos/base-nova/src/core/platform_thread.cc index 4ff9746ad..0b12fc456 100644 --- a/repos/base-nova/src/core/platform_thread.cc +++ b/repos/base-nova/src/core/platform_thread.cc @@ -39,12 +39,7 @@ using namespace Genode; void Platform_thread::affinity(Affinity::Location location) { - if (_sel_exc_base != Native_thread::INVALID_INDEX) { - PERR("Failure - affinity of thread could not be set"); - return; - } - - _location = location; + PERR("dynamic affinity change not supported on NOVA"); } @@ -350,10 +345,11 @@ unsigned long long Platform_thread::execution_time() const } -Platform_thread::Platform_thread(const char *name, unsigned prio, int thread_id) +Platform_thread::Platform_thread(const char *name, unsigned prio, + Affinity::Location affinity, int thread_id) : _pd(0), _pager(0), _id_base(cap_map()->insert(2)), - _sel_exc_base(Native_thread::INVALID_INDEX), _location(boot_cpu(), 0, 0, 0), + _sel_exc_base(Native_thread::INVALID_INDEX), _location(affinity), _features(0), _priority(Cpu_session::scale_priority(Nova::Qpd::DEFAULT_PRIORITY, prio)), _name(name) diff --git a/repos/base-nova/src/core/target.inc b/repos/base-nova/src/core/target.inc index c92a1a0b5..8d965965e 100644 --- a/repos/base-nova/src/core/target.inc +++ b/repos/base-nova/src/core/target.inc @@ -23,6 +23,7 @@ SRC_CC = stack_area.cc \ pager.cc \ pd_session_component.cc \ native_pd_component.cc \ + native_cpu_component.cc \ pd_upgrade_ram_quota.cc \ pd_assign_pci.cc \ rpc_cap_factory.cc \ diff --git a/repos/base-nova/src/core/thread_start.cc b/repos/base-nova/src/core/thread_start.cc index c2fb4518a..2f53b6486 100644 --- a/repos/base-nova/src/core/thread_start.cc +++ b/repos/base-nova/src/core/thread_start.cc @@ -95,11 +95,7 @@ void Thread_base::start() Utcb * utcb_obj = reinterpret_cast(&_stack->utcb()); addr_t pd_sel = Platform_pd::pd_core_sel(); - /* - * In core, the affinity location has been written to the stack base by - * the server or pager code. So - read the value from there. - */ - Affinity::Location location = reinterpret_cast(stack_base())[0]; + Affinity::Location location = _affinity; if (!location.valid()) location = Affinity::Location(boot_cpu(), 0); diff --git a/repos/base-okl4/src/core/core_region_map.cc b/repos/base-okl4/src/core/core_region_map.cc index 509d012d8..b36591044 100644 --- a/repos/base-okl4/src/core/core_region_map.cc +++ b/repos/base-okl4/src/core/core_region_map.cc @@ -61,5 +61,8 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size, return virt_addr; }; - return _ds_ep->apply(ds_cap, lambda); + return _ep.apply(ds_cap, lambda); } + + +void Core_region_map::detach(Local_addr) { } diff --git a/repos/base-okl4/src/core/include/core_region_map.h b/repos/base-okl4/src/core/include/core_region_map.h deleted file mode 100644 index 1343c2225..000000000 --- a/repos/base-okl4/src/core/include/core_region_map.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief OKL4-specific core-local region map - * \author Norman Feske - * \date 2009-04-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 _CORE__INCLUDE__CORE_REGION_MAP_H_ -#define _CORE__INCLUDE__CORE_REGION_MAP_H_ - -/* Genode includes */ -#include -#include - -/* core includes */ -#include - -namespace Genode { class Core_region_map; } - - -class Genode::Core_region_map : public Region_map -{ - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, - off_t offset=0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false); - - void detach(Local_addr) { } - - Pager_capability add_client(Thread_capability thread) { - return Pager_capability(); } - - void remove_client(Pager_capability) { } - - void fault_handler(Signal_context_capability handler) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } -}; - -#endif /* _CORE__INCLUDE__CORE_REGION_MAP_H_ */ diff --git a/repos/base-okl4/src/core/include/platform_pd.h b/repos/base-okl4/src/core/include/platform_pd.h index e50392e88..b5518ec15 100644 --- a/repos/base-okl4/src/core/include/platform_pd.h +++ b/repos/base-okl4/src/core/include/platform_pd.h @@ -173,7 +173,7 @@ namespace Genode { * * This function allocates the physical L4 thread ID. */ - void bind_thread(Platform_thread *thread); + bool bind_thread(Platform_thread *thread); /** * Unbind thread from protection domain diff --git a/repos/base-okl4/src/core/include/platform_thread.h b/repos/base-okl4/src/core/include/platform_thread.h index 4b1ff0de9..c0f1c00cd 100644 --- a/repos/base-okl4/src/core/include/platform_thread.h +++ b/repos/base-okl4/src/core/include/platform_thread.h @@ -49,8 +49,9 @@ namespace Genode { * Constructor */ Platform_thread(size_t, const char *name = 0, - unsigned priority = 0, addr_t utcb = 0, - int thread_id = THREAD_INVALID); + unsigned priority = 0, + Affinity::Location = Affinity::Location(), + addr_t utcb = 0, int thread_id = THREAD_INVALID); /** * Destructor diff --git a/repos/base-okl4/src/core/include/util.h b/repos/base-okl4/src/core/include/util.h index e30fb51c0..33afb7774 100644 --- a/repos/base-okl4/src/core/include/util.h +++ b/repos/base-okl4/src/core/include/util.h @@ -21,6 +21,9 @@ #include #include +/* base-internal includes */ +#include + /* OKL4 includes */ namespace Okl4 { extern "C" { #include @@ -61,8 +64,6 @@ namespace Genode { } } - constexpr size_t get_page_size_log2() { return 12; } - constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline size_t get_super_page_size_log2() diff --git a/repos/base-okl4/src/core/platform_pd.cc b/repos/base-okl4/src/core/platform_pd.cc index 234a11b4c..94831ceaf 100644 --- a/repos/base-okl4/src/core/platform_pd.cc +++ b/repos/base-okl4/src/core/platform_pd.cc @@ -176,7 +176,7 @@ void Platform_pd::_free_thread(int thread_id) ** Public object members ** ***************************/ -void Platform_pd::bind_thread(Platform_thread *thread) +bool Platform_pd::bind_thread(Platform_thread *thread) { using namespace Okl4; @@ -187,13 +187,14 @@ void Platform_pd::bind_thread(Platform_thread *thread) int t = _alloc_thread(thread_id, thread); if (t < 0) { PERR("thread alloc failed"); - return; + return false; } thread_id = t; l4_thread_id = make_l4_id(_pd_id, thread_id); /* finally inform thread about binding */ thread->bind(thread_id, l4_thread_id, this); + return true; } diff --git a/repos/base-okl4/src/core/platform_thread.cc b/repos/base-okl4/src/core/platform_thread.cc index 42f178184..1a96061a3 100644 --- a/repos/base-okl4/src/core/platform_thread.cc +++ b/repos/base-okl4/src/core/platform_thread.cc @@ -1,3 +1,4 @@ + /* * \brief OKL4 thread facility * \author Julian Stecklina @@ -178,7 +179,8 @@ Weak_ptr Platform_thread::address_space() } -Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, addr_t, int thread_id) +Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, + Affinity::Location, addr_t, int thread_id) : _thread_id(thread_id), _l4_thread_id(L4_nilthread), _platform_pd(0), _priority(prio), _pager(0) { diff --git a/repos/base-pistachio/src/core/include/platform_pd.h b/repos/base-pistachio/src/core/include/platform_pd.h index 2f4500a66..ab3967ffe 100644 --- a/repos/base-pistachio/src/core/include/platform_pd.h +++ b/repos/base-pistachio/src/core/include/platform_pd.h @@ -205,7 +205,7 @@ namespace Genode { * * This function allocates the physical L4 thread ID. */ - void bind_thread(Platform_thread *thread); + bool bind_thread(Platform_thread *thread); int bind_initial_thread(Platform_thread *thread); diff --git a/repos/base-pistachio/src/core/include/platform_thread.h b/repos/base-pistachio/src/core/include/platform_thread.h index 220a5863b..8a533b4ef 100644 --- a/repos/base-pistachio/src/core/include/platform_thread.h +++ b/repos/base-pistachio/src/core/include/platform_thread.h @@ -67,6 +67,7 @@ namespace Genode { * Constructor */ Platform_thread(size_t, const char *name = 0, unsigned priority = 0, + Affinity::Location = Affinity::Location(), addr_t utcb = 0, int thread_id = THREAD_INVALID); /** @@ -120,15 +121,6 @@ namespace Genode { */ void unbind(); - /** - * Return pointer to the thread's PD - * - * Used to validate the success of the bind operation. - * - * XXX to be removed - */ - Platform_pd *pd() { return _platform_pd; } - /** * Override thread state with 's' * diff --git a/repos/base-pistachio/src/core/include/util.h b/repos/base-pistachio/src/core/include/util.h index e5f601b13..51830b1d5 100644 --- a/repos/base-pistachio/src/core/include/util.h +++ b/repos/base-pistachio/src/core/include/util.h @@ -21,6 +21,9 @@ #include #include +/* base-internal includes */ +#include + /* core-local includes */ #include @@ -80,8 +83,6 @@ namespace Genode { touch_read_write(bptr); } - constexpr size_t get_page_size_log2() { return 12; } - constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline size_t get_super_page_size_log2() diff --git a/repos/base-pistachio/src/core/platform.cc b/repos/base-pistachio/src/core/platform.cc index ae2f6002a..73cbeb3ef 100644 --- a/repos/base-pistachio/src/core/platform.cc +++ b/repos/base-pistachio/src/core/platform.cc @@ -202,7 +202,9 @@ static void _core_pager_loop() } -Platform::Sigma0::Sigma0() : Pager_object(0, Affinity::Location()) +Platform::Sigma0::Sigma0() +: + Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { cap(Native_capability(Pistachio::get_sigma0(), 0)); } @@ -217,7 +219,8 @@ Platform::Sigma0 *Platform::sigma0() Platform::Core_pager::Core_pager(Platform_pd *core_pd) : - Platform_thread(0, "core.pager"), Pager_object(0, Affinity::Location()) + Platform_thread(0, "core.pager"), + Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { Platform_thread::pager(sigma0()); diff --git a/repos/base-pistachio/src/core/platform_pd.cc b/repos/base-pistachio/src/core/platform_pd.cc index b31e20667..29541ce5c 100644 --- a/repos/base-pistachio/src/core/platform_pd.cc +++ b/repos/base-pistachio/src/core/platform_pd.cc @@ -192,7 +192,7 @@ void Platform_pd::_free_thread(int thread_id) ** Public object members ** ***************************/ -void Platform_pd::bind_thread(Platform_thread *thread) +bool Platform_pd::bind_thread(Platform_thread *thread) { using namespace Pistachio; @@ -203,7 +203,7 @@ void Platform_pd::bind_thread(Platform_thread *thread) int t = _alloc_thread(thread_id, thread); if (t < 0) { PERR("thread alloc failed"); - return; + return false; } thread_id = t; l4_thread_id = make_l4_id(_pd_id, thread_id, _version); @@ -212,6 +212,7 @@ void Platform_pd::bind_thread(Platform_thread *thread) thread->bind(thread_id, l4_thread_id, this); if (verbose) _debug_log_threads(); + return true; } diff --git a/repos/base-pistachio/src/core/platform_thread.cc b/repos/base-pistachio/src/core/platform_thread.cc index aacb4f686..5b31c0fe0 100644 --- a/repos/base-pistachio/src/core/platform_thread.cc +++ b/repos/base-pistachio/src/core/platform_thread.cc @@ -243,7 +243,7 @@ Weak_ptr Platform_thread::address_space() Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, - addr_t, int id) + Affinity::Location, addr_t, int id) : _thread_id(id), _l4_thread_id(L4_nilthread), _priority(prio), _pager(0) { strncpy(_name, name, sizeof(_name)); diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index a55d4c80b..1fb097186 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -7,6 +7,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core SRC_CC = stack_area.cc \ core_printf.cc \ core_rpc_cap_alloc.cc \ + core_region_map.cc \ cpu_session_component.cc \ cpu_session_platform.cc \ dataspace_component.cc \ @@ -59,6 +60,7 @@ vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) +vpath core_region_map.cc $(GEN_CORE_DIR) vpath stack_area.cc $(GEN_CORE_DIR) vpath pager_ep.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console diff --git a/repos/base-sel4/src/core/core_region_map.cc b/repos/base-sel4/src/core/core_region_map.cc index 75415a33c..2a463fe18 100644 --- a/repos/base-sel4/src/core/core_region_map.cc +++ b/repos/base-sel4/src/core/core_region_map.cc @@ -62,5 +62,8 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size, return virt_addr; }; - return _ds_ep->apply(ds_cap, lambda); + return _ep.apply(ds_cap, lambda); } + + +void Core_region_map::detach(Local_addr) { } diff --git a/repos/base-sel4/src/core/include/core_region_map.h b/repos/base-sel4/src/core/include/core_region_map.h deleted file mode 100644 index a58d16d09..000000000 --- a/repos/base-sel4/src/core/include/core_region_map.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief Core-local region map - * \author Norman Feske - * \date 2015-05-01 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CORE__INCLUDE__CORE_RM_SESSION_H_ -#define _CORE__INCLUDE__CORE_RM_SESSION_H_ - -/* Genode includes */ -#include -#include - -/* core includes */ -#include - -namespace Genode { class Core_region_map; } - - -class Genode::Core_region_map : public Region_map -{ - private: - - Rpc_entrypoint *_ds_ep; - - public: - - Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } - - Local_addr attach(Dataspace_capability ds_cap, size_t size = 0, - off_t offset = 0, bool use_local_addr = false, - Local_addr local_addr = 0, - bool executable = false) override; - - void detach(Local_addr) override { } - - Pager_capability add_client(Thread_capability) override { - return Pager_capability(); } - - void remove_client(Pager_capability) override { } - - void fault_handler(Signal_context_capability) override { } - - State state() override { return State(); } - - Dataspace_capability dataspace() override { return Dataspace_capability(); } -}; - -#endif /* _CORE__INCLUDE__CORE_RM_SESSION_H_ */ diff --git a/repos/base-sel4/src/core/include/platform_pd.h b/repos/base-sel4/src/core/include/platform_pd.h index b3d2cfd7d..020389790 100644 --- a/repos/base-sel4/src/core/include/platform_pd.h +++ b/repos/base-sel4/src/core/include/platform_pd.h @@ -75,7 +75,7 @@ class Genode::Platform_pd : public Address_space /** * Bind thread to protection domain */ - void bind_thread(Platform_thread *thread); + bool bind_thread(Platform_thread *thread); /** * Unbind thread from protection domain diff --git a/repos/base-sel4/src/core/include/platform_thread.h b/repos/base-sel4/src/core/include/platform_thread.h index 1f5b6cb7c..8cf5bc594 100644 --- a/repos/base-sel4/src/core/include/platform_thread.h +++ b/repos/base-sel4/src/core/include/platform_thread.h @@ -73,7 +73,7 @@ class Genode::Platform_thread : public List::Element * Constructor */ Platform_thread(size_t, const char *name = 0, unsigned priority = 0, - addr_t utcb = 0); + Affinity::Location = Affinity::Location(), addr_t utcb = 0); /** * Destructor @@ -173,15 +173,6 @@ class Genode::Platform_thread : public List::Element */ const char *name() const { return "noname"; } - /** - * Return pointer to the thread's PD - * - * Used to validate the success of the bind operation. - * - * XXX to be removed - */ - Platform_pd *pd() { return _pd; } - /***************************** ** seL4-specific interface ** diff --git a/repos/base-sel4/src/core/include/util.h b/repos/base-sel4/src/core/include/util.h index 6607845de..53432ad69 100644 --- a/repos/base-sel4/src/core/include/util.h +++ b/repos/base-sel4/src/core/include/util.h @@ -18,14 +18,15 @@ #include #include +/* base-internal includes */ +#include + /* core includes */ #include namespace Genode { - constexpr size_t get_page_size_log2() { return 12; } - constexpr size_t get_page_size() { return 1 << get_page_size_log2(); } constexpr addr_t get_page_mask() { return ~(get_page_size() - 1); } inline addr_t trunc_page(addr_t addr) { return addr & get_page_mask(); } inline addr_t round_page(addr_t addr) { return trunc_page(addr + get_page_size() - 1); } diff --git a/repos/base-sel4/src/core/platform_pd.cc b/repos/base-sel4/src/core/platform_pd.cc index e86d2a422..e5b24b74f 100644 --- a/repos/base-sel4/src/core/platform_pd.cc +++ b/repos/base-sel4/src/core/platform_pd.cc @@ -52,7 +52,7 @@ static Pd_id_alloc &pd_id_alloc() } -void Platform_pd::bind_thread(Platform_thread *thread) +bool Platform_pd::bind_thread(Platform_thread *thread) { ASSERT(thread); @@ -73,6 +73,7 @@ void Platform_pd::bind_thread(Platform_thread *thread) } else { _vm_space.map(thread->_info.ipc_buffer_phys, thread->INITIAL_IPC_BUFFER_VIRT, 1); } + return true; } diff --git a/repos/base-sel4/src/core/platform_thread.cc b/repos/base-sel4/src/core/platform_thread.cc index 2f04c1e5e..e233f7d03 100644 --- a/repos/base-sel4/src/core/platform_thread.cc +++ b/repos/base-sel4/src/core/platform_thread.cc @@ -203,7 +203,7 @@ void Platform_thread::install_mapping(Mapping const &mapping) Platform_thread::Platform_thread(size_t, const char *name, unsigned priority, - addr_t utcb) + Affinity::Location, addr_t utcb) : _name(name), _utcb(utcb), diff --git a/repos/base-sel4/src/core/stack_area.cc b/repos/base-sel4/src/core/stack_area.cc index 6d455c78e..5b4461a94 100644 --- a/repos/base-sel4/src/core/stack_area.cc +++ b/repos/base-sel4/src/core/stack_area.cc @@ -62,7 +62,7 @@ class Stack_area_region_map : public Region_map Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */ size_t size, off_t offset, bool use_local_addr, Local_addr local_addr, - bool executable) + bool executable) override { size = round_page(size); @@ -98,18 +98,13 @@ class Stack_area_region_map : public Region_map return local_addr; } - void detach(Local_addr local_addr) { PWRN("Not implemented!"); } + void detach(Local_addr) override { PWRN("Not implemented!"); } - Pager_capability add_client(Thread_capability) { - return Pager_capability(); } + void fault_handler(Signal_context_capability) override { } - void remove_client(Pager_capability) { } + State state() override { return State(); } - void fault_handler(Signal_context_capability) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } + Dataspace_capability dataspace() override { return Dataspace_capability(); } }; diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h index e79a78b2f..b19cbb129 100644 --- a/repos/base/include/base/child.h +++ b/repos/base/include/base/child.h @@ -156,11 +156,13 @@ class Genode::Child : protected Rpc_object /* PD session representing the protection domain of the child */ Pd_session_capability _pd; - Pd_session_client _pd_session_client; + + /* PD session presented to the child as environment */ + Pd_session_capability _env_pd; /* RAM session that contains the quota of the child */ Ram_session_capability _ram; - Ram_session_client _ram_session_client; + Ram_session_client _ram_session_client { _ram }; /* CPU session that contains the quota of the child */ Cpu_session_capability _cpu; @@ -250,16 +252,25 @@ class Genode::Child : protected Rpc_object * needed to direct quota upgrades referring to the resources of * the child environment. By default, we expect that these * resources are provided by the parent. + * + * The 'env_pd' argument override the PD session capability that is + * handed out as part of the child's environment. Normally, a child + * will receive the physical PD capability of the PD session at core. + * However, a runtime environment may wish to intercept the interaction + * of the child with its PD session by specifying a capability to a + * locally implemented PD session. */ Child(Dataspace_capability elf_ds, Pd_session_capability pd, Ram_session_capability ram, Cpu_session_capability cpu, + Region_map &address_space, Rpc_entrypoint *entrypoint, Child_policy *policy, Service &pd_service = *_parent_service(), Service &ram_service = *_parent_service(), - Service &cpu_service = *_parent_service()); + Service &cpu_service = *_parent_service(), + Pd_session_capability env_pd = Pd_session_capability()); /** * Destructor @@ -279,6 +290,10 @@ class Genode::Child : protected Rpc_object Cpu_session_capability cpu_session_cap() const { return _cpu; } Parent_capability parent_cap() const { return cap(); } + /** + */ + void env_pd(Pd_session_capability pd) { _env_pd = pd; } + /** * Discard all sessions to specified service * diff --git a/repos/base/include/base/process.h b/repos/base/include/base/process.h index cc972a8ee..0701ac1da 100644 --- a/repos/base/include/base/process.h +++ b/repos/base/include/base/process.h @@ -43,6 +43,7 @@ class Genode::Process * \param ram_session RAM session providing the BSS for the * new protection domain * \param cpu_session CPU session for the new protection domain + * \param address_space region map of new protection domain * \param parent parent of the new protection domain * \param name name of protection domain (can be used * for debugging) @@ -56,6 +57,7 @@ class Genode::Process Pd_session_capability pd_session, Ram_session_capability ram_session, Cpu_session_capability cpu_session, + Region_map &address_space, Parent_capability parent, char const *name); diff --git a/repos/base/include/base/thread.h b/repos/base/include/base/thread.h index ec27e6ac6..e709ced6b 100644 --- a/repos/base/include/base/thread.h +++ b/repos/base/include/base/thread.h @@ -89,16 +89,16 @@ class Genode::Thread_base */ Thread_capability _thread_cap; - /** - * Capability to pager paging this thread (created by _start()) - */ - Pager_capability _pager_cap; - /** * Pointer to cpu session used for this thread */ Cpu_session *_cpu_session = nullptr; + /** + * Session-local thread affinity + */ + Affinity::Location _affinity; + /** * Base pointer to Trace::Control area used by this thread */ @@ -159,7 +159,7 @@ class Genode::Thread_base * stack. */ Thread_base(size_t weight, const char *name, size_t stack_size, - Type type); + Type type, Affinity::Location affinity = Affinity::Location()); /** * Constructor @@ -177,8 +177,9 @@ class Genode::Thread_base * internally used by the framework for storing thread-specific * information such as the thread's name. */ - Thread_base(size_t weight, const char *name, size_t stack_size) - : Thread_base(weight, name, stack_size, NORMAL) { } + Thread_base(size_t weight, const char *name, size_t stack_size, + Affinity::Location affinity = Affinity::Location()) + : Thread_base(weight, name, stack_size, NORMAL, affinity) { } /** * Constructor @@ -200,7 +201,8 @@ class Genode::Thread_base * \throw Out_of_stack_space */ Thread_base(size_t weight, const char *name, size_t stack_size, - Type type, Cpu_session *); + Type type, Cpu_session *, + Affinity::Location affinity = Affinity::Location()); /** * Destructor diff --git a/repos/base/include/cpu_session/client.h b/repos/base/include/cpu_session/client.h index 8f6e1a64b..4980cfb71 100644 --- a/repos/base/include/cpu_session/client.h +++ b/repos/base/include/cpu_session/client.h @@ -26,8 +26,9 @@ struct Genode::Cpu_session_client : Rpc_client : Rpc_client(session) { } Thread_capability - create_thread(size_t quota, Name const &name, addr_t utcb = 0) override { - return call(quota, name, utcb); } + create_thread(Capability pd, size_t quota, Name const &name, + Affinity::Location affinity, addr_t utcb = 0) override { + return call(pd, quota, name, affinity, utcb); } Ram_dataspace_capability utcb(Thread_capability thread) override { return call(thread); } @@ -35,9 +36,6 @@ struct Genode::Cpu_session_client : Rpc_client void kill_thread(Thread_capability thread) override { call(thread); } - int set_pager(Thread_capability thread, Pager_capability pager) override { - return call(thread, pager); } - int start(Thread_capability thread, addr_t ip, addr_t sp) override { return call(thread, ip, sp); } diff --git a/repos/base/include/cpu_session/cpu_session.h b/repos/base/include/cpu_session/cpu_session.h index d799acaf9..9e5a7a418 100644 --- a/repos/base/include/cpu_session/cpu_session.h +++ b/repos/base/include/cpu_session/cpu_session.h @@ -22,9 +22,9 @@ #include #include #include -#include #include #include +#include namespace Genode { struct Cpu_session; } @@ -61,17 +61,22 @@ struct Genode::Cpu_session : Session /** * Create a new thread * - * \param quota CPU quota that shall be granted to the thread - * \param name name for the thread - * \param utcb Base of the UTCB that will be used by the thread - * \return capability representing the new thread - * \throw Thread_creation_failed - * \throw Out_of_metadata - * \throw Quota_exceeded + * \param pd protection domain where the thread will be executed + * \param quota CPU quota that shall be granted to the thread + * \param name name for the thread + * \param affinity CPU affinity, referring to the session-local + * affinity space + * \param utcb Base of the UTCB that will be used by the thread + * \return capability representing the new thread + * \throw Thread_creation_failed + * \throw Out_of_metadata + * \throw Quota_exceeded */ - virtual Thread_capability create_thread(size_t quota, - Name const &name, - addr_t utcb = 0) = 0; + virtual Thread_capability create_thread(Capability pd, + size_t quota, + Name const &name, + Affinity::Location affinity = Affinity::Location(), + addr_t utcb = 0) = 0; /** * Get dataspace of the UTCB that is used by the specified thread @@ -85,15 +90,6 @@ struct Genode::Cpu_session : Session */ virtual void kill_thread(Thread_capability thread) = 0; - /** - * Set paging capabilities for thread - * - * \param thread thread to configure - * \param pager capability used to propagate page faults - */ - virtual int set_pager(Thread_capability thread, - Pager_capability pager) = 0; - /** * Modify instruction and stack pointer of thread - start the * thread @@ -321,10 +317,10 @@ struct Genode::Cpu_session : Session GENODE_RPC_THROW(Rpc_create_thread, Thread_capability, create_thread, GENODE_TYPE_LIST(Thread_creation_failed, Out_of_metadata), - size_t, Name const &, addr_t); + Capability, size_t, Name const &, + Affinity::Location, addr_t); GENODE_RPC(Rpc_utcb, Ram_dataspace_capability, utcb, Thread_capability); GENODE_RPC(Rpc_kill_thread, void, kill_thread, Thread_capability); - GENODE_RPC(Rpc_set_pager, int, set_pager, Thread_capability, Pager_capability); GENODE_RPC(Rpc_start, int, start, Thread_capability, addr_t, addr_t); GENODE_RPC(Rpc_pause, void, pause, Thread_capability); GENODE_RPC(Rpc_resume, void, resume, Thread_capability); @@ -360,7 +356,6 @@ struct Genode::Cpu_session : Session typedef Meta::Type_tuple - > > > > > > > > > > > > > > > > > > > > > Rpc_functions; + > > > > > > > > > > > > > > > > > > > > Rpc_functions; }; struct Genode::Cpu_session::Quota diff --git a/repos/base/include/pd_session/client.h b/repos/base/include/pd_session/client.h index ab42423d7..307910058 100644 --- a/repos/base/include/pd_session/client.h +++ b/repos/base/include/pd_session/client.h @@ -25,9 +25,6 @@ struct Genode::Pd_session_client : Rpc_client explicit Pd_session_client(Pd_session_capability session) : Rpc_client(session) { } - void bind_thread(Thread_capability thread) override { - call(thread); } - void assign_parent(Capability parent) override { call(parent); } diff --git a/repos/base/include/pd_session/pd_session.h b/repos/base/include/pd_session/pd_session.h index c2974c65c..f553be4cf 100644 --- a/repos/base/include/pd_session/pd_session.h +++ b/repos/base/include/pd_session/pd_session.h @@ -37,17 +37,6 @@ struct Genode::Pd_session : Session virtual ~Pd_session() { } - /** - * Bind thread to protection domain - * - * \param thread capability of thread to bind - * - * After binding, the thread will execute inside this protection domain - * when started. A thread can be bound to a PD only once. Subsequent - * attempts to bind the thread to another PD are ignored. - */ - virtual void bind_thread(Thread_capability thread) = 0; - /** * Assign parent to protection domain * @@ -197,7 +186,6 @@ struct Genode::Pd_session : Session ** RPC declaration ** *********************/ - GENODE_RPC(Rpc_bind_thread, void, bind_thread, Thread_capability); GENODE_RPC(Rpc_assign_parent, void, assign_parent, Capability); GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t, uint16_t); @@ -224,8 +212,7 @@ struct Genode::Pd_session : Session /* * Manual definition of 'Rpc_functions', see the comment in cpu_session.h. */ - typedef Meta::Type_tuple - > > > > > > > > > > > > > Rpc_functions; + > > > > > > > > > > > > Rpc_functions; }; #endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */ diff --git a/repos/base/include/region_map/client.h b/repos/base/include/region_map/client.h index 48e790b0f..bba3f4959 100644 --- a/repos/base/include/region_map/client.h +++ b/repos/base/include/region_map/client.h @@ -47,8 +47,6 @@ class Genode::Region_map_client : public Rpc_client bool executable = false) override; void detach(Local_addr) override; - Pager_capability add_client(Thread_capability) override; - void remove_client(Pager_capability) override; void fault_handler(Signal_context_capability) override; State state() override; Dataspace_capability dataspace() override; diff --git a/repos/base/include/region_map/region_map.h b/repos/base/include/region_map/region_map.h index d1987a577..968197639 100644 --- a/repos/base/include/region_map/region_map.h +++ b/repos/base/include/region_map/region_map.h @@ -19,7 +19,6 @@ #include #include #include -#include namespace Genode { struct Region_map; } @@ -142,28 +141,6 @@ struct Genode::Region_map */ virtual void detach(Local_addr local_addr) = 0; - /** - * Add client to pager - * - * \param thread thread that will be paged - * \throw Invalid_thread - * \throw Out_of_metadata - * \throw Unbound_thread - * \return capability to be used for handling page faults - * - * This method must be called at least once to establish a valid - * communication channel between the pager part of the region manager - * and the client thread. - */ - virtual Pager_capability add_client(Thread_capability thread) = 0; - - /** - * Remove client from pager - * - * \param pager pager capability of client to be removed - */ - virtual void remove_client(Pager_capability) = 0; - /** * Register signal handler for region-manager faults * @@ -194,16 +171,11 @@ struct Genode::Region_map Out_of_metadata, Invalid_args), Dataspace_capability, size_t, off_t, bool, Local_addr, bool); GENODE_RPC(Rpc_detach, void, detach, Local_addr); - GENODE_RPC_THROW(Rpc_add_client, Pager_capability, add_client, - GENODE_TYPE_LIST(Unbound_thread, Invalid_thread, Out_of_metadata), - Thread_capability); - GENODE_RPC(Rpc_remove_client, void, remove_client, Pager_capability); GENODE_RPC(Rpc_fault_handler, void, fault_handler, Signal_context_capability); GENODE_RPC(Rpc_state, State, state); GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace); - GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_add_client, - Rpc_remove_client, Rpc_fault_handler, Rpc_state, + GENODE_RPC_INTERFACE(Rpc_attach, Rpc_detach, Rpc_fault_handler, Rpc_state, Rpc_dataspace); }; diff --git a/repos/base/src/base/child/child.cc b/repos/base/src/base/child/child.cc index 2469dea6b..da2ffa818 100644 --- a/repos/base/src/base/child/child.cc +++ b/repos/base/src/base/child/child.cc @@ -316,7 +316,7 @@ Session_capability Child::session(Parent::Service_name const &name, /* return sessions that we created for the child */ if (!strcmp("Env::ram_session", name.string())) return _ram; if (!strcmp("Env::cpu_session", name.string())) return _cpu; - if (!strcmp("Env::pd_session", name.string())) return _pd; + if (!strcmp("Env::pd_session", name.string())) return _env_pd; /* filter session arguments according to the child policy */ strncpy(_args, args.string(), sizeof(_args)); @@ -479,13 +479,15 @@ Child::Child(Dataspace_capability elf_ds, Pd_session_capability pd, Ram_session_capability ram, Cpu_session_capability cpu, + Region_map &address_space, Rpc_entrypoint *entrypoint, Child_policy *policy, Service &pd_service, Service &ram_service, - Service &cpu_service) + Service &cpu_service, + Pd_session_capability env_pd) : - _pd(pd), _pd_session_client(pd), _ram(ram), _ram_session_client(ram), + _pd(pd), _env_pd(env_pd.valid() ? env_pd : pd), _ram(ram), _cpu(cpu), _pd_service(pd_service), _ram_service(ram_service), _cpu_service(cpu_service), _heap(&_ram_session_client, env()->rm_session()), @@ -493,7 +495,7 @@ Child::Child(Dataspace_capability elf_ds, _parent_cap(_entrypoint->manage(this)), _policy(policy), _server(ram), - _process(elf_ds, pd, ram, cpu, _parent_cap, policy->name()) + _process(elf_ds, pd, ram, cpu, address_space, _parent_cap, policy->name()) { } diff --git a/repos/base/src/base/process/process.cc b/repos/base/src/base/process/process.cc index 7d5d37225..ec062aeac 100644 --- a/repos/base/src/base/process/process.cc +++ b/repos/base/src/base/process/process.cc @@ -176,6 +176,7 @@ Process::Process(Dataspace_capability elf_ds_cap, Pd_session_capability pd_session_cap, Ram_session_capability ram_session_cap, Cpu_session_capability cpu_session_cap, + Region_map &address_space, Parent_capability parent_cap, char const *name) : _pd_session_client(pd_session_cap), @@ -184,14 +185,7 @@ Process::Process(Dataspace_capability elf_ds_cap, if (!pd_session_cap.valid()) return; - /* region map of the new protection domain */ - Region_map_client rm(Pd_session_client(pd_session_cap).address_space()); - - enum Local_exception - { - THREAD_FAIL, ELF_FAIL, THREAD_ADD_FAIL, - THREAD_PAGER_FAIL, THREAD_START_FAIL, - }; + enum Local_exception { THREAD_FAIL, ELF_FAIL, THREAD_START_FAIL }; /* XXX this only catches local exceptions */ @@ -202,9 +196,12 @@ Process::Process(Dataspace_capability elf_ds_cap, /* create thread0 */ try { enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT }; - _thread0_cap = _cpu_session_client.create_thread(WEIGHT, name); + _thread0_cap = _cpu_session_client.create_thread(pd_session_cap, WEIGHT, name); } catch (Cpu_session::Thread_creation_failed) { - PERR("Creation of thread0 failed"); + PERR("creation of initial thread failed"); + throw THREAD_FAIL; + } catch (Cpu_session::Out_of_metadata) { + PERR("out of meta data while creating initial thread"); throw THREAD_FAIL; } @@ -233,7 +230,7 @@ Process::Process(Dataspace_capability elf_ds_cap, /* parse ELF binary and setup segment dataspaces */ addr_t entry = 0; if (elf_ds_cap.valid()) { - entry = _setup_elf(parent_cap, elf_ds_cap, ram, rm); + entry = _setup_elf(parent_cap, elf_ds_cap, ram, address_space); if (!entry) { PERR("Setup ELF failed"); throw ELF_FAIL; @@ -243,25 +240,6 @@ Process::Process(Dataspace_capability elf_ds_cap, /* register parent interface for new protection domain */ _pd_session_client.assign_parent(parent_cap); - /* bind thread0 */ - _pd_session_client.bind_thread(_thread0_cap); - - /* register thread0 at region manager session */ - Pager_capability pager; - try { - pager = rm.add_client(_thread0_cap); - } catch (...) { - PERR("Pager setup failed"); - throw THREAD_ADD_FAIL; - } - - /* set pager in thread0 */ - err = _cpu_session_client.set_pager(_thread0_cap, pager); - if (err) { - PERR("Setting pager for thread0 failed"); - throw THREAD_PAGER_FAIL; - } - /* * Inhibit start of main thread if the new process happens to be forked * from another. In this case, the main thread will get manually @@ -282,8 +260,6 @@ Process::Process(Dataspace_capability elf_ds_cap, switch (cause) { case THREAD_START_FAIL: - case THREAD_PAGER_FAIL: - case THREAD_ADD_FAIL: case ELF_FAIL: _cpu_session_client.kill_thread(_thread0_cap); diff --git a/repos/base/src/base/region_map_client.cc b/repos/base/src/base/region_map_client.cc index 181cf13cf..91d544683 100644 --- a/repos/base/src/base/region_map_client.cc +++ b/repos/base/src/base/region_map_client.cc @@ -34,16 +34,6 @@ void Region_map_client::detach(Local_addr local_addr) { call(local_addr); } -Pager_capability Region_map_client::add_client(Thread_capability thread) -{ - return call(thread); -} - - -void Region_map_client::remove_client(Pager_capability pager) { - call(pager); } - - void Region_map_client::fault_handler(Signal_context_capability cap) { call(cap); } diff --git a/repos/base/src/base/server/common.cc b/repos/base/src/base/server/common.cc index eb81d656d..70043f7c4 100644 --- a/repos/base/src/base/server/common.cc +++ b/repos/base/src/base/server/common.cc @@ -68,16 +68,12 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, char const *name, bool start_on_construction, Affinity::Location location) : - Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size), + Thread_base(Cpu_session::DEFAULT_WEIGHT, name, stack_size, location), _cap(Untyped_capability()), _cap_valid(Lock::LOCKED), _delay_start(Lock::LOCKED), _delay_exit(Lock::LOCKED), _pd_session(*pd_session) { - /* set CPU affinity, if specified */ - if (location.valid()) - env()->cpu_session()->affinity(Thread_base::cap(), location); - Thread_base::start(); _block_until_cap_valid(); diff --git a/repos/base/src/base/thread/thread.cc b/repos/base/src/base/thread/thread.cc index 62245deb1..ea46180e6 100644 --- a/repos/base/src/base/thread/thread.cc +++ b/repos/base/src/base/thread/thread.cc @@ -174,7 +174,9 @@ void Thread_base::free_secondary_stack(void* stack_addr) } -Native_thread &Thread_base::native_thread() { return _stack->native_thread(); } +Native_thread &Thread_base::native_thread() { + + return _stack->native_thread(); } void *Thread_base::stack_top() const { return (void *)_stack->top(); } @@ -205,9 +207,10 @@ size_t Thread_base::stack_area_virtual_size() Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, - Type type, Cpu_session *cpu_session) + Type type, Cpu_session *cpu_session, Affinity::Location affinity) : _cpu_session(cpu_session), + _affinity(affinity), _trace_control(nullptr), _stack(type == REINITIALIZED_MAIN ? _stack : _alloc_stack(stack_size, name, type == MAIN)), @@ -224,8 +227,8 @@ Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, - Type type) -: Thread_base(weight, name, stack_size, type, nullptr) { } + Type type, Affinity::Location affinity) +: Thread_base(weight, name, stack_size, type, nullptr, affinity) { } Thread_base::~Thread_base() diff --git a/repos/base/src/base/thread/thread_start.cc b/repos/base/src/base/thread/thread_start.cc index 6548ab775..e1e636a0d 100644 --- a/repos/base/src/base/thread/thread_start.cc +++ b/repos/base/src/base/thread/thread_start.cc @@ -59,25 +59,12 @@ void Thread_base::start() name(buf, sizeof(buf)); enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT }; addr_t const utcb = (addr_t)&_stack->utcb(); - _thread_cap = _cpu_session->create_thread(WEIGHT, buf, utcb); + _thread_cap = _cpu_session->create_thread(env()->pd_session_cap(), + WEIGHT, buf, _affinity, utcb); if (!_thread_cap.valid()) throw Cpu_session::Thread_creation_failed(); - /* assign thread to protection domain */ - env()->pd_session()->bind_thread(_thread_cap); - - /* create new pager object and assign it to the new thread */ - Pager_capability pager_cap; - try { - pager_cap = env()->rm_session()->add_client(_thread_cap); - } catch (Region_map::Unbound_thread) { } - - if (!pager_cap.valid()) - throw Cpu_session::Thread_creation_failed(); - - _cpu_session->set_pager(_thread_cap, pager_cap); - - /* register initial IP and SP at core */ + /* start execution at initial instruction pointer and stack pointer */ _cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top()); } diff --git a/repos/base/src/core/core_region_map.cc b/repos/base/src/core/core_region_map.cc new file mode 100644 index 000000000..e9de94567 --- /dev/null +++ b/repos/base/src/core/core_region_map.cc @@ -0,0 +1,39 @@ +/* + * \brief Default implementation of core-local region map + * \author Norman Feske + * \date 2009-04-02 + * + * This implementation assumes that dataspaces are identity-mapped within + * core. This is the case for traditional L4 kernels. + */ + +/* + * Copyright (C) 2009-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include + +using namespace Genode; + + +Region_map::Local_addr +Core_region_map::attach(Dataspace_capability ds_cap, size_t size, + off_t offset, bool use_local_addr, + Region_map::Local_addr, bool executable) +{ + auto lambda = [] (Dataspace_component *ds) { + if (!ds) + throw Invalid_dataspace(); + + return (void *)ds->phys_addr(); + }; + return _ep.apply(ds_cap, lambda); +} + + +void Core_region_map::detach(Local_addr) { } diff --git a/repos/base/src/core/cpu_session_component.cc b/repos/base/src/core/cpu_session_component.cc index 8e8da6fc8..63d368ec3 100644 --- a/repos/base/src/core/cpu_session_component.cc +++ b/repos/base/src/core/cpu_session_component.cc @@ -20,6 +20,7 @@ /* core includes */ #include #include +#include #include using namespace Genode; @@ -33,17 +34,12 @@ void Cpu_thread_component::update_exception_sigh() }; -Thread_capability Cpu_session_component::create_thread(size_t weight, +Thread_capability Cpu_session_component::create_thread(Capability pd_cap, + size_t weight, Name const &name, + Affinity::Location affinity, addr_t utcb) { - unsigned trace_control_index = 0; - if (!_trace_control_area.alloc(trace_control_index)) - throw Out_of_metadata(); - - Trace::Control * const trace_control = - _trace_control_area.at(trace_control_index); - Trace::Thread_name thread_name(name.string()); Cpu_thread_component *thread = 0; @@ -61,33 +57,58 @@ Thread_capability Cpu_session_component::create_thread(size_t weight, Lock::Guard thread_list_lock_guard(_thread_list_lock); _incr_weight(weight); - try { + /* + * Create thread associated with its protection domain + */ + auto create_thread_lambda = [&] (Pd_session_component *pd) { + if (!pd) { + PERR("create_thread: invalid PD argument"); + throw Thread_creation_failed(); + } Lock::Guard slab_lock_guard(_thread_alloc_lock); - thread = new(&_thread_alloc) + thread = new (&_thread_alloc) Cpu_thread_component( - weight, _weight_to_quota(weight), _label, thread_name, - _priority, utcb, _default_exception_handler, - trace_control_index, *trace_control); + cap(), *_thread_ep, *_pager_ep, *pd, _trace_control_area, + weight, _weight_to_quota(weight), + _thread_affinity(affinity), _label, thread_name, + _priority, utcb, _default_exception_handler); + }; - /* set default affinity defined by CPU session */ - thread->platform_thread()->affinity(_location); - } catch (Allocator::Out_of_memory) { - throw Out_of_metadata(); - } + try { _thread_ep->apply(pd_cap, create_thread_lambda); } + catch (Region_map::Out_of_metadata) { throw Out_of_metadata(); } + catch (Allocator::Out_of_memory) { throw Out_of_metadata(); } _thread_list.insert(thread); _trace_sources.insert(thread->trace_source()); - return _thread_ep->manage(thread); + return thread->cap(); +} + + +Affinity::Location Cpu_session_component::_thread_affinity(Affinity::Location location) const +{ + /* convert session-local location to physical location */ + int const x1 = location.xpos() + _location.xpos(), + y1 = location.ypos() + _location.ypos(), + x2 = location.xpos() + location.width(), + y2 = location.ypos() + location.height(); + + int const clipped_x1 = max(_location.xpos(), x1), + clipped_y1 = max(_location.ypos(), y1), + clipped_x2 = max(_location.xpos() + (int)_location.width() - 1, x2), + clipped_y2 = max(_location.ypos() + (int)_location.height() - 1, y2); + + return Affinity::Location(clipped_x1, clipped_y1, + clipped_x2 - clipped_x1 + 1, + clipped_y2 - clipped_y1 + 1); } void Cpu_session_component::_unsynchronized_kill_thread(Thread_capability thread_cap) { - Cpu_thread_component *thread; - _thread_ep->apply(thread_cap, [&] (Cpu_thread_component *t) { - if ((thread = t)) _thread_ep->dissolve(thread); }); + Cpu_thread_component *thread = nullptr; + _thread_ep->apply(thread_cap, [&] (Cpu_thread_component *t) { thread = t; }); if (!thread) return; @@ -95,16 +116,12 @@ void Cpu_session_component::_unsynchronized_kill_thread(Thread_capability thread _trace_sources.remove(thread->trace_source()); - unsigned const trace_control_index = thread->trace_control_index(); - _decr_weight(thread->weight()); { Lock::Guard lock_guard(_thread_alloc_lock); destroy(&_thread_alloc, thread); } - - _trace_control_area.free(trace_control_index); } @@ -116,27 +133,6 @@ void Cpu_session_component::kill_thread(Thread_capability thread_cap) } -int Cpu_session_component::set_pager(Thread_capability thread_cap, - Pager_capability pager_cap) -{ - auto lambda = [&] (Cpu_thread_component *thread) { - if (!thread) return -1; - - auto p_lambda = [&] (Pager_object *p) { - if (!p) return -2; - - thread->platform_thread()->pager(p); - - p->thread_cap(thread->cap()); - - return 0; - }; - return _pager_ep->apply(pager_cap, p_lambda); - }; - return _thread_ep->apply(thread_cap, lambda); -} - - int Cpu_session_component::start(Thread_capability thread_cap, addr_t ip, addr_t sp) { @@ -268,20 +264,7 @@ void Cpu_session_component::affinity(Thread_capability thread_cap, auto lambda = [&] (Cpu_thread_component *thread) { if (!thread) return; - /* convert session-local location to physical location */ - int const x1 = location.xpos() + _location.xpos(), - y1 = location.ypos() + _location.ypos(), - x2 = location.xpos() + location.width(), - y2 = location.ypos() + location.height(); - - int const clipped_x1 = max(_location.xpos(), x1), - clipped_y1 = max(_location.ypos(), y1), - clipped_x2 = max(_location.xpos() + (int)_location.width() - 1, x2), - clipped_y2 = max(_location.ypos() + (int)_location.height() - 1, y2); - - thread->platform_thread()->affinity(Affinity::Location(clipped_x1, clipped_y1, - clipped_x2 - clipped_x1 + 1, - clipped_y2 - clipped_y1 + 1)); + thread->affinity(_thread_affinity(location)); }; _thread_ep->apply(thread_cap, lambda); } diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index fdc0e5ed3..9736b45de 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -152,7 +152,7 @@ namespace Genode { Core_env() : _entrypoint(nullptr, ENTRYPOINT_STACK_SIZE, "entrypoint"), - _region_map(&_entrypoint), + _region_map(_entrypoint), _ram_session(&_entrypoint, &_entrypoint, platform()->ram_alloc(), platform()->core_mem_alloc(), "ram_quota=4M", platform()->ram_alloc()->avail()), diff --git a/repos/base/src/core/include/core_pd_session.h b/repos/base/src/core/include/core_pd_session.h index 37abd8428..a70719993 100644 --- a/repos/base/src/core/include/core_pd_session.h +++ b/repos/base/src/core/include/core_pd_session.h @@ -45,11 +45,6 @@ class Genode::Core_pd_session_component : public Rpc_object _signal_source_ep(signal_source_ep) { } - void bind_thread(Thread_capability thread) override - { - ASSERT_NEVER_CALLED; - } - void assign_parent(Capability parent) override { ASSERT_NEVER_CALLED; diff --git a/repos/base/src/core/include/core_region_map.h b/repos/base/src/core/include/core_region_map.h index dc52bdd0f..994ca6bc5 100644 --- a/repos/base/src/core/include/core_region_map.h +++ b/repos/base/src/core/include/core_region_map.h @@ -28,36 +28,21 @@ class Genode::Core_region_map : public Region_map { private: - Rpc_entrypoint *_ds_ep; + Rpc_entrypoint &_ep; public: - Core_region_map(Rpc_entrypoint *ds_ep): _ds_ep(ds_ep) { } + Core_region_map(Rpc_entrypoint &ep) : _ep(ep) { } - Local_addr attach(Dataspace_capability ds_cap, size_t size=0, + Local_addr attach(Dataspace_capability, size_t size = 0, off_t offset=0, bool use_local_addr = false, Local_addr local_addr = 0, - bool executable = false) override - { - auto lambda = [] (Dataspace_component *ds) { - if (!ds) - throw Invalid_dataspace(); + bool executable = false) override; - return (void *)ds->phys_addr(); - }; - return _ds_ep->apply(ds_cap, lambda); - } + void detach(Local_addr); - void detach(Local_addr) override { } - - Pager_capability add_client(Thread_capability) override { - return Pager_capability(); } - - void remove_client(Pager_capability) override { } - - void fault_handler(Signal_context_capability) override { } - - State state() override { return State(); } + void fault_handler (Signal_context_capability) override { } + State state () override { return State(); } Dataspace_capability dataspace() override { return Dataspace_capability(); } }; diff --git a/repos/base/src/core/include/cpu_session_component.h b/repos/base/src/core/include/cpu_session_component.h index f1d1df73b..67de5b1d6 100644 --- a/repos/base/src/core/include/cpu_session_component.h +++ b/repos/base/src/core/include/cpu_session_component.h @@ -24,6 +24,7 @@ /* core includes */ #include #include +#include #include #include #include @@ -55,20 +56,66 @@ namespace Genode { private: + Rpc_entrypoint &_ep; + Pager_entrypoint &_pager_ep; + Capability _pd; + Region_map_component &_address_space_region_map; size_t const _weight; Session_label const _session_label; Thread_name const _name; Platform_thread _platform_thread; - bool _bound; /* pd binding flag */ + bool const _bound_to_pd; + + bool _bind_to_pd(Pd_session_component &pd) + { + if (!pd.bind_thread(_platform_thread)) + throw Cpu_session::Thread_creation_failed(); + return true; + } + Signal_context_capability _sigh; /* exception handler */ - unsigned const _trace_control_index; - Trace::Source _trace_source; + + struct Trace_control_slot + { + unsigned index = 0; + Trace::Control_area &trace_control_area; + + Trace_control_slot(Trace::Control_area &trace_control_area) + : trace_control_area(trace_control_area) + { + if (!trace_control_area.alloc(index)) + throw Cpu_session::Out_of_metadata(); + } + + ~Trace_control_slot() + { + trace_control_area.free(index); + } + + Trace::Control &control() + { + return *trace_control_area.at(index); + } + }; + + Trace_control_slot _trace_control_slot; + + Trace::Source _trace_source { *this, _trace_control_slot.control() }; + + Weak_ptr _address_space = _platform_thread.address_space(); + + Rm_client _rm_client; public: /** * Constructor * + * \param ep entrypoint used for managing the thread RPC + * object + * \param pager_ep pager entrypoint used for handling the page + * faults of the thread + * \param pd PD session where the thread is executed * \param weight weighting regarding the CPU session quota * \param quota initial quota counter-value of the weight * \param labal label of the threads session @@ -77,23 +124,52 @@ namespace Genode { * \param utcb user-local UTCB base * \param sigh initial exception handler */ - Cpu_thread_component(size_t const weight, + Cpu_thread_component(Cpu_session_capability cpu_session_cap, + Rpc_entrypoint &ep, + Pager_entrypoint &pager_ep, + Pd_session_component &pd, + Trace::Control_area &trace_control_area, + size_t const weight, size_t const quota, + Affinity::Location affinity, Session_label const &label, Thread_name const &name, unsigned priority, addr_t utcb, - Signal_context_capability sigh, - unsigned trace_control_index, - Trace::Control &trace_control) + Signal_context_capability sigh) : + _ep(ep), _pager_ep(pager_ep), _pd(pd.cap()), + _address_space_region_map(pd.address_space_region_map()), _weight(weight), _session_label(label), _name(name), - _platform_thread(quota, name.string(), priority, utcb), - _bound(false), _sigh(sigh), - _trace_control_index(trace_control_index), - _trace_source(*this, trace_control) + _platform_thread(quota, name.string(), priority, affinity, utcb), + _bound_to_pd(_bind_to_pd(pd)), + _sigh(sigh), + _trace_control_slot(trace_control_area), + _rm_client(cpu_session_cap, _ep.manage(this), + &_address_space_region_map, + _platform_thread.pager_object_badge(), + _address_space, _platform_thread.affinity()) { update_exception_sigh(); + + _address_space_region_map.add_client(_rm_client); + + /* acquaint thread with its pager object */ + _pager_ep.manage(&_rm_client); + _platform_thread.pager(&_rm_client); + } + + ~Cpu_thread_component() + { + _pager_ep.dissolve(&_rm_client); + _ep.dissolve(this); + + _address_space_region_map.remove_client(_rm_client); + } + + void affinity(Affinity::Location affinity) + { + _platform_thread.affinity(affinity); } @@ -113,11 +189,13 @@ namespace Genode { ** Accessor functions ** ************************/ + Capability pd() const { return _pd; } + Platform_thread *platform_thread() { return &_platform_thread; } - bool bound() const { return _bound; } - void bound(bool b) { _bound = b; } - Trace::Source *trace_source() { return &_trace_source; } - size_t weight() const { return _weight; } + + Trace::Source *trace_source() { return &_trace_source; } + + size_t weight() const { return _weight; } void sigh(Signal_context_capability sigh) { @@ -133,7 +211,7 @@ namespace Genode { /** * Return index within the CPU-session's trace control area */ - unsigned trace_control_index() const { return _trace_control_index; } + unsigned trace_control_index() const { return _trace_control_slot.index; } }; @@ -229,6 +307,11 @@ namespace Genode { */ void _unsynchronized_kill_thread(Thread_capability cap); + /** + * Convert session-local affinity location to physical location + */ + Affinity::Location _thread_affinity(Affinity::Location) const; + public: /** @@ -257,30 +340,29 @@ namespace Genode { ** CPU session interface ** ***************************/ - Thread_capability create_thread(size_t, Name const &, addr_t); - Ram_dataspace_capability utcb(Thread_capability thread); - void kill_thread(Thread_capability); - int set_pager(Thread_capability, Pager_capability); - int start(Thread_capability, addr_t, addr_t); - void pause(Thread_capability thread_cap); - void resume(Thread_capability thread_cap); - void single_step(Thread_capability thread_cap, bool enable); - void cancel_blocking(Thread_capability); - int name(Thread_capability, char *, size_t); - Thread_state state(Thread_capability); - void state(Thread_capability, Thread_state const &); - void exception_handler(Thread_capability, Signal_context_capability); - Affinity::Space affinity_space() const; - void affinity(Thread_capability, Affinity::Location); - Dataspace_capability trace_control(); - unsigned trace_control_index(Thread_capability); - Dataspace_capability trace_buffer(Thread_capability); - Dataspace_capability trace_policy(Thread_capability); - int ref_account(Cpu_session_capability c); - int transfer_quota(Cpu_session_capability, size_t); + Thread_capability create_thread(Capability, size_t, Name const &, + Affinity::Location, addr_t) override; + Ram_dataspace_capability utcb(Thread_capability thread) override; + void kill_thread(Thread_capability) override; + int start(Thread_capability, addr_t, addr_t) override; + void pause(Thread_capability thread_cap) override; + void resume(Thread_capability thread_cap) override; + void single_step(Thread_capability thread_cap, bool enable) override; + void cancel_blocking(Thread_capability) override; + Thread_state state(Thread_capability) override; + void state(Thread_capability, Thread_state const &) override; + void exception_handler(Thread_capability, Signal_context_capability) override; + Affinity::Space affinity_space() const override; + void affinity(Thread_capability, Affinity::Location) override; + Dataspace_capability trace_control() override; + unsigned trace_control_index(Thread_capability) override; + Dataspace_capability trace_buffer(Thread_capability) override; + Dataspace_capability trace_policy(Thread_capability) override; + int ref_account(Cpu_session_capability c) override; + int transfer_quota(Cpu_session_capability, size_t) override; Quota quota() override; - Capability native_cpu() { return _native_cpu.cap(); } + Capability native_cpu() override { return _native_cpu.cap(); } }; } diff --git a/repos/base/src/core/include/cpu_thread_allocator.h b/repos/base/src/core/include/cpu_thread_allocator.h index c66d2fb49..9b4d8a265 100644 --- a/repos/base/src/core/include/cpu_thread_allocator.h +++ b/repos/base/src/core/include/cpu_thread_allocator.h @@ -17,6 +17,9 @@ /* Genode includes */ #include +/* base-internal includes */ +#include + namespace Genode { class Cpu_thread_component; @@ -24,7 +27,7 @@ namespace Genode /** * Allocator to manage CPU threads associated with a CPU session */ - typedef Tslab Cpu_thread_allocator; + typedef Tslab Cpu_thread_allocator; } #endif /* _CORE__INCLUDE__CPU_THREAD_ALLOCATOR_H_ */ diff --git a/repos/base/src/core/include/pager.h b/repos/base/src/core/include/pager.h index a25fb7705..ba9657417 100644 --- a/repos/base/src/core/include/pager.h +++ b/repos/base/src/core/include/pager.h @@ -55,7 +55,8 @@ class Genode::Pager_object : public Object_pool::Entry */ unsigned long _badge; - Thread_capability _thread_cap; + Cpu_session_capability _cpu_session_cap; + Thread_capability _thread_cap; /** * User-level signal handler registered for this pager object via @@ -75,8 +76,11 @@ class Genode::Pager_object : public Object_pool::Entry * * \param location affinity of paged thread to physical CPU */ - Pager_object(unsigned long badge, Affinity::Location location) - : _badge(badge) { } + Pager_object(Cpu_session_capability cpu_sesion, Thread_capability thread, + unsigned long badge, Affinity::Location location) + : + _badge(badge), _cpu_session_cap(cpu_sesion), _thread_cap(thread) + { } virtual ~Pager_object() { } @@ -116,11 +120,17 @@ class Genode::Pager_object : public Object_pool::Entry } /** - * Remember thread cap so that rm_session can tell thread that - * rm_client is gone. + * Return CPU session that was used to created the thread */ - Thread_capability thread_cap() { return _thread_cap; } const - void thread_cap(Thread_capability cap) { _thread_cap = cap; } + Cpu_session_capability cpu_session_cap() const { return _cpu_session_cap; } + + /** + * Return thread capability + * + * This function enables the destructor of the thread's + * address-space region map to kill the thread. + */ + Thread_capability thread_cap() const { return _thread_cap; } /* * Note in the thread state that an unresolved page diff --git a/repos/base/src/core/include/pd_session_component.h b/repos/base/src/core/include/pd_session_component.h index 2feb7f6a4..b796ddfb3 100644 --- a/repos/base/src/core/include/pd_session_component.h +++ b/repos/base/src/core/include/pd_session_component.h @@ -59,6 +59,7 @@ class Genode::Pd_session_component : public Rpc_object Platform_pd _pd; Capability _parent; Rpc_entrypoint &_thread_ep; + Pager_entrypoint &_pager_ep; Signal_broker _signal_broker; Rpc_cap_factory _rpc_cap_factory; Native_pd_component _native_pd; @@ -99,7 +100,7 @@ class Genode::Pd_session_component : public Rpc_object _label(args), _md_alloc(&md_alloc, _ram_quota(args)), _pd(&_md_alloc, _label.string), - _thread_ep(thread_ep), + _thread_ep(thread_ep), _pager_ep(pager_ep), _signal_broker(_md_alloc, receiver_ep, context_ep), _rpc_cap_factory(_md_alloc), _native_pd(*this, args), @@ -114,12 +115,30 @@ class Genode::Pd_session_component : public Rpc_object */ void upgrade_ram_quota(size_t ram_quota); + /** + * Associate thread with PD + * + * \return true on success + * + * This function may fail for platform-specific reasons such as a + * limit on the number of threads per protection domain or a limited + * thread ID namespace. + */ + bool bind_thread(Platform_thread &thread) + { + return _pd.bind_thread(&thread); + } + + Region_map_component &address_space_region_map() + { + return _address_space; + } + /************************** ** PD session interface ** **************************/ - void bind_thread(Thread_capability) override; void assign_parent(Capability) override; bool assign_pci(addr_t, uint16_t) override; diff --git a/repos/base/src/core/include/region_map_component.h b/repos/base/src/core/include/region_map_component.h index 298c8899d..7a57b0598 100644 --- a/repos/base/src/core/include/region_map_component.h +++ b/repos/base/src/core/include/region_map_component.h @@ -38,6 +38,7 @@ namespace Genode { + class Cpu_thread_component; class Dataspace_component; class Region_map_component; class Rm_client; @@ -179,16 +180,18 @@ class Genode::Rm_client : public Pager_object, public Rm_faulter, /** * Constructor * - * \param rm region map to which the client belongs - * \param badge pager-object badge used of identifying the client - * when a page-fault occurs - * \param location affinity to physical CPU + * \param rm address-space region map of the client + * \param badge pager-object badge used of identifying the client + * when a page fault occurs + * \param location affinity to physical CPU */ - Rm_client(Region_map_component *rm, unsigned long badge, + Rm_client(Cpu_session_capability cpu_session, + Thread_capability thread, + Region_map_component *rm, unsigned long badge, Weak_ptr &address_space, Affinity::Location location) : - Pager_object(badge, location), Rm_faulter(this), + Pager_object(cpu_session, thread, badge, location), Rm_faulter(this), _region_map(rm), _address_space(address_space) { } @@ -270,10 +273,6 @@ class Genode::Region_map_component : public Rpc_object, void sub_rm(Native_capability cap) { _rm_cap = cap; } }; - - typedef Synced_allocator > Client_slab_alloc; - Client_slab_alloc _client_slab; /* backing store for - client structures, synchronized */ Tslab _ref_slab; /* backing store for region list */ Allocator_avl_tpl _map; /* region map for attach, @@ -384,14 +383,21 @@ class Genode::Region_map_component : public Rpc_object, return _apply_to_dataspace(addr, f, 0, RECURSION_LIMIT); } + /** + * Register thread as user of the region map as its address space + * + * Called at thread-construction time only. + */ + void add_client(Rm_client &); + void remove_client(Rm_client &); + + /************************** ** Region map interface ** **************************/ Local_addr attach (Dataspace_capability, size_t, off_t, bool, Local_addr, bool) override; void detach (Local_addr) override; - Pager_capability add_client (Thread_capability) override; - void remove_client (Pager_capability) override; void fault_handler (Signal_context_capability handler) override; State state () override; diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index 0135038ac..1e556ffa9 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -111,6 +111,8 @@ class Core_child : public Child_policy Service_registry &_local_services; + Region_map_client _address_space; + Child _child; public: @@ -125,7 +127,8 @@ class Core_child : public Child_policy : _entrypoint(nullptr, STACK_SIZE, "init", false), _local_services(services), - _child(elf_ds, pd, ram, cpu, + _address_space(Pd_session_client(pd).address_space()), + _child(elf_ds, pd, ram, cpu, _address_space, &_entrypoint, this, *_local_services.find(Pd_session::service_name()), *_local_services.find(Ram_session::service_name()), diff --git a/repos/base/src/core/pd_session_component.cc b/repos/base/src/core/pd_session_component.cc index 548800ea3..f982027a8 100644 --- a/repos/base/src/core/pd_session_component.cc +++ b/repos/base/src/core/pd_session_component.cc @@ -1,9 +1,8 @@ /* * \brief Core implementation of the PD session interface * \author Christian Helmuth + * \author Norman Feske * \date 2006-07-17 - * - * FIXME arg_string and quota missing */ /* @@ -13,10 +12,10 @@ * under the terms of the GNU General Public License version 2. */ -/* Genode */ +/* Genode includes */ #include -/* Core */ +/* core-local includes */ #include #include #include @@ -24,26 +23,6 @@ using namespace Genode; -void Pd_session_component::bind_thread(Thread_capability thread) -{ - return _thread_ep.apply(thread, [&] (Cpu_thread_component *cpu_thread) { - if (!cpu_thread) return; - - if (cpu_thread->bound()) { - PWRN("rebinding of threads not supported"); - return; - } - - Platform_thread *p_thread = cpu_thread->platform_thread(); - - _pd.bind_thread(p_thread); - - if (p_thread->pd()) - cpu_thread->bound(true); - }); -} - - void Pd_session_component::assign_parent(Parent_capability parent) { _pd.assign_parent(parent); diff --git a/repos/base/src/core/region_map_component.cc b/repos/base/src/core/region_map_component.cc index 9dc3c005b..485f0cc1e 100644 --- a/repos/base/src/core/region_map_component.cc +++ b/repos/base/src/core/region_map_component.cc @@ -451,7 +451,7 @@ void Region_map_component::detach(Local_addr local_addr) Rm_region *region_ptr = _map.metadata(local_addr); if (!region_ptr) { - PDBG("no attachment at %p", (void *)local_addr); + PWRN("detach: no attachment at %p", (void *)local_addr); return; } @@ -565,85 +565,20 @@ void Region_map_component::detach(Local_addr local_addr) } -Pager_capability Region_map_component::add_client(Thread_capability thread) +void Region_map_component::add_client(Rm_client &rm_client) { - unsigned long badge; - Affinity::Location location; - Weak_ptr address_space; - - { - /* lookup thread and setup correct parameters */ - auto lambda = [&] (Cpu_thread_component *cpu_thread) { - if (!cpu_thread) throw Invalid_thread(); - - if (!cpu_thread->bound()) { - PERR("attempt to create pager for unbound thread"); - throw Region_map::Unbound_thread(); - } - - /* determine identification of client when faulting */ - badge = cpu_thread->platform_thread()->pager_object_badge(); - - /* determine cpu affinity of client thread */ - location = cpu_thread->platform_thread()->affinity(); - - address_space = cpu_thread->platform_thread()->address_space(); - if (!Locked_ptr(address_space).is_valid()) - throw Unbound_thread(); - }; - _thread_ep->apply(thread, lambda); - } - - /* serialize access */ Lock::Guard lock_guard(_lock); - Rm_client *cl; - try { cl = new(&_client_slab) Rm_client(this, badge, address_space, location); } - catch (Allocator::Out_of_memory) { throw Out_of_metadata(); } - catch (Cpu_session::Thread_creation_failed) { throw Out_of_metadata(); } - catch (Thread_base::Stack_alloc_failed) { throw Out_of_metadata(); } - - _clients.insert(cl); - - return Pager_capability(_pager_ep->manage(cl)); + _clients.insert(&rm_client); } -void Region_map_component::remove_client(Pager_capability pager_cap) +void Region_map_component::remove_client(Rm_client &rm_client) { - Rm_client *client; + Lock::Guard lock_guard(_lock); - auto lambda = [&] (Rm_client *cl) { - client = cl; - - if (!client) return; - - /* - * Rm_client is derived from Pager_object. If the Pager_object is also - * derived from Thread_base then the Rm_client object must be - * destructed without holding the region_map lock. The native - * platform specific Thread_base implementation has to take care that - * all in-flight page handling requests are finished before - * destruction. (Either by waiting until the end of or by - * cancellation of the last in-flight request. - * This operation can also require taking the region_map lock. - */ - { - Lock::Guard lock_guard(_lock); - _clients.remove(client); - } - - /* call platform specific dissolve routines */ - _pager_ep->dissolve(client); - - { - Lock::Guard lock_guard(_lock); - client->dissolve_from_faulting_region_map(this); - } - }; - _pager_ep->apply(pager_cap, lambda); - - destroy(&_client_slab, client); + _clients.remove(&rm_client); + rm_client.dissolve_from_faulting_region_map(this); } @@ -705,7 +640,7 @@ Region_map_component::Region_map_component(Rpc_entrypoint &ep, : _ds_ep(&ep), _thread_ep(&ep), _session_ep(&ep), _md_alloc(md_alloc), - _client_slab(&_md_alloc), _ref_slab(&_md_alloc), + _ref_slab(&_md_alloc), _map(&_md_alloc), _pager_ep(&pager_ep), _ds(align_addr(vm_size, get_page_size_log2())), _ds_cap(_type_deduction_helper(_ds_ep->manage(&_ds))) @@ -725,16 +660,27 @@ Region_map_component::~Region_map_component() /* dissolve all clients from pager entrypoint */ Rm_client *cl; do { + Cpu_session_capability cpu_session_cap; + Thread_capability thread_cap; { Lock::Guard lock_guard(_lock); cl = _clients.first(); if (!cl) break; + cl->dissolve_from_faulting_region_map(this); + + cpu_session_cap = cl->cpu_session_cap(); + thread_cap = cl->thread_cap(); + _clients.remove(cl); } - /* call platform specific dissolve routines */ - _pager_ep->dissolve(cl); + /* destroy thread */ + auto lambda = [&] (Cpu_session_component *cpu_session) { + if (cpu_session) + cpu_session->kill_thread(thread_cap); + }; + _thread_ep->apply(cpu_session_cap, lambda); } while (cl); /* detach all regions */ @@ -752,36 +698,4 @@ Region_map_component::~Region_map_component() /* revoke dataspace representation */ _ds_ep->dissolve(&_ds); - - /* serialize access */ - _lock.lock(); - - /* remove all faulters with pending page faults at this region map */ - while (Rm_faulter *faulter = _faulters.head()) - faulter->dissolve_from_faulting_region_map(this); - - /* remove all clients, invalidate rm_client pointers in cpu_thread objects */ - while (Rm_client *cl = _client_slab()->first_object()) { - cl->dissolve_from_faulting_region_map(this); - - Thread_capability thread_cap = cl->thread_cap(); - if (thread_cap.valid()) - /* invalidate thread cap in rm_client object */ - cl->thread_cap(Thread_capability()); - - _lock.unlock(); - - /* lookup thread and reset pager pointer */ - auto lambda = [&] (Cpu_thread_component *cpu_thread) { - if (cpu_thread && (cpu_thread->platform_thread()->pager() == cl)) - cpu_thread->platform_thread()->pager(0); - }; - _thread_ep->apply(thread_cap, lambda); - - destroy(&_client_slab, cl); - - _lock.lock(); - } - - _lock.unlock(); } diff --git a/repos/base/src/core/stack_area.cc b/repos/base/src/core/stack_area.cc index b264d59ae..cba9553ab 100644 --- a/repos/base/src/core/stack_area.cc +++ b/repos/base/src/core/stack_area.cc @@ -71,7 +71,7 @@ class Stack_area_region_map : public Region_map Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */ size_t size, off_t offset, bool use_local_addr, Local_addr local_addr, - bool executable) + bool executable) override { /* allocate physical memory */ size = round_page(size); @@ -111,7 +111,7 @@ class Stack_area_region_map : public Region_map return local_addr; } - void detach(Local_addr local_addr) + void detach(Local_addr local_addr) override { using Genode::addr_t; @@ -126,16 +126,11 @@ class Stack_area_region_map : public Region_map unmap_local(detach, pages); } - Pager_capability add_client(Thread_capability) { - return Pager_capability(); } + void fault_handler(Signal_context_capability) override { } - void remove_client(Pager_capability) { } + State state() override { return State(); } - void fault_handler(Signal_context_capability) { } - - State state() { return State(); } - - Dataspace_capability dataspace() { return Dataspace_capability(); } + Dataspace_capability dataspace() override { return Dataspace_capability(); } }; @@ -143,19 +138,14 @@ class Stack_area_ram_session : public Ram_session { public: - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached) { + Ram_dataspace_capability alloc(size_t, Cache_attribute) override { return reinterpret_cap_cast(Native_capability()); } - void free(Ram_dataspace_capability ds) { } - - int ref_account(Ram_session_capability ram_session) { return 0; } - - int transfer_quota(Ram_session_capability ram_session, size_t amount) { - return 0; } - - size_t quota() { return 0; } - - size_t used() { return 0; } + void free (Ram_dataspace_capability) override { } + int ref_account (Ram_session_capability) override { return 0; } + int transfer_quota (Ram_session_capability, size_t) override { return 0; } + size_t quota () override { return 0; } + size_t used () override { return 0; } }; diff --git a/repos/base/src/include/base/internal/platform_env.h b/repos/base/src/include/base/internal/platform_env.h index 24b140abd..944b107c2 100644 --- a/repos/base/src/include/base/internal/platform_env.h +++ b/repos/base/src/include/base/internal/platform_env.h @@ -49,11 +49,12 @@ struct Genode::Expanding_cpu_session_client : Upgradeable_client( [&] () { - return Cpu_session_client::create_thread(quota, name, utcb); }, + return Cpu_session_client::create_thread(pd, quota, name, affinity, utcb); }, [&] () { upgrade_ram(8*1024); }); } }; diff --git a/repos/base/src/include/base/internal/platform_env_common.h b/repos/base/src/include/base/internal/platform_env_common.h index a8913e434..4cc1bef80 100644 --- a/repos/base/src/include/base/internal/platform_env_common.h +++ b/repos/base/src/include/base/internal/platform_env_common.h @@ -80,7 +80,7 @@ struct Genode::Expanding_region_map_client : Region_map_client Local_addr attach(Dataspace_capability ds, size_t size, off_t offset, bool use_local_addr, Local_addr local_addr, - bool executable) + bool executable) override { return retry( [&] () { @@ -90,13 +90,6 @@ struct Genode::Expanding_region_map_client : Region_map_client executable); }, [&] () { _pd_client.upgrade_ram(8*1024); }); } - - Pager_capability add_client(Thread_capability thread) - { - return retry( - [&] () { return Region_map_client::add_client(thread); }, - [&] () { _pd_client.upgrade_ram(8*1024); }); - } }; @@ -105,7 +98,7 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client(cap) { } - Ram_dataspace_capability alloc(size_t size, Cache_attribute cached = UNCACHED) + Ram_dataspace_capability alloc(size_t size, Cache_attribute cached = UNCACHED) override { /* * If the RAM session runs out of quota, issue a resource request @@ -143,7 +136,7 @@ struct Genode::Expanding_ram_session_client : Upgradeable_client( @@ -254,7 +247,7 @@ class Genode::Expanding_parent_client : public Parent_client NUM_ATTEMPTS); } - void upgrade(Session_capability to_session, Upgrade_args const &args) + void upgrade(Session_capability to_session, Upgrade_args const &args) override { /* * If the upgrade fails, attempt to issue a resource request twice. @@ -277,7 +270,7 @@ class Genode::Expanding_parent_client : public Parent_client NUM_ATTEMPTS); } - void resource_avail_sigh(Signal_context_capability sigh) + void resource_avail_sigh(Signal_context_capability sigh) override { Lock::Guard guard(_lock); @@ -298,7 +291,7 @@ class Genode::Expanding_parent_client : public Parent_client } } - void resource_request(Resource_args const &args) + void resource_request(Resource_args const &args) override { Lock::Guard guard(_lock); diff --git a/repos/base/include/pager/capability.h b/repos/base/src/include/pager/capability.h similarity index 100% rename from repos/base/include/pager/capability.h rename to repos/base/src/include/pager/capability.h diff --git a/repos/base/src/test/rm_fault/main.cc b/repos/base/src/test/rm_fault/main.cc index 59fca09bd..79c14622a 100644 --- a/repos/base/src/test/rm_fault/main.cc +++ b/repos/base/src/test/rm_fault/main.cc @@ -79,6 +79,8 @@ class Test_child : public Child_policy */ Rpc_entrypoint _entrypoint; + Region_map_client _address_space; + Child _child; Parent_service _log_service; @@ -89,13 +91,14 @@ class Test_child : public Child_policy * Constructor */ Test_child(Genode::Dataspace_capability elf_ds, - Genode::Pd_session_capability pd, + Genode::Pd_connection &pd, Genode::Ram_session_capability ram, Genode::Cpu_session_capability cpu, Genode::Cap_session *cap) : _entrypoint(cap, STACK_SIZE, "child", false), - _child(elf_ds, pd, ram, cpu, &_entrypoint, this), + _address_space(pd.address_space()), + _child(elf_ds, pd, ram, cpu, _address_space, &_entrypoint, this), _log_service("LOG") { /* start execution of the new child */ @@ -147,7 +150,7 @@ void main_parent(Dataspace_capability elf_ds) address_space.fault_handler(fault_handler.manage(&signal_context)); /* create child */ - static Test_child child(elf_ds, pd.cap(), ram.cap(), cpu.cap(), &cap); + static Test_child child(elf_ds, pd, ram.cap(), cpu.cap(), &cap); /* allocate dataspace used for creating shared memory between parent and child */ Dataspace_capability ds = env()->ram_session()->alloc(4096); diff --git a/repos/demo/include/launchpad/launchpad.h b/repos/demo/include/launchpad/launchpad.h index 06b1ce948..a9eb8881e 100644 --- a/repos/demo/include/launchpad/launchpad.h +++ b/repos/demo/include/launchpad/launchpad.h @@ -167,6 +167,8 @@ class Launchpad_child : public Genode::List::Element enum { ENTRYPOINT_STACK_SIZE = 12*1024 }; Genode::Rpc_entrypoint _entrypoint; + Genode::Region_map_client _address_space; + Launchpad_child_policy _policy; Genode::Child _child; @@ -187,9 +189,10 @@ class Launchpad_child : public Genode::List::Element _launchpad(launchpad), _rom(rom), _ram(ram), _cpu(cpu), _server(_ram), _entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false), + _address_space(Genode::Pd_session_client(pd).address_space()), _policy(name, &_server, parent_services, child_services, config_ds, elf_ds, &_entrypoint), - _child(elf_ds, pd, ram, cpu, &_entrypoint, &_policy) { + _child(elf_ds, pd, ram, cpu, _address_space, &_entrypoint, &_policy) { _entrypoint.activate(); } Genode::Rom_session_capability rom_session_cap() { return _rom; } diff --git a/repos/libports/src/lib/pthread/thread.h b/repos/libports/src/lib/pthread/thread.h index 7faefd3d0..dd72dd768 100644 --- a/repos/libports/src/lib/pthread/thread.h +++ b/repos/libports/src/lib/pthread/thread.h @@ -42,8 +42,8 @@ extern "C" { pthread(pthread_attr_t attr, void *(*start_routine) (void *), void *arg, size_t stack_size, char const * name, - Genode::Cpu_session * cpu) - : Thread_base(WEIGHT, name, stack_size, Type::NORMAL, cpu), + Genode::Cpu_session * cpu, Genode::Affinity::Location location) + : Thread_base(WEIGHT, name, stack_size, Type::NORMAL, cpu, location), _attr(attr), _start_routine(start_routine), _arg(arg) diff --git a/repos/libports/src/lib/pthread/thread_create.cc b/repos/libports/src/lib/pthread/thread_create.cc index ea4d89b14..42ed4e4e0 100644 --- a/repos/libports/src/lib/pthread/thread_create.cc +++ b/repos/libports/src/lib/pthread/thread_create.cc @@ -32,7 +32,8 @@ extern "C" pthread_t thread_obj = new (Genode::env()->heap()) pthread(attr ? *attr : 0, start_routine, - arg, STACK_SIZE, "pthread", nullptr); + arg, STACK_SIZE, "pthread", nullptr, + Genode::Affinity::Location()); if (!thread_obj) return EAGAIN; diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h index e1afd24c9..8cd5944a0 100644 --- a/repos/os/include/cli_monitor/child.h +++ b/repos/os/include/cli_monitor/child.h @@ -67,11 +67,12 @@ class Child_base : public Genode::Child_policy } }; - size_t _ram_quota; - size_t _ram_limit; - Resources _resources; - Genode::Service_registry _parent_services; - Genode::Rom_connection _binary_rom; + size_t _ram_quota; + size_t _ram_limit; + Resources _resources; + Genode::Region_map_client _address_space { _resources.pd.address_space() }; + Genode::Service_registry _parent_services; + Genode::Rom_connection _binary_rom; enum { ENTRYPOINT_STACK_SIZE = 12*1024 }; Genode::Rpc_entrypoint _entrypoint; @@ -120,7 +121,7 @@ class Child_base : public Genode::Child_policy _binary_policy("binary", _binary_rom.dataspace(), &_entrypoint), _config_policy("config", _entrypoint, &_resources.ram), _child(_binary_rom.dataspace(), _resources.pd.cap(), - _resources.ram.cap(), _resources.cpu.cap(), + _resources.ram.cap(), _resources.cpu.cap(), _address_space, &_entrypoint, this), _yield_response_sigh_cap(yield_response_sig_cap), _exit_sig_cap(exit_sig_cap) diff --git a/repos/os/include/init/child.h b/repos/os/include/init/child.h index 2087d1fe9..125b5bbb4 100644 --- a/repos/os/include/init/child.h +++ b/repos/os/include/init/child.h @@ -524,6 +524,7 @@ class Init::Child : Genode::Child_policy */ Genode::Server _server; + Genode::Region_map_client _address_space { _resources.pd.address_space() }; Genode::Child _child; Genode::Service_registry *_parent_services; @@ -563,7 +564,7 @@ class Init::Child : Genode::Child_policy _config(_resources.ram.cap(), start_node), _server(_resources.ram.cap()), _child(_binary_rom_ds, _resources.pd.cap(), _resources.ram.cap(), - _resources.cpu.cap(), &_entrypoint, this), + _resources.cpu.cap(), _address_space, &_entrypoint, this), _parent_services(parent_services), _child_services(child_services), _labeling_policy(_name.unique), diff --git a/repos/os/include/os/slave.h b/repos/os/include/os/slave.h index edd2b2764..04b840721 100644 --- a/repos/os/include/os/slave.h +++ b/repos/os/include/os/slave.h @@ -178,8 +178,9 @@ class Genode::Slave } }; - Resources _resources; - Genode::Child _child; + Resources _resources; + Genode::Region_map_client _address_space { _resources.pd.address_space() }; + Genode::Child _child; public: @@ -191,7 +192,7 @@ class Genode::Slave _resources(slave_policy.name(), ram_quota, ram_ref_cap), _child(slave_policy.binary(), _resources.pd.cap(), _resources.ram.cap(), _resources.cpu.cap(), - &entrypoint, &slave_policy) + _address_space, &entrypoint, &slave_policy) { } Genode::Ram_connection &ram() { return _resources.ram; } diff --git a/repos/os/src/server/loader/child.h b/repos/os/src/server/loader/child.h index 41bb3a06d..5f61f34f9 100644 --- a/repos/os/src/server/loader/child.h +++ b/repos/os/src/server/loader/child.h @@ -73,6 +73,7 @@ namespace Loader { } } _resources; + Region_map_client _address_space { _resources.pd.address_space() }; Service_registry &_parent_services; Service &_local_nitpicker_service; @@ -125,7 +126,8 @@ namespace Loader { _binary_policy("binary", _binary_rom_session.dataspace(), &_ep), _labeling_policy(_label.string), _child(_binary_rom_session.dataspace(), _resources.pd.cap(), - _resources.ram.cap(), _resources.cpu.cap(), &_ep, this) + _resources.ram.cap(), _resources.cpu.cap(), + _address_space, &_ep, this) { } ~Child() diff --git a/repos/os/src/test/bomb/main.cc b/repos/os/src/test/bomb/main.cc index 1d6b5e78c..8ab73ce56 100644 --- a/repos/os/src/test/bomb/main.cc +++ b/repos/os/src/test/bomb/main.cc @@ -44,6 +44,8 @@ class Bomb_child_resources Genode::Cpu_connection _cpu; char _name[32]; + Genode::Region_map_client _address_space { _pd.address_space() }; + Bomb_child_resources(const char *file_name, const char *name, Genode::size_t ram_quota) : _pd(name), _rom(file_name, name), _ram(name), _cpu(name) @@ -91,7 +93,7 @@ class Bomb_child : private Bomb_child_resources, Init::Child_policy_enforce_labeling(Bomb_child_resources::_name), _entrypoint(cap_session, STACK_SIZE, "bomb_ep_child", false), _child(_rom.dataspace(), _pd.cap(), _ram.cap(), _cpu.cap(), - &_entrypoint, this), + _address_space, &_entrypoint, this), _parent_services(parent_services), _config_policy("config", _entrypoint, &_ram) { diff --git a/repos/os/src/test/fault_detection/main.cc b/repos/os/src/test/fault_detection/main.cc index c77f07d4c..532c94ddf 100644 --- a/repos/os/src/test/fault_detection/main.cc +++ b/repos/os/src/test/fault_detection/main.cc @@ -83,10 +83,11 @@ class Test_child : public Genode::Child_policy * executing. Otherwise, the child may hand out already destructed * local services when dispatching an incoming session call. */ - Genode::Rom_connection _elf; - Genode::Parent_service _log_service; - Genode::Parent_service _rm_service; - Genode::Child _child; + Genode::Rom_connection _elf; + Genode::Parent_service _log_service; + Genode::Parent_service _rm_service; + Genode::Region_map_client _address_space { _resources.pd.address_space() }; + Genode::Child _child; public: @@ -101,7 +102,7 @@ class Test_child : public Genode::Child_policy _elf(elf_name), _log_service("LOG"), _rm_service("RM"), _child(_elf.dataspace(), _resources.pd.cap(), _resources.ram.cap(), - _resources.cpu.cap(), &ep, this) + _resources.cpu.cap(), _address_space, &ep, this) { } diff --git a/repos/ports-foc/src/lib/l4lx/include/vcpu.h b/repos/ports-foc/src/lib/l4lx/include/vcpu.h index 7fc4e4550..a90d38e48 100644 --- a/repos/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/repos/ports-foc/src/lib/l4lx/include/vcpu.h @@ -55,7 +55,8 @@ namespace L4lx { Genode::size_t stack_size, Genode::addr_t vcpu_state, unsigned cpu_nr) - : Genode::Thread_base(WEIGHT, str, stack_size), + : Genode::Thread_base(WEIGHT, str, stack_size, + Genode::Affinity::Location(cpu_nr, 0)), _lock(Genode::Cancelable_lock::LOCKED), _func(func), _data(data ? *data : 0), @@ -73,9 +74,6 @@ namespace L4lx { Genode::Foc_native_cpu_client native_cpu(cpu_connection()->native_cpu()); native_cpu.enable_vcpu(_thread_cap, _vcpu_state); } - - /* set cpu affinity */ - set_affinity(_cpu_nr); } void entry() diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index 2ebcf1c54..15d1e31e5 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -72,13 +72,10 @@ class Vmm::Vcpu_dispatcher : public T Cpu_session * cpu_session, Genode::Affinity::Location location) : - T(WEIGHT, "vCPU dispatcher", stack_size), _pd(pd) + T(WEIGHT, "vCPU dispatcher", stack_size, location), _pd(pd) { using namespace Genode; - /* place the thread on CPU described by location object */ - cpu_session->affinity(T::cap(), location); - /* request creation of a 'local' EC */ T::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1; T::start(); @@ -90,14 +87,11 @@ class Vmm::Vcpu_dispatcher : public T Cpu_session * cpu_session, Genode::Affinity::Location location, X attr, void *(*start_routine) (void *), void *arg) - : T(attr, start_routine, arg, stack_size, "vCPU dispatcher", nullptr), + : T(attr, start_routine, arg, stack_size, "vCPU dispatcher", nullptr, location), _pd(pd) { using namespace Genode; - /* place the thread on CPU described by location object */ - cpu_session->affinity(T::cap(), location); - /* request creation of a 'local' EC */ T::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1; T::start(); diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index 6727afd4f..59e844e61 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -22,6 +22,7 @@ #include #include #include +#include /* NOVA includes */ #include @@ -68,16 +69,7 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT }; Thread_capability vcpu_vm = - _cpu_session->create_thread(WEIGHT, "vCPU"); - - /* assign thread to protection domain */ - _pd_session.bind_thread(vcpu_vm); - - /* create new pager object and assign it to the new thread */ - Genode::Region_map_client address_space(_pd_session.address_space()); - Pager_capability pager_cap = address_space.add_client(vcpu_vm); - - _cpu_session->set_pager(vcpu_vm, pager_cap); + _cpu_session->create_thread(_pd_session, WEIGHT, "vCPU", _location); /* tell parent that this will be a vCPU */ Thread_state state; @@ -86,15 +78,18 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread _cpu_session->state(vcpu_vm, state); + /* obtain interface to NOVA-specific CPU session operations */ + Nova_native_cpu_client native_cpu(_cpu_session->native_cpu()); + + /* create new pager object and assign it to the new thread */ + Native_capability pager_cap = native_cpu.pager_cap(vcpu_vm); + /* * Delegate parent the vCPU exception portals required during PD * creation. */ delegate_vcpu_portals(pager_cap, exc_base()); - /* place the thread on CPU described by location object */ - _cpu_session->affinity(vcpu_vm, _location); - /* start vCPU in separate PD */ _cpu_session->start(vcpu_vm, 0, 0); @@ -118,7 +113,7 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base Vcpu_same_pd(size_t stack_size, Cpu_session * cpu_session, Genode::Affinity::Location location) : - Thread_base(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_session) + Thread_base(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_session, location) { /* release pre-allocated selectors of Thread */ Genode::cap_map()->remove(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2); @@ -128,9 +123,6 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base /* tell generic thread code that this becomes a vCPU */ this->native_thread().is_vcpu = true; - - /* place the thread on CPU described by location object */ - cpu_session->affinity(Thread_base::cap(), location); } ~Vcpu_same_pd() @@ -150,11 +142,15 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base { this->Thread_base::start(); + /* obtain interface to NOVA-specific CPU session operations */ + Nova_native_cpu_client native_cpu(_cpu_session->native_cpu()); + /* * Request native EC thread cap and put it next to the * SM cap - see Vcpu_dispatcher->sel_sm_ec description */ - request_native_ec_cap(_pager_cap, sel_ec); + Native_capability pager_cap = native_cpu.pager_cap(_thread_cap); + request_native_ec_cap(pager_cap, sel_ec); } void entry() { } diff --git a/repos/ports/src/app/gdb_monitor/app_child.h b/repos/ports/src/app/gdb_monitor/app_child.h index ef789e233..e5dca66e0 100644 --- a/repos/ports/src/app/gdb_monitor/app_child.h +++ b/repos/ports/src/app/gdb_monitor/app_child.h @@ -63,6 +63,8 @@ namespace Gdb_monitor { Pd_session_component _pd { _unique_name, _entrypoint, _managed_ds_map }; + Region_map_client _address_space { _pd.address_space() }; + Child _child; Genode::Rpc_entrypoint *_root_ep; @@ -242,7 +244,7 @@ namespace Gdb_monitor { _cpu_session_cap(_get_cpu_session_cap()), _ram_session_cap(ram_session), _child(elf_ds, _pd.cap(), ram_session, _cpu_session_cap, - &_entrypoint, this), + _address_space, &_entrypoint, this), _root_ep(root_ep), _rom_service(&_entrypoint, _child.heap()) { diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc index 50320ee66..7f24db4fc 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc @@ -64,11 +64,12 @@ Thread_capability Cpu_session_component::thread_cap(unsigned long lwpid) Thread_capability -Cpu_session_component::create_thread(size_t weight, Name const &name, +Cpu_session_component::create_thread(Capability pd, size_t weight, + Name const &name, Affinity::Location location, addr_t utcb) { Thread_capability thread_cap = - _parent_cpu_session.create_thread(weight, name.string(), utcb); + _parent_cpu_session.create_thread(pd, weight, name.string(), location, utcb); if (thread_cap.valid()) { Thread_info *thread_info = new (env()->heap()) Thread_info(thread_cap, new_lwpid++); @@ -120,13 +121,6 @@ Thread_capability Cpu_session_component::next(Thread_capability thread_cap) } -int Cpu_session_component::set_pager(Thread_capability thread_cap, - Pager_capability pager_cap) -{ - return _parent_cpu_session.set_pager(thread_cap, pager_cap); -} - - int Cpu_session_component::start(Thread_capability thread_cap, addr_t ip, addr_t sp) { diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.h b/repos/ports/src/app/gdb_monitor/cpu_session_component.h index 977e4c0c1..778583afe 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.h +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.h @@ -56,28 +56,26 @@ class Cpu_session_component : public Rpc_object ** CPU session interface ** ***************************/ - Thread_capability create_thread(size_t, Name const &, addr_t); - Ram_dataspace_capability utcb(Thread_capability thread); - void kill_thread(Thread_capability); - int set_pager(Thread_capability, Pager_capability); - int start(Thread_capability, addr_t, addr_t); - void pause(Thread_capability thread_cap); - void resume(Thread_capability thread_cap); - void cancel_blocking(Thread_capability); - int name(Thread_capability, char *, Genode::size_t); - Thread_state state(Thread_capability); - void state(Thread_capability, Thread_state const &); + Thread_capability create_thread(Capability, size_t, Name const &, Affinity::Location, addr_t) override; + Ram_dataspace_capability utcb(Thread_capability thread) override; + void kill_thread(Thread_capability) override; + int start(Thread_capability, addr_t, addr_t) override; + void pause(Thread_capability thread_cap) override; + void resume(Thread_capability thread_cap) override; + void cancel_blocking(Thread_capability) override; + Thread_state state(Thread_capability) override; + void state(Thread_capability, Thread_state const &) override; void exception_handler(Thread_capability thread, - Signal_context_capability handler); - void single_step(Thread_capability thread, bool enable); - Affinity::Space affinity_space() const; - void affinity(Thread_capability, Affinity::Location); - Dataspace_capability trace_control(); - unsigned trace_control_index(Thread_capability); - Dataspace_capability trace_buffer(Thread_capability); - Dataspace_capability trace_policy(Thread_capability); - int ref_account(Cpu_session_capability c); - int transfer_quota(Cpu_session_capability c, size_t q); + Signal_context_capability handler) override; + void single_step(Thread_capability thread, bool enable) override; + Affinity::Space affinity_space() const override; + void affinity(Thread_capability, Affinity::Location) override; + Dataspace_capability trace_control() override; + unsigned trace_control_index(Thread_capability) override; + Dataspace_capability trace_buffer(Thread_capability) override; + Dataspace_capability trace_policy(Thread_capability) override; + int ref_account(Cpu_session_capability c) override; + int transfer_quota(Cpu_session_capability c, size_t q) override; Quota quota() override; Capability native_cpu() override; }; diff --git a/repos/ports/src/app/gdb_monitor/pd_session_component.h b/repos/ports/src/app/gdb_monitor/pd_session_component.h index bd7abcd1d..e74653965 100644 --- a/repos/ports/src/app/gdb_monitor/pd_session_component.h +++ b/repos/ports/src/app/gdb_monitor/pd_session_component.h @@ -64,9 +64,6 @@ class Pd_session_component : public Rpc_object ** Pd_session interface ** **************************/ - void bind_thread(Thread_capability thread) override { - _pd.bind_thread(thread); } - void assign_parent(Capability parent) override { _pd.assign_parent(parent); } diff --git a/repos/ports/src/app/gdb_monitor/region_map_component.cc b/repos/ports/src/app/gdb_monitor/region_map_component.cc index 9e3b90aab..24948215d 100644 --- a/repos/ports/src/app/gdb_monitor/region_map_component.cc +++ b/repos/ports/src/app/gdb_monitor/region_map_component.cc @@ -110,24 +110,6 @@ void Region_map_component::detach(Region_map::Local_addr local_addr) } -Pager_capability Region_map_component::add_client(Thread_capability thread) -{ - if (verbose) - PDBG("add_client()"); - - return _parent_region_map.add_client(thread); -} - - -void Region_map_component::remove_client(Pager_capability pager) -{ - if (verbose) - PDBG("remove_client()"); - - return _parent_region_map.remove_client(pager); -} - - void Region_map_component::fault_handler(Signal_context_capability handler) { if (verbose) diff --git a/repos/ports/src/app/gdb_monitor/region_map_component.h b/repos/ports/src/app/gdb_monitor/region_map_component.h index 2fdbc6e3e..7e6c3c141 100644 --- a/repos/ports/src/app/gdb_monitor/region_map_component.h +++ b/repos/ports/src/app/gdb_monitor/region_map_component.h @@ -95,13 +95,11 @@ namespace Gdb_monitor { **************************************/ Local_addr attach (Dataspace_capability, Genode::size_t, - Genode::off_t, bool, Local_addr, bool); - void detach (Local_addr); - Pager_capability add_client (Thread_capability); - void remove_client (Pager_capability); - void fault_handler (Signal_context_capability); - State state (); - Dataspace_capability dataspace (); + Genode::off_t, bool, Local_addr, bool) override; + void detach (Local_addr) override; + void fault_handler (Signal_context_capability) override; + State state () override; + Dataspace_capability dataspace () override; }; } diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h index d4241e0fa..ccc7ccd2c 100644 --- a/repos/ports/src/noux/child.h +++ b/repos/ports/src/noux/child.h @@ -124,6 +124,13 @@ namespace Noux { enum { STACK_SIZE = 4*1024*sizeof(long) }; Rpc_entrypoint _entrypoint; + /** + * Registry of dataspaces owned by the Noux process + */ + Dataspace_registry _ds_registry; + + Pd_session_component _pd; + /** * Resources assigned to the child */ @@ -135,10 +142,6 @@ namespace Noux { */ Rpc_entrypoint &ep; - /** - * Registry of dataspaces owned by the Noux process - */ - Dataspace_registry ds_registry; /** * Locally-provided services for accessing platform resources @@ -146,9 +149,11 @@ namespace Noux { Ram_session_component ram; Cpu_session_component cpu; - Resources(char const *label, Rpc_entrypoint &ep, bool forked) + Resources(char const *label, Rpc_entrypoint &ep, + Dataspace_registry &ds_registry, + Pd_session_capability core_pd_cap, bool forked) : - ep(ep), ram(ds_registry), cpu(label, forked) + ep(ep), ram(ds_registry), cpu(label, core_pd_cap, forked) { ep.manage(&ram); ep.manage(&cpu); @@ -162,7 +167,7 @@ namespace Noux { } _resources; - Pd_session_component _pd; + Region_map_client _address_space { _pd.address_space() }; /** * Command line arguments @@ -211,6 +216,7 @@ namespace Noux { Local_noux_service _local_noux_service; Parent_service _parent_ram_service; + Parent_service _parent_pd_service; Local_cpu_service _local_cpu_service; Local_rom_service _local_rom_service; Service_registry &_parent_services; @@ -349,8 +355,8 @@ namespace Noux { _destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)), _cap_session(cap_session), _entrypoint(cap_session, STACK_SIZE, "noux_process", false), - _resources(binary_name, resources_ep, false), - _pd(binary_name, resources_ep, _resources.ds_registry), + _pd(binary_name, resources_ep, _ds_registry), + _resources(binary_name, resources_ep, _ds_registry, _pd.core_pd_cap(), false), _args(ARGS_DS_SIZE, args), _env(env), _elf(binary_name, root_dir, root_dir->dataspace(binary_name)), @@ -359,23 +365,25 @@ namespace Noux { _noux_session_cap(Session_capability(_entrypoint.manage(this))), _local_noux_service(_noux_session_cap), _parent_ram_service(""), + _parent_pd_service(""), _local_cpu_service(_entrypoint, _resources.cpu.cpu_cap()), - _local_rom_service(_entrypoint, _resources.ds_registry), + _local_rom_service(_entrypoint, _ds_registry), _parent_services(parent_services), - _binary_ds_info(_resources.ds_registry, _elf._binary_ds), - _sysio_ds_info(_resources.ds_registry, _sysio_ds.cap()), - _ldso_ds_info(_resources.ds_registry, ldso_ds_cap()), - _args_ds_info(_resources.ds_registry, _args.cap()), - _env_ds_info(_resources.ds_registry, _env.cap()), + _binary_ds_info(_ds_registry, _elf._binary_ds), + _sysio_ds_info(_ds_registry, _sysio_ds.cap()), + _ldso_ds_info(_ds_registry, ldso_ds_cap()), + _args_ds_info(_ds_registry, _args.cap()), + _env_ds_info(_ds_registry, _env.cap()), _child_policy(_elf._name, _elf._binary_ds, _args.cap(), _env.cap(), _entrypoint, _local_noux_service, _local_rom_service, _parent_services, *this, parent_exit, *this, _destruct_context_cap, _resources.ram, verbose), _child(forked ? Dataspace_capability() : _elf._binary_ds, - _pd.cap(), _resources.ram.cap(), _resources.cpu.cap(), - &_entrypoint, &_child_policy, _parent_ram_service, - _local_cpu_service) + _pd.core_pd_cap(), _resources.ram.cap(), _resources.cpu.cap(), + _address_space, + &_entrypoint, &_child_policy, _parent_pd_service, + _parent_ram_service, _local_cpu_service, _pd.cap()) { if (verbose) _args.dump(); @@ -422,7 +430,7 @@ namespace Noux { Ram_session_capability ram() const { return _resources.ram.cap(); } Pd_session_capability pd() const { return _pd.cap(); } - Dataspace_registry &ds_registry() { return _resources.ds_registry; } + Dataspace_registry &ds_registry() { return _ds_registry; } /**************************** diff --git a/repos/ports/src/noux/cpu_session_component.h b/repos/ports/src/noux/cpu_session_component.h index 001a69f90..da62f6beb 100644 --- a/repos/ports/src/noux/cpu_session_component.h +++ b/repos/ports/src/noux/cpu_session_component.h @@ -36,8 +36,9 @@ namespace Noux { { private: - bool const _forked; - Cpu_connection _cpu; + Pd_session_capability _core_pd; + bool const _forked; + Cpu_connection _cpu; enum { MAX_THREADS = 8, MAIN_THREAD_IDX = 0 }; @@ -48,16 +49,19 @@ namespace Noux { /** * Constructor * - * \param forked false if the CPU session belongs to a child - * created via execve or to the init process, or - * true if the CPU session belongs to a newly forked - * process. + * \param core_pd capability of PD session at core to be used + * as argument of 'create_thread' + * \param forked false if the CPU session belongs to a child + * created via execve or to the init process, or + * true if the CPU session belongs to a newly + * forked process. * * The 'forked' parameter controls the policy applied to the * startup of the main thread. */ - Cpu_session_component(char const *label, bool forked) - : _forked(forked), _cpu(label) { } + Cpu_session_component(char const *label, + Pd_session_capability core_pd, bool forked) + : _core_pd(core_pd), _forked(forked), _cpu(label) { } /** * Explicitly start main thread, only meaningful when @@ -75,15 +79,24 @@ namespace Noux { ** Cpu_session interface ** ***************************/ - Thread_capability create_thread(size_t weight, Name const &name, - addr_t utcb) + Thread_capability create_thread(Capability, + size_t weight, Name const &name, + Affinity::Location affinity, + addr_t utcb) override { /* create thread at core, keep local copy (needed on NOVA) */ for (unsigned i = 0; i < MAX_THREADS; i++) { if (_threads[i].valid()) continue; - Thread_capability cap =_cpu.create_thread(weight, name, utcb); + /* + * Note that we don't use the PD-capability argument (which + * refers to our virtualized PD session) but the physical + * core PD. + */ + Thread_capability cap = + _cpu.create_thread(_core_pd, weight, name, affinity, utcb); + _threads[i] = cap; return cap; } @@ -92,10 +105,10 @@ namespace Noux { throw Thread_creation_failed(); } - Ram_dataspace_capability utcb(Thread_capability thread) { + Ram_dataspace_capability utcb(Thread_capability thread) override { return _cpu.utcb(thread); } - void kill_thread(Thread_capability thread) + void kill_thread(Thread_capability thread) override { /* purge local copy of thread capability */ for (unsigned i = 0; i < MAX_THREADS; i++) @@ -105,11 +118,7 @@ namespace Noux { _cpu.kill_thread(thread); } - int set_pager(Thread_capability thread, - Pager_capability pager) { - return _cpu.set_pager(thread, pager); } - - int start(Thread_capability thread, addr_t ip, addr_t sp) + int start(Thread_capability thread, addr_t ip, addr_t sp) override { if (_forked) { PINF("defer attempt to start thread at ip 0x%lx", ip); @@ -118,44 +127,44 @@ namespace Noux { return _cpu.start(thread, ip, sp); } - void pause(Thread_capability thread) { + void pause(Thread_capability thread) override { _cpu.pause(thread); } - void resume(Thread_capability thread) { + void resume(Thread_capability thread) override { _cpu.resume(thread); } - void cancel_blocking(Thread_capability thread) { + void cancel_blocking(Thread_capability thread) override { _cpu.cancel_blocking(thread); } - Thread_state state(Thread_capability thread) { + Thread_state state(Thread_capability thread) override { return _cpu.state(thread); } - void state(Thread_capability thread, Thread_state const &state) { + void state(Thread_capability thread, Thread_state const &state) override { _cpu.state(thread, state); } void exception_handler(Thread_capability thread, - Signal_context_capability handler) { + Signal_context_capability handler) override { _cpu.exception_handler(thread, handler); } - void single_step(Thread_capability thread, bool enable) { + void single_step(Thread_capability thread, bool enable) override { _cpu.single_step(thread, enable); } - Affinity::Space affinity_space() const { + Affinity::Space affinity_space() const override { return _cpu.affinity_space(); } - void affinity(Thread_capability thread, Affinity::Location location) { + void affinity(Thread_capability thread, Affinity::Location location) override { _cpu.affinity(thread, location); } - Dataspace_capability trace_control() { + Dataspace_capability trace_control() override { return _cpu.trace_control(); } - unsigned trace_control_index(Thread_capability thread) { + unsigned trace_control_index(Thread_capability thread) override { return _cpu.trace_control_index(thread); } - Dataspace_capability trace_buffer(Thread_capability thread) { + Dataspace_capability trace_buffer(Thread_capability thread) override { return _cpu.trace_buffer(thread); } - Dataspace_capability trace_policy(Thread_capability thread) { + Dataspace_capability trace_policy(Thread_capability thread) override { return _cpu.trace_policy(thread); } Quota quota() override { return _cpu.quota(); } diff --git a/repos/ports/src/noux/pd_session_component.h b/repos/ports/src/noux/pd_session_component.h index b98be9b4f..96b1579fc 100644 --- a/repos/ports/src/noux/pd_session_component.h +++ b/repos/ports/src/noux/pd_session_component.h @@ -58,6 +58,8 @@ class Noux::Pd_session_component : public Rpc_object _ep.dissolve(this); } + Pd_session_capability core_pd_cap() { return _pd.cap(); } + void poke(addr_t dst_addr, void const *src, size_t len) { _address_space.poke(dst_addr, src, len); @@ -102,9 +104,6 @@ class Noux::Pd_session_component : public Rpc_object ** Pd_session interface ** **************************/ - void bind_thread(Thread_capability thread) override { - _pd.bind_thread(thread); } - void assign_parent(Capability parent) override { _pd.assign_parent(parent); } diff --git a/repos/ports/src/noux/region_map_component.h b/repos/ports/src/noux/region_map_component.h index 8624c4b58..184bf7c39 100644 --- a/repos/ports/src/noux/region_map_component.h +++ b/repos/ports/src/noux/region_map_component.h @@ -95,16 +95,6 @@ class Noux::Region_map_component : public Rpc_object, Dataspace_registry &_ds_registry; - /** - * Remember last pager capability returned by add_client - * - * On NOVA, we need to preserve a local copy of the pager capability - * until we have passed to a call of 'Cpu_session::set_pager'. - * Otherwise, NOVA would transitively revoke the capability that we - * handed out to our child. - */ - Pager_capability _last_pager; - public: /** @@ -307,21 +297,6 @@ class Noux::Region_map_component : public Rpc_object, } - Pager_capability add_client(Thread_capability thread) override - { - return retry( - [&] () { - Pager_capability cap = _rm.add_client(thread); - _last_pager = cap; - return cap; - }, [&] () { Genode::env()->parent()->upgrade(_pd, "ram_quota=8192"); }); - } - - void remove_client(Pager_capability pager) override - { - _rm.remove_client(pager); - } - void fault_handler(Signal_context_capability handler) override { return _rm.fault_handler(handler); diff --git a/repos/ports/src/virtualbox/thread.cc b/repos/ports/src/virtualbox/thread.cc index b0815cc5b..25d62ed46 100644 --- a/repos/ports/src/virtualbox/thread.cc +++ b/repos/ports/src/virtualbox/thread.cc @@ -105,7 +105,8 @@ static int create_thread(pthread_t *thread, const pthread_attr_t *attr, pthread_t thread_obj = new (Genode::env()->heap()) pthread(attr ? *attr : 0, start_routine, arg, stack_size, rtthread->szName, - cpu_connection(rtthread->enmType)); + cpu_connection(rtthread->enmType), + Genode::Affinity::Location()); if (!thread_obj) return EAGAIN;