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;