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 a6ae468a1b..a0f4448878 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 4d157f152d..02da9255cb 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 23c729025a..92df7e7961 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 fb98694df3..49c110e195 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 fe727f6b9e..25ef4901f5 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 ba9b611c81..5bd1835475 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 85266de735..6468c6e856 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 8aee5ecc5e..b4a3428c51 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 bf1fd037b2..a64499f695 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 b80343efe8..2fbcce33a3 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 6564de4894..9d9d2ec9f7 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 50a264b569..a94d51d772 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 17a87e6a43..de66f41bc0 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 2cd026db5b..a8bbbd4522 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 daf6309360..ec65c3e681 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 68fff85974..ca491cf305 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 178ac5eb9e..5831e0d4dd 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 1ad0c25f86..f84c745885 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 176cf06d01..0000000000 --- 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 4acbf38bb6..cd6f466f98 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 b176dc9aa5..9b1e69f714 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 89afced765..68dc4a8267 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 9d283a4fb1..8981e04f99 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 fc47bcdd99..0012dffad4 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 91f59241d6..ad5670493e 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 7515f68545..d5355dbebc 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 e5ee05537f..7f3364f435 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 96bcd81945..71211911d3 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 ed56e0c2f8..7b736563af 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 9a05be50e5..7dcc2bc7bb 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 84486d2b0e..14c5777170 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 5942112c26..28f59b46a4 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 2ff35dc9c3..9283e96b6e 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 c512997a45..f0322bb2c2 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 f7fe433a39..77ce98bf04 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 ee830177f9..5936177c52 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 70e4a8e173..a4660020fb 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 90e5c52047..9cc10e464b 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 1faa056282..ad1a735ddd 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 32aec3fa9f..aa8d34a69b 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 0000000000..252172ab59 --- /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 0000000000..582346002f --- /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 0b0fe232ab..827c104a48 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 6d7324c6c1..d6fc61fbb7 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 5f252691c4..e6463b3ba5 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 0c9a76b6e2..35ef276828 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 c08349a651..3bc9f9d1cd 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 23b006ca2a..f325da3d88 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 68269d2c59..4324f19247 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 9f995243cc..0000000000 --- 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 709b7b3576..5fb3a1fc3d 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 0000000000..dd318bad83 --- /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 6b83b0117c..364529fc4f 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 168f4b54f8..2cdc8e496c 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 899e3c90b8..53b9cae12c 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 7dbf9ea464..dc8dbca00b 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 0000000000..d8d6a39192 --- /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 0e73d8ecaa..0a8d8cb627 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 b198a04a0d..0ea4a4e44c 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 4ff9746ada..0b12fc456b 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 c92a1a0b59..8d965965e9 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 c2fb4518a3..2f53b64866 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 509d012d8a..b36591044d 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 1343c2225c..0000000000 --- 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 e50392e886..b5518ec15e 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 4b1ff0de98..c0f1c00cd8 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 e30fb51c01..33afb77742 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 234a11b4c6..94831ceaf6 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 42f178184a..1a96061a32 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 2f4500a661..ab3967ffe5 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 220a5863b8..8a533b4efa 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 e5f601b138..51830b1d5b 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 ae2f6002a8..73cbeb3ef3 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 b31e206675..29541ce5ca 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 aacb4f6863..5b31c0fe0b 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 a55d4c80b8..1fb097186d 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 75415a33c9..2a463fe183 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 a58d16d096..0000000000 --- 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 b3d2cfd7db..020389790f 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 1f5b6cb7c7..8cf5bc5943 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 6607845def..53432ad69f 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 e86d2a4228..e5b24b74f0 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 2f04c1e5e7..e233f7d034 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 6d455c78e1..5b4461a94e 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 e79a78b2f6..b19cbb1299 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 cc972a8ee3..0701ac1da2 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 ec27e6ac6b..e709ced6ba 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 8f6e1a64be..4980cfb71b 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 d799acaf98..9e5a7a418c 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 ab42423d7b..3079100585 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 c2974c65c0..f553be4cf2 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 48e790b0f1..bba3f4959e 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 d1987a5776..968197639a 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 2469dea6bb..da2ffa8184 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 7d5d37225f..ec062aeacc 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 181cf13cfa..91d5446837 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 eb81d656d2..70043f7c4b 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 62245deb14..ea46180e60 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 6548ab7756..e1e636a0dd 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 0000000000..e9de945679 --- /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 8e8da6fc82..63d368ec36 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 fdc0e5ed32..9736b45de9 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 37abd8428a..a70719993c 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 dc52bdd0ff..994ca6bc5a 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 f1d1df73ba..67de5b1d67 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 c66d2fb493..9b4d8a2657 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 a25fb77052..ba9657417a 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 2feb7f6a4e..b796ddfb34 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 298c8899d0..7a57b0598b 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 0135038ac5..1e556ffa91 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 548800ea3a..f982027a83 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 9dc3c005b0..485f0cc1e8 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 b264d59ae7..cba9553ab4 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 24b140abd8..944b107c27 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 a8913e434b..4cc1bef803 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 59fca09bdb..79c14622a6 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 06b1ce9485..a9eb8881ef 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 7faefd3d0d..dd72dd7689 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 ea4d89b149..42ed4e4e08 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 e1afd24c9f..8cd5944a05 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 2087d1fe9e..125b5bbb41 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 edd2b27645..04b8407214 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 41bb3a06d9..5f61f34f91 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 1d6b5e78c3..8ab73ce568 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 c77f07d4c5..532c94ddf4 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 7fc4e45500..a90d38e489 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 2ebcf1c54c..15d1e31e5c 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 6727afd4f7..59e844e615 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 ef789e2334..e5dca66e0f 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 50320ee66b..7f24db4fcd 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 977e4c0c19..778583afe3 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 bd7abcd1d5..e746539657 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 9e3b90aabc..24948215dc 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 2fdbc6e3ed..7e6c3c1410 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 d4241e0fa2..ccc7ccd2ce 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 001a69f901..da62f6beb3 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 b98be9b4fe..96b1579fc5 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 8624c4b589..184bf7c39e 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 b0815cc5b4..25d62ed46f 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;