Assign threads to PD at its creation time

This patch replaces the former 'Pd_session::bind_thread' function by a
PD-capability argument of the 'Cpu_session::create_thread' function, and
removes the ancient thread-start protocol via 'Rm_session::add_client' and
'Cpu_session::set_pager'. Threads are now bound to PDs at their creation
time and implicitly paged according to the address space of the PD.

Note the API change:

This patch changes the signature of the 'Child' and 'Process' constructors.
There is a new 'address_space' argument, which represents the region map
representing the child's address space. It is supplied separately to the
PD session capability (which principally can be invoked to obtain the
PD's address space) to allow the population of the address space
without relying on an 'Pd_session::address_space' RPC call.
Furthermore, a new (optional) env_pd argument allows the explicit
overriding of the PD capability handed out to the child as part of its
environment. It can be used to intercept the interaction of the child
with its PD session at core. This is used by Noux.

Issue #1938
This commit is contained in:
Norman Feske 2016-04-20 21:12:57 +02:00 committed by Christian Helmuth
parent 2bc8a0f76a
commit b49e588c1c
140 changed files with 1112 additions and 1221 deletions

View File

@ -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

View File

@ -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'
*

View File

@ -24,6 +24,7 @@
/* base-internal includes */
#include <base/internal/fiasco_thread_helper.h>
#include <base/internal/page_size.h>
/* 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; }

View File

@ -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<Cpu_thread>(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());

View File

@ -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;
}

View File

@ -151,7 +151,8 @@ Weak_ptr<Address_space> 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)
{

View File

@ -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)

View File

@ -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); }

View File

@ -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
*/
/*

View File

@ -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

View File

@ -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'
*

View File

@ -23,6 +23,9 @@
#include <rm_session/rm_session.h>
#include <util/touch.h>
/* base-internal includes */
#include <base/internal/page_size.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
@ -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; }

View File

@ -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);

View File

@ -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());
}
}

View File

@ -278,7 +278,8 @@ Weak_ptr<Address_space> 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);
}

View File

@ -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

View File

@ -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);

View File

@ -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) { }

View File

@ -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 <region_map/region_map.h>
#include <base/rpc_server.h>
/* core includes */
#include <dataspace_component.h>
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_ */

View File

@ -121,16 +121,17 @@ class Genode::Ipc_pager
void set_reply_mapping(Mapping m);
};
class Genode::Pager_object
: public Object_pool<Pager_object>::Entry,
public Genode::Kernel_object<Kernel::Signal_context>
class Genode::Pager_object : public Object_pool<Pager_object>::Entry,
public Genode::Kernel_object<Kernel::Signal_context>
{
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; }
};

View File

@ -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

View File

@ -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

View File

@ -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<Kernel::Signal_context>;
@ -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<Pager_object>::Entry(Kernel_object<Kernel::Signal_context>::_cap),
_badge(badge)
Pager_object::Pager_object(Cpu_session_capability cpu_session_cap,
Thread_capability thread_cap, unsigned const badge,
Affinity::Location)
:
Object_pool<Pager_object>::Entry(Kernel_object<Kernel::Signal_context>::_cap),
_badge(badge), _cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap)
{ }

View File

@ -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;
}

View File

@ -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<Kernel::Thread>(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);
}

View File

@ -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<Linux_native_pd>(_pd_session_client.native_pd()));

View File

@ -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*/)
{
/*

View File

@ -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 */

View File

@ -53,6 +53,10 @@ namespace Genode {
template <typename FUNC>
auto apply(Pager_capability, FUNC f) -> decltype(f(nullptr)) {
return f(nullptr); }
Pager_capability manage(Pager_object *) { return Pager_capability(); }
void dissolve(Pager_object *) { }
};
}

View File

@ -18,8 +18,16 @@
#include <base/allocator.h>
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_ */

View File

@ -19,6 +19,7 @@
/* Genode includes */
#include <base/thread_state.h>
#include <cpu_session/cpu_session.h>
#include <base/weak_ptr.h>
/* base-internal includes */
#include <base/internal/server_socket_pair.h>
@ -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> address_space() { return Weak_ptr<Address_space>(); }
unsigned long pager_object_badge() const { return 0; }
};
}

View File

@ -22,8 +22,9 @@
#include <base/rpc_server.h>
#include <region_map/region_map.h>
/* Core includes */
/* core includes */
#include <pager.h>
#include <platform_thread.h>
namespace Genode {
struct Rm_client;
@ -46,16 +47,14 @@ class Genode::Region_map_component : public Rpc_object<Region_map>,
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<Region_map>,
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> &address_space,
Affinity::Location location)
{ }
};
#endif /* _CORE__INCLUDE__REGION_MAP_COMPONENT_H_ */

View File

@ -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 <base/internal/page_size.h>
#endif /* _CORE__INCLUDE__UTIL_H_ */

View File

@ -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 = parent;

View File

@ -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));

View File

@ -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(); }

View File

@ -45,10 +45,12 @@ struct Genode::Expanding_cpu_session_client
Expanding_cpu_session_client(Genode::Capability<Cpu_session> cap)
: Upgradeable_client<Genode::Cpu_session_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<Cpu_session::Out_of_metadata>(
[&] () { 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(); }

View File

@ -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()

View File

@ -28,22 +28,21 @@ namespace Genode {
explicit Cpu_session_client(Cpu_session_capability session)
: Rpc_client<Nova_cpu_session>(static_cap_cast<Nova_cpu_session>(session)) { }
Thread_capability create_thread(size_t weight, Name const &name, addr_t utcb = 0) {
return call<Rpc_create_thread>(weight, name, utcb); }
Thread_capability
create_thread(Capability<Pd_session> pd, size_t quota, Name const &name,
Affinity::Location affinity, addr_t utcb = 0) override {
return call<Rpc_create_thread>(pd, quota, name, affinity, utcb); }
Ram_dataspace_capability utcb(Thread_capability thread) {
Ram_dataspace_capability utcb(Thread_capability thread) override {
return call<Rpc_utcb>(thread); }
void kill_thread(Thread_capability thread) {
void kill_thread(Thread_capability thread) override {
call<Rpc_kill_thread>(thread); }
int set_pager(Thread_capability thread, Pager_capability pager) {
return call<Rpc_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 {
return call<Rpc_start>(thread, ip, sp); }
void pause(Thread_capability thread)
void pause(Thread_capability thread) override
{
Native_capability block = call<Rpc_pause_sync>(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<Rpc_resume>(thread); }
void cancel_blocking(Thread_capability thread) {
void cancel_blocking(Thread_capability thread) override {
call<Rpc_cancel_blocking>(thread); }
Thread_state state(Thread_capability thread) {
Thread_state state(Thread_capability thread) override {
return call<Rpc_get_state>(thread); }
void state(Thread_capability thread, Thread_state const &state) {
void state(Thread_capability thread, Thread_state const &state) override {
call<Rpc_set_state>(thread, state); }
void exception_handler(Thread_capability thread, Signal_context_capability handler) {
void exception_handler(Thread_capability thread, Signal_context_capability handler) override {
call<Rpc_exception_handler>(thread, handler); }
void single_step(Thread_capability thread, bool enable)
void single_step(Thread_capability thread, bool enable) override
{
Native_capability block = call<Rpc_single_step_sync>(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<Rpc_affinity_space>(); }
void affinity(Thread_capability thread, Affinity::Location location) {
void affinity(Thread_capability thread, Affinity::Location location) override {
call<Rpc_affinity>(thread, location); }
Dataspace_capability trace_control() {
Dataspace_capability trace_control() override {
return call<Rpc_trace_control>(); }
unsigned trace_control_index(Thread_capability thread) {
unsigned trace_control_index(Thread_capability thread) override {
return call<Rpc_trace_control_index>(thread); }
Dataspace_capability trace_buffer(Thread_capability thread) {
Dataspace_capability trace_buffer(Thread_capability thread) override {
return call<Rpc_trace_buffer>(thread); }
Dataspace_capability trace_policy(Thread_capability thread) {
Dataspace_capability trace_policy(Thread_capability thread) override {
return call<Rpc_trace_policy>(thread); }
int ref_account(Cpu_session_capability session) {
int ref_account(Cpu_session_capability session) override {
return call<Rpc_ref_account>(session); }
int transfer_quota(Cpu_session_capability session, size_t amount) {
int transfer_quota(Cpu_session_capability session, size_t amount) override {
return call<Rpc_transfer_quota>(session, amount); }
Quota quota() override { return call<Rpc_quota>(); }

View File

@ -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) { }
};

View File

@ -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 <nova_native_cpu/nova_native_cpu.h>
#include <base/rpc_client.h>
namespace Genode { struct Nova_native_cpu_client; }
struct Genode::Nova_native_cpu_client : Rpc_client<Nova_native_cpu>
{
explicit Nova_native_cpu_client(Capability<Native_cpu> cap)
: Rpc_client<Nova_native_cpu>(static_cap_cast<Nova_native_cpu>(cap)) { }
Native_capability pager_cap(Thread_capability cap) {
return call<Rpc_pager_cap>(cap); }
};
#endif /* _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_ */

View File

@ -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 <base/rpc.h>
#include <cpu_session/cpu_session.h>
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_ */

View File

@ -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

View File

@ -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

View File

@ -20,6 +20,7 @@ using namespace Genode;
Region_map_client::Region_map_client(Capability<Region_map> session)
: Rpc_client<Region_map>(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<Rpc_detach>(local_addr); }
Pager_capability Region_map_client::add_client(Thread_capability thread)
{
return call<Rpc_add_client>(thread);
}
void Region_map_client::remove_client(Pager_capability pager) {
call<Rpc_remove_client>(pager); }
void Region_map_client::fault_handler(Signal_context_capability cap) {
call<Rpc_fault_handler>(cap); }
Region_map::State Region_map_client::state() { return call<Rpc_state>(); }
Region_map::State Region_map_client::state() { return call<Rpc_state>(); }
Dataspace_capability Region_map_client::dataspace()
{

View File

@ -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<Affinity::Location *>(stack_base())[0] = location;
}
/* required to create a 'local' EC */
Thread_base::start();

View File

@ -20,6 +20,7 @@
#include <base/env.h>
#include <base/rpc_client.h>
#include <session/session.h>
#include <nova_native_cpu/client.h>
/* base-internal includes */
#include <base/internal/stack.h>
@ -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_object>(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 *>(utcb());

View File

@ -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);
}

View File

@ -14,7 +14,7 @@
/* Genode includes */
#include <base/stdint.h>
/* Core includes */
/* core-local includes */
#include <cpu_session_component.h>
using namespace Genode;

View File

@ -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 <region_map/region_map.h>
/* core includes */
#include <dataspace_component.h>
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_ */

View File

@ -26,6 +26,8 @@
/* core includes */
#include <pager.h>
#include <cpu_thread_allocator.h>
#include <pd_session_component.h>
#include <platform_thread.h>
#include <trace/control_area.h>
#include <trace/source_registry.h>
@ -57,31 +59,120 @@ namespace Genode {
private:
Rpc_entrypoint &_ep;
Pager_entrypoint &_pager_ep;
Capability<Pd_session> _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> _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_component, 1024> Cpu_thread_allocator;
Session_label _label;
Rpc_entrypoint *_session_ep;
Rpc_entrypoint *_thread_ep;
@ -167,7 +250,7 @@ namespace Genode {
List<Cpu_session_component> _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<Pd_session>, 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> native_cpu() { return Capability<Native_cpu>(); }
Capability<Native_cpu> 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;
};
}

View File

@ -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 <base/rpc_server.h>
#include <nova_native_cpu/nova_native_cpu.h>
namespace Genode {
class Cpu_session_component;
class Native_cpu_component;
}
class Genode::Native_cpu_component : public Rpc_object<Nova_native_cpu,
Native_cpu_component>
{
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_ */

View File

@ -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

View File

@ -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

View File

@ -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);
/**

View File

@ -18,10 +18,11 @@
#include <rm_session/rm_session.h>
#include <base/printf.h>
/* base-internal includes */
#include <base/internal/page_size.h>
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()); }

View File

@ -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 <base/stdint.h>
/* core-local includes */
#include <native_cpu_component.h>
#include <cpu_session_component.h>
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);
}

View File

@ -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<Affinity::Location *>(stack_base())[0] = Affinity::Location(which_cpu(this), 0);
/* creates local EC */
Thread_base::start();

View File

@ -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;
}

View File

@ -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)

View File

@ -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 \

View File

@ -95,11 +95,7 @@ void Thread_base::start()
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_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<Affinity::Location *>(stack_base())[0];
Affinity::Location location = _affinity;
if (!location.valid())
location = Affinity::Location(boot_cpu(), 0);

View File

@ -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) { }

View File

@ -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 <region_map/region_map.h>
#include <base/rpc_server.h>
/* core includes */
#include <dataspace_component.h>
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_ */

View File

@ -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

View File

@ -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

View File

@ -21,6 +21,9 @@
#include <base/printf.h>
#include <util/touch.h>
/* base-internal includes */
#include <base/internal/page_size.h>
/* OKL4 includes */
namespace Okl4 { extern "C" {
#include <l4/types.h>
@ -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()

View File

@ -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;
}

View File

@ -1,3 +1,4 @@
/*
* \brief OKL4 thread facility
* \author Julian Stecklina
@ -178,7 +179,8 @@ Weak_ptr<Address_space> 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)
{

View File

@ -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);

View File

@ -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'
*

View File

@ -21,6 +21,9 @@
#include <util/touch.h>
#include <base/native_types.h>
/* base-internal includes */
#include <base/internal/page_size.h>
/* core-local includes */
#include <kip.h>
@ -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()

View File

@ -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());

View File

@ -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;
}

View File

@ -243,7 +243,7 @@ Weak_ptr<Address_space> 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));

View File

@ -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

View File

@ -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) { }

View File

@ -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 <base/printf.h>
#include <region_map/region_map.h>
/* core includes */
#include <dataspace_component.h>
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_ */

View File

@ -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

View File

@ -73,7 +73,7 @@ class Genode::Platform_thread : public List<Platform_thread>::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<Platform_thread>::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 **

View File

@ -18,14 +18,15 @@
#include <rm_session/rm_session.h>
#include <base/printf.h>
/* base-internal includes */
#include <base/internal/page_size.h>
/* core includes */
#include <core_cspace.h>
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); }

View File

@ -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;
}

View File

@ -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),

View File

@ -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(); }
};

View File

@ -156,11 +156,13 @@ class Genode::Child : protected Rpc_object<Parent>
/* 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<Parent>
* 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<Parent>
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
*

View File

@ -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);

View File

@ -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

View File

@ -26,8 +26,9 @@ struct Genode::Cpu_session_client : Rpc_client<Cpu_session>
: Rpc_client<Cpu_session>(session) { }
Thread_capability
create_thread(size_t quota, Name const &name, addr_t utcb = 0) override {
return call<Rpc_create_thread>(quota, name, utcb); }
create_thread(Capability<Pd_session> pd, size_t quota, Name const &name,
Affinity::Location affinity, addr_t utcb = 0) override {
return call<Rpc_create_thread>(pd, quota, name, affinity, utcb); }
Ram_dataspace_capability utcb(Thread_capability thread) override {
return call<Rpc_utcb>(thread); }
@ -35,9 +36,6 @@ struct Genode::Cpu_session_client : Rpc_client<Cpu_session>
void kill_thread(Thread_capability thread) override {
call<Rpc_kill_thread>(thread); }
int set_pager(Thread_capability thread, Pager_capability pager) override {
return call<Rpc_set_pager>(thread, pager); }
int start(Thread_capability thread, addr_t ip, addr_t sp) override {
return call<Rpc_start>(thread, ip, sp); }

View File

@ -22,9 +22,9 @@
#include <base/signal.h>
#include <base/affinity.h>
#include <thread/capability.h>
#include <pager/capability.h>
#include <session/session.h>
#include <ram_session/ram_session.h>
#include <pd_session/pd_session.h>
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_session> 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<Pd_session>, 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_create_thread,
Meta::Type_tuple<Rpc_utcb,
Meta::Type_tuple<Rpc_kill_thread,
Meta::Type_tuple<Rpc_set_pager,
Meta::Type_tuple<Rpc_start,
Meta::Type_tuple<Rpc_pause,
Meta::Type_tuple<Rpc_resume,
@ -380,7 +375,7 @@ struct Genode::Cpu_session : Session
Meta::Type_tuple<Rpc_quota,
Meta::Type_tuple<Rpc_native_cpu,
Meta::Empty>
> > > > > > > > > > > > > > > > > > > > > Rpc_functions;
> > > > > > > > > > > > > > > > > > > > Rpc_functions;
};
struct Genode::Cpu_session::Quota

View File

@ -25,9 +25,6 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
explicit Pd_session_client(Pd_session_capability session)
: Rpc_client<Pd_session>(session) { }
void bind_thread(Thread_capability thread) override {
call<Rpc_bind_thread>(thread); }
void assign_parent(Capability<Parent> parent) override {
call<Rpc_assign_parent>(parent); }

View File

@ -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<Parent>);
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_bind_thread,
Meta::Type_tuple<Rpc_assign_parent,
typedef Meta::Type_tuple<Rpc_assign_parent,
Meta::Type_tuple<Rpc_assign_pci,
Meta::Type_tuple<Rpc_alloc_signal_source,
Meta::Type_tuple<Rpc_free_signal_source,
@ -239,7 +226,7 @@ struct Genode::Pd_session : Session
Meta::Type_tuple<Rpc_linker_area,
Meta::Type_tuple<Rpc_native_pd,
Meta::Empty>
> > > > > > > > > > > > > Rpc_functions;
> > > > > > > > > > > > Rpc_functions;
};
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -47,8 +47,6 @@ class Genode::Region_map_client : public Rpc_client<Region_map>
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;

View File

@ -19,7 +19,6 @@
#include <base/signal.h>
#include <dataspace/capability.h>
#include <thread/capability.h>
#include <pager/capability.h>
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);
};

View File

@ -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())
{ }

View File

@ -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);

View File

@ -34,16 +34,6 @@ void Region_map_client::detach(Local_addr local_addr) {
call<Rpc_detach>(local_addr); }
Pager_capability Region_map_client::add_client(Thread_capability thread)
{
return call<Rpc_add_client>(thread);
}
void Region_map_client::remove_client(Pager_capability pager) {
call<Rpc_remove_client>(pager); }
void Region_map_client::fault_handler(Signal_context_capability cap) {
call<Rpc_fault_handler>(cap); }

View File

@ -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();

View File

@ -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()

View File

@ -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());
}

View File

@ -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 <platform.h>
#include <core_region_map.h>
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) { }

Some files were not shown because too many files have changed in this diff Show More