Integrate CAP session into PD session

This patch integrates the functionality of the former CAP session into
the PD session and unifies the approch of supplementing the generic PD
session with kernel-specific functionality. The latter is achieved by
the new 'Native_pd' interface. The kernel-specific interface can be
obtained via the Pd_session::native_pd accessor function. The
kernel-specific interfaces are named Nova_native_pd, Foc_native_pd, and
Linux_native_pd.

The latter change allowed for to deduplication of the
pd_session_component code among the various base platforms.

To retain API compatibility, we keep the 'Cap_session' and
'Cap_connection' around. But those classes have become mere wrappers
around the PD session interface.

Issue #1841
This commit is contained in:
Norman Feske 2016-01-19 20:24:22 +01:00 committed by Christian Helmuth
parent b1910cdd54
commit 62b1c55399
118 changed files with 2040 additions and 2258 deletions

View File

@ -11,6 +11,7 @@ SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(BASE_DIR)/src/base/env

View File

@ -2,9 +2,9 @@ TARGET = core
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += cap_session_component.cc \
context_area.cc \
SRC_CC += context_area.cc \
core_printf.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_support.cc \
dataspace_component.cc \
@ -19,6 +19,7 @@ SRC_CC += cap_session_component.cc \
pager_ep.cc \
pager_object.cc \
pd_session_component.cc \
rpc_cap_factory.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
platform.cc \
@ -50,6 +51,8 @@ vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.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 pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)

View File

@ -0,0 +1,32 @@
/*
* \brief Client-side Fiasco.OC specific PD session interface
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2011-04-14
*/
/*
* Copyright (C) 2011-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 _INCLUDE__FOC_NATIVE_PD__CLIENT_H_
#define _INCLUDE__FOC_NATIVE_PD__CLIENT_H_
#include <foc_native_pd/foc_native_pd.h>
#include <base/rpc_client.h>
namespace Genode { struct Foc_native_pd_client; }
struct Genode::Foc_native_pd_client : Rpc_client<Foc_native_pd>
{
explicit Foc_native_pd_client(Capability<Native_pd> cap)
: Rpc_client<Foc_native_pd>(static_cap_cast<Foc_native_pd>(cap)) { }
Native_capability task_cap() { return call<Rpc_task_cap>(); }
};
#endif /* _INCLUDE__FOC_NATIVE_PD__CLIENT_H_ */

View File

@ -0,0 +1,33 @@
/*
* \brief Fiasco.OC-specific part of the PD session interface
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2011-04-14
*/
/*
* Copyright (C) 2011-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__FOC_NATIVE_PD__FOC_NATIVE_PD_H_
#define _INCLUDE__FOC_NATIVE_PD__FOC_NATIVE_PD_H_
#include <base/capability.h>
#include <base/rpc.h>
#include <pd_session/pd_session.h>
namespace Genode { struct Foc_native_pd; }
struct Genode::Foc_native_pd : Pd_session::Native_pd
{
virtual Native_capability task_cap() = 0;
GENODE_RPC(Rpc_task_cap, Native_capability, task_cap);
GENODE_RPC_INTERFACE(Rpc_task_cap);
};
#endif /* _INCLUDE__FOC_NATIVE_PD__FOC_NATIVE_PD_H_ */

View File

@ -1,38 +0,0 @@
/*
* \brief Client-side Fiasco.OC specific PD session interface
* \author Stefan Kalkowski
* \date 2011-04-14
*/
/*
* Copyright (C) 2011-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 _INCLUDE__FOC_PD_SESSION__CLIENT_H_
#define _INCLUDE__FOC_PD_SESSION__CLIENT_H_
#include <foc_pd_session/foc_pd_session.h>
#include <base/rpc_client.h>
namespace Genode {
struct Foc_pd_session_client : Rpc_client<Foc_pd_session>
{
explicit Foc_pd_session_client(Capability<Foc_pd_session> session)
: Rpc_client<Foc_pd_session>(session) { }
int bind_thread(Thread_capability thread) {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Parent_capability parent) {
return call<Rpc_assign_parent>(parent); }
Native_capability task_cap() { return call<Rpc_task_cap>(); }
};
}
#endif /* _INCLUDE__FOC_PD_SESSION__CLIENT_H_ */

View File

@ -1,40 +0,0 @@
/*
* \brief Connection to Fiasco.OC specific PD service
* \author Stefan Kalkowski
* \date 2011-04-14
*/
/*
* Copyright (C) 2011-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 _INCLUDE__FOC_PD_SESSION__CONNECTION_H_
#define _INCLUDE__FOC_PD_SESSION__CONNECTION_H_
#include <foc_pd_session/client.h>
#include <base/connection.h>
namespace Genode {
struct Foc_pd_connection : Connection<Foc_pd_session>, Foc_pd_session_client
{
/**
* Constructor
*
* \param args additional session arguments
*/
Foc_pd_connection(const char *args = 0)
:
Connection<Foc_pd_session>(
session("ram_quota=4K%s%s",
args ? ", " : "",
args ? args : "")),
Foc_pd_session_client(cap())
{ }
};
}
#endif /* _INCLUDE__FOC_PD_SESSION__CONNECTION_H_ */

View File

@ -1,40 +0,0 @@
/*
* \brief Fiasco.OC specific PD session extension
* \author Stefan Kalkowski
* \date 2011-04-14
*/
/*
* Copyright (C) 2011-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 _INCLUDE__FOC_PD_SESSION__FOC_PD_SESSION_H_
#define _INCLUDE__FOC_PD_SESSION__FOC_PD_SESSION_H_
#include <base/capability.h>
#include <base/rpc.h>
#include <pd_session/pd_session.h>
namespace Genode {
struct Foc_pd_session : Pd_session
{
virtual ~Foc_pd_session() { }
virtual Native_capability task_cap() = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_task_cap, Native_capability, task_cap);
GENODE_RPC_INTERFACE_INHERIT(Pd_session, Rpc_task_cap);
};
}
#endif /* _INCLUDE__FOC_PD_SESSION__FOC_PD_SESSION_H_ */

View File

@ -12,6 +12,7 @@ SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc \
env/cap_map_remove.cc env/cap_alloc.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(BASE_DIR)/src/base/env

View File

@ -28,7 +28,7 @@ using namespace Genode;
Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
{
Untyped_capability new_obj_cap = _cap_session->alloc(_cap);
Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap);
/* add server object to object pool */
obj->cap(new_obj_cap);

View File

@ -17,33 +17,32 @@
/* Genode includes */
#include <base/cap_map.h>
/* Core includes */
#include <cap_session_component.h>
namespace Genode {
class Platform_thread;
class Pd_session_component;
class Core_cap_index : public Cap_index
{
private:
Cap_session_component *_session;
Pd_session_component *_session;
Platform_thread *_pt;
Native_thread _gate;
public:
Core_cap_index(Cap_session_component *session = 0,
Platform_thread *pt = 0,
Native_thread gate = Native_thread() )
Core_cap_index(Pd_session_component *session = 0,
Platform_thread *pt = 0,
Native_thread gate = Native_thread() )
: _session(session), _pt(pt), _gate(gate) {}
Cap_session_component *session() { return _session; }
Platform_thread *pt() { return _pt; }
Native_thread gate() { return _gate; }
Pd_session_component *session() { return _session; }
Platform_thread *pt() { return _pt; }
Native_thread gate() { return _gate; }
void session(Cap_session_component* c) { _session = c; }
void pt(Platform_thread* t) { _pt = t; }
void session(Pd_session_component *c) { _session = c; }
void pt(Platform_thread *t) { _pt = t; }
};
}

View File

@ -1,51 +0,0 @@
/*
* \brief Capability session service
* \author Stefan Kalkowski
* \date 2011-01-13
*/
/*
* Copyright (C) 2011-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__CAP_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <base/allocator.h>
#include <base/object_pool.h>
namespace Genode {
class Cap_session_component : public Rpc_object<Cap_session>
{
private:
struct Entry : Object_pool<Entry>::Entry
{
Entry(Native_capability cap) : Object_pool<Entry>::Entry(cap) {}
};
Object_pool<Entry> _pool;
Allocator *_md_alloc;
public:
Cap_session_component(Allocator *md_alloc, const char *args)
: _md_alloc(md_alloc) {}
~Cap_session_component();
void upgrade_ram_quota(size_t ram_quota) { }
Native_capability alloc(Native_capability ep);
void free(Native_capability cap);
};
}
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,45 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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_PD_COMPONENT_H_
#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_
/* Genode includes */
#include <foc_native_pd/foc_native_pd.h>
/* core-local includes */
#include <rpc_cap_factory.h>
namespace Genode {
class Pd_session_component;
class Native_pd_component;
}
class Genode::Native_pd_component : public Rpc_object<Foc_native_pd>
{
private:
Pd_session_component &_pd_session;
public:
Native_capability task_cap() override;
Native_pd_component(Pd_session_component &pd, char const *args);
~Native_pd_component();
};
#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */

View File

@ -1,105 +0,0 @@
/*
* \brief Core-specific instance of the PD session interface
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-07-17
*/
/*
* Copyright (C) 2006-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__PD_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
/* Genode includes */
#include <util/arg_string.h>
#include <foc_pd_session/foc_pd_session.h>
#include <base/rpc_server.h>
/* core includes */
#include <platform_pd.h>
#include <signal_broker.h>
namespace Genode { class Pd_session_component; }
class Genode::Pd_session_component : public Rpc_object<Foc_pd_session>
{
private:
Allocator_guard _md_alloc; /* guarded meta-data allocator */
Platform_pd _pd;
Capability<Parent> _parent;
Rpc_entrypoint &_thread_ep;
Signal_broker _signal_broker;
size_t _ram_quota(char const * args) {
return Arg_string::find_arg(args, "ram_quota").long_value(0); }
public:
Pd_session_component(Rpc_entrypoint &thread_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
char const *args)
:
_md_alloc(&md_alloc, _ram_quota(args)),
_thread_ep(thread_ep),
_signal_broker(_md_alloc, receiver_ep, context_ep)
{ }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) {
_md_alloc.upgrade(ram_quota); }
/**************************
** PD session interface **
**************************/
int bind_thread(Thread_capability) override;
int assign_parent(Capability<Parent>) override;
bool assign_pci(addr_t, uint16_t) override
{
PWRN("not implemented"); return false;
};
Signal_source_capability alloc_signal_source() override {
return _signal_broker.alloc_signal_source(); }
void free_signal_source(Signal_source_capability sig_rec_cap) override {
_signal_broker.free_signal_source(sig_rec_cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
try {
return _signal_broker.alloc_context(sig_rec_cap, imprint); }
catch (Genode::Allocator::Out_of_memory) {
throw Pd_session::Out_of_metadata(); }
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/**********************************
** Fiasco.OC specific functions **
**********************************/
Native_capability task_cap();
};
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -69,7 +69,7 @@ namespace Genode {
/**
* Constructor for all tasks except core.
*/
Platform_pd();
Platform_pd(Allocator *, char const *label);
/**
* Destructor

View File

@ -22,7 +22,6 @@
/* core includes */
#include <pager.h>
#include <platform_pd.h>
#include <cap_session_component.h>
#include <cap_mapping.h>
#include <address_space.h>

View File

@ -0,0 +1,47 @@
/*
* \brief RPC capability factory
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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__RPC_CAP_FACTORY_H_
#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <base/allocator.h>
#include <base/object_pool.h>
namespace Genode { class Rpc_cap_factory; }
class Genode::Rpc_cap_factory
{
private:
struct Entry : Object_pool<Entry>::Entry
{
Entry(Native_capability cap) : Object_pool<Entry>::Entry(cap) {}
};
Object_pool<Entry> _pool;
Allocator &_md_alloc;
public:
Rpc_cap_factory(Allocator &md_alloc) : _md_alloc(md_alloc) { }
~Rpc_cap_factory();
Native_capability alloc(Native_capability ep);
void free(Native_capability cap);
};
#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */

View File

@ -0,0 +1,40 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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.
*/
#include <pd_session_component.h>
#include <native_pd_component.h>
using namespace Genode;
Native_capability Native_pd_component::task_cap()
{
return Native_capability(_pd_session._pd.native_task());
}
Native_pd_component::Native_pd_component(Pd_session_component &pd_session,
char const *args)
:
_pd_session(pd_session)
{
_pd_session._thread_ep.manage(this);
}
Native_pd_component::~Native_pd_component()
{
_pd_session._thread_ep.dissolve(this);
}

View File

@ -138,7 +138,7 @@ void Pager_entrypoint::entry()
void Pager_entrypoint::dissolve(Pager_object *obj)
{
/* cleanup at cap session */
_cap_session->free(obj->Object_pool<Pager_object>::Entry::cap());
_cap_factory.free(obj->Object_pool<Pager_object>::Entry::cap());
remove(obj);
}
@ -148,7 +148,7 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
{
using namespace Fiasco;
Native_capability cap(_cap_session->alloc({Thread_base::_thread_cap}));
Native_capability cap(_cap_factory.alloc(Thread_base::_thread_cap));
/* add server object to object pool */
obj->cap(cap);

View File

@ -1,22 +0,0 @@
/*
* \brief Core implementation of the PD session extension
* \author Stefan Kalkowski
* \date 2011-04-14
*/
/*
* Copyright (C) 2011-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.
*/
/* Genode includes */
#include <base/native_types.h>
/* Core includes */
#include <pd_session_component.h>
Genode::Native_capability Genode::Pd_session_component::task_cap() {
return Native_capability(_pd.native_task()); }

View File

@ -111,7 +111,7 @@ Platform_pd::Platform_pd(Core_cap_index* i)
}
Platform_pd::Platform_pd()
Platform_pd::Platform_pd(Allocator *, char const *)
: _task(true, TASK_CAP)
{
for (unsigned i = 0; i < THREAD_MAX; i++)

View File

@ -17,7 +17,6 @@
#include <util/string.h>
/* core includes */
#include <cap_session_component.h>
#include <platform_thread.h>
#include <platform.h>
#include <core_env.h>
@ -219,6 +218,13 @@ Affinity::Location Platform_thread::affinity() const
}
static Rpc_cap_factory &thread_cap_factory()
{
static Rpc_cap_factory inst(*platform()->core_mem_alloc());
return inst;
}
void Platform_thread::_create_thread()
{
l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP,
@ -226,13 +232,8 @@ void Platform_thread::_create_thread()
if (l4_msgtag_has_error(tag))
PERR("cannot create more thread kernel-objects!");
/* for core threads we can't use core_env, it is to early */
static Cap_session_component core_thread_cap_session(0,"");
Cap_session &csc = (_core_thread)
? core_thread_cap_session : *core_env()->cap_session();
/* create initial gate for thread */
_gate.local = csc.alloc(_thread.local);
_gate.local = thread_cap_factory().alloc(_thread.local);
}
@ -316,7 +317,7 @@ Platform_thread::Platform_thread(const char *name)
Platform_thread::~Platform_thread()
{
core_env()->cap_session()->free(_gate.local);
thread_cap_factory().free(_gate.local);
/*
* We inform our protection domain about thread destruction, which will end up in

View File

@ -1,11 +1,12 @@
/*
* \brief Fiasco.oc platform-specific capability allocation
* \brief Fiasco.OC-specific RPC capability factory
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2011-01-13
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
* Copyright (C) 2011-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.
@ -17,7 +18,7 @@
#include <util/misc_math.h>
/* core includes */
#include <cap_session_component.h>
#include <rpc_cap_factory.h>
#include <cap_id_alloc.h>
#include <cap_index.h>
#include <platform.h>
@ -80,11 +81,11 @@ Cap_mapping::Cap_mapping(Native_capability cap, Native_thread_id r)
: local(cap), remote(r) { }
/*****************************
** Cap_session_component **
*****************************/
/***********************
** Rpc_cap_factory **
***********************/
Native_capability Cap_session_component::alloc(Native_capability ep)
Native_capability Rpc_cap_factory::alloc(Native_capability ep)
{
Native_capability cap;
@ -124,7 +125,8 @@ Native_capability Cap_session_component::alloc(Native_capability ep)
/* set debugger-name of ipc-gate to thread's name */
Fiasco::l4_debugger_set_object_name(idx->kcap(), ref->pt()->name());
idx->session(this);
// XXX remove cast
idx->session((Pd_session_component *)this);
idx->pt(ref->pt());
cap = Native_capability(idx);
} catch (Cap_id_allocator::Out_of_ids) {
@ -138,20 +140,20 @@ Native_capability Cap_session_component::alloc(Native_capability ep)
* doesn't have an allocator set. But this session gets never destroyed
* so this is not an issue.
*/
if (cap.valid() && _md_alloc)
if (cap.valid())
_pool.insert(new (_md_alloc) Entry(cap));
return cap;
}
void Cap_session_component::free(Native_capability cap)
void Rpc_cap_factory::free(Native_capability cap)
{
using namespace Fiasco;
if (!cap.valid()) return;
/* proof whether the capability was created by this cap_session */
if (static_cast<Core_cap_index*>(cap.idx())->session() != this) return;
if (static_cast<Core_cap_index*>(cap.idx())->session() != (Pd_session_component *)this) return;
Entry * entry;
_pool.apply(cap, [&] (Entry *e) {
@ -165,7 +167,7 @@ void Cap_session_component::free(Native_capability cap)
}
Cap_session_component::~Cap_session_component()
Rpc_cap_factory::~Rpc_cap_factory()
{
_pool.remove_all([this] (Entry *e) {
if (!e) return;

View File

@ -5,9 +5,9 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core
LIBS += base-common
SRC_CC += cap_session_component.cc \
context_area.cc \
SRC_CC += context_area.cc \
core_printf.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_extension.cc \
dataspace_component.cc \
@ -21,7 +21,10 @@ SRC_CC += cap_session_component.cc \
pager.cc \
pager_object.cc \
pd_session_component.cc \
pd_session_extension.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
native_pd_component.cc \
rpc_cap_factory.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \
@ -53,10 +56,13 @@ vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath main.cc $(GEN_CORE_DIR)
vpath multiboot_info.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rm_session_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 pager_object.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath %.cc $(REP_DIR)/src/core

View File

@ -17,7 +17,6 @@
#include <base/sleep.h>
/* core includes */
#include <cap_session_component.h>
#include <platform.h>
#include <core_env.h>

View File

@ -1,33 +0,0 @@
/*
* \brief Connection to CAP service
* \author Stefan Kalkowski
* \author Norman Feske
* \date 2015-05-20
*
* This is a shadow copy of the generic header in base,
* due to higher memory donation requirements in base-hw
*/
/*
* 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 _INCLUDE__CAP_SESSION__CONNECTION_H_
#define _INCLUDE__CAP_SESSION__CONNECTION_H_
#include <cap_session/client.h>
#include <base/connection.h>
namespace Genode { struct Cap_connection; }
struct Genode::Cap_connection : Connection<Cap_session>, Cap_session_client
{
Cap_connection() : Connection<Cap_session>(session("ram_quota=8K")),
Cap_session_client(cap()) { }
};
#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */

View File

@ -26,7 +26,7 @@ namespace Genode { struct Pd_connection; }
struct Genode::Pd_connection : Connection<Pd_session>, Pd_session_client
{
enum { RAM_QUOTA = 28*1024 };
enum { RAM_QUOTA = 36*1024 };
/**
* Constructor

View File

@ -17,6 +17,7 @@ SRC_CC += thread/start.cc
SRC_CC += irq/platform.cc
SRC_CC += env.cc
SRC_CC += capability.cc
SRC_CC += server/rpc_cap_alloc.cc
# add include paths
INC_DIR += $(REP_DIR)/src/base/lock

View File

@ -23,6 +23,7 @@ SRC_CC += cpu_session_component.cc
SRC_CC += cpu_session_support.cc
SRC_CC += core_rm_session.cc
SRC_CC += core_mem_alloc.cc
SRC_CC += core_rpc_cap_alloc.cc
SRC_CC += dataspace_component.cc
SRC_CC += dump_alloc.cc
SRC_CC += io_mem_session_component.cc

View File

@ -16,7 +16,6 @@
#include <base/sleep.h>
#include <base/env.h>
#include <util/retry.h>
#include <cap_session/client.h>
using namespace Genode;
@ -27,15 +26,7 @@ using namespace Genode;
Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
{
Untyped_capability new_obj_cap =
retry<Genode::Cap_session::Out_of_metadata>(
[&] () { return _cap_session->alloc(_cap); },
[&] () {
Cap_session_client *client =
dynamic_cast<Cap_session_client*>(_cap_session);
if (client)
env()->parent()->upgrade(*client, "ram_quota=16K");
});
Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap);
/* add server object to object pool */
obj->cap(new_obj_cap);

View File

@ -1,122 +0,0 @@
/*
* \brief Capability allocation service
* \author Stefan Kalkowski
* \date 2015-03-05
*/
/*
* 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__CAP_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_
#include <base/allocator_guard.h>
#include <base/rpc_server.h>
#include <cap_session/cap_session.h>
#include <util/arg_string.h>
#include <util/construct_at.h>
#include <kernel/object.h>
namespace Genode { class Cap_session_component; }
class Genode::Cap_session_component : public Rpc_object<Cap_session>
{
private:
/**
* Kernel object placeholder hold in a list
*/
struct Kobject : List<Kobject>::Element
{
using Identity = Kernel::Core_object_identity<Kernel::Thread>;
Native_capability cap;
uint8_t data[sizeof(Identity)]
__attribute__((aligned(sizeof(addr_t))));
};
using Slab = Tslab<Kobject, get_page_size()>;
Allocator_guard _guard;
uint8_t _initial_sb[get_page_size()]; /* initial slab block */
Slab _slab;
List<Kobject> _list;
Lock _lock;
/**
* Returns the right meta-data allocator,
* for core it returns a non-guarded one, otherwise a guard
*/
Allocator * _md_alloc(Allocator *md_alloc)
{
Allocator * core_mem_alloc =
static_cast<Allocator*>(platform()->core_mem_alloc());
return (md_alloc == core_mem_alloc) ? core_mem_alloc : &_guard;
}
public:
Cap_session_component(Allocator *md_alloc, const char *args)
: _guard(md_alloc,
Arg_string::find_arg(args, "ram_quota").long_value(0)),
_slab(_md_alloc(md_alloc), (Slab_block*)&_initial_sb) { }
~Cap_session_component()
{
Lock::Guard guard(_lock);
while (Kobject * obj = _list.first()) {
Kernel::delete_obj(obj->data);
_list.remove(obj);
destroy(&_slab, obj);
}
}
void upgrade_ram_quota(size_t ram_quota) { _guard.upgrade(ram_quota); }
Native_capability alloc(Native_capability ep)
{
Lock::Guard guard(_lock);
/* allocate kernel object */
Kobject * obj;
if (!_slab.alloc(sizeof(Kobject), (void**)&obj))
throw Out_of_metadata();
construct_at<Kobject>(obj);
/* create kernel object via syscall */
obj->cap = Kernel::new_obj(obj->data, ep.dst());
if (!obj->cap.valid()) {
PWRN("Invalid entrypoint %u for allocating a capability!",
ep.dst());
destroy(&_slab, obj);
return Native_capability();
}
/* store it in the list and return result */
_list.insert(obj);
return obj->cap;
}
void free(Native_capability cap)
{
Lock::Guard guard(_lock);
for (Kobject * obj = _list.first(); obj; obj = obj->next())
if (obj->cap.dst() == cap.dst()) {
Kernel::delete_obj(obj->data);
_list.remove(obj);
destroy(&_slab, obj);
return;
}
}
};
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */

View File

@ -20,12 +20,14 @@
#include <base/signal.h>
#include <pager/capability.h>
#include <unmanaged_singleton.h>
/* core-local includes */
#include <kernel/signal_receiver.h>
#include <object.h>
#include <rpc_cap_factory.h>
namespace Genode
{
class Cap_session;
/**
* Translation of a virtual page frame
@ -199,10 +201,8 @@ class Genode::Pager_entrypoint : public Object_pool<Pager_object>,
/**
* Constructor
*
* \param a activation that shall handle the objects of the entrypoint
*/
Pager_entrypoint(Cap_session * cap_session);
Pager_entrypoint(Rpc_cap_factory &);
/**
* Associate pager object 'obj' with entry point

View File

@ -0,0 +1,117 @@
/*
* \brief RPC capability factory
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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__RPC_CAP_FACTORY_H_
#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_
/* Genode includes */
#include <util/list.h>
#include <util/construct_at.h>
#include <base/lock.h>
#include <base/tslab.h>
#include <base/capability.h>
/* core-local includes */
#include <object.h>
#include <kernel/thread.h>
namespace Genode { class Rpc_cap_factory; }
class Genode::Rpc_cap_factory
{
private:
/**
* Kernel object placeholder held in a list
*/
struct Kobject : List<Kobject>::Element
{
using Identity = Kernel::Core_object_identity<Kernel::Thread>;
Native_capability cap;
uint8_t data[sizeof(Identity)]
__attribute__((aligned(sizeof(addr_t))));
};
using Slab = Tslab<Kobject, get_page_size()>;
uint8_t _initial_slab_block[get_page_size()];
Slab _slab;
List<Kobject> _list;
Lock _lock;
public:
Rpc_cap_factory(Allocator &md_alloc)
:
_slab(&md_alloc, (Slab_block*)&_initial_slab_block)
{ }
~Rpc_cap_factory()
{
Lock::Guard guard(_lock);
while (Kobject * obj = _list.first()) {
Kernel::delete_obj(obj->data);
_list.remove(obj);
destroy(&_slab, obj);
}
}
/**
* Allocate RPC capability
*
* \throw Allocator::Out_of_memory
*/
Native_capability alloc(Native_capability ep)
{
Lock::Guard guard(_lock);
/* allocate kernel object */
Kobject * obj;
if (!_slab.alloc(sizeof(Kobject), (void**)&obj))
throw Allocator::Out_of_memory();
construct_at<Kobject>(obj);
/* create kernel object via syscall */
obj->cap = Kernel::new_obj(obj->data, ep.dst());
if (!obj->cap.valid()) {
PWRN("Invalid entrypoint %u for allocating a capability!",
ep.dst());
destroy(&_slab, obj);
return Native_capability();
}
/* store it in the list and return result */
_list.insert(obj);
return obj->cap;
}
void free(Native_capability cap)
{
Lock::Guard guard(_lock);
for (Kobject * obj = _list.first(); obj; obj = obj->next()) {
if (obj->cap.dst() == cap.dst()) {
Kernel::delete_obj(obj->data);
_list.remove(obj);
destroy(&_slab, obj);
return;
}
}
}
};
#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */

View File

@ -108,7 +108,7 @@ void Pager_entrypoint::dissolve(Pager_object * const o)
}
Pager_entrypoint::Pager_entrypoint(Cap_session *)
Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &)
: Thread<PAGER_EP_STACK_SIZE>("pager_ep"),
Kernel_object<Kernel::Signal_receiver>(true)
{ start(); }

View File

@ -0,0 +1,31 @@
/*
* \brief Client-side of the Linux-specific PD session interface
* \author Norman Feske
* \date 2012-08-15
*/
/*
* Copyright (C) 2012-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 _INCLUDE__LINUX_PD_SESSION__CLIENT_H_
#define _INCLUDE__LINUX_PD_SESSION__CLIENT_H_
#include <linux_native_pd/linux_native_pd.h>
#include <base/rpc_client.h>
namespace Genode { struct Linux_native_pd_client; }
struct Genode::Linux_native_pd_client : Rpc_client<Linux_native_pd>
{
explicit Linux_native_pd_client(Capability<Native_pd> cap)
: Rpc_client<Linux_native_pd>(static_cap_cast<Linux_native_pd>(cap)) { }
void start(Capability<Dataspace> binary) {
call<Rpc_start>(binary); }
};
#endif /* _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ */

View File

@ -0,0 +1,31 @@
/*
* \brief Linux-specific extension of the PD session interface
* \author Norman Feske
* \date 2012-08-15
*/
/*
* Copyright (C) 2012-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__LINUX_NATIVE_PD__LINUX_NATIVE_PD_
#define _INCLUDE__LINUX_NATIVE_PD__LINUX_NATIVE_PD_
#include <pd_session/pd_session.h>
#include <dataspace/dataspace.h>
namespace Genode { struct Linux_native_pd; }
struct Genode::Linux_native_pd : Pd_session::Native_pd
{
void start(Capability<Dataspace> binary);
GENODE_RPC(Rpc_start, void, start, Capability<Dataspace>);
GENODE_RPC_INTERFACE(Rpc_start);
};
#endif /* _INCLUDE__LINUX_NATIVE_PD__LINUX_NATIVE_PD_ */

View File

@ -1,61 +0,0 @@
/*
* \brief Client-side PD session interface
* \author Norman Feske
* \date 2012-08-15
*/
/*
* Copyright (C) 2012-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 _INCLUDE__LINUX_PD_SESSION__CLIENT_H_
#define _INCLUDE__LINUX_PD_SESSION__CLIENT_H_
#include <linux_pd_session/linux_pd_session.h>
#include <base/rpc_client.h>
namespace Genode { struct Linux_pd_session_client; }
struct Genode::Linux_pd_session_client : Rpc_client<Linux_pd_session>
{
explicit Linux_pd_session_client(Capability<Linux_pd_session> session)
: Rpc_client<Linux_pd_session>(session) { }
int bind_thread(Thread_capability thread) override {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Capability<Parent> parent) override {
return call<Rpc_assign_parent>(parent); }
bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override {
return call<Rpc_assign_pci>(pci_config_memory_address, bdf); }
Signal_source_capability alloc_signal_source() override {
return call<Rpc_alloc_signal_source>(); }
void free_signal_source(Signal_source_capability cap) override {
call<Rpc_free_signal_source>(cap); }
Signal_context_capability alloc_context(Signal_source_capability source,
unsigned long imprint) override {
return call<Rpc_alloc_context>(source, imprint); }
void free_context(Signal_context_capability cap) override {
call<Rpc_free_context>(cap); }
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
/*****************************
* Linux-specific extension **
*****************************/
void start(Capability<Dataspace> binary) {
call<Rpc_start>(binary); }
};
#endif /* _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ */

View File

@ -1,36 +0,0 @@
/*
* \brief Linux-specific extension of the PD session interface
* \author Norman Feske
* \date 2012-08-15
*/
/*
* Copyright (C) 2012-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 _INCLUDE__LINUX_PD_SESSION__LINUX_PD_SESSION_H_
#define _INCLUDE__LINUX_PD_SESSION__LINUX_PD_SESSION_H_
#include <pd_session/pd_session.h>
#include <dataspace/dataspace.h>
namespace Genode {
struct Linux_pd_session : Pd_session
{
void start(Capability<Dataspace> binary);
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_start, void, start, Capability<Dataspace>);
GENODE_RPC_INTERFACE_INHERIT(Pd_session, Rpc_start);
};
}
#endif /* _INCLUDE__LINUX_PD_SESSION__LINUX_PD_SESSION_H_ */

View File

@ -90,7 +90,7 @@ namespace Genode {
Pd_connection(char const *label = "", Native_pd_args const *pd_args = 0)
:
Connection<Pd_session>(
session("ram_quota=4K, label=\"%s\"%s%s%s", label,
session("ram_quota=36K, label=\"%s\"%s%s%s", label,
Root_arg(pd_args).string,
Uid_arg(pd_args).string,
Gid_arg(pd_args).string)),

View File

@ -11,6 +11,7 @@ LIBS += base-common syscall cxx
SRC_CC += console/log_console.cc
SRC_CC += env/env.cc env/platform_env.cc env/context_area.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(REP_DIR)/src/base/env $(BASE_DIR)/src/base/env

View File

@ -6,6 +6,7 @@
LIBS += startup cxx
SRC_CC += thread/thread.cc thread/myself.cc thread/thread_linux.cc
SRC_CC += server/rpc_cap_alloc.cc
vpath %.cc $(REP_DIR)/src/base
vpath %.cc $(BASE_DIR)/src/base

View File

@ -454,8 +454,8 @@ namespace Genode {
** Env interface **
*******************/
Parent *parent() override { return &_parent(); }
Heap *heap() override { return &_heap; }
Parent *parent() override { return &_parent(); }
Heap *heap() override { return &_heap; }
};
}

View File

@ -16,7 +16,7 @@
#include <base/env.h>
#include <base/process.h>
#include <base/printf.h>
#include <linux_pd_session/client.h>
#include <linux_native_pd/client.h>
/* framework-internal includes */
#include <linux_syscalls.h>
@ -84,10 +84,10 @@ Process::Process(Dataspace_capability elf_data_ds_cap,
enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
_thread0_cap = _cpu_session_client.create_thread(WEIGHT, name);
Linux_pd_session_client
lx_pd(static_cap_cast<Linux_pd_session>(pd_session_cap));
Linux_native_pd_client
lx_pd(static_cap_cast<Linux_native_pd>(_pd_session_client.native_pd()));
lx_pd.assign_parent(parent_cap);
_pd_session_client.assign_parent(parent_cap);
lx_pd.start(elf_data_ds_cap);
}

View File

@ -1,52 +0,0 @@
/*
* \brief Capability allocation service
* \author Norman Feske
* \date 2006-06-26
*/
/*
* Copyright (C) 2006-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__LINUX__CAP_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_
#include <cap_session/cap_session.h>
#include <base/allocator.h>
#include <base/rpc_server.h>
#include <base/lock.h>
namespace Genode {
class Cap_session_component : public Rpc_object<Cap_session>
{
private:
static long _unique_id_cnt;
static Lock &_lock()
{
static Lock static_lock;
return static_lock;
}
public:
Cap_session_component(Allocator *md_alloc, const char *args) {}
void upgrade_ram_quota(size_t ram_quota) { }
Native_capability alloc(Native_capability ep)
{
Lock::Guard lock_guard(_lock());
return Native_capability(ep.dst(), ++_unique_id_cnt);
}
void free(Native_capability cap) { }
};
}
#endif /* _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_ */

View File

@ -21,7 +21,7 @@
/* core includes */
#include <platform.h>
#include <core_parent.h>
#include <cap_session_component.h>
#include <core_pd_session.h>
#include <ram_session_component.h>
#include <core_pd_session.h>
@ -127,9 +127,9 @@ namespace Genode {
{
enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) };
Entrypoint(Cap_session *cap_session)
Entrypoint()
:
Rpc_entrypoint(cap_session, STACK_SIZE, "entrypoint")
Rpc_entrypoint(nullptr, STACK_SIZE, "entrypoint")
{ }
};
@ -138,7 +138,6 @@ namespace Genode {
typedef Synchronized_ram_session<Ram_session_component> Core_ram_session;
Core_parent _core_parent;
Cap_session_component _cap_session;
Entrypoint _entrypoint;
Core_ram_session _ram_session;
@ -165,8 +164,6 @@ namespace Genode {
Platform_env_base(Ram_session_capability(),
Cpu_session_capability(),
Pd_session_capability()),
_cap_session(platform()->core_mem_alloc(), "ram_quota=4K"),
_entrypoint(&_cap_session),
_ram_session(&_entrypoint, &_entrypoint,
platform()->ram_alloc(), platform()->core_mem_alloc(),
"ram_quota=4M", platform()->ram_alloc()->avail()),
@ -186,7 +183,6 @@ namespace Genode {
** Core-specific accessor functions **
**************************************/
Cap_session *cap_session() { return &_cap_session; }
Entrypoint *entrypoint() { return &_entrypoint; }
@ -194,13 +190,14 @@ namespace Genode {
** Env interface **
*******************/
Parent *parent() { return &_core_parent; }
Ram_session *ram_session() { return &_ram_session; }
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
Pd_session *pd_session() { return &_pd_session_client; }
Allocator *heap() { return &_heap; }
Parent *parent() override { return &_core_parent; }
Ram_session *ram_session() override { return &_ram_session; }
Ram_session_capability ram_session_cap() override { return _ram_session_cap; }
Pd_session *pd_session() override { return &_pd_session_client; }
Allocator *heap() override { return &_heap; }
Cpu_session_capability cpu_session_cap() {
Cpu_session_capability cpu_session_cap()
{
PWRN("%s:%u not implemented", __FILE__, __LINE__);
return Cpu_session_capability();
}

View File

@ -0,0 +1,53 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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_PD_COMPONENT_H_
#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_
/* Genode includes */
#include <linux_native_pd/linux_native_pd.h>
namespace Genode {
class Dataspace_component;
class Pd_session_component;
class Native_pd_component;
}
class Genode::Native_pd_component : public Rpc_object<Linux_native_pd,
Native_pd_component>
{
private:
enum { LABEL_MAX_LEN = 1024 };
enum { ROOT_PATH_MAX_LEN = 512 };
Pd_session_component &_pd_session;
char _root[ROOT_PATH_MAX_LEN];
unsigned long _pid = 0;
unsigned _uid = 0;
unsigned _gid = 0;
void _start(Dataspace_component &ds);
public:
Native_pd_component(Pd_session_component &pd, char const *args);
~Native_pd_component();
void start(Capability<Dataspace> binary);
};
#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */

View File

@ -17,11 +17,15 @@
#ifndef _CORE__INCLUDE__PAGER_H_
#define _CORE__INCLUDE__PAGER_H_
/* Genode includes */
#include <base/signal.h>
#include <pager/capability.h>
#include <cap_session/cap_session.h>
#include <thread/capability.h>
/* core-local includes */
#include <rpc_cap_factory.h>
namespace Genode {
struct Pager_object
@ -44,7 +48,7 @@ namespace Genode {
struct Pager_entrypoint
{
Pager_entrypoint(Cap_session *) { }
Pager_entrypoint(Rpc_cap_factory &) { }
template <typename FUNC>
auto apply(Pager_capability, FUNC f) -> decltype(f(nullptr)) {

View File

@ -1,112 +0,0 @@
/*
* \brief Linux-specific PD session
* \author Norman Feske
* \date 2012-08-15
*/
/*
* Copyright (C) 2012-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__PD_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/allocator.h>
#include <base/rpc_server.h>
#include <linux_pd_session/linux_pd_session.h>
/* core includes */
#include <platform_pd.h>
#include <signal_broker.h>
namespace Genode {
class Dataspace_component;
class Pd_session_component;
class Parent;
}
class Genode::Pd_session_component : public Rpc_object<Linux_pd_session, Pd_session_component>
{
private:
enum { LABEL_MAX_LEN = 1024 };
enum { ROOT_PATH_MAX_LEN = 512 };
unsigned long _pid;
char _label[LABEL_MAX_LEN];
char _root[ROOT_PATH_MAX_LEN];
unsigned _uid;
unsigned _gid;
Capability<Parent> _parent;
Rpc_entrypoint &_ds_ep;
Signal_broker _signal_broker;
void _start(Dataspace_component *ds);
public:
/**
* Constructor
*
* \param ds_ep entrypoint where the dataspaces are managed
* \param receiver_ep entrypoint holding signal-receiver component
* objects
* \param context_ep global pool of all signal contexts
* \param md_alloc meta-data allocator
* \param args additional session arguments
*/
Pd_session_component(Rpc_entrypoint &ds_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
const char *args);
~Pd_session_component();
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
/**************************
** PD session interface **
**************************/
int bind_thread(Thread_capability);
int assign_parent(Capability<Parent>);
bool assign_pci(addr_t, uint16_t) { return false; }
Signal_source_capability alloc_signal_source() override {
return _signal_broker.alloc_signal_source(); }
void free_signal_source(Signal_source_capability cap) override {
_signal_broker.free_signal_source(cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
return _signal_broker.alloc_context(sig_rec_cap, imprint);
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/******************************
** Linux-specific extension **
******************************/
void start(Capability<Dataspace> binary);
};
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */

View File

@ -16,10 +16,10 @@
#ifndef _CORE__INCLUDE__LINUX__PLATFORM_PD_H_
#define _CORE__INCLUDE__LINUX__PLATFORM_PD_H_
namespace Genode {
#include <base/allocator.h>
class Platform_pd
{ };
}
namespace Genode { struct Platform_pd; }
struct Genode::Platform_pd { Platform_pd(Allocator *, char const *) { } };
#endif /* _CORE__INCLUDE__LINUX__PLATFORM_PD_H_ */

View File

@ -0,0 +1,454 @@
/*
* \brief Core implementation of the PD session interface
* \author Norman Feske
* \date 2012-08-15
*/
/*
* Copyright (C) 2012-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.
*/
/* Genode includes */
#include <util/arg_string.h>
#include <base/printf.h>
#include <base/snprintf.h>
/* core-local includes */
#include <pd_session_component.h>
#include <dataspace_component.h>
/* Linux includes */
#include <core_linux_syscalls.h>
using namespace Genode;
/***********************************
** Utilities for chroot handling **
***********************************/
enum { MAX_PATH_LEN = 256 };
/**
* Return true if specified path is an existing directory
*/
static bool is_directory(char const *path)
{
struct stat64 s;
if (lx_stat(path, &s) != 0)
return false;
if (!(s.st_mode & S_IFDIR))
return false;
return true;
}
static bool is_path_delimiter(char c) { return c == '/'; }
static bool has_trailing_path_delimiter(char const *path)
{
char last_char = 0;
for (; *path; path++)
last_char = *path;
return is_path_delimiter(last_char);
}
/**
* Return number of path elements of given path
*/
static Genode::size_t num_path_elements(char const *path)
{
Genode::size_t count = 0;
/*
* If path starts with non-slash, the first characters belongs to a path
* element.
*/
if (*path && !is_path_delimiter(*path))
count = 1;
/* count slashes */
for (; *path; path++)
if (is_path_delimiter(*path))
count++;
return count;
}
static bool leading_path_elements(char const *path, unsigned num,
char *dst, Genode::size_t dst_len)
{
/* counter of path delimiters */
unsigned count = 0;
unsigned i = 0;
if (is_path_delimiter(path[0]))
num++;
for (; path[i] && (count < num) && (i < dst_len); i++)
{
if (is_path_delimiter(path[i]))
count++;
if (count == num)
break;
dst[i] = path[i];
}
if (i + 1 < dst_len) {
dst[i] = 0;
return true;
}
/* string is cut, append null termination anyway */
dst[dst_len - 1] = 0;
return false;
}
static void mirror_path_to_chroot(char const *chroot_path, char const *path)
{
char target_path[MAX_PATH_LEN];
Genode::snprintf(target_path, sizeof(target_path), "%s%s",
chroot_path, path);
/*
* Create directory hierarchy pointing to the target path except for the
* last element. The last element will be bind-mounted to refer to the
* original 'path'.
*/
for (unsigned i = 1; i <= num_path_elements(target_path); i++)
{
char buf[MAX_PATH_LEN];
leading_path_elements(target_path, i, buf, sizeof(buf));
/* skip existing directories */
if (is_directory(buf))
continue;
/* create new directory */
lx_mkdir(buf, 0777);
}
lx_umount(target_path);
int ret = 0;
if ((ret = lx_bindmount(path, target_path)))
PERR("bind mount failed (errno=%d)", ret);
}
/**
* Setup content of chroot environment as prerequisite to 'execve' new
* processes within the environment. I.e., the current working directory
* containing the ROM modules must be mounted at the same location within the
* chroot environment.
*/
static bool setup_chroot_environment(char const *chroot_path)
{
using namespace Genode;
static char cwd_path[MAX_PATH_LEN];
lx_getcwd(cwd_path, sizeof(cwd_path));
/*
* Validate chroot path
*/
if (!is_directory(chroot_path)) {
PERR("chroot path does not point to valid directory");
return false;
}
if (has_trailing_path_delimiter(chroot_path)) {
PERR("chroot path has trailing slash");
return false;
}
/*
* Hardlink directories needed for running Genode within the chroot
* environment.
*/
mirror_path_to_chroot(chroot_path, cwd_path);
return true;
}
/***************
** Utilities **
***************/
/**
* Argument frame for passing 'execve' paremeters through 'clone'
*/
struct Execve_args
{
char const *filename;
char const *root;
char * const *argv;
char * const *envp;
unsigned int const uid;
unsigned int const gid;
int const parent_sd;
Execve_args(char const *filename,
char const *root,
char * const *argv,
char * const *envp,
unsigned int uid,
unsigned int gid,
int parent_sd)
:
filename(filename), root(root), argv(argv), envp(envp),
uid(uid), gid(gid), parent_sd(parent_sd)
{ }
};
/**
* Startup code of the new child process
*/
static int _exec_child(Execve_args *arg)
{
lx_dup2(arg->parent_sd, PARENT_SOCKET_HANDLE);
/* change to chroot environment */
if (arg->root && arg->root[0]) {
char cwd[1024];
PDBG("arg->root='%s'", arg->root);
if (setup_chroot_environment(arg->root) == false) {
PERR("Could not setup chroot environment");
return -1;
}
if (!lx_getcwd(cwd, sizeof(cwd))) {
PERR("Failed to getcwd");
return -1;
}
PLOG("changing root of %s (PID %d) to %s",
arg->filename, lx_getpid(), arg->root);
int ret = lx_chroot(arg->root);
if (ret < 0) {
PERR("Syscall chroot failed (errno %d)", ret);
return -1;
}
ret = lx_chdir(cwd);
if (ret < 0) {
PERR("chdir to new chroot failed");
return -1;
}
}
/*
* Set UID and GID
*
* We must set the GID prior setting the UID because setting the GID won't
* be possible anymore once we set the UID to non-root.
*/
if (arg->gid) {
int const ret = lx_setgid(arg->gid);
if (ret)
PWRN("Could not set PID %d (%s) to GID %u (error %d)",
lx_getpid(), arg->filename, arg->gid, ret);
}
if (arg->uid) {
int const ret = lx_setuid(arg->uid);
if (ret)
PWRN("Could not set PID %d (%s) to UID %u (error %d)",
lx_getpid(), arg->filename, arg->uid, ret);
}
return lx_execve(arg->filename, arg->argv, arg->envp);
}
/**
* List of Unix environment variables, initialized by the startup code
*/
extern char **lx_environ;
/**
* Read environment variable as string
*
* If no matching key exists, return an empty string.
*/
static const char *get_env(const char *key)
{
Genode::size_t key_len = Genode::strlen(key);
for (char **curr = lx_environ; curr && *curr; curr++)
if ((Genode::strcmp(*curr, key, key_len) == 0) && (*curr)[key_len] == '=')
return (const char *)(*curr + key_len + 1);
return "";
}
/**************************
** PD session interface **
**************************/
void Native_pd_component::_start(Dataspace_component &ds)
{
const char *tmp_filename = "temporary_executable_elf_dataspace_file_for_execve";
/* we need 's' on stack to make it an lvalue with an lvalue member we use the pointer to */
Linux_dataspace::Filename s = ds.fname();
const char *filename = s.buf;
/*
* In order to be executable via 'execve', a program must be represented as
* a file on the Linux file system. However, this is not the case for a
* plain RAM dataspace that contains an ELF image. In this case, we copy
* the dataspace content into a temporary file whose path is passed to
* 'execve()'.
*/
if (strcmp(filename, "") == 0) {
filename = tmp_filename;
int tmp_binary_fd = lx_open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRWXU);
if (tmp_binary_fd < 0) {
PERR("Could not create file '%s'", filename);
return; /* XXX reflect error to client */
}
char buf[4096];
int num_bytes = 0;
while ((num_bytes = lx_read(ds.fd().dst().socket, buf, sizeof(buf))) != 0)
lx_write(tmp_binary_fd, buf, num_bytes);
lx_close(tmp_binary_fd);
}
/* pass parent capability as environment variable to the child */
enum { ENV_STR_LEN = 256 };
static char envbuf[5][ENV_STR_LEN];
Genode::snprintf(envbuf[1], ENV_STR_LEN, "parent_local_name=%lu",
_pd_session._parent.local_name());
Genode::snprintf(envbuf[2], ENV_STR_LEN, "DISPLAY=%s",
get_env("DISPLAY"));
Genode::snprintf(envbuf[3], ENV_STR_LEN, "HOME=%s",
get_env("HOME"));
Genode::snprintf(envbuf[4], ENV_STR_LEN, "LD_LIBRARY_PATH=%s",
get_env("LD_LIBRARY_PATH"));
char *env[] = { &envbuf[0][0], &envbuf[1][0], &envbuf[2][0],
&envbuf[3][0], &envbuf[4][0], 0 };
/* prefix name of Linux program (helps killing some zombies) */
char const *prefix = "[Genode] ";
char pname_buf[sizeof(_pd_session._label) + sizeof(prefix)];
snprintf(pname_buf, sizeof(pname_buf), "%s%s", prefix, _pd_session._label.string);
char *argv_buf[2];
argv_buf[0] = pname_buf;
argv_buf[1] = 0;
/*
* We cannot create the new process via 'fork()' because all our used
* memory including stack memory is backed by dataspaces, which had been
* mapped with the 'MAP_SHARED' flag. Therefore, after being created, the
* new process starts using the stack with the same physical memory pages
* as used by parent process. This would ultimately lead to stack
* corruption. To prevent both processes from concurrently accessing the
* same stack, we pause the execution of the parent until the child calls
* 'execve'. From then on, the child has its private memory layout. The
* desired behaviour is normally provided by 'vfork' but we use the more
* modern 'clone' call for this purpose.
*/
enum { STACK_SIZE = 4096 };
static char stack[STACK_SIZE]; /* initial stack used by the child until
calling 'execve' */
/*
* Argument frame as passed to 'clone'. Because, we can only pass a single
* pointer, all arguments are embedded within the 'execve_args' struct.
*/
Execve_args arg(filename, _root, argv_buf, env, _uid, _gid,
_pd_session._parent.dst().socket);
_pid = lx_create_process((int (*)(void *))_exec_child,
stack + STACK_SIZE - sizeof(umword_t), &arg);
if (strcmp(filename, tmp_filename) == 0)
lx_unlink(filename);
}
Native_pd_component::Native_pd_component(Pd_session_component &pd_session,
const char *args)
:
_pd_session(pd_session)
{
_pd_session._thread_ep.manage(this);
/*
* Read Linux-specific session arguments
*/
Arg_string::find_arg(args, "root").string(_root, sizeof(_root), "");
_uid = Arg_string::find_arg(args, "uid").ulong_value(0);
_gid = Arg_string::find_arg(args, "gid").ulong_value(0);
bool const is_chroot = (Genode::strcmp(_root, "") != 0);
/*
* If a UID is specified but no GID, we use the UID as GID. This way, a
* configuration error where the UID is defined but the GID is left
* undefined won't result in the execution of the new process with the
* root user's GID.
*/
if (_gid == 0)
_gid = _uid;
/*
* Print Linux-specific session arguments if specified
*
* This output used for the automated 'lx_pd_args' test.
*/
if (is_chroot || _uid || _gid)
printf("PD session for '%s'\n", _pd_session._label.string);
if (is_chroot) printf(" root: %s\n", _root);
if (_uid) printf(" uid: %u\n", _uid);
if (_gid) printf(" gid: %u\n", _gid);
}
Native_pd_component::~Native_pd_component()
{
if (_pid)
lx_kill(_pid, 9);
_pd_session._thread_ep.dissolve(this);
}
void Native_pd_component::start(Capability<Dataspace> binary)
{
/* lookup binary dataspace */
_pd_session._thread_ep.apply(binary, [&] (Dataspace_component *ds) {
if (ds)
_start(*ds);
else
PERR("failed to lookup binary to start");
});
};

View File

@ -11,444 +11,12 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <util/arg_string.h>
#include <base/printf.h>
#include <base/snprintf.h>
/* core-local includes */
#include <pd_session_component.h>
#include <dataspace_component.h>
/* Linux includes */
#include <core_linux_syscalls.h>
using namespace Genode;
/***********************************
** Utilities for chroot handling **
***********************************/
enum { MAX_PATH_LEN = 256 };
/**
* Return true if specified path is an existing directory
*/
static bool is_directory(char const *path)
{
struct stat64 s;
if (lx_stat(path, &s) != 0)
return false;
if (!(s.st_mode & S_IFDIR))
return false;
return true;
}
static bool is_path_delimiter(char c) { return c == '/'; }
static bool has_trailing_path_delimiter(char const *path)
{
char last_char = 0;
for (; *path; path++)
last_char = *path;
return is_path_delimiter(last_char);
}
/**
* Return number of path elements of given path
*/
static Genode::size_t num_path_elements(char const *path)
{
Genode::size_t count = 0;
/*
* If path starts with non-slash, the first characters belongs to a path
* element.
*/
if (*path && !is_path_delimiter(*path))
count = 1;
/* count slashes */
for (; *path; path++)
if (is_path_delimiter(*path))
count++;
return count;
}
static bool leading_path_elements(char const *path, unsigned num,
char *dst, Genode::size_t dst_len)
{
/* counter of path delimiters */
unsigned count = 0;
unsigned i = 0;
if (is_path_delimiter(path[0]))
num++;
for (; path[i] && (count < num) && (i < dst_len); i++)
{
if (is_path_delimiter(path[i]))
count++;
if (count == num)
break;
dst[i] = path[i];
}
if (i + 1 < dst_len) {
dst[i] = 0;
return true;
}
/* string is cut, append null termination anyway */
dst[dst_len - 1] = 0;
return false;
}
static void mirror_path_to_chroot(char const *chroot_path, char const *path)
{
char target_path[MAX_PATH_LEN];
Genode::snprintf(target_path, sizeof(target_path), "%s%s",
chroot_path, path);
/*
* Create directory hierarchy pointing to the target path except for the
* last element. The last element will be bind-mounted to refer to the
* original 'path'.
*/
for (unsigned i = 1; i <= num_path_elements(target_path); i++)
{
char buf[MAX_PATH_LEN];
leading_path_elements(target_path, i, buf, sizeof(buf));
/* skip existing directories */
if (is_directory(buf))
continue;
/* create new directory */
lx_mkdir(buf, 0777);
}
lx_umount(target_path);
int ret = 0;
if ((ret = lx_bindmount(path, target_path)))
PERR("bind mount failed (errno=%d)", ret);
}
/**
* Setup content of chroot environment as prerequisite to 'execve' new
* processes within the environment. I.e., the current working directory
* containing the ROM modules must be mounted at the same location within the
* chroot environment.
*/
static bool setup_chroot_environment(char const *chroot_path)
{
using namespace Genode;
static char cwd_path[MAX_PATH_LEN];
lx_getcwd(cwd_path, sizeof(cwd_path));
/*
* Validate chroot path
*/
if (!is_directory(chroot_path)) {
PERR("chroot path does not point to valid directory");
return false;
}
if (has_trailing_path_delimiter(chroot_path)) {
PERR("chroot path has trailing slash");
return false;
}
/*
* Hardlink directories needed for running Genode within the chroot
* environment.
*/
mirror_path_to_chroot(chroot_path, cwd_path);
return true;
}
/***************
** Utilities **
***************/
/**
* Argument frame for passing 'execve' paremeters through 'clone'
*/
struct Execve_args
{
char const *filename;
char const *root;
char * const *argv;
char * const *envp;
unsigned int const uid;
unsigned int const gid;
int const parent_sd;
Execve_args(char const *filename,
char const *root,
char * const *argv,
char * const *envp,
unsigned int uid,
unsigned int gid,
int parent_sd)
:
filename(filename), root(root), argv(argv), envp(envp),
uid(uid), gid(gid), parent_sd(parent_sd)
{ }
};
/**
* Startup code of the new child process
*/
static int _exec_child(Execve_args *arg)
{
lx_dup2(arg->parent_sd, PARENT_SOCKET_HANDLE);
/* change to chroot environment */
if (arg->root && arg->root[0]) {
char cwd[1024];
PDBG("arg->root='%s'", arg->root);
if (setup_chroot_environment(arg->root) == false) {
PERR("Could not setup chroot environment");
return -1;
}
if (!lx_getcwd(cwd, sizeof(cwd))) {
PERR("Failed to getcwd");
return -1;
}
PLOG("changing root of %s (PID %d) to %s",
arg->filename, lx_getpid(), arg->root);
int ret = lx_chroot(arg->root);
if (ret < 0) {
PERR("Syscall chroot failed (errno %d)", ret);
return -1;
}
ret = lx_chdir(cwd);
if (ret < 0) {
PERR("chdir to new chroot failed");
return -1;
}
}
/*
* Set UID and GID
*
* We must set the GID prior setting the UID because setting the GID won't
* be possible anymore once we set the UID to non-root.
*/
if (arg->gid) {
int const ret = lx_setgid(arg->gid);
if (ret)
PWRN("Could not set PID %d (%s) to GID %u (error %d)",
lx_getpid(), arg->filename, arg->gid, ret);
}
if (arg->uid) {
int const ret = lx_setuid(arg->uid);
if (ret)
PWRN("Could not set PID %d (%s) to UID %u (error %d)",
lx_getpid(), arg->filename, arg->uid, ret);
}
return lx_execve(arg->filename, arg->argv, arg->envp);
}
/**
* List of Unix environment variables, initialized by the startup code
*/
extern char **lx_environ;
/**
* Read environment variable as string
*
* If no matching key exists, return an empty string.
*/
static const char *get_env(const char *key)
{
Genode::size_t key_len = Genode::strlen(key);
for (char **curr = lx_environ; curr && *curr; curr++)
if ((Genode::strcmp(*curr, key, key_len) == 0) && (*curr)[key_len] == '=')
return (const char *)(*curr + key_len + 1);
return "";
}
/**************************
** PD session interface **
**************************/
void Pd_session_component::_start(Dataspace_component *ds)
{
const char *tmp_filename = "temporary_executable_elf_dataspace_file_for_execve";
if (!ds) {
PERR("could not lookup binary, aborted PD startup");
return; /* XXX reflect error to client */
}
/* we need 's' on stack to make it an lvalue with an lvalue member we use the pointer to */
Linux_dataspace::Filename s = ds->fname();
const char *filename = s.buf;
/*
* In order to be executable via 'execve', a program must be represented as
* a file on the Linux file system. However, this is not the case for a
* plain RAM dataspace that contains an ELF image. In this case, we copy
* the dataspace content into a temporary file whose path is passed to
* 'execve()'.
*/
if (strcmp(filename, "") == 0) {
filename = tmp_filename;
int tmp_binary_fd = lx_open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRWXU);
if (tmp_binary_fd < 0) {
PERR("Could not create file '%s'", filename);
return; /* XXX reflect error to client */
}
char buf[4096];
int num_bytes = 0;
while ((num_bytes = lx_read(ds->fd().dst().socket, buf, sizeof(buf))) != 0)
lx_write(tmp_binary_fd, buf, num_bytes);
lx_close(tmp_binary_fd);
}
/* pass parent capability as environment variable to the child */
enum { ENV_STR_LEN = 256 };
static char envbuf[5][ENV_STR_LEN];
Genode::snprintf(envbuf[1], ENV_STR_LEN, "parent_local_name=%lu",
_parent.local_name());
Genode::snprintf(envbuf[2], ENV_STR_LEN, "DISPLAY=%s",
get_env("DISPLAY"));
Genode::snprintf(envbuf[3], ENV_STR_LEN, "HOME=%s",
get_env("HOME"));
Genode::snprintf(envbuf[4], ENV_STR_LEN, "LD_LIBRARY_PATH=%s",
get_env("LD_LIBRARY_PATH"));
char *env[] = { &envbuf[0][0], &envbuf[1][0], &envbuf[2][0],
&envbuf[3][0], &envbuf[4][0], 0 };
/* prefix name of Linux program (helps killing some zombies) */
char const *prefix = "[Genode] ";
char pname_buf[sizeof(_label) + sizeof(prefix)];
snprintf(pname_buf, sizeof(pname_buf), "%s%s", prefix, _label);
char *argv_buf[2];
argv_buf[0] = pname_buf;
argv_buf[1] = 0;
/*
* We cannot create the new process via 'fork()' because all our used
* memory including stack memory is backed by dataspaces, which had been
* mapped with the 'MAP_SHARED' flag. Therefore, after being created, the
* new process starts using the stack with the same physical memory pages
* as used by parent process. This would ultimately lead to stack
* corruption. To prevent both processes from concurrently accessing the
* same stack, we pause the execution of the parent until the child calls
* 'execve'. From then on, the child has its private memory layout. The
* desired behaviour is normally provided by 'vfork' but we use the more
* modern 'clone' call for this purpose.
*/
enum { STACK_SIZE = 4096 };
static char stack[STACK_SIZE]; /* initial stack used by the child until
calling 'execve' */
/*
* Argument frame as passed to 'clone'. Because, we can only pass a single
* pointer, all arguments are embedded within the 'execve_args' struct.
*/
Execve_args arg(filename, _root, argv_buf, env, _uid, _gid,
_parent.dst().socket);
_pid = lx_create_process((int (*)(void *))_exec_child,
stack + STACK_SIZE - sizeof(umword_t), &arg);
if (strcmp(filename, tmp_filename) == 0)
lx_unlink(filename);
}
Pd_session_component::Pd_session_component(Rpc_entrypoint &ds_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc,
const char *args)
:
_pid(0), _uid(0), _gid(0), _ds_ep(ds_ep),
_signal_broker(md_alloc, receiver_ep, context_ep)
{
Arg_string::find_arg(args, "label").string(_label, sizeof(_label),
"<unlabeled>");
/*
* Read Linux-specific session arguments
*/
Arg_string::find_arg(args, "root").string(_root, sizeof(_root), "");
_uid = Arg_string::find_arg(args, "uid").ulong_value(0);
_gid = Arg_string::find_arg(args, "gid").ulong_value(0);
bool const is_chroot = (Genode::strcmp(_root, "") != 0);
/*
* If a UID is specified but no GID, we use the UID as GID. This way, a
* configuration error where the UID is defined but the GID is left
* undefined won't result in the execution of the new process with the
* root user's GID.
*/
if (_gid == 0)
_gid = _uid;
/*
* Print Linux-specific session arguments if specified
*
* This output used for the automated 'lx_pd_args' test.
*/
if (is_chroot || _uid || _gid)
printf("PD session for '%s'\n", _label);
if (is_chroot) printf(" root: %s\n", _root);
if (_uid) printf(" uid: %u\n", _uid);
if (_gid) printf(" gid: %u\n", _gid);
}
Pd_session_component::~Pd_session_component()
{
if (_pid)
lx_kill(_pid, 9);
}
int Pd_session_component::bind_thread(Thread_capability) { return -1; }
@ -459,9 +27,5 @@ int Pd_session_component::assign_parent(Capability<Parent> parent)
}
void Pd_session_component::start(Capability<Dataspace> binary)
{
/* lookup binary dataspace */
_ds_ep.apply(binary, [&] (Dataspace_component *ds) {
_start(ds); });
};
bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; }

View File

@ -11,12 +11,15 @@ SRC_CC = main.cc \
ram_session_component.cc \
ram_session_support.cc \
rom_session_component.cc \
cap_session_component.cc \
cpu_session_component.cc \
cpu_session_extension.cc \
cpu_session_support.cc \
dataspace_component.cc \
pd_session_component.cc \
pd_upgrade_ram_quota.cc \
dataspace_component.cc \
native_pd_component.cc \
rpc_cap_factory.cc \
core_rpc_cap_alloc.cc \
io_mem_session_component.cc \
signal_source_component.cc \
trace_session_component.cc \
@ -40,11 +43,13 @@ include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath platform_services.cc $(GEN_CORE_DIR)
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath thread.cc $(BASE_DIR)/src/base/thread
vpath myself.cc $(BASE_DIR)/src/base/thread

View File

@ -1,62 +0,0 @@
/*
* \brief CAP-session interface
* \author Norman Feske
* \date 2006-06-23
*
* A 'Cap_session' is an allocator of user-level capabilities.
* User-level capabilities are used to reference server objects
* across address spaces.
*/
/*
* Copyright (C) 2006-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 _INCLUDE__CAP_SESSION__CAP_SESSION_H_
#define _INCLUDE__CAP_SESSION__CAP_SESSION_H_
#include <base/native_types.h>
#include <session/session.h>
namespace Genode {
struct Cap_session : Session
{
static const char *service_name() { return "CAP"; }
virtual ~Cap_session() { }
/**
* Allocate new unique userland capability
*
* \param ep entry point that will use this capability
*
* \return new userland capability
*/
virtual Native_capability alloc(Native_capability ep,
addr_t entry = 0,
addr_t flags = 0) = 0;
/**
* Free userland capability
*
* \param cap userland capability to free
*/
virtual void free(Native_capability cap) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_alloc, Native_capability, alloc,
Native_capability, addr_t, addr_t);
GENODE_RPC(Rpc_free, void, free, Native_capability);
GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free);
};
}
#endif /* _INCLUDE__CAP_SESSION__CAP_SESSION_H_ */

View File

@ -1,39 +0,0 @@
/*
* \brief Client-side CAP session interface
* \author Norman Feske
* \author Alexander Boettcher
* \date 2006-07-10
*/
/*
* Copyright (C) 2006-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 _INCLUDE__CAP_SESSION__CLIENT_H_
#define _INCLUDE__CAP_SESSION__CLIENT_H_
#include <cap_session/capability.h>
#include <cap_session/cap_session.h>
#include <base/rpc_client.h>
namespace Genode {
struct Cap_session_client : Rpc_client<Cap_session>
{
explicit Cap_session_client(Cap_session_capability session)
: Rpc_client<Cap_session>(session) { }
Native_capability alloc(Native_capability ep, addr_t entry = 0,
addr_t flags = 0)
{
return call<Rpc_alloc>(ep, entry, flags);
}
void free(Native_capability cap) { call<Rpc_free>(cap); }
};
}
#endif /* _INCLUDE__CAP_SESSION__CLIENT_H_ */

View File

@ -0,0 +1,40 @@
/*
* \brief Client-side stub for the NOVA-specific PD session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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_PD__CLIENT_H_
#define _INCLUDE__NOVA_NATIVE_PD__CLIENT_H_
#include <nova_native_pd/nova_native_pd.h>
#include <base/rpc_client.h>
namespace Genode { struct Nova_native_pd_client; }
struct Genode::Nova_native_pd_client : Rpc_client<Nova_native_pd>
{
explicit Nova_native_pd_client(Capability<Native_pd> cap)
: Rpc_client<Nova_native_pd>(static_cap_cast<Nova_native_pd>(cap)) { }
Native_capability alloc_rpc_cap(Native_capability ep,
addr_t entry, addr_t mtd) override
{
return call<Rpc_alloc_rpc_cap>(ep, entry, mtd);
}
void imprint_rpc_cap(Native_capability cap, unsigned long badge) override
{
call<Rpc_imprint_rpc_cap>(cap, badge);
}
};
#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */

View File

@ -0,0 +1,51 @@
/*
* \brief NOVA-specific part of the PD session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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_PD__NOVA_NATIVE_PD_H_
#define _INCLUDE__NOVA_NATIVE_PD__NOVA_NATIVE_PD_H_
#include <base/rpc.h>
#include <pd_session/pd_session.h>
namespace Genode { struct Nova_native_pd; }
struct Genode::Nova_native_pd : Pd_session::Native_pd
{
/**
* Allocate RPC object capability
*
* \param ep entry point that will use this capability
* \param entry server-side instruction pointer of the RPC handler
* \param mtd NOVA message transfer descriptor
*
* \throw Pd_session::Out_of_metadata
*
* \return new RPC object capability
*/
virtual Native_capability alloc_rpc_cap(Native_capability ep,
addr_t entry, addr_t mtd) = 0;
/**
* Imprint badge into the portal of the specified RPC capability
*/
virtual void imprint_rpc_cap(Native_capability cap, unsigned long badge) = 0;
GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap,
GENODE_TYPE_LIST(Pd_session::Out_of_metadata),
Native_capability, addr_t, addr_t);
GENODE_RPC(Rpc_imprint_rpc_cap, void, imprint_rpc_cap,
Native_capability, unsigned long);
GENODE_RPC_INTERFACE(Rpc_alloc_rpc_cap, Rpc_imprint_rpc_cap);
};
#endif /* _INCLUDE__NOVA_NATIVE_PD__NOVA_NATIVE_PD_H_ */

View File

@ -1,68 +0,0 @@
/*
* \brief Client-side pd session interface
* \author Christian Helmuth
* \date 2006-07-12
*/
/*
* Copyright (C) 2006-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 _INCLUDE__PD_SESSION__CLIENT_H_
#define _INCLUDE__PD_SESSION__CLIENT_H_
#include <pd_session/capability.h>
#include <base/rpc_client.h>
namespace Genode { struct Pd_session_client; }
/*
* This implementation overrides the corresponding header in base/include
* to tweak the way the parent capability is passed to core.
*/
struct Genode::Pd_session_client : Rpc_client<Pd_session>
{
explicit Pd_session_client(Pd_session_capability session)
: Rpc_client<Pd_session>(session) { }
int bind_thread(Thread_capability thread) override {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Capability<Parent> parent) override
{
/*
* NOVA-specific implementation
*
* We need to prevent NOVA from creating a new branch in the mapping
* tree. Instead, we need core to re-associate the supplied PD cap with
* the core-known PD session component of the parent.
*/
parent.solely_map();
return call<Rpc_assign_parent>(parent);
}
bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override {
return call<Rpc_assign_pci>(pci_config_memory_address, bdf); }
Signal_source_capability alloc_signal_source() override {
return call<Rpc_alloc_signal_source>(); }
void free_signal_source(Signal_source_capability cap) override {
call<Rpc_free_signal_source>(cap); }
Signal_context_capability alloc_context(Signal_source_capability source,
unsigned long imprint) override {
return call<Rpc_alloc_context>(source, imprint); }
void free_context(Signal_context_capability cap) override {
call<Rpc_free_context>(cap); }
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
};
#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */

View File

@ -11,6 +11,7 @@ SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += thread/thread_nova.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(BASE_DIR)/src/base/env

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/core/include
vpath %.cc $(REP_DIR)/src/core/spec/x86_32

View File

@ -0,0 +1,56 @@
/*
* \brief Core-specific back end of the RPC entrypoint
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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/env.h>
#include <util/retry.h>
#include <base/rpc_server.h>
#include <pd_session/client.h>
/* NOVA-specific part of the PD session interface */
#include <nova_native_pd/client.h>
using namespace Genode;
Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &pd, Native_capability ep,
addr_t entry)
{
if (!_native_pd_cap.valid())
_native_pd_cap = pd.native_pd();
Nova_native_pd_client native_pd(_native_pd_cap);
Untyped_capability new_obj_cap =
retry<Genode::Pd_session::Out_of_metadata>(
[&] () {
return native_pd.alloc_rpc_cap(ep, entry, 0);
},
[&] () {
Pd_session_client *client =
dynamic_cast<Pd_session_client*>(&pd);
if (client)
env()->parent()->upgrade(*client, "ram_quota=16K");
});
native_pd.imprint_rpc_cap(new_obj_cap, new_obj_cap.local_name());
return new_obj_cap;
}
void Rpc_entrypoint::_free_rpc_cap(Pd_session &pd, Native_capability cap)
{
return pd.free_rpc_cap(cap);
}

View File

@ -25,32 +25,6 @@
using namespace Genode;
static Untyped_capability create_portal(Cap_session * cap_session,
Untyped_capability ec_cap,
addr_t entry)
{
Untyped_capability obj_cap;
obj_cap = cap_session->alloc(ec_cap, entry);
if (!obj_cap.valid())
return obj_cap;
using namespace Nova;
/* set local badge */
if (pt_ctrl(obj_cap.local_name(), obj_cap.local_name()) != NOVA_OK) {
cap_session->free(obj_cap);
return Untyped_capability();
}
/* disable PT_CTRL permission - feature for security reasons now */
revoke(Obj_crd(obj_cap.local_name(), 0, Obj_crd::RIGHT_PT_CTRL));
return obj_cap;
}
/***********************
** Server entrypoint **
***********************/
@ -59,7 +33,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
{
using namespace Nova;
Untyped_capability ec_cap, obj_cap;
Untyped_capability ec_cap;
/* _ec_sel is invalid until thread gets started */
if (tid().ec_sel != Native_thread::INVALID_INDEX)
@ -67,7 +41,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
else
ec_cap = _thread_cap;
obj_cap = create_portal(_cap_session, ec_cap, (addr_t)_activation_entry);
Untyped_capability obj_cap = _alloc_rpc_cap(_pd_session, ec_cap,
(addr_t)&_activation_entry);
if (!obj_cap.valid())
return obj_cap;
@ -83,7 +58,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
{
/* de-announce object from cap_session */
_cap_session->free(obj->cap());
_free_rpc_cap(_pd_session, obj->cap());
/* avoid any incoming IPC */
Nova::revoke(Nova::Obj_crd(obj->cap().local_name(), 0), true);
@ -206,13 +181,13 @@ void Rpc_entrypoint::activate()
}
Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
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),
_delay_start(Lock::LOCKED),
_cap_session(cap_session)
_pd_session(*pd_session)
{
/* when not running in core set the affinity via cpu session */
if (_tid.ec_sel == Native_thread::INVALID_INDEX) {
@ -232,8 +207,8 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
Thread_base::start();
/* create cleanup portal */
_cap = create_portal(cap_session, Native_capability(_tid.ec_sel),
(addr_t)_activation_entry);
_cap = _alloc_rpc_cap(_pd_session, Native_capability(_tid.ec_sel),
(addr_t)_activation_entry);
if (!_cap.valid())
throw Cpu_session::Thread_creation_failed();
@ -258,6 +233,5 @@ Rpc_entrypoint::~Rpc_entrypoint()
if (!_cap.valid())
return;
/* de-announce object from cap_session */
_cap_session->free(_cap);
_free_rpc_cap(_pd_session, _cap);
}

View File

@ -0,0 +1,44 @@
/*
* \brief Core-specific back end of the RPC entrypoint
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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/rpc_server.h>
/* core-local includes */
#include <platform_generic.h>
#include <rpc_cap_factory.h>
#include <imprint_badge.h>
using namespace Genode;
static Rpc_cap_factory &rpc_cap_factory()
{
static Rpc_cap_factory inst(*platform()->core_mem_alloc());
return inst;
}
Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &, Native_capability ep,
addr_t entry)
{
Native_capability cap = rpc_cap_factory().alloc(ep, entry, 0);
imprint_badge(cap.local_name(), cap.local_name());
return cap;
}
void Rpc_entrypoint::_free_rpc_cap(Pd_session &, Native_capability cap)
{
rpc_cap_factory().free(cap);
}

View File

@ -1,126 +0,0 @@
/*
* \brief Capability allocation service
* \author Alexander Boettcher
* \date 2012-07-27
*/
/*
* Copyright (C) 2006-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__CAP_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_
#include <cap_session/cap_session.h>
#include <base/rpc_server.h>
#include <base/lock.h>
/* core includes */
#include <platform_pd.h>
namespace Genode {
class Cap_session_component : public Rpc_object<Cap_session>
{
private:
struct Cap_object : List<Cap_object>::Element
{
Genode::addr_t _cap_sel;
Cap_object(addr_t cap_sel) : _cap_sel(cap_sel) {}
};
Tslab<Cap_object, 128> _cap_slab;
List<Cap_object> _cap_list;
Lock _cap_lock;
public:
/**
* Constructor
*/
Cap_session_component(Allocator *md_alloc, const char *args)
: _cap_slab(md_alloc) { }
/**
* Destructor
*/
~Cap_session_component()
{
Lock::Guard cap_lock(_cap_lock);
for (Cap_object *obj; (obj = _cap_list.first()); ) {
Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0));
cap_map()->remove(obj->_cap_sel, 0, false);
_cap_list.remove(obj);
destroy(&_cap_slab, obj);
}
}
void upgrade_ram_quota(size_t ram_quota) { }
Native_capability alloc(Native_capability ep, addr_t entry,
addr_t mtd)
{
addr_t pt_sel = cap_map()->insert();
addr_t pd_sel = Platform_pd::pd_core_sel();
addr_t ec_sel = ep.local_name();
using namespace Nova;
Lock::Guard cap_lock(_cap_lock);
/* create cap object */
Cap_object * pt_cap = new (&_cap_slab) Cap_object(pt_sel);
if (!pt_cap)
return Native_capability::invalid_cap();
_cap_list.insert(pt_cap);
/* create portal */
uint8_t res = create_pt(pt_sel, pd_sel, ec_sel, Mtd(mtd),
entry);
if (res == NOVA_OK)
return Native_capability(pt_sel);
PERR("cap_session - cap=%lx:%lx"
" addr=%lx flags=%lx xpt=%lx res=%u",
ec_sel, ep.local_name(),
entry, mtd, pt_sel, res);
_cap_list.remove(pt_cap);
destroy(&_cap_slab, pt_cap);
/* cleanup unused selectors */
cap_map()->remove(pt_sel, 0, false);
return Native_capability::invalid_cap();
}
void free(Native_capability cap)
{
if (!cap.valid()) return;
Lock::Guard cap_lock(_cap_lock);
for (Cap_object *obj = _cap_list.first(); obj ; obj = obj->next()) {
if (cap.local_name() == obj->_cap_sel) {
Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0));
cap_map()->remove(obj->_cap_sel, 0, false);
_cap_list.remove(obj);
destroy(&_cap_slab, obj);
return;
}
}
PDBG("invalid cap object");
}
};
}
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */

View File

@ -0,0 +1,30 @@
/*
* \brief Utility to imprint a badge into a NOVA portal
* \author Norman Feske
* \date 2016-03-03
*/
/*
* 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__IMPRINT_BADGE_H_
#define _CORE__INCLUDE__IMPRINT_BADGE_H_
static inline bool imprint_badge(unsigned long pt_sel, unsigned long badge)
{
using namespace Nova;
/* assign badge to portal */
if (pt_ctrl(pt_sel, badge) != NOVA_OK)
return false;
/* disable PT_CTRL permission to prevent subsequent imprint attempts */
revoke(Obj_crd(pt_sel, 0, Obj_crd::RIGHT_PT_CTRL));
return true;
}
#endif /* _CORE__INCLUDE__IMPRINT_BADGE_H_ */

View File

@ -0,0 +1,49 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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_PD_COMPONENT_H_
#define _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_
/* Genode includes */
#include <nova_native_pd/nova_native_pd.h>
/* core-local includes */
#include <rpc_cap_factory.h>
namespace Genode {
class Pd_session_component;
class Native_pd_component;
}
class Genode::Native_pd_component : public Rpc_object<Nova_native_pd>
{
private:
Pd_session_component &_pd_session;
public:
Native_pd_component(Pd_session_component &pd, char const *args);
~Native_pd_component();
/**
* Nova_native_pd interface
*/
Native_capability alloc_rpc_cap(Native_capability, addr_t, addr_t) override;
void imprint_rpc_cap(Native_capability, unsigned long) override;
};
#endif /* _CORE__INCLUDE__NATIVE_PD_COMPONENT_H_ */

View File

@ -21,8 +21,9 @@
#include <cap_session/cap_session.h>
#include <pager/capability.h>
/* Core includes */
/* core-local includes */
#include <ipc_pager.h>
#include <rpc_cap_factory.h>
namespace Genode {
@ -416,18 +417,18 @@ namespace Genode {
private:
Pager_activation_base *_activation;
Cap_session *_cap_session;
Rpc_cap_factory &_cap_factory;
public:
/**
* Constructor
*
* \param cap_session Cap_session for creating capabilities
* \param cap_factory factory for creating capabilities
* for the pager objects managed by this
* entry point
*/
Pager_entrypoint(Cap_session *cap_session);
Pager_entrypoint(Rpc_cap_factory &cap_factory);
/**
* Associate Pager_object with the entry point

View File

@ -0,0 +1,66 @@
/*
* \brief RPC capability factory
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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__RPC_CAP_FACTORY_H_
#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_
/* Genode includes */
#include <util/list.h>
#include <base/lock.h>
#include <base/capability.h>
#include <base/tslab.h>
#include <base/printf.h>
namespace Genode { class Rpc_cap_factory; }
class Genode::Rpc_cap_factory
{
private:
struct Cap_object : List<Cap_object>::Element
{
Genode::addr_t _cap_sel;
Cap_object(addr_t cap_sel) : _cap_sel(cap_sel) {}
};
Tslab<Cap_object, 128> _slab;
List<Cap_object> _list;
Lock _lock;
public:
Rpc_cap_factory(Allocator &md_alloc);
~Rpc_cap_factory();
/**
* Allocate RPC capability
*
* \throw Allocator::Out_of_memory
*
* This function is invoked via Nova_native_pd::alloc_rpc_cap.
*/
Native_capability alloc(Native_capability ep, addr_t entry, addr_t mtd);
Native_capability alloc(Native_capability)
{
PWRN("unexpected call to non-implemented Rpc_cap_factory::alloc");
return Native_capability();
}
void free(Native_capability cap);
};
#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */

View File

@ -0,0 +1,55 @@
/*
* \brief Kernel-specific part of the PD-session interface
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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.
*/
#include <pd_session_component.h>
#include <native_pd_component.h>
/* core-local includes */
#include <imprint_badge.h>
using namespace Genode;
Native_capability Native_pd_component::alloc_rpc_cap(Native_capability ep,
addr_t entry, addr_t mtd)
{
try {
return _pd_session._rpc_cap_factory.alloc(ep, entry, mtd); }
catch (Allocator::Out_of_memory) {
throw Pd_session::Out_of_metadata(); }
}
void Native_pd_component::imprint_rpc_cap(Native_capability cap, unsigned long badge)
{
if (cap.valid())
imprint_badge(cap.local_name(), badge);
}
Native_pd_component::Native_pd_component(Pd_session_component &pd_session,
char const *args)
:
_pd_session(pd_session)
{
_pd_session._thread_ep.manage(this);
}
Native_pd_component::~Native_pd_component()
{
_pd_session._thread_ep.dissolve(this);
}

View File

@ -18,8 +18,9 @@
#include <util/construct_at.h>
#include <rm_session/rm_session.h>
/* Core includes */
/* core-local includes */
#include <pager.h>
#include <imprint_badge.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -832,8 +833,8 @@ void Pager_activation_base::entry() { }
**********************/
Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session)
: _cap_session(cap_session)
Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &cap_factory)
: _cap_factory(cap_factory)
{
/* sanity check space for pager threads */
if (kernel_hip()->cpu_max() > PAGER_CPUS) {
@ -869,10 +870,9 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
/* request creation of portal bind to pager thread */
Native_capability cap_session =
_cap_session->alloc(pager_thread_cap, obj->handler_address());
_cap_factory.alloc(pager_thread_cap, obj->handler_address(), 0);
if (NOVA_OK != pt_ctrl(cap_session.local_name(), reinterpret_cast<mword_t>(obj)))
nova_die();
imprint_badge(cap_session.local_name(), reinterpret_cast<mword_t>(obj));
/* disable the feature for security reasons now */
revoke(Obj_crd(cap_session.local_name(), 0, Obj_crd::RIGHT_PT_CTRL));
@ -890,12 +890,16 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
void Pager_entrypoint::dissolve(Pager_object *obj)
{
Native_capability pager_obj = obj->Object_pool<Pager_object>::Entry::cap();
/* cleanup at cap session */
_cap_session->free(pager_obj);
/* cleanup at cap factory */
_cap_factory.free(pager_obj);
/* revoke cap selector locally */
revoke(pager_obj.dst(), true);
/* remove object from pool */
remove(obj);
/* take care that no faults are in-flight */
obj->cleanup_call();
}

View File

@ -0,0 +1,90 @@
/*
* \brief RPC capability factory
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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.
*/
/* core-local includes */
#include <rpc_cap_factory.h>
#include <platform_pd.h>
using namespace Genode;
Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, addr_t mtd)
{
addr_t pt_sel = cap_map()->insert();
addr_t pd_sel = Platform_pd::pd_core_sel();
addr_t ec_sel = ep.local_name();
using namespace Nova;
Lock::Guard guard(_lock);
/* create cap object */
Cap_object * pt_cap = new (&_slab) Cap_object(pt_sel);
if (!pt_cap)
return Native_capability::invalid_cap();
_list.insert(pt_cap);
/* create portal */
uint8_t const res = create_pt(pt_sel, pd_sel, ec_sel, Mtd(mtd), entry);
if (res == NOVA_OK)
return Native_capability(pt_sel);
PERR("cap_session - cap=%lx:%lx addr=%lx mtd=%lx xpt=%lx res=%u",
ec_sel, ep.local_name(), entry, mtd, pt_sel, res);
_list.remove(pt_cap);
destroy(&_slab, pt_cap);
/* cleanup unused selectors */
cap_map()->remove(pt_sel, 0, false);
return Native_capability::invalid_cap();
}
void Rpc_cap_factory::free(Native_capability cap)
{
if (!cap.valid()) return;
Lock::Guard guard(_lock);
for (Cap_object *obj = _list.first(); obj ; obj = obj->next()) {
if (cap.local_name() == obj->_cap_sel) {
Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0));
cap_map()->remove(obj->_cap_sel, 0, false);
_list.remove(obj);
destroy(&_slab, obj);
return;
}
}
PDBG("invalid cap object");
}
Rpc_cap_factory::Rpc_cap_factory(Allocator &md_alloc) : _slab(&md_alloc) { }
Rpc_cap_factory::~Rpc_cap_factory()
{
Lock::Guard guard(_lock);
for (Cap_object *obj; (obj = _list.first()); ) {
Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0));
cap_map()->remove(obj->_cap_sel, 0, false);
_list.remove(obj);
destroy(&_slab, obj);
}
}

View File

@ -7,6 +7,7 @@ SRC_CC = context_area.cc \
core_mem_alloc.cc \
core_printf.cc \
core_rm_session.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_extension.cc \
cpu_session_support.cc \
@ -21,8 +22,10 @@ SRC_CC = context_area.cc \
main.cc \
pager.cc \
pd_session_component.cc \
native_pd_component.cc \
pd_upgrade_ram_quota.cc \
pd_assign_pci.cc \
rpc_cap_factory.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \

View File

@ -1,41 +0,0 @@
/*
* \brief Client-side OKL4 specific pd session interface
* \author Stefan Kalkowski
* \date 2009-06-03
*/
/*
* 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 _INCLUDE__OKL4_PD_SESSION__CLIENT_H_
#define _INCLUDE__OKL4_PD_SESSION__CLIENT_H_
#include <pd_session/client.h>
#include <okl4_pd_session/okl4_pd_session.h>
namespace Genode {
struct Okl4_pd_session_client : Rpc_client<Okl4_pd_session>
{
explicit Okl4_pd_session_client(Pd_session_capability cap)
: Rpc_client<Okl4_pd_session>(static_cap_cast<Okl4_pd_session>(cap)) { }
int bind_thread(Thread_capability thread) {
return call<Rpc_bind_thread>(thread); }
int assign_parent(Parent_capability parent) {
return call<Rpc_assign_parent>(parent); }
Okl4::L4_SpaceId_t space_id() {
return call<Rpc_space_id>(); }
void space_pager(Thread_capability thread) {
call<Rpc_space_pager>(thread); }
};
}
#endif /* _INCLUDE__OKL4_PD_SESSION__CLIENT_H_ */

View File

@ -1,32 +0,0 @@
/*
* \brief Connection to OKL4-specific PD service
* \author Stefan Kalkowski
* \date 2009-06-22
*/
/*
* 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 _INCLUDE__OKL4_PD_SESSION__CONNECTION_H_
#define _INCLUDE__OKL4_PD_SESSION__CONNECTION_H_
#include <okl4_pd_session/client.h>
#include <base/connection.h>
namespace Genode {
struct Pd_connection : Connection<Pd_session>, Okl4_pd_session_client
{
Pd_connection()
:
Connection<Pd_session>(session("ram_quota=4K")),
Okl4_pd_session_client(cap())
{ }
};
}
#endif /* _INCLUDE__OKL4_PD_SESSION__CONNECTION_H_ */

View File

@ -1,62 +0,0 @@
/*
* \brief OKL4 specific extension of the PD session interface
* \author Stefan Kalkowski
* \date 2009-06-03
*/
/*
* 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 _INCLUDE__OKL4_PD_SESSION__OKL4_PD_SESSION_H_
#define _INCLUDE__OKL4_PD_SESSION__OKL4_PD_SESSION_H_
/* OKL4 includes */
namespace Okl4 { extern "C" {
#include <l4/types.h>
} }
/* Genode includes */
#include <pd_session/pd_session.h>
namespace Genode {
struct Okl4_pd_session : Pd_session
{
virtual ~Okl4_pd_session() { }
/**
* Get the OKL4 specific space ID of the PD
*
* Should be used only by OKLinux, as it will be removed
* in the future!
*
* \return the space ID
*/
virtual Okl4::L4_SpaceId_t space_id() = 0;
/**
* Set the thread/space allowed to page the PD
*
* (have a look at SpaceControl in OKL4)
* Should be used only by OKLinux, as it will be removed
* in the future!
*/
virtual void space_pager(Thread_capability) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_space_id, Okl4::L4_SpaceId_t, space_id);
GENODE_RPC(Rpc_space_pager, void, space_pager, Thread_capability);
GENODE_RPC_INTERFACE_INHERIT(Pd_session, Rpc_space_id, Rpc_space_pager);
};
}
#endif /* _INCLUDE__OKL4_PD_SESSION__OKL4_PD_SESSION_H_ */

View File

@ -3,6 +3,7 @@ SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc
vpath %.cc $(REP_DIR)/src/base
vpath %.cc $(BASE_DIR)/src/base

View File

@ -1,91 +0,0 @@
/*
* \brief Core-specific instance of the PD session interface for OKL4
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-07-17
*/
/*
* Copyright (C) 2006-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__OKL4__PD_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_
/* Genode includes */
#include <okl4_pd_session/okl4_pd_session.h>
#include <base/rpc_server.h>
/* core includes */
#include <platform.h>
#include <signal_broker.h>
namespace Genode { class Pd_session_component; }
class Genode::Pd_session_component : public Rpc_object<Okl4_pd_session>
{
private:
Platform_pd _pd;
Rpc_entrypoint &_thread_ep;
Signal_broker _signal_broker;
public:
Pd_session_component(Rpc_entrypoint &thread_ep,
Rpc_entrypoint &receiver_ep,
Rpc_entrypoint &context_ep,
Allocator &md_alloc, const char *args)
:
_thread_ep(thread_ep),
_signal_broker(md_alloc, receiver_ep, context_ep)
{ }
/**
* Register quota donation at allocator guard
*/
void upgrade_ram_quota(size_t ram_quota) { }
/**************************
** Pd session interface **
**************************/
int bind_thread(Thread_capability);
int assign_parent(Capability<Parent>);
bool assign_pci(addr_t, uint16_t) { return false; }
Signal_source_capability alloc_signal_source() override {
return _signal_broker.alloc_signal_source(); }
void free_signal_source(Signal_source_capability cap) override {
_signal_broker.free_signal_source(cap); }
Signal_context_capability
alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override
{
return _signal_broker.alloc_context(sig_rec_cap, imprint);
}
void free_context(Signal_context_capability cap) override {
_signal_broker.free_context(cap); }
void submit(Signal_context_capability cap, unsigned n) override {
_signal_broker.submit(cap, n); }
/*****************************
** OKL4-specific additions **
*****************************/
void space_pager(Thread_capability thread);
Okl4::L4_SpaceId_t space_id() {
return Okl4::L4_SpaceId(_pd.pd_id()); }
};
#endif /* _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_ */

View File

@ -14,6 +14,9 @@
#ifndef _CORE__INCLUDE__PLATFORM_PD_H_
#define _CORE__INCLUDE__PLATFORM_PD_H_
/* Genode includes */
#include <base/allocator.h>
/* core includes */
#include <platform_thread.h>
#include <address_space.h>
@ -121,11 +124,8 @@ namespace Genode {
/**
* Protection domain allocation
*
* Find free L4 task and use it. We need the special case for Core
* startup.
*/
int _alloc_pd(signed pd_id);
int _alloc_pd();
/**
* Protection domain deallocation
@ -153,7 +153,7 @@ namespace Genode {
* Constructors
*/
Platform_pd(bool core);
Platform_pd(signed pd_id = PD_INVALID, bool create = true);
Platform_pd(Allocator *, char const *);
/**
* Destructor

View File

@ -1,29 +0,0 @@
/*
* \brief Core implementation of the PD session interface extension
* \author Stefan Kalkowski
* \date 2009-06-21
*/
/*
* 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 <util.h>
#include <pd_session_component.h>
#include <cpu_session_component.h>
using namespace Genode;
void Pd_session_component::space_pager(Thread_capability thread)
{
_thread_ep.apply(thread, [this] (Cpu_thread_component *cpu_thread)
{
if (!cpu_thread) return;
_pd.space_pager(cpu_thread->platform_thread());
});
}

View File

@ -91,29 +91,19 @@ void Platform_pd::_destroy_pd()
}
int Platform_pd::_alloc_pd(signed pd_id)
int Platform_pd::_alloc_pd()
{
if (pd_id == PD_INVALID) {
unsigned i;
unsigned i;
for (i = PD_FIRST; i <= PD_MAX; i++)
if (_pds()[i].free) break;
for (i = PD_FIRST; i <= PD_MAX; i++)
if (_pds()[i].free) break;
/* no free protection domains available */
if (i > PD_MAX) return -1;
/* no free protection domains available */
if (i > PD_MAX) return -1;
pd_id = i;
_pds()[i].free = 0;
} else {
if (!_pds()[pd_id].reserved || !_pds()[pd_id].free)
return -1;
}
_pds()[pd_id].free = 0;
_pd_id = pd_id;
return pd_id;
return i;
}
@ -329,26 +319,23 @@ Platform_pd::Platform_pd(bool core)
_init_threads();
_pd_id = _alloc_pd(PD_INVALID);
_pd_id = _alloc_pd();
_create_pd(false);
}
Platform_pd::Platform_pd(signed pd_id, bool create)
Platform_pd::Platform_pd(Allocator *, char const *label)
: _space_pager(0)
{
if (!create)
panic("create must be true.");
_init_threads();
_pd_id = _alloc_pd(pd_id);
_pd_id = _alloc_pd();
if (_pd_id > PD_MAX)
PERR("pd alloc failed");
_create_pd(create);
_create_pd(true);
}

View File

@ -4,11 +4,11 @@ LIBS += boot_info base-common
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += cap_session_component.cc \
context_area.cc \
SRC_CC += context_area.cc \
core_mem_alloc.cc \
core_printf.cc \
core_rm_session.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_support.cc \
dataspace_component.cc \
@ -17,11 +17,13 @@ SRC_CC += cap_session_component.cc \
io_mem_session_support.cc \
irq_session_component.cc \
main.cc \
okl4_pd_session_component.cc \
pager.cc \
pager_ep.cc \
pager_object.cc \
pd_session_component.cc \
pd_upgrade_ram_quota.cc \
pd_assign_pci.cc \
rpc_cap_factory.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \
@ -46,9 +48,11 @@ include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
@ -56,6 +60,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)

View File

@ -11,6 +11,7 @@ SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(BASE_DIR)/src/base/env

View File

@ -4,9 +4,9 @@ LIBS = base-common
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC = cap_session_component.cc \
context_area.cc \
SRC_CC = context_area.cc \
core_printf.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
cpu_session_platform.cc \
dataspace_component.cc \
@ -18,6 +18,7 @@ SRC_CC = cap_session_component.cc \
main.cc \
multiboot_info.cc \
pd_session_component.cc \
rpc_cap_factory.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
pager.cc \
@ -46,9 +47,9 @@ include $(GEN_CORE_DIR)/version.inc
vpath main.cc $(GEN_CORE_DIR)
vpath ram_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath cap_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rm_session_component.cc $(GEN_CORE_DIR)
@ -58,6 +59,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR)
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 context_area.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR)

View File

@ -11,6 +11,7 @@ SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += env/capability_space.cc
SRC_CC += thread/thread_start.cc thread/thread_init.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(REP_DIR)/src/base
INC_DIR += $(BASE_DIR)/src/base/env

View File

@ -7,10 +7,10 @@ SRC_CC += \
ram_session_component.cc \
ram_session_support.cc \
rom_session_component.cc \
cap_session_component.cc \
cpu_session_component.cc \
cpu_session_support.cc \
pd_session_component.cc \
rpc_cap_factory.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
io_mem_session_component.cc \
@ -28,6 +28,7 @@ SRC_CC += \
trace_session_component.cc \
core_rm_session.cc \
core_mem_alloc.cc \
core_rpc_cap_alloc.cc \
dump_alloc.cc \
context_area.cc \
capability_space.cc \
@ -58,6 +59,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)
vpath %.cc $(REP_DIR)/src/core

View File

@ -29,7 +29,7 @@ using namespace Genode;
Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
{
Untyped_capability new_obj_cap = _cap_session->alloc(_cap);
Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, _cap);
/* add server object to object pool */
obj->cap(new_obj_cap);

View File

@ -23,8 +23,6 @@
#include <core_capability_space.h>
#include <platform.h>
namespace Genode { class Cap_session; }
/**
* Core-specific supplement of the capability meta data
@ -33,20 +31,20 @@ class Genode::Native_capability::Data : public Capability_data
{
private:
Cap_session const *_cap_session = nullptr;
Pd_session const *_pd_session = nullptr;
public:
Data(Cap_session const *cap_session, Rpc_obj_key key)
Data(Pd_session const *pd_session, Rpc_obj_key key)
:
Capability_data(key), _cap_session(cap_session)
Capability_data(key), _pd_session(pd_session)
{ }
Data() { }
bool belongs_to(Cap_session const *session) const
bool belongs_to(Pd_session const *session) const
{
return _cap_session == session;
return _pd_session == session;
}
};
@ -79,7 +77,7 @@ namespace {
Native_capability
Capability_space::create_rpc_obj_cap(Native_capability ep_cap,
Cap_session const *cap_session,
Pd_session const *pd_session,
Rpc_obj_key rpc_obj_key)
{
/* allocate core-local selector for RPC object */
@ -87,7 +85,7 @@ Capability_space::create_rpc_obj_cap(Native_capability ep_cap,
/* create Genode capability */
Native_capability::Data &data =
local_capability_space().create_capability(rpc_obj_sel, cap_session,
local_capability_space().create_capability(rpc_obj_sel, pd_session,
rpc_obj_key);
ASSERT(ep_cap.valid());
@ -128,11 +126,11 @@ Native_capability Capability_space::create_ep_cap(Thread_base &ep_thread)
{
Cap_sel const ep_sel(ep_thread.tid().ep_sel);
/* entrypoint capabilities are not allocated from a CAP session */
Cap_session const *cap_session = nullptr;
/* entrypoint capabilities are not allocated from a PD session */
Pd_session const *pd_session = nullptr;
Native_capability::Data &data =
local_capability_space().create_capability(ep_sel, cap_session,
local_capability_space().create_capability(ep_sel, pd_session,
Rpc_obj_key());
return Native_capability(data);
@ -185,11 +183,11 @@ void Capability_space::reset_sel(unsigned sel)
Native_capability Capability_space::import(Ipc_cap_data ipc_cap_data)
{
/* imported capabilities are not associated with a CAP session */
Cap_session const *cap_session = nullptr;
/* imported capabilities are not associated with a PD session */
Pd_session const *pd_session = nullptr;
Native_capability::Data &data =
local_capability_space().create_capability(ipc_cap_data.sel, cap_session,
local_capability_space().create_capability(ipc_cap_data.sel, pd_session,
ipc_cap_data.rpc_obj_key);
return Native_capability(data);

View File

@ -1,37 +0,0 @@
/*
* \brief Capability session service
* \author Norman Feske
* \date 2015-05-08
*/
/*
* 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__CAP_SESSION_COMPONENT_H_
#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <base/allocator.h>
namespace Genode { class Cap_session_component; }
struct Genode::Cap_session_component : Rpc_object<Cap_session>
{
Cap_session_component(Allocator *md_alloc, const char *args) {}
void upgrade_ram_quota(size_t ram_quota) { }
Native_capability alloc(Native_capability ep);
void free(Native_capability cap);
static Native_capability alloc(Cap_session_component *session,
Native_capability ep);
};
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */

View File

@ -17,7 +17,7 @@
/* base-internal includes */
#include <internal/rpc_obj_key.h>
namespace Genode { class Cap_session; }
namespace Genode { class Pd_session; }
namespace Genode { namespace Capability_space {
@ -26,7 +26,7 @@ namespace Genode { namespace Capability_space {
* Create new RPC object capability for the specified entrypoint
*/
Native_capability create_rpc_obj_cap(Native_capability ep_cap,
Cap_session const *,
Pd_session const *,
Rpc_obj_key);
} }

View File

@ -0,0 +1,39 @@
/*
* \brief RPC capability factory
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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__RPC_CAP_FACTORY_H_
#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_
#include <base/allocator.h>
#include <base/lock.h>
#include <base/capability.h>
namespace Genode { class Rpc_cap_factory; }
class Genode::Rpc_cap_factory
{
private:
static Native_capability _alloc(Rpc_cap_factory *owner,
Native_capability ep);
public:
Rpc_cap_factory(Allocator &md_alloc) { }
Native_capability alloc(Native_capability ep);
void free(Native_capability cap);
};
#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */

View File

@ -1,14 +1,11 @@
/*
* \brief seL4-specific capability allocation
* \brief seL4-specific RPC capability factory
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2015-05-08
*
* Based on base-foc/src/core/cap_session_component.cc
* \date 2016-01-19
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
* 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.
@ -19,7 +16,8 @@
#include <util/misc_math.h>
/* core includes */
#include <cap_session_component.h>
#include <cap_session/cap_session.h>
#include <rpc_cap_factory.h>
#include <platform.h>
/* base-internal include */
@ -31,8 +29,8 @@ using namespace Genode;
static unsigned unique_id_cnt;
Native_capability Cap_session_component::alloc(Cap_session_component *session,
Native_capability ep)
Native_capability Rpc_cap_factory::_alloc(Rpc_cap_factory *owner,
Native_capability ep)
{
if (!ep.valid()) {
PWRN("Invalid entrypoint capability");
@ -41,17 +39,18 @@ Native_capability Cap_session_component::alloc(Cap_session_component *session,
Rpc_obj_key const rpc_obj_key(++unique_id_cnt);
return Capability_space::create_rpc_obj_cap(ep, session, rpc_obj_key);
// XXX remove cast
return Capability_space::create_rpc_obj_cap(ep, (Cap_session*)owner, rpc_obj_key);
}
Native_capability Cap_session_component::alloc(Native_capability ep)
Native_capability Rpc_cap_factory::alloc(Native_capability ep)
{
return Cap_session_component::alloc(this, ep);
return Rpc_cap_factory::_alloc(this, ep);
}
void Cap_session_component::free(Native_capability cap)
void Rpc_cap_factory::free(Native_capability cap)
{
if (!cap.valid())
return;

View File

@ -278,10 +278,18 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool<Rpc_object_base>
Lock _cap_valid; /* thread startup synchronization */
Lock _delay_start; /* delay start of request dispatching */
Lock _delay_exit; /* delay destructor until server settled */
Cap_session *_cap_session; /* for creating capabilities */
Pd_session &_pd_session; /* for creating capabilities */
Exit_handler _exit_handler;
Capability<Exit> _exit_cap;
/**
* Access to kernel-specific part of the PD session interface
*
* Some kernels like NOVA need a special interface for creating RPC
* object capabilities.
*/
Capability<Pd_session::Native_pd> _native_pd_cap;
/**
* Back end used to associate RPC object with the entry point
*
@ -303,6 +311,24 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool<Rpc_object_base>
*/
void _block_until_cap_valid();
/**
* Allocate new RPC object capability
*
* Regular servers allocate capabilities from their protection domain
* via the component's environment. This method allows core to have a
* special implementation that does not rely on a PD session.
*
* The 'entry' argument is used only on NOVA. It is the server-side
* instruction pointer to be associated with the RPC object capability.
*/
Native_capability _alloc_rpc_cap(Pd_session &, Native_capability ep,
addr_t entry = 0);
/**
* Free RPC object capability
*/
void _free_rpc_cap(Pd_session &, Native_capability);
/**
* Thread interface
*
@ -322,7 +348,7 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool<Rpc_object_base>
* \param name name of entrypoint thread
* \param location CPU affinity
*/
Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
char const *name, bool start_on_construction = true,
Affinity::Location location = Affinity::Location());

View File

@ -3,9 +3,9 @@
* \author Norman Feske
* \date 2006-06-23
*
* A 'Cap_session' is an allocator of user-level capabilities.
* User-level capabilities are used to reference server objects
* across address spaces.
* \deprecated
*
* This header is scheduled for removal. It exists for API compatiblity only.
*/
/*
@ -18,48 +18,8 @@
#ifndef _INCLUDE__CAP_SESSION__CAP_SESSION_H_
#define _INCLUDE__CAP_SESSION__CAP_SESSION_H_
#include <base/exception.h>
#include <base/native_types.h>
#include <session/session.h>
#include <pd_session/pd_session.h>
namespace Genode { struct Cap_session; }
struct Genode::Cap_session : Session
{
class Out_of_metadata : public Exception { };
static const char *service_name() { return "CAP"; }
virtual ~Cap_session() { }
/**
* Allocate new unique userland capability
*
* \param ep entry point that will use this capability
*
* \throw Out_of_metadata if meta-data backing store is exhausted
*
* \return new userland capability
*/
virtual Native_capability alloc(Native_capability ep) = 0;
/**
* Free userland capability
*
* \param cap userland capability to free
*/
virtual void free(Native_capability cap) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_alloc, Native_capability, alloc,
GENODE_TYPE_LIST(Out_of_metadata), Native_capability);
GENODE_RPC(Rpc_free, void, free, Native_capability);
GENODE_RPC_INTERFACE(Rpc_alloc, Rpc_free);
};
namespace Genode { typedef Pd_session Cap_session; }
#endif /* _INCLUDE__CAP_SESSION__CAP_SESSION_H_ */

View File

@ -1,22 +0,0 @@
/*
* \brief CAP-session capability type
* \author Norman Feske
* \date 2008-08-16
*/
/*
* Copyright (C) 2008-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 _INCLUDE__CAP_SESSION__CAPABILITY_H_
#define _INCLUDE__CAP_SESSION__CAPABILITY_H_
#include <base/capability.h>
#include <cap_session/cap_session.h>
namespace Genode { typedef Capability<Cap_session> Cap_session_capability; }
#endif /* _INCLUDE__CAP_SESSION__CAPABILITY_H_ */

View File

@ -1,35 +0,0 @@
/*
* \brief Client-side CAP session interface
* \author Norman Feske
* \date 2006-07-10
*/
/*
* Copyright (C) 2006-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 _INCLUDE__CAP_SESSION__CLIENT_H_
#define _INCLUDE__CAP_SESSION__CLIENT_H_
#include <cap_session/capability.h>
#include <cap_session/cap_session.h>
#include <base/rpc_client.h>
namespace Genode { struct Cap_session_client; }
struct Genode::Cap_session_client : Rpc_client<Cap_session>
{
explicit Cap_session_client(Cap_session_capability session)
: Rpc_client<Cap_session>(session) { }
Native_capability alloc(Native_capability ep) override {
return call<Rpc_alloc>(ep); }
void free(Native_capability cap) override { call<Rpc_free>(cap); }
};
#endif /* _INCLUDE__CAP_SESSION__CLIENT_H_ */

View File

@ -2,6 +2,10 @@
* \brief Connection to CAP service
* \author Norman Feske
* \date 2008-08-22
*
* \deprecated
*
* This header is scheduled for removal. It exists for API compatiblity only.
*/
/*
@ -14,19 +18,26 @@
#ifndef _INCLUDE__CAP_SESSION__CONNECTION_H_
#define _INCLUDE__CAP_SESSION__CONNECTION_H_
#include <cap_session/client.h>
#include <base/connection.h>
#include <cap_session/cap_session.h>
#include <pd_session/client.h>
#include <base/env.h>
namespace Genode { struct Cap_connection; }
struct Genode::Cap_connection : Connection<Cap_session>, Cap_session_client
/*
* There are no CAP connections anymore. The only situation where CAP
* connections were created was inside old-fashioned servers that used
* to create an 'Rpc_entrypoint' manually. The 'Rpc_entrypoint' requires
* a CAP session as constructor argument. We accommodate this use case
* by allocating RPC capabilities from the server's protection domain.
*
* Modern components no longer create 'Rpc_entrypoint' objects directly
* but instead use the new 'Entrypoint' interface.
*/
struct Genode::Cap_connection : Pd_session_client
{
Cap_connection()
:
Connection<Cap_session>(session("ram_quota=4K")),
Cap_session_client(cap())
{ }
Cap_connection() : Pd_session_client(env()->pd_session_cap()) { }
};
#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */

View File

@ -49,6 +49,14 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
void submit(Signal_context_capability receiver, unsigned cnt = 1) override {
call<Rpc_submit>(receiver, cnt); }
Native_capability alloc_rpc_cap(Native_capability ep) override {
return call<Rpc_alloc_rpc_cap>(ep); }
void free_rpc_cap(Native_capability cap) override {
call<Rpc_free_rpc_cap>(cap); }
Capability<Native_pd> native_pd() override { return call<Rpc_native_pd>(); }
};
#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */

View File

@ -138,6 +138,39 @@ struct Genode::Pd_session : Session
** Support for the RPC framework **
***********************************/
/**
* Allocate new RPC-object capability
*
* \param ep entry point that will use this capability
*
* \throw Out_of_metadata if meta-data backing store is exhausted
*
* \return new RPC capability
*/
virtual Native_capability alloc_rpc_cap(Native_capability ep) = 0;
/**
* Free RPC-object capability
*
* \param cap capability to free
*/
virtual void free_rpc_cap(Native_capability cap) = 0;
/*****************************************
** Access to kernel-specific interface **
*****************************************/
/**
* Common base class of kernel-specific PD interfaces
*/
struct Native_pd { };
/**
* Return capability to kernel-specific PD operations
*/
virtual Capability<Native_pd> native_pd() = 0;
/*********************
** RPC declaration **
@ -161,10 +194,29 @@ struct Genode::Pd_session : Session
GENODE_RPC(Rpc_submit, void, submit, Capability<Signal_context>, unsigned);
GENODE_RPC_THROW(Rpc_alloc_rpc_cap, Native_capability, alloc_rpc_cap,
GENODE_TYPE_LIST(Out_of_metadata), Native_capability);
GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent, Rpc_assign_pci,
Rpc_alloc_signal_source, Rpc_free_signal_source,
Rpc_alloc_context, Rpc_free_context, Rpc_submit);
GENODE_RPC(Rpc_free_rpc_cap, void, free_rpc_cap, Native_capability);
GENODE_RPC(Rpc_native_pd, Capability<Native_pd>, native_pd);
/*
* 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,
Meta::Type_tuple<Rpc_assign_pci,
Meta::Type_tuple<Rpc_alloc_signal_source,
Meta::Type_tuple<Rpc_free_signal_source,
Meta::Type_tuple<Rpc_alloc_context,
Meta::Type_tuple<Rpc_free_context,
Meta::Type_tuple<Rpc_submit,
Meta::Type_tuple<Rpc_alloc_rpc_cap,
Meta::Type_tuple<Rpc_free_rpc_cap,
Meta::Type_tuple<Rpc_native_pd,
Meta::Empty>
> > > > > > > > > > Rpc_functions;
};
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */

View File

@ -23,7 +23,7 @@
/* Genode includes */
#include <base/printf.h>
#include <base/env.h>
#include <base/heap.h>
#include <base/heap.h>
/* local includes */
#include <platform_env_common.h>
@ -137,15 +137,15 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve
** Env interface **
*******************/
Parent *parent() { return &_parent_client; }
Ram_session *ram_session() { return &_resources.ram; }
Ram_session_capability ram_session_cap() { return _resources.ram; }
Cpu_session *cpu_session() { return &_resources.cpu; }
Cpu_session_capability cpu_session_cap() { return _resources.cpu; }
Rm_session *rm_session() { return &_resources.rm; }
Pd_session *pd_session() { return &_resources.pd; }
Pd_session_capability pd_session_cap() { return _resources.pd; }
Allocator *heap() { return &_heap; }
Parent *parent() override { return &_parent_client; }
Ram_session *ram_session() override { return &_resources.ram; }
Ram_session_capability ram_session_cap() override { return _resources.ram; }
Cpu_session *cpu_session() override { return &_resources.cpu; }
Cpu_session_capability cpu_session_cap() override { return _resources.cpu; }
Rm_session *rm_session() override { return &_resources.rm; }
Pd_session *pd_session() override { return &_resources.pd; }
Pd_session_capability pd_session_cap() override { return _resources.pd; }
Allocator *heap() override { return &_heap; }
};
#endif /* _PLATFORM_ENV_H_ */

View File

@ -24,7 +24,7 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
/* make sure nobody is able to find this object */
remove(obj);
_cap_session->free(obj->cap());
_free_rpc_cap(_pd_session, obj->cap());
/* now the object may be safely destructed */
}
@ -79,7 +79,7 @@ bool Rpc_entrypoint::is_myself() const
}
Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
char const *name, bool start_on_construction,
Affinity::Location location)
:
@ -87,7 +87,7 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
_cap(Untyped_capability()),
_cap_valid(Lock::LOCKED), _delay_start(Lock::LOCKED),
_delay_exit(Lock::LOCKED),
_cap_session(cap_session)
_pd_session(*pd_session)
{
/* set CPU affinity, if specified */
if (location.valid())

View File

@ -0,0 +1,44 @@
/*
* \brief Core-specific back end of the RPC entrypoint
* \author Norman Feske
* \date 2016-01-19
*/
/*
* 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/env.h>
#include <util/retry.h>
#include <base/rpc_server.h>
#include <pd_session/client.h>
using namespace Genode;
Native_capability Rpc_entrypoint::_alloc_rpc_cap(Pd_session &pd,
Native_capability ep, addr_t)
{
Untyped_capability new_obj_cap =
retry<Genode::Pd_session::Out_of_metadata>(
[&] () { return pd.alloc_rpc_cap(_cap); },
[&] () {
Pd_session_client *client =
dynamic_cast<Pd_session_client*>(&pd);
if (client)
env()->parent()->upgrade(*client, "ram_quota=16K");
});
return new_obj_cap;
}
void Rpc_entrypoint::_free_rpc_cap(Pd_session &pd, Native_capability cap)
{
return pd.free_rpc_cap(cap);
}

View File

@ -29,7 +29,7 @@ using namespace Genode;
Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
{
Untyped_capability ep_cap = Native_capability(_cap.dst(), 0);
Untyped_capability new_obj_cap = _cap_session->alloc(ep_cap);
Untyped_capability new_obj_cap = _alloc_rpc_cap(_pd_session, ep_cap);
/* add server object to object pool */
obj->cap(new_obj_cap);

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