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;