Unification of native_capability.h

This patch establishes the sole use of generic headers across all
kernels. The common 'native_capability.h' is based on the version of
base-sel4. All traditional L4 kernels and Linux use the same
implementation of the capability-lifetime management. On base-hw, NOVA,
Fiasco.OC, and seL4, custom implementations (based on their original
mechanisms) are used, with the potential to unify them further in the
future.

This change achieves binary compatibility of dynamically linked programs
across all kernels.

Furthermore, the patch introduces a Native_capability::print method,
which allows the easy output of the kernel-specific capability
representation using the base/log.h API.

Issue #1993
This commit is contained in:
Norman Feske 2016-06-15 15:04:54 +02:00
parent d71f0a9606
commit 88b358c5ef
173 changed files with 2614 additions and 1333 deletions

View File

@ -1,42 +0,0 @@
/*
* \brief Native capability type on L4/Fiasco
* \author Norman Feske
* \date 2008-07-26
*/
/*
* 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__BASE__NATIVE_CAPABILITY_H_
#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_
/* Genode includes */
#include <base/native_capability_tpl.h>
#include <base/stdint.h>
namespace Fiasco {
#include <l4/sys/types.h>
}
namespace Genode {
struct Cap_dst_policy
{
typedef Fiasco::l4_threadid_t Dst;
static bool valid(Dst id) { return !Fiasco::l4_is_invalid_id(id); }
static Dst invalid()
{
using namespace Fiasco;
return L4_INVALID_ID;
}
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
}
#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */

View File

@ -8,9 +8,7 @@ include $(BASE_DIR)/lib/mk/base-common.inc
LIBS += startup
SRC_CC += cap_copy.cc
SRC_CC += capability.cc capability_raw.cc
SRC_CC += signal_submit.cc
SRC_CC += rpc_dispatch_loop.cc
SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc
vpath cap_copy.cc $(BASE_DIR)/src/lib/startup

View File

@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc
SRC_CC += thread_start.cc
SRC_CC += cache.cc
SRC_CC += capability_space.cc

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

@ -20,6 +20,7 @@
/* base-internal includes */
#include <base/internal/native_thread.h>
#include <base/internal/capability_space_tpl.h>
namespace Fiasco {
#include <l4/sys/ipc.h>
@ -83,5 +84,5 @@ void Ipc_pager::acknowledge_wakeup()
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
{
return Untyped_capability(native_thread().l4id, badge);
return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge));
}

View File

@ -14,6 +14,9 @@
/* core includes */
#include <pager.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
@ -37,7 +40,7 @@ void Pager_object::wake_up()
l4_msgdope_t ipc_result;
l4_umword_t dummy = 0;
l4_ipc_call(cap().dst(), L4_IPC_SHORT_MSG,
l4_ipc_call(Capability_space::ipc_cap_data(cap()).dst, L4_IPC_SHORT_MSG,
0, /* fault address */
(l4_umword_t)this, /* instruction pointer */
&rcv_header, &dummy, &dummy, L4_IPC_NEVER, &ipc_result);

View File

@ -21,6 +21,7 @@
#include <base/internal/crt0.h>
#include <base/internal/fiasco_thread_helper.h>
#include <base/internal/stack_area.h>
#include <base/internal/capability_space_tpl.h>
/* core includes */
#include <core_parent.h>
@ -137,7 +138,7 @@ Platform::Sigma0::Sigma0()
:
Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location())
{
cap(reinterpret_cap_cast<Cpu_thread>(Native_capability(Fiasco::sigma0_threadid, 0)));
cap(Capability_space::import(Fiasco::sigma0_threadid, Rpc_obj_key()));
}
@ -156,7 +157,7 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd)
Platform_thread::pager(sigma0());
core_pd->bind_thread(this);
cap(Native_capability(native_thread_id(), 0));
cap(Capability_space::import(native_thread_id(), Rpc_obj_key()));
/* pager needs to know core's pd ID */
_core_pager_arg = core_pd->pd_id();

View File

@ -22,6 +22,9 @@
/* core includes */
#include <platform_thread.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
@ -38,7 +41,9 @@ int Platform_thread::start(void *ip, void *sp)
{
l4_umword_t dummy, old_eflags;
l4_threadid_t thread = _l4_thread_id;
l4_threadid_t pager = _pager ? _pager->cap().dst() : L4_INVALID_ID;
l4_threadid_t pager = _pager
? Capability_space::ipc_cap_data(_pager->cap()).dst
: L4_INVALID_ID;
l4_threadid_t preempter = L4_INVALID_ID;
l4_threadid_t cap_handler = L4_INVALID_ID;

View File

@ -9,6 +9,7 @@ SRC_CC += stack_area.cc \
cpu_session_component.cc \
cpu_thread_component.cc \
cpu_session_support.cc \
capability_space.cc \
dataspace_component.cc \
default_log.cc \
dump_alloc.cc \
@ -22,7 +23,7 @@ SRC_CC += stack_area.cc \
pager_ep.cc \
pager_object.cc \
pd_session_component.cc \
rpc_cap_factory.cc \
rpc_cap_factory_l4.cc \
pd_assign_pci.cc \
pd_upgrade_ram_quota.cc \
platform.cc \
@ -56,7 +57,8 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)
vpath cpu_thread_component.cc $(GEN_CORE_DIR)
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath capability_space.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath core_region_map.cc $(GEN_CORE_DIR)
vpath pd_assign_pci.cc $(GEN_CORE_DIR)

View File

@ -0,0 +1,40 @@
/*
* \brief Interface to obtain the parent capability for the component
* \author Norman Feske
* \date 2015-05-12
*/
/*
* Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_
#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_
/* Genode includes */
#include <parent/capability.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
#include <base/internal/crt0.h>
namespace Genode {
static inline Parent_capability parent_cap()
{
Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap;
Fiasco::l4_threadid_t tid;
tid.raw = raw.v[0];
Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1]));
return reinterpret_cap_cast<Parent>(cap);
}
}
#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */

View File

@ -0,0 +1,38 @@
/*
* \brief RPC destination type
* \author Norman Feske
* \date 2016-03-11
*/
/*
* 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__BASE__INTERNAL__RPC_DESTINATION_H_
#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
namespace Genode {
typedef Fiasco::l4_threadid_t Rpc_destination;
static inline Rpc_destination invalid_rpc_destination()
{
using namespace Fiasco;
return L4_INVALID_ID;
}
static void print(Output &out, Rpc_destination const &dst)
{
Genode::print(out, "thread=", dst.id.task, ".", dst.id.lthread);
}
}
#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */

View File

@ -0,0 +1,28 @@
/*
* \brief Capability
* \author Norman Feske
* \date 2016-06-16
*/
/*
* 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 <base/log.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
using namespace Genode;
Native_capability::Raw Native_capability::raw() const
{
Capability_space::Ipc_cap_data const cap_data =
Capability_space::ipc_cap_data(*this);
return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } };
}

View File

@ -13,17 +13,18 @@
/* Genode includes */
#include <base/printf.h>
#include <base/log.h>
#include <base/ipc.h>
#include <base/blocking.h>
/* base-internal includes */
#include <base/internal/ipc_server.h>
#include <base/internal/capability_space_tpl.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
#include <l4/sys/syscalls.h>
#include <l4/sys/kdebug.h>
}
using namespace Genode;
@ -93,8 +94,14 @@ class Msg_header
for (unsigned i = 0; i < num_caps; i++) {
Native_capability const &cap = snd_msg.cap(i);
_cap_tid[i] = cap.dst();
_cap_local_name[i] = cap.local_name();
if (cap.valid()) {
Capability_space::Ipc_cap_data const cap_data =
Capability_space::ipc_cap_data(snd_msg.cap(i));
_cap_tid[i] = cap_data.dst;
_cap_local_name[i] = cap_data.rpc_obj_key.value();
}
}
}
@ -115,9 +122,20 @@ class Msg_header
*/
void extract_caps(Msgbuf_base &rcv_msg) const
{
for (unsigned i = 0; i < min((unsigned)MAX_CAPS_PER_MSG, num_caps); i++)
rcv_msg.insert(Native_capability(_cap_tid[i],
_cap_local_name[i]));
for (unsigned i = 0; i < min((unsigned)MAX_CAPS_PER_MSG, num_caps); i++) {
Rpc_obj_key const rpc_obj_key(_cap_local_name[i]);
bool const cap_valid = !Fiasco::l4_is_invalid_id(_cap_tid[i]);
Native_capability cap;
if (cap_valid) {
cap = Capability_space::lookup(rpc_obj_key);
if (!cap.valid())
cap = Capability_space::import(_cap_tid[i], rpc_obj_key);
}
rcv_msg.insert(cap);
}
}
};
@ -132,14 +150,17 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
{
using namespace Fiasco;
Capability_space::Ipc_cap_data const dst_data =
Capability_space::ipc_cap_data(dst);
Msg_header &snd_header = snd_msg.header<Msg_header>();
snd_header.prepare_snd_msg(dst.local_name(), snd_msg);
snd_header.prepare_snd_msg(dst_data.rpc_obj_key.value(), snd_msg);
Msg_header &rcv_header = rcv_msg.header<Msg_header>();
rcv_header.prepare_rcv_msg(rcv_msg);
l4_msgdope_t ipc_result;
l4_ipc_call(dst.dst(),
l4_ipc_call(dst_data.dst,
snd_header.msg_start(),
snd_header.protocol_word,
snd_header.num_caps,
@ -176,7 +197,8 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc,
snd_header.prepare_snd_msg(exc.value, snd_msg);
l4_msgdope_t result;
l4_ipc_send(caller.dst(), snd_header.msg_start(),
l4_ipc_send(Capability_space::ipc_cap_data(caller).dst,
snd_header.msg_start(),
snd_header.protocol_word,
snd_header.num_caps,
L4_IPC_SEND_TIMEOUT_0, &result);
@ -212,7 +234,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller,
* Use short IPC for reply if possible. This is the common case of
* returning an integer as RPC result.
*/
l4_ipc_reply_and_wait(last_caller.dst(), snd_header.msg_start(),
l4_ipc_reply_and_wait(Capability_space::ipc_cap_data(last_caller).dst,
snd_header.msg_start(),
snd_header.protocol_word,
snd_header.num_caps,
&caller, rcv_header.msg_start(),
@ -250,11 +273,15 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller,
rcv_header.extract_caps(request_msg);
return Rpc_request(Native_capability(caller, 0), rcv_header.protocol_word);
return Rpc_request(Capability_space::import(caller, Rpc_obj_key()),
rcv_header.protocol_word);
}
Ipc_server::Ipc_server() : Native_capability(Fiasco::l4_myself(), 0) { }
Ipc_server::Ipc_server()
:
Native_capability(Capability_space::import(Fiasco::l4_myself(), Rpc_obj_key()))
{ }
Ipc_server::~Ipc_server() { }

View File

@ -1,114 +0,0 @@
/*
* \brief Platform-specific capability type
* \author Norman Feske
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__NATIVE_CAPABILITY_H_
#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
/* Genode includes */
#include <base/cap_map.h>
namespace Genode {
/**
* Native_capability in Fiasco.OC is just a reference to a Cap_index.
*
* As Cap_index objects cannot be copied around, but Native_capability
* have to, we have to use this indirection.
*/
class Native_capability
{
public:
typedef Fiasco::l4_cap_idx_t Dst;
struct Raw
{
long local_name;
};
private:
Cap_index* _idx;
protected:
inline void _inc()
{
if (_idx)
_idx->inc();
}
inline void _dec()
{
if (_idx && !_idx->dec()) {
cap_map()->remove(_idx);
}
}
public:
/**
* Default constructor creates an invalid capability
*/
Native_capability() : _idx(0) { }
/**
* Construct capability manually
*/
Native_capability(Cap_index* idx)
: _idx(idx) { _inc(); }
Native_capability(const Native_capability &o)
: _idx(o._idx) { _inc(); }
~Native_capability() { _dec(); }
/**
* Return Cap_index object referenced by this object
*/
Cap_index* idx() const { return _idx; }
/**
* Overloaded comparision operator
*/
bool operator==(const Native_capability &o) const {
return _idx == o._idx; }
Native_capability& operator=(const Native_capability &o){
if (this == &o)
return *this;
_dec();
_idx = o._idx;
_inc();
return *this;
}
/*******************************************
** Interface provided by all platforms **
*******************************************/
long local_name() const { return _idx ? _idx->id() : 0; }
Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); }
bool valid() const { return (_idx != 0) && _idx->valid(); }
Raw raw() const { return { local_name() }; }
};
}
#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */

View File

@ -20,6 +20,11 @@
#include <base/lock.h>
#include <base/thread_state_base.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
namespace Genode {
struct Thread_state : Thread_state_base

View File

@ -0,0 +1,42 @@
/*
* \brief Utilities for direct capability-space manipulation
* \author Norman Feske
* \date 2016-07-08
*
* This interface is needed by L4Linux.
*/
/*
* 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__FOC__CAPABILITY_SPACE_H_
#define _INCLUDE__FOC__CAPABILITY_SPACE_H_
#include <base/capability.h>
#include <foc/native_capability.h>
namespace Genode { namespace Capability_space {
/**
* Allocate kernel capability selector without associating it with a
* Genode capability
*/
Fiasco::l4_cap_idx_t alloc_kcap();
/**
* Release kernel capability selector
*/
void free_kcap(Fiasco::l4_cap_idx_t);
/**
* Request kernel capability selector associated with Genode capability
*/
Fiasco::l4_cap_idx_t kcap(Native_capability);
} }
#endif /* _INCLUDE__FOC__CAPABILITY_SPACE_H_ */

View File

@ -17,7 +17,6 @@
/* Genode includes */
#include <base/stdint.h>
#include <base/ipc_msgbuf.h>
#include <base/cap_map.h>
namespace Genode { struct Receive_window; }
@ -29,7 +28,7 @@ class Genode::Receive_window
/**
* Base of capability receive window.
*/
Cap_index* _rcv_idx_base = nullptr;
Native_capability::Data * _rcv_idx_base = nullptr;
enum { MAX_CAPS_PER_MSG = Msgbuf_base::MAX_CAPS_PER_MSG };
@ -37,29 +36,21 @@ class Genode::Receive_window
Receive_window() { }
~Receive_window()
{
if (_rcv_idx_base)
cap_idx_alloc()->free(_rcv_idx_base, MAX_CAPS_PER_MSG);
}
~Receive_window();
void init()
{
_rcv_idx_base = cap_idx_alloc()->alloc_range(MAX_CAPS_PER_MSG);
}
void init();
/**
* Return address of capability receive window
*/
addr_t rcv_cap_sel_base() { return _rcv_idx_base->kcap(); }
addr_t rcv_cap_sel_base();
/**
* Return received selector with index i
*
* \return capability selector, or 0 if index is invalid
*/
addr_t rcv_cap_sel(unsigned i) {
return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE; }
addr_t rcv_cap_sel(unsigned i);
};
#endif /* _INCLUDE__FOC__RECEIVE_WINDOW_H_ */

View File

@ -27,17 +27,11 @@
#include <base/thread.h>
#include <signal_source/foc_signal_source.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
namespace Genode { class Signal_source_client; }
namespace Fiasco {
#include <l4/sys/irq.h>
}
namespace Genode {
class Signal_source_client : public Rpc_client<Foc_signal_source>
{
class Genode::Signal_source_client : public Rpc_client<Foc_signal_source>
{
private:
/**
@ -45,69 +39,28 @@ namespace Genode {
*/
Native_capability _sem;
/**
* Request Fiasco.OC IRQ object from signal-source server
*/
void _init_sem()
{
using namespace Fiasco;
/* request mapping of semaphore capability selector */
_sem = call<Rpc_request_semaphore>();
l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0,
Thread::myself()->native_thread().kcap);
if (l4_error(tag))
PERR("l4_irq_attach failed with %ld!", l4_error(tag));
}
public:
/**
* Constructor
*/
Signal_source_client(Capability<Signal_source> cap)
: Rpc_client<Foc_signal_source>(static_cap_cast<Foc_signal_source>(cap))
{ _init_sem(); }
Signal_source_client(Capability<Signal_source> cap);
/**
* Destructor
*/
~Signal_source_client()
{
Fiasco::l4_irq_detach(_sem.dst());
}
~Signal_source_client();
/*****************************
** Signal source interface **
*****************************/
/* Build with frame pointer to make GDB backtraces work. See issue #1061. */
__attribute__((optimize("-fno-omit-frame-pointer")))
__attribute__((noinline))
Signal wait_for_signal()
{
using namespace Fiasco;
Signal signal;
do {
/* block on semaphore until signal context was submitted */
l4_irq_receive(_sem.dst(), L4_IPC_NEVER);
/*
* The following request will return immediately and either
* return a valid or a null signal. The latter may happen in
* the case a submitted signal context was destroyed (by the
* submitter) before we have a chance to raise our request.
* Build with frame pointer to make GDB backtraces work. See issue #1061.
*/
signal = call<Rpc_wait_for_signal>();
} while (!signal.imprint());
return signal;
}
};
}
__attribute__((optimize("-fno-omit-frame-pointer")))
Signal wait_for_signal();
};
#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */

View File

@ -12,3 +12,5 @@ SRC_CC += spin_lock.cc cap_map.cc
SRC_CC += signal_submit.cc
SRC_CC += rpc_dispatch_loop.cc
SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc utcb.cc
SRC_CC += capability.cc
SRC_CC += signal_source_client.cc

View File

@ -1,5 +1,5 @@
/*
* \brief Core-specific capability index.
* \brief Core-specific capability index
* \author Stefan Kalkowski
* \date 2012-02-22
*/
@ -14,23 +14,24 @@
#ifndef _CORE__INCLUDE__CAP_INDEX_H_
#define _CORE__INCLUDE__CAP_INDEX_H_
/* Genode includes */
#include <base/cap_map.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
#include <base/internal/cap_map.h>
namespace Genode {
class Platform_thread;
class Pd_session_component;
class Core_cap_index;
}
class Core_cap_index : public Cap_index
{
class Genode::Core_cap_index : public Native_capability::Data
{
private:
Pd_session_component *_session;
Platform_thread *_pt;
Platform_thread const *_pt;
Native_thread _gate;
public:
@ -40,13 +41,12 @@ namespace Genode {
Native_thread gate = Native_thread() )
: _session(session), _pt(pt), _gate(gate) {}
Pd_session_component *session() { return _session; }
Platform_thread *pt() { return _pt; }
Native_thread gate() { return _gate; }
Pd_session_component const *session() const { return _session; }
Platform_thread const *pt() const { return _pt; }
Native_thread gate() const { return _gate; }
void session(Pd_session_component *c) { _session = c; }
void pt(Platform_thread *t) { _pt = t; }
};
}
void pt(Platform_thread const *t) { _pt = t; }
};
#endif /* _CORE__INCLUDE__CAP_INDEX_H_ */

View File

@ -170,7 +170,7 @@ namespace Genode {
* Return identification of thread when faulting
*/
unsigned long pager_object_badge() {
return (unsigned long) _thread.local.dst(); }
return (unsigned long) _thread.local.data()->kcap(); }
/**
* Set CPU quota of the thread to 'quota'
@ -187,8 +187,8 @@ namespace Genode {
** Fiasco-specific Accessors **
*******************************/
Cap_mapping& thread() { return _thread; }
Cap_mapping& gate() { return _gate; }
Cap_mapping const & thread() const { return _thread; }
Cap_mapping & gate() { return _gate; }
const char *name() const { return _name; }
bool core_thread() const { return _core_thread; }
addr_t utcb() const { return _utcb; }

View File

@ -20,6 +20,7 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
#include <base/internal/cap_map.h>
/* Fiasco includes */
namespace Fiasco {
@ -139,6 +140,8 @@ void Ipc_pager::acknowledge_exception()
Ipc_pager::Ipc_pager()
: Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]),
_badge(0) { }
:
Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]),
_badge(0)
{ }

View File

@ -56,7 +56,7 @@ class Genode::Interrupt_handler : public Thread_deprecated<2048*sizeof(long)>
static Fiasco::l4_cap_idx_t handler_cap()
{
static Interrupt_handler handler;
return handler._thread_cap.dst();
return handler._thread_cap.data()->kcap();
}
};

View File

@ -38,7 +38,7 @@ void Genode::Native_cpu_component::enable_vcpu(Genode::Thread_capability thread_
auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) return;
l4_cap_idx_t tid = thread->platform_thread().thread().local.dst();
l4_cap_idx_t tid = thread->platform_thread().thread().local.data()->kcap();
l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state);
if (l4_msgtag_has_error(tag))
@ -86,7 +86,7 @@ Genode::Native_capability Genode::Native_cpu_component::alloc_irq()
}
/* construct cap and hold a reference in the irq container object */
Genode::Native_capability cap(i);
Genode::Native_capability cap(*i);
return (node->add(cap)) ? cap : Genode::Native_capability();
}

View File

@ -14,6 +14,9 @@
/* core includes */
#include <pager.h>
/* base-internal includes */
#include <base/internal/cap_map.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/ipc.h>
@ -32,7 +35,7 @@ void Pager_object::wake_up()
l4_utcb_mr()->mr[0] = 0; /* fault address */
l4_utcb_mr()->mr[1] = (l4_umword_t)this; /* instruction pointer */
l4_ipc_call(cap().dst(), l4_utcb(), l4_msgtag(0, 2, 0, 0), L4_IPC_NEVER);
l4_ipc_call(cap().data()->kcap(), l4_utcb(), l4_msgtag(0, 2, 0, 0), L4_IPC_NEVER);
}

View File

@ -137,7 +137,7 @@ Platform::Sigma0::Sigma0(Cap_index* i)
* We use the Pager_object here in a slightly different manner,
* just to tunnel the pager cap to the Platform_thread::start method.
*/
cap(i);
cap(*i);
}
@ -158,8 +158,8 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd, Sigma0 *sigma0)
using namespace Fiasco;
l4_thread_control_start();
l4_thread_control_pager(thread().local.dst());
l4_thread_control_exc_handler(thread().local.dst());
l4_thread_control_pager(thread().local.data()->kcap());
l4_thread_control_exc_handler(thread().local.data()->kcap());
l4_msgtag_t tag = l4_thread_control_commit(L4_BASE_THREAD_CAP);
if (l4_msgtag_has_error(tag))
PWRN("l4_thread_control_commit failed!");

View File

@ -70,7 +70,7 @@ bool Platform_pd::bind_thread(Platform_thread *thread)
/* if it's no core-thread we have to map parent and pager gate cap */
if (!thread->core_thread())
_task.map(_task.local.dst());
_task.map(_task.local.data()->kcap());
/* inform thread about binding */
thread->bind(this);
@ -100,13 +100,13 @@ void Platform_pd::assign_parent(Native_capability parent)
if (_parent.remote == Fiasco::L4_INVALID_CAP && parent.valid()) {
_parent.local = parent;
_parent.remote = PARENT_CAP;
_parent.map(_task.local.dst());
_parent.map(_task.local.data()->kcap());
}
}
Platform_pd::Platform_pd(Core_cap_index* i)
: _task(Native_capability(i), TASK_CAP)
: _task(Native_capability(*i), TASK_CAP)
{
for (unsigned i = 0; i < THREAD_MAX; i++)
_threads[i] = (Platform_thread*) 0;
@ -122,7 +122,7 @@ Platform_pd::Platform_pd(Allocator *, char const *)
l4_fpage_t utcb_area = l4_fpage(utcb_area_start(),
log2<unsigned>(UTCB_AREA_SIZE), 0);
l4_msgtag_t tag = l4_factory_create_task(L4_BASE_FACTORY_CAP,
_task.local.dst(), utcb_area);
_task.local.data()->kcap(), utcb_area);
if (l4_msgtag_has_error(tag))
PERR("pd creation failed");
}

View File

@ -39,24 +39,24 @@ int Platform_thread::start(void *ip, void *sp)
{
/* map the pager cap */
if (_platform_pd)
_pager.map(_platform_pd->native_task().dst());
_pager.map(_platform_pd->native_task().data()->kcap());
/* reserve utcb area and associate thread with this task */
l4_thread_control_start();
l4_thread_control_pager(_pager.remote);
l4_thread_control_exc_handler(_pager.remote);
l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().dst());
l4_msgtag_t tag = l4_thread_control_commit(_thread.local.dst());
l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().data()->kcap());
l4_msgtag_t tag = l4_thread_control_commit(_thread.local.data()->kcap());
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_control_commit for %lx failed!",
(unsigned long) _thread.local.dst());
(unsigned long) _thread.local.data()->kcap());
return -1;
}
_state = RUNNING;
/* set ip and sp and run the thread */
tag = l4_thread_ex_regs(_thread.local.dst(), (l4_addr_t) ip,
tag = l4_thread_ex_regs(_thread.local.data()->kcap(), (l4_addr_t) ip,
(l4_addr_t) sp, 0);
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_ex_regs failed!");
@ -92,7 +92,7 @@ void Platform_thread::pause()
* The pager thread, which also acts as exception handler, will
* leave the thread in exception state until, it gets woken again
*/
l4_thread_ex_regs_ret(_thread.local.dst(), &_pager_obj->state.ip,
l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &_pager_obj->state.ip,
&_pager_obj->state.sp, &flags);
/*
@ -111,14 +111,14 @@ void Platform_thread::pause()
* the requested thread, and stored its thread state
*/
while (exc == _pager_obj->state.exceptions && !_pager_obj->state.in_exception)
l4_thread_switch(_thread.local.dst());
l4_thread_switch(_thread.local.data()->kcap());
}
}
void Platform_thread::single_step(bool enabled)
{
Fiasco::l4_cap_idx_t const tid = thread().local.dst();
Fiasco::l4_cap_idx_t const tid = thread().local.data()->kcap();
enum { THREAD_SINGLE_STEP = 0x40000 };
int const flags = enabled ? THREAD_SINGLE_STEP : 0;
@ -148,8 +148,8 @@ void Platform_thread::resume()
void Platform_thread::bind(Platform_pd *pd)
{
_platform_pd = pd;
_gate.map(pd->native_task().dst());
_irq.map(pd->native_task().dst());
_gate.map(pd->native_task().data()->kcap());
_irq.map(pd->native_task().data()->kcap());
}
@ -160,12 +160,12 @@ void Platform_thread::unbind()
l4_thread_control_start();
l4_thread_control_pager(_gate.remote);
l4_thread_control_exc_handler(_gate.remote);
if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.dst())))
if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.data()->kcap())))
PWRN("l4_thread_control_commit for %lx failed!",
(unsigned long) _thread.local.dst());
(unsigned long) _thread.local.data()->kcap());
/* now force it into a pagefault */
l4_thread_ex_regs(_thread.local.dst(), 0, 0, L4_THREAD_EX_REGS_CANCEL);
l4_thread_ex_regs(_thread.local.data()->kcap(), 0, 0, L4_THREAD_EX_REGS_CANCEL);
}
_platform_pd = (Platform_pd*) 0;
@ -204,7 +204,7 @@ Thread_state Platform_thread::state()
void Platform_thread::cancel_blocking()
{
l4_irq_trigger(_irq.local.dst());
l4_irq_trigger(_irq.local.data()->kcap());
}
@ -217,9 +217,9 @@ void Platform_thread::affinity(Affinity::Location location)
l4_sched_param_t params = l4_sched_param(_prio);
params.affinity = l4_sched_cpu_set(cpu, 0, 1);
l4_msgtag_t tag = l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP,
_thread.local.dst(), &params);
_thread.local.data()->kcap(), &params);
if (l4_error(tag))
PWRN("setting affinity of %lx to %d failed!", _thread.local.dst(), cpu);
PWRN("setting affinity of %lx to %d failed!", _thread.local.data()->kcap(), cpu);
}
@ -239,7 +239,7 @@ static Rpc_cap_factory &thread_cap_factory()
void Platform_thread::_create_thread()
{
l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP,
_thread.local.dst());
_thread.local.data()->kcap());
if (l4_msgtag_has_error(tag))
PERR("cannot create more thread kernel-objects!");
@ -252,22 +252,22 @@ void Platform_thread::_finalize_construction(const char *name)
{
/* create irq for new thread */
l4_msgtag_t tag = l4_factory_create_irq(L4_BASE_FACTORY_CAP,
_irq.local.dst());
_irq.local.data()->kcap());
if (l4_msgtag_has_error(tag))
PWRN("creating thread's irq failed");
/* attach thread to irq */
tag = l4_irq_attach(_irq.local.dst(), 0, _thread.local.dst());
tag = l4_irq_attach(_irq.local.data()->kcap(), 0, _thread.local.data()->kcap());
if (l4_msgtag_has_error(tag))
PWRN("attaching thread's irq failed");
/* set human readable name in kernel debugger */
strncpy(_name, name, sizeof(_name));
Fiasco::l4_debugger_set_object_name(_thread.local.dst(), name);
Fiasco::l4_debugger_set_object_name(_thread.local.data()->kcap(), name);
/* set priority of thread */
l4_sched_param_t params = l4_sched_param(_prio);
l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local.dst(),
l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local.data()->kcap(),
&params);
}
@ -289,7 +289,8 @@ Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, prio))
{
((Core_cap_index*)_thread.local.idx())->pt(this);
/* XXX remove const cast */
((Core_cap_index *)_thread.local.data())->pt(this);
_create_thread();
_finalize_construction(name);
affinity(location);
@ -300,14 +301,15 @@ Platform_thread::Platform_thread(Core_cap_index* thread,
Core_cap_index* irq, const char *name)
: _state(RUNNING),
_core_thread(true),
_thread(Native_capability(thread), L4_BASE_THREAD_CAP),
_irq(Native_capability(irq)),
_thread(Native_capability(*thread), L4_BASE_THREAD_CAP),
_irq(Native_capability(*irq)),
_utcb(0),
_platform_pd(0),
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0))
{
reinterpret_cast<Core_cap_index*>(_thread.local.idx())->pt(this);
/* XXX remove const cast */
((Core_cap_index *)_thread.local.data())->pt(this);
_finalize_construction(name);
}
@ -322,7 +324,8 @@ Platform_thread::Platform_thread(const char *name)
_pager_obj(0),
_prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0))
{
((Core_cap_index*)_thread.local.idx())->pt(this);
/* XXX remove const cast */
((Core_cap_index *)_thread.local.data())->pt(this);
_create_thread();
_finalize_construction(name);
}

View File

@ -69,7 +69,7 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task)
return;
l4_msgtag_t tag = l4_task_map(task, L4_BASE_TASK_CAP,
l4_obj_fpage(local.dst(), 0, L4_FPAGE_RWX),
l4_obj_fpage(local.data()->kcap(), 0, L4_FPAGE_RWX),
((l4_cap_idx_t)remote) | L4_ITEM_MAP);
if (l4_msgtag_has_error(tag))
PERR("mapping cap failed");
@ -77,7 +77,7 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task)
Cap_mapping::Cap_mapping(bool alloc, Fiasco::l4_cap_idx_t r)
: local(alloc ? _get_cap() : 0), remote(r) { }
: local(alloc ? *_get_cap() : *(Native_capability::Data *)nullptr), remote(r) { }
Cap_mapping::Cap_mapping(Native_capability cap, Fiasco::l4_cap_idx_t r)
@ -100,7 +100,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep)
try {
using namespace Fiasco;
Core_cap_index* ref = static_cast<Core_cap_index*>(ep.idx());
Core_cap_index const * ref = static_cast<Core_cap_index const*>(ep.data());
ASSERT(ref && ref->pt(), "No valid platform_thread");
@ -118,7 +118,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep)
l4_msgtag_t tag = l4_factory_create_gate(L4_BASE_FACTORY_CAP,
idx->kcap(),
ref->pt()->thread().local.dst(), id);
ref->pt()->thread().local.data()->kcap(), id);
if (l4_msgtag_has_error(tag)) {
PERR("l4_factory_create_gate failed!");
cap_map()->remove(idx);
@ -131,7 +131,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep)
// XXX remove cast
idx->session((Pd_session_component *)this);
idx->pt(ref->pt());
cap = Native_capability(idx);
cap = Native_capability(*idx);
} catch (Cap_id_allocator::Out_of_ids) {
PERR("Out of capability ids");
}
@ -155,8 +155,9 @@ void Rpc_cap_factory::free(Native_capability cap)
if (!cap.valid()) return;
/* proof whether the capability was created by this cap_session */
if (static_cast<Core_cap_index*>(cap.idx())->session() != (Pd_session_component *)this) return;
/* check whether the capability was created by this cap_session */
if (static_cast<Core_cap_index const *>(cap.data())->session() != (Pd_session_component *)this)
return;
Entry * entry;
_pool.apply(cap, [&] (Entry *e) {

View File

@ -48,7 +48,7 @@ void Signal_source_component::submit(Signal_context_component *context,
_signal_queue.enqueue(context);
/* wake up client */
Fiasco::l4_irq_trigger(_blocking_semaphore.dst());
Fiasco::l4_irq_trigger(_blocking_semaphore.data()->kcap());
}
}
@ -70,14 +70,14 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
:
Signal_source_rpc_object(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
Signal_source_rpc_object(*cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
_entrypoint(ep), _finalizer(*this),
_finalizer_cap(_entrypoint->manage(&_finalizer))
{
using namespace Fiasco;
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP,
_blocking_semaphore.dst());
_blocking_semaphore.data()->kcap());
if (l4_error(res))
PERR("Allocation of irq object failed!");
}

View File

@ -61,7 +61,7 @@ void Thread::start()
pt->pager(platform_specific()->core_pager());
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx();
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.data();
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
pt->start((void *)_thread_start, stack_top());

View File

@ -14,12 +14,15 @@
#ifndef _INCLUDE__BASE__CAP_ALLOC_H_
#define _INCLUDE__BASE__CAP_ALLOC_H_
#include <base/cap_map.h>
/* Genode includes */
#include <base/native_capability.h>
#include <util/assert.h>
#include <util/construct_at.h>
#include <foc/native_capability.h>
/* base-internal includes */
#include <base/internal/cap_map.h>
namespace Genode {
/**
@ -117,8 +120,8 @@ namespace Genode {
}
}
addr_t idx_to_kcap(Cap_index *idx) {
return ((T*)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT;
addr_t idx_to_kcap(Cap_index const *idx) const {
return ((T const *)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT;
}
Cap_index* kcap_to_idx(addr_t kcap) {

View File

@ -35,50 +35,12 @@
#include <util/noncopyable.h>
#include <util/string.h>
namespace Genode
{
/**
* A Cap_index represents a single mapping of the global capability id
* to the address in the local capability space.
*
* The address of the Cap_index determines the location in the
* (platform-specific) capability space of the process. Therefore it
* shouldn't be copied around, but only referenced by
* e.g. Native_capability.
*/
class Cap_index : public Avl_node<Cap_index>,
Noncopyable
{
private:
/* base-internal includes */
#include <base/internal/capability_data.h>
enum { INVALID_ID = -1, UNUSED = 0 };
namespace Genode {
uint8_t _ref_cnt; /* reference counter */
uint16_t _id; /* global capability id */
public:
Cap_index() : _ref_cnt(0), _id(INVALID_ID) { }
bool valid() const { return _id != INVALID_ID; }
bool used() const { return _id != UNUSED; }
uint16_t id() const { return _id; }
void id(uint16_t id) { _id = id; }
uint8_t inc();
uint8_t dec();
addr_t kcap();
void* operator new (size_t size, Cap_index* idx) { return idx; }
void operator delete (void* idx) { memset(idx, 0, sizeof(Cap_index)); }
/************************
** Avl node interface **
************************/
bool higher(Cap_index *n);
Cap_index *find_by_id(uint16_t id);
};
typedef Native_capability::Data Cap_index;
/**
@ -129,7 +91,7 @@ namespace Genode
*
* \param idx pointer to the Cap_index object in question
*/
virtual addr_t idx_to_kcap(Cap_index *idx) = 0;
virtual addr_t idx_to_kcap(Cap_index const *idx) const = 0;
/**
* Get the Cap_index object of a specific location

View File

@ -0,0 +1,63 @@
/*
* \brief Internal capability representation
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2016-06-22
*/
/*
* 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__BASE__INTERNAL__CAPABILITY_DATA_H_
#define _INCLUDE__BASE__INTERNAL__CAPABILITY_DATA_H_
/* Genode includes */
#include <base/capability.h>
/**
* A Native_capability::Data object represents a single mapping of the global
* capability id to the address in the local capability space.
*
* The address of the data object determines the location in the
* (platform-specific) capability space of the component. Therefore it
* shouldn't be copied around, but only referenced by e.g. Native_capability.
*/
class Genode::Native_capability::Data : public Avl_node<Data>, Noncopyable
{
private:
enum { INVALID_ID = -1, UNUSED = 0 };
uint8_t _ref_cnt; /* reference counter */
uint16_t _id; /* global capability id */
public:
Data() : _ref_cnt(0), _id(INVALID_ID) { }
bool valid() const { return _id != INVALID_ID; }
bool used() const { return _id != UNUSED; }
uint16_t id() const { return _id; }
void id(uint16_t id) { _id = id; }
uint8_t inc();
uint8_t dec();
addr_t kcap() const;
void* operator new (size_t size, Data* idx) { return idx; }
void operator delete (void* idx) { memset(idx, 0, sizeof(Data)); }
/************************
** Avl node interface **
************************/
bool higher(Data *n);
Data *find_by_id(uint16_t id);
};
#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_DATA_H_ */

View File

@ -24,6 +24,7 @@
/* base-internal includes */
#include <base/internal/crt0.h>
#include <base/internal/cap_map.h>
namespace Genode {
@ -43,7 +44,7 @@ namespace Genode {
i = cap_map()->insert(local_name, Fiasco::PARENT_CAP);
}
return reinterpret_cap_cast<Parent>(Native_capability(i));
return reinterpret_cap_cast<Parent>(Native_capability(*i));
}
}

View File

@ -14,19 +14,15 @@
*/
/* Genode includes */
#include <base/cap_map.h>
#include <base/native_capability.h>
#include <util/assert.h>
#include <base/log.h>
/* base-internal includes */
#include <base/internal/spin_lock.h>
#include <base/internal/cap_map.h>
/* kernel includes */
namespace Fiasco {
#include <l4/sys/consts.h>
#include <l4/sys/task.h>
}
#include <foc/capability_space.h>
/***********************
@ -50,7 +46,7 @@ Genode::Cap_index* Genode::Cap_index::find_by_id(Genode::uint16_t id)
}
Genode::addr_t Genode::Cap_index::kcap() {
Genode::addr_t Genode::Cap_index::kcap() const {
return cap_idx_alloc()->idx_to_kcap(this); }
@ -181,3 +177,28 @@ Genode::Capability_map* Genode::cap_map()
static Genode::Capability_map map;
return &map;
}
/**********************
** Capability_space **
**********************/
Fiasco::l4_cap_idx_t Genode::Capability_space::alloc_kcap()
{
return cap_idx_alloc()->alloc_range(1)->kcap();
}
void Genode::Capability_space::free_kcap(Fiasco::l4_cap_idx_t kcap)
{
Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(kcap);
Genode::cap_idx_alloc()->free(idx, 1);
}
Fiasco::l4_cap_idx_t Genode::Capability_space::kcap(Native_capability cap)
{
if (cap.data() == nullptr)
Genode::raw("Native_capability data is NULL!");
return cap.data()->kcap();
}

View File

@ -13,7 +13,7 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/cap_map.h>
#include <base/internal/cap_map.h>
void Genode::Capability_map::remove(Genode::Cap_index* i)
{

View File

@ -0,0 +1,72 @@
/*
* \brief Capability lifetime management
* \author Norman Feske
* \date 2015-05-06
*/
/*
* 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.
*/
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
/* base-internal includes */
#include <base/internal/cap_map.h>
#include <base/internal/capability_data.h>
using namespace Genode;
Native_capability::Native_capability() { }
void Native_capability::_inc()
{
if (_data)
_data->inc();
}
void Native_capability::_dec()
{
if (_data && !_data->dec())
cap_map()->remove(_data);
}
long Native_capability::local_name() const
{
return _data ? _data->id() : 0;
}
bool Native_capability::valid() const
{
return (_data != 0) && _data->valid();
}
Native_capability::Raw Native_capability::raw() const
{
return { (unsigned long)local_name(), 0, 0, 0 };
}
void Native_capability::print(Genode::Output &out) const
{
using Genode::print;
print(out, "cap<");
if (_data) {
print(out, "kcap=", Hex(_data->kcap()), ",key=", (unsigned)_data->id());
} else {
print(out, "invalid");
}
print(out, ">");
}

View File

@ -32,6 +32,7 @@
#include <base/internal/lock_helper.h> /* for 'thread_get_my_native_id()' */
#include <base/internal/ipc_server.h>
#include <base/internal/native_utcb.h>
#include <base/internal/cap_map.h>
/* Fiasco.OC includes */
namespace Fiasco {
@ -168,7 +169,7 @@ static unsigned long extract_msg_from_utcb(l4_msgtag_t tag,
*/
for (unsigned i = 0; i < num_caps; i++) {
if (caps[i].valid) {
rcv_msg.insert(Native_capability(cap_map()->insert_map(caps[i].badge,
rcv_msg.insert(Native_capability(*cap_map()->insert_map(caps[i].badge,
caps[i].sel)));
} else {
rcv_msg.insert(Native_capability());
@ -200,7 +201,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg,
if (!cap.valid())
continue;
if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst())))
if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.data()->kcap())))
cap = Native_capability();
}
@ -217,7 +218,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg,
if (cap.valid()) {
caps[i].valid = true;
caps[i].badge = cap.local_name();
caps[i].sel = cap.dst();
caps[i].sel = cap.data()->kcap();
}
}
@ -285,8 +286,11 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
rcv_cap_sel += L4_CAP_SIZE;
}
if (!dst.valid())
throw Genode::Ipc_error();
l4_msgtag_t const reply_tag =
l4_ipc_call(dst.dst(), l4_utcb(), call_tag, L4_IPC_NEVER);
l4_ipc_call(dst.data()->kcap(), l4_utcb(), call_tag, L4_IPC_NEVER);
if (l4_ipc_error(reply_tag, l4_utcb()) == L4_IPC_RECANCELED)
throw Genode::Blocking_canceled();
@ -370,10 +374,40 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller,
Ipc_server::Ipc_server()
:
Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE])
Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE])
{
Thread::myself()->native_thread().rcv_window.init();
}
Ipc_server::~Ipc_server() { }
/********************
** Receive_window **
********************/
Receive_window::~Receive_window()
{
if (_rcv_idx_base)
cap_idx_alloc()->free(_rcv_idx_base, MAX_CAPS_PER_MSG);
}
void Receive_window::init()
{
_rcv_idx_base = cap_idx_alloc()->alloc_range(MAX_CAPS_PER_MSG);
}
addr_t Receive_window::rcv_cap_sel_base()
{
return _rcv_idx_base->kcap();
}
addr_t Receive_window::rcv_cap_sel(unsigned i)
{
return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE;
}

View File

@ -0,0 +1,77 @@
/*
* \brief Fiasco.OC-specific signal-source client interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2010-02-03
*/
/*
* 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 <signal_source/client.h>
#include <base/thread.h>
#include <base/log.h>
/* base-internal includes */
#include <base/internal/capability_data.h>
#include <base/internal/native_thread.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/irq.h>
}
using namespace Genode;
Signal_source_client::Signal_source_client(Capability<Signal_source> cap)
:
Rpc_client<Foc_signal_source>(static_cap_cast<Foc_signal_source>(cap))
{
using namespace Fiasco;
/* request mapping of semaphore capability selector */
_sem = call<Rpc_request_semaphore>();
l4_msgtag_t tag = l4_irq_attach(_sem.data()->kcap(), 0,
Thread::myself()->native_thread().kcap);
if (l4_error(tag))
Genode::raw("l4_irq_attach failed with ", l4_error(tag));
}
Signal_source_client::~Signal_source_client()
{
Fiasco::l4_irq_detach(_sem.data()->kcap());
}
__attribute__((optimize("-fno-omit-frame-pointer")))
__attribute__((noinline))
Signal_source_client::Signal Signal_source_client::wait_for_signal()
{
using namespace Fiasco;
Signal signal;
do {
/* block on semaphore until signal context was submitted */
l4_irq_receive(_sem.data()->kcap(), L4_IPC_NEVER);
/*
* The following request will return immediately and either
* return a valid or a null signal. The latter may happen in
* the case a submitted signal context was destroyed (by the
* submitter) before we have a chance to raise our request.
*/
signal = call<Rpc_wait_for_signal>();
} while (!signal.imprint());
return signal;
}

View File

@ -13,10 +13,8 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/cap_map.h>
/* base-internal includes */
#include <base/internal/cap_map.h>
#include <base/internal/spin_lock.h>

View File

@ -20,6 +20,7 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
#include <base/internal/cap_map.h>
/*****************************

View File

@ -23,6 +23,7 @@
/* base-internal includes */
#include <base/internal/stack.h>
#include <base/internal/cap_map.h>
/* Fiasco includes */
namespace Fiasco {

View File

@ -13,8 +13,13 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <log_session/connection.h>
#include <foc/capability_space.h>
/* base-internal includes */
#include <base/internal/cap_map.h> /* cap_idx_alloc */
using namespace Genode;
using namespace Fiasco;
@ -26,7 +31,7 @@ int main(int argc, char **argv)
enum { COUNT = 1000 };
Cap_index* idx = cap_idx_alloc()->alloc_range(COUNT);
Fiasco::l4_cap_idx_t tid = env()->ram_session_cap().dst();
Fiasco::l4_cap_idx_t tid = Capability_space::kcap(env()->ram_session_cap());
/* try the first 1000 local name IDs */
for (int local_name = 0; local_name < COUNT; local_name++, idx++) {
@ -36,7 +41,7 @@ int main(int argc, char **argv)
idx->kcap() | L4_ITEM_MAP);
Log_session_capability log_session_cap =
reinterpret_cap_cast<Log_session>(Native_capability(idx));
reinterpret_cap_cast<Log_session>(Native_capability(*idx));
Log_session_client log_session_client(log_session_cap);
try {
log_session_client.write("test message");

View File

@ -1,4 +1,5 @@
REQUIRES = foc
TARGET = test-cap_integrity
SRC_CC = main.cc
INC_DIR += $(REP_DIR)/src/include
LIBS = base

View File

@ -1,91 +0,0 @@
/*
* \brief Native capability of base-hw
* \author Stefan Kalkowski
* \date 2015-05-15
*/
/*
* 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__BASE__NATIVE_CAPABILITY_H_
#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_
/* Genode includes */
#include <kernel/interface.h>
#include <base/stdint.h>
namespace Genode { class Native_capability; }
class Genode::Native_capability
{
public:
using Dst = Kernel::capid_t;
private:
Dst _dst;
void _inc() const;
void _dec() const;
public:
struct Raw { };
/**
* Create an invalid capability
*/
Native_capability() : _dst(Kernel::cap_id_invalid()) { }
/**
* Create a capability out of a kernel's capability id
*/
Native_capability(Kernel::capid_t dst) : _dst(dst) { _inc(); }
/**
* Create a capability from another one
*/
Native_capability(const Native_capability &o) : _dst(o._dst) { _inc(); }
~Native_capability() { _dec(); }
/**
* Returns true if it is a valid capability otherwise false
*/
bool valid() const { return (_dst != Kernel::cap_id_invalid()); }
/*****************
** Accessors **
*****************/
addr_t local_name() const { return _dst; }
Dst dst() const { return _dst; }
/**************************
** Operator overloads **
**************************/
bool operator==(const Native_capability &o) const {
return _dst == _dst; }
Native_capability& operator=(const Native_capability &o)
{
if (this == &o) return *this;
_dec();
_dst = o._dst;
_inc();
return *this;
}
Raw raw() const { return Raw(); }
};
#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */

View File

@ -10,8 +10,29 @@
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/capability.h>
void Genode::Native_capability::_inc() const { }
#include <base/internal/capability_space.h>
void Genode::Native_capability::_dec() const { }
using namespace Genode;
Native_capability::Native_capability() { }
void Native_capability::_inc() { }
void Native_capability::_dec() { }
long Native_capability::local_name() const
{
return (long)_data;
}
bool Native_capability::valid() const
{
return (addr_t)_data != Kernel::cap_id_invalid();
}
Native_capability::Raw Native_capability::raw() const { return { 0, 0, 0, 0 }; }

View File

@ -14,6 +14,8 @@
#ifndef _CORE__INCLUDE__KERNEL__CONFIGURATION_H_
#define _CORE__INCLUDE__KERNEL__CONFIGURATION_H_
#include <kernel/interface.h>
namespace Kernel
{
enum {

View File

@ -14,13 +14,17 @@
#ifndef _CORE__INCLUDE__OBJECT_H_
#define _CORE__INCLUDE__OBJECT_H_
#include <base/capability.h>
#include <kernel/interface.h>
#include <kernel/object.h>
/* Genode includes */
#include <util/construct_at.h>
namespace Genode
{
/* base-internal includes */
#include <base/internal/capability_space.h>
/* base-hw includes */
#include <kernel/interface.h>
#include <kernel/object.h>
namespace Genode {
/**
* Represents a kernel object in core
*
@ -51,9 +55,11 @@ class Genode::Kernel_object
*/
template <typename... ARGS>
Kernel_object(bool syscall, ARGS &&... args)
: _cap(syscall ? T::syscall_create(&_data, args...)
: Kernel::cap_id_invalid()) {
if (!syscall) construct_at<T>(&_data, args...); }
: _cap(Capability_space::import(syscall ? T::syscall_create(&_data, args...)
: Kernel::cap_id_invalid()))
{
if (!syscall) construct_at<T>(&_data, args...);
}
~Kernel_object() { T::syscall_destroy(kernel_object()); }
@ -66,7 +72,7 @@ class Genode::Kernel_object
bool create(ARGS &&... args)
{
if (_cap.valid()) return false;
_cap = T::syscall_create(&_data, args...);
_cap = Capability_space::import(T::syscall_create(&_data, args...));
return _cap.valid();
}
};

View File

@ -40,7 +40,7 @@ namespace Genode
{
class Platform_thread; /* forward declaration */
class Capability_space;
class Cap_space;
/**
* Platform specific part of a Genode protection domain
@ -128,7 +128,7 @@ class Hw::Address_space : public Genode::Address_space
};
class Genode::Capability_space
class Genode::Cap_space
{
private:
@ -142,7 +142,7 @@ class Genode::Capability_space
public:
Capability_space();
Cap_space();
Cap_slab & capability_slab() { return _slab; }
@ -151,7 +151,7 @@ class Genode::Capability_space
class Genode::Platform_pd : public Hw::Address_space,
public Genode::Capability_space,
public Genode::Cap_space,
public Kernel_object<Kernel::Pd>
{
private:

View File

@ -20,11 +20,15 @@
#include <base/lock.h>
#include <base/tslab.h>
#include <base/capability.h>
#include <base/log.h>
/* core-local includes */
#include <object.h>
#include <kernel/thread.h>
/* base-internal includes */
#include <base/internal/capability_space.h>
namespace Genode { class Rpc_cap_factory; }
@ -86,10 +90,11 @@ class Genode::Rpc_cap_factory
construct_at<Kobject>(obj);
/* create kernel object via syscall */
obj->cap = Kernel::new_obj(obj->data, ep.dst());
Kernel::capid_t capid = Kernel::new_obj(obj->data, Capability_space::capid(ep));
obj->cap = Capability_space::import(capid);
if (!obj->cap.valid()) {
PWRN("Invalid entrypoint %u for allocating a capability!",
ep.dst());
raw("Invalid entrypoint ", (addr_t)Capability_space::capid(ep),
" for allocating a capability!");
destroy(&_slab, obj);
return Native_capability();
}
@ -104,7 +109,7 @@ class Genode::Rpc_cap_factory
Lock::Guard guard(_lock);
for (Kobject * obj = _list.first(); obj; obj = obj->next()) {
if (obj->cap.dst() == cap.dst()) {
if (obj->cap.data() == cap.data()) {
Kernel::delete_obj(obj->data);
_list.remove(obj);
destroy(&_slab, obj);

View File

@ -50,7 +50,7 @@ class Genode::Vm_session_component
void exception_handler(Signal_context_capability handler)
{
if (!create(&_state, handler.dst(), nullptr))
if (!create(&_state, Capability_space::capid(handler), nullptr))
PWRN("Cannot instantiate vm kernel object, "
"invalid signal context?");
}

View File

@ -21,6 +21,9 @@
/* base-internal includes */
#include <base/internal/page_size.h>
/* base-hw includes */
#include <kernel/interface.h>
namespace Genode
{
struct Native_region

View File

@ -20,6 +20,9 @@
#include <irq_root.h>
#include <core_env.h>
/* base-internal includes */
#include <base/internal/capability_space.h>
using namespace Genode;
@ -47,7 +50,8 @@ void Irq_session_component::sigh(Signal_context_capability cap)
_sig_cap = cap;
if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number, _sig_cap.dst()))
if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number,
Capability_space::capid(_sig_cap)))
PWRN("invalid signal handler for IRQ %u", _irq_number);
}

View File

@ -19,6 +19,9 @@
#include <platform_thread.h>
#include <platform_pd.h>
/* base-internal includes */
#include <base/internal/capability_space.h>
using namespace Genode;
@ -65,7 +68,7 @@ void Ipc_pager::set_reply_mapping(Mapping m) { _mapping = m; }
void Pager_object::wake_up()
{
using Object = Kernel_object<Kernel::Signal_context>;
Kernel::ack_signal(Object::_cap.dst());
Kernel::ack_signal(Capability_space::capid(Object::_cap));
}
void Pager_object::start_paging(Kernel::Signal_receiver * receiver)

View File

@ -103,15 +103,14 @@ Hw::Address_space::~Address_space()
}
/*************************************
** Capability_space implementation **
*************************************/
/******************************
** Cap_space implementation **
******************************/
Capability_space::Capability_space()
: _slab(nullptr, &_initial_sb) { }
Cap_space::Cap_space() : _slab(nullptr, &_initial_sb) { }
void Capability_space::upgrade_slab(Allocator &alloc)
void Cap_space::upgrade_slab(Allocator &alloc)
{
for (;;) {
void *block = nullptr;

View File

@ -22,6 +22,7 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
#include <base/internal/capability_space.h>
/* kernel includes */
#include <kernel/pd.h>
@ -171,10 +172,10 @@ int Platform_thread::start(void * const ip, void * const sp)
/* reset capability counter */
utcb->cap_cnt(0);
utcb->cap_add(_cap.dst());
utcb->cap_add(Capability_space::capid(_cap));
if (_main_thread) {
utcb->cap_add(_pd->parent().dst());
utcb->cap_add(_utcb.dst());
utcb->cap_add(Capability_space::capid(_pd->parent()));
utcb->cap_add(Capability_space::capid(_utcb));
}
Kernel::start_thread(kernel_object(), cpu, _pd->kernel_pd(),
_utcb_core_addr);
@ -187,7 +188,8 @@ void Platform_thread::pager(Pager_object * const pager)
using namespace Kernel;
if (route_thread_event(kernel_object(), Thread_event_id::FAULT,
pager ? pager->cap().dst() : cap_id_invalid()))
pager ? Capability_space::capid(pager->cap())
: cap_id_invalid()))
PERR("failed to set pager object for thread %s", label());
_pager = pager;

View File

@ -20,6 +20,8 @@
#include <platform_thread.h>
#include <translation_table.h>
/* base-internal includes */
using namespace Genode;
@ -45,7 +47,7 @@ void Pager_entrypoint::entry()
while (1)
{
/* receive fault */
if (Kernel::await_signal(_cap.dst())) continue;
if (Kernel::await_signal(Capability_space::capid(_cap))) continue;
Untyped_capability cap =
(*(Pager_object**)Thread::myself()->utcb()->data())->cap();

View File

@ -20,7 +20,9 @@ using namespace Genode;
void Vm_session_component::exception_handler(Signal_context_capability handler)
{
if (!create((void*)_ds.core_local_addr(), handler.dst(), nullptr)) {
if (!create((void*)_ds.core_local_addr(), Capability_space::capid(handler),
nullptr))
{
PWRN("Cannot instantiate vm kernel object twice,"
"or invalid signal context?");
}

View File

@ -28,7 +28,7 @@ void Vm_session_component::exception_handler(Signal_context_capability handler)
Core_mem_allocator * cma =
static_cast<Core_mem_allocator*>(platform()->core_mem_alloc());
if (!create((void*)_ds.core_local_addr(), handler.dst(),
if (!create((void*)_ds.core_local_addr(), Capability_space::capid(handler),
cma->phys_addr(_table)))
PWRN("Cannot instantiate vm kernel object, invalid signal context?");
}

View File

@ -69,5 +69,5 @@ void Thread::_init_platform_thread(size_t, Type type)
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
/* adjust initial object state in case of a main thread */
native_thread().cap = Hw::_main_thread_cap.dst();
native_thread().cap = Hw::_main_thread_cap;
}

View File

@ -0,0 +1,40 @@
/*
* \brief Capability helper
* \author Norman Feske
* \date 2016-06-22
*/
/*
* 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__BASE__INTERNAL__CAPABILITY_SPACE_H_
#define _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_
/* Genode includes */
#include <base/capability.h>
/* base-hw includes */
#include <kernel/interface.h>
namespace Genode { namespace Capability_space {
/**
* Return kernel capability selector of Genode capability
*/
static inline Kernel::capid_t capid(Native_capability const &cap)
{
addr_t const index = (addr_t)cap.data();
return index;
}
static inline Native_capability import(Kernel::capid_t capid)
{
return Native_capability(*(Native_capability::Data *)(addr_t)capid);
}
} }
#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ */

View File

@ -17,9 +17,11 @@
/* Genode includes */
#include <base/thread.h>
namespace Hw {
extern Genode::Untyped_capability _main_thread_cap;
}
/* base-internal includes */
#include <base/internal/capability_space.h>
namespace Hw { extern Genode::Untyped_capability _main_thread_cap; }
/**
* Yield execution time-slice of current thread
@ -34,7 +36,8 @@ static inline void thread_yield() {
static inline Kernel::capid_t
native_thread_id(Genode::Thread * const t)
{
return t ? t->native_thread().cap.dst() : Hw::_main_thread_cap.dst();
using Genode::Capability_space::capid;
return t ? capid(t->native_thread().cap) : capid(Hw::_main_thread_cap);
}

View File

@ -17,24 +17,63 @@
/* base-internal includes */
#include <base/internal/spin_lock.h>
/* kernel includes */
#include <kernel/interface.h>
using namespace Genode;
static volatile int spinlock = SPINLOCK_UNLOCKED;
static Genode::uint8_t ref_counter[1 << (sizeof(Kernel::capid_t)*8)];
void Genode::Native_capability::_inc() const
static uint8_t ref_counter[1 << (sizeof(Kernel::capid_t)*8)];
Native_capability::Native_capability() { }
void Native_capability::_inc()
{
if (!valid()) return;
spinlock_lock(&spinlock);
ref_counter[_dst]++;
ref_counter[(addr_t)_data]++;
spinlock_unlock(&spinlock);
}
void Genode::Native_capability::_dec() const
void Native_capability::_dec()
{
if (!valid()) return;
spinlock_lock(&spinlock);
if (!--ref_counter[_dst]) { Kernel::delete_cap(_dst); }
if (!--ref_counter[(addr_t)_data]) { Kernel::delete_cap((addr_t)_data); }
spinlock_unlock(&spinlock);
}
long Native_capability::local_name() const
{
return (long)_data;
}
bool Native_capability::valid() const
{
return (addr_t)_data != Kernel::cap_id_invalid();
}
Native_capability::Raw Native_capability::raw() const { return { 0, 0, 0, 0 }; }
void Native_capability::print(Genode::Output &out) const
{
using Genode::print;
print(out, "cap<");
if (_data) {
print(out, (addr_t)_data);
} else {
print(out, "invalid");
}
print(out, ">");
}

View File

@ -25,6 +25,7 @@
#include <base/internal/native_thread.h>
#include <base/internal/ipc_server.h>
#include <base/internal/native_env.h>
#include <base/internal/capability_space.h>
/* base-hw includes */
#include <kernel/interface.h>
@ -44,7 +45,7 @@ static inline void copy_msg_to_utcb(Msgbuf_base const &snd_msg, Native_utcb &utc
snd_msg.used_caps());
for (unsigned i = 0; i < num_caps; i++)
utcb.cap_set(i, snd_msg.cap(i).dst());
utcb.cap_set(i, Capability_space::capid(snd_msg.cap(i)));
utcb.cap_cnt(num_caps);
@ -68,9 +69,9 @@ static inline void copy_utcb_to_msg(Native_utcb const &utcb, Msgbuf_base &rcv_ms
utcb.cap_cnt());
for (unsigned i = 0; i < num_caps; i++) {
rcv_msg.cap(i) = utcb.cap_get(i);
rcv_msg.cap(i) = Capability_space::import(utcb.cap_get(i));
if (rcv_msg.cap(i).valid())
Kernel::ack_cap(rcv_msg.cap(i).dst());
Kernel::ack_cap(Capability_space::capid(rcv_msg.cap(i)));
}
rcv_msg.used_caps(num_caps);
@ -100,8 +101,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
copy_msg_to_utcb(snd_msg, *Thread::myself()->utcb());
switch (Kernel::send_request_msg(dst.dst(),
rcv_caps)) {
switch (Kernel::send_request_msg(Capability_space::capid(dst), rcv_caps)) {
case -1: throw Blocking_canceled();
case -2: throw Allocator::Out_of_memory();
default:

View File

@ -20,9 +20,7 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
/* base-hw includes */
#include <kernel/interface.h>
#include <base/internal/capability_space.h>
using namespace Genode;
@ -54,7 +52,7 @@ void Signal_transmitter::submit(unsigned cnt)
{
Trace::Signal_submit trace_event(cnt);
}
Kernel::submit_signal(_context.dst(), cnt);
Kernel::submit_signal(Capability_space::capid(_context), cnt);
}
@ -85,7 +83,7 @@ void Signal_receiver::_platform_destructor()
void Signal_receiver::_platform_begin_dissolve(Signal_context * const c)
{
Kernel::kill_signal_context(c->_cap.dst());
Kernel::kill_signal_context(Capability_space::capid(c->_cap));
}
void Signal_receiver::_platform_finish_dissolve(Signal_context *) { }
@ -119,7 +117,7 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c)
void Signal_receiver::block_for_signal()
{
/* wait for a signal */
if (Kernel::await_signal(_cap.dst())) {
if (Kernel::await_signal(Capability_space::capid(_cap))) {
PERR("failed to receive signal");
return;
}
@ -135,7 +133,7 @@ void Signal_receiver::block_for_signal()
context->_curr_signal = Signal::Data(context, num);
}
/* end kernel-aided life-time management */
Kernel::ack_signal(data->context->_cap.dst());
Kernel::ack_signal(Capability_space::capid(data->context->_cap));
}

View File

@ -20,9 +20,7 @@
/* base-internal includes */
#include <base/internal/stack.h>
#include <base/internal/native_utcb.h>
/* base-hw includes */
#include <kernel/interface.h>
#include <base/internal/capability_space.h>
using namespace Genode;
@ -47,10 +45,13 @@ void prepare_init_main_thread()
* before the UTCB gets polluted by the following function calls.
*/
Native_utcb * utcb = Thread::myself()->utcb();
_parent_cap = utcb->cap_get(Native_utcb::PARENT);
Untyped_capability ds_cap(utcb->cap_get(Native_utcb::UTCB_DATASPACE));
_parent_cap = Capability_space::import(utcb->cap_get(Native_utcb::PARENT));
Untyped_capability ds_cap =
Capability_space::import(utcb->cap_get(Native_utcb::UTCB_DATASPACE));
_main_thread_utcb_ds = reinterpret_cap_cast<Ram_dataspace>(ds_cap);
_main_thread_cap = utcb->cap_get(Native_utcb::THREAD_MYSELF);
_main_thread_cap = Capability_space::import(utcb->cap_get(Native_utcb::THREAD_MYSELF));
}
@ -76,5 +77,8 @@ void Thread::_thread_start()
Genode::sleep_forever();
}
void Thread::_thread_bootstrap() {
native_thread().cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); }
void Thread::_thread_bootstrap()
{
Kernel::capid_t capid = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF);
native_thread().cap = Capability_space::import(capid);
}

View File

@ -1,45 +0,0 @@
/*
* \brief Native capability type
* \author Norman Feske
* \date 2007-10-15
*/
/*
* Copyright (C) 2007-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__BASE__NATIVE_CAPABILITY_H_
#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_
#include <util/string.h>
#include <base/native_capability_tpl.h>
#include <base/stdint.h>
namespace Genode {
struct Cap_dst_policy
{
struct Dst
{
int socket;
/**
* Default constructor creates invalid destination
*/
Dst() : socket(-1) { }
explicit Dst(int socket) : socket(socket) { }
};
static bool valid(Dst id) { return id.socket != -1; }
static Dst invalid() { return Dst(); }
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
}
#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */

View File

@ -12,3 +12,4 @@ SRC_CC += region_map_mmap.cc debug.cc
SRC_CC += signal_submit.cc
SRC_CC += rpc_dispatch_loop.cc
SRC_CC += thread_env.cc
SRC_CC += capability.cc

View File

@ -8,4 +8,5 @@ include $(REP_DIR)/lib/mk/base.inc
LIBS += startup
SRC_CC += thread.cc thread_myself.cc thread_linux.cc
SRC_CC += capability_space.cc capability_raw.cc

View File

@ -1,4 +1,4 @@
SRC_CC += lx_hybrid.cc new_delete.cc
SRC_CC += lx_hybrid.cc new_delete.cc capability_space.cc
vpath new_delete.cc $(BASE_DIR)/src/lib/cxx
vpath lx_hybrid.cc $(REP_DIR)/src/lib/lx_hybrid

View File

@ -210,8 +210,6 @@ namespace Genode {
PWRN("%s:%u not implemented", __FILE__, __LINE__);
return Cpu_session_capability();
}
void reload_parent_cap(Capability<Parent>::Dst, long) { }
};

View File

@ -25,6 +25,9 @@
#include <base/rpc_server.h>
#include <base/printf.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
namespace Genode {
/**
@ -122,9 +125,10 @@ namespace Genode {
Untyped_capability fd()
{
typedef Untyped_capability::Dst Dst;
enum { DUMMY_LOCAL_NAME = 0 };
return Untyped_capability(Dst(_fd), DUMMY_LOCAL_NAME);
Untyped_capability fd_cap =
Capability_space::import(Rpc_destination(_fd), Rpc_obj_key());
return fd_cap;
}
};
}

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

@ -15,6 +15,9 @@
#include <cpu_session_component.h>
#include <native_cpu_component.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
using namespace Genode;
@ -30,10 +33,8 @@ Untyped_capability Native_cpu_component::server_sd(Thread_capability thread_cap)
auto lambda = [] (Cpu_thread_component *thread) {
if (!thread) return Untyped_capability();
enum { DUMMY_LOCAL_NAME = 0 };
typedef Native_capability::Dst Dst;
return Untyped_capability(Dst(thread->platform_thread().server_sd()),
DUMMY_LOCAL_NAME);
return Capability_space::import(Rpc_destination(thread->platform_thread().server_sd()),
Rpc_obj_key());
};
return _thread_ep.apply(thread_cap, lambda);
}
@ -44,10 +45,8 @@ Untyped_capability Native_cpu_component::client_sd(Thread_capability thread_cap)
auto lambda = [] (Cpu_thread_component *thread) {
if (!thread) return Untyped_capability();
enum { DUMMY_LOCAL_NAME = 0 };
typedef Native_capability::Dst Dst;
return Untyped_capability(Dst(thread->platform_thread().client_sd()),
DUMMY_LOCAL_NAME);
return Capability_space::import(Rpc_destination(thread->platform_thread().client_sd()),
Rpc_obj_key());
};
return _thread_ep.apply(thread_cap, lambda);
}

View File

@ -22,6 +22,7 @@
/* base-internal includes */
#include <base/internal/parent_socket_handle.h>
#include <base/internal/capability_space_tpl.h>
/* Linux includes */
#include <core_linux_syscalls.h>
@ -117,7 +118,8 @@ void Native_pd_component::_start(Dataspace_component &ds)
char buf[4096];
int num_bytes = 0;
while ((num_bytes = lx_read(ds.fd().dst().socket, buf, sizeof(buf))) != 0)
int const fd_socket = Capability_space::ipc_cap_data(ds.fd()).dst.socket;
while ((num_bytes = lx_read(fd_socket, buf, sizeof(buf))) != 0)
lx_write(tmp_binary_fd, buf, num_bytes);
lx_close(tmp_binary_fd);
@ -167,7 +169,7 @@ void Native_pd_component::_start(Dataspace_component &ds)
* pointer, all arguments are embedded within the 'execve_args' struct.
*/
Execve_args arg(filename, argv_buf, env,
_pd_session._parent.dst().socket);
Capability_space::ipc_cap_data(_pd_session._parent).dst.socket);
_pid = lx_create_process((int (*)(void *))_exec_child,
stack + STACK_SIZE - sizeof(umword_t), &arg);

View File

@ -18,6 +18,7 @@
/* base-internal includes */
#include <base/internal/native_thread.h>
#include <base/internal/parent_socket_handle.h>
#include <base/internal/capability_space_tpl.h>
/* local includes */
#include "platform.h"
@ -206,7 +207,8 @@ int Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
if (!core_env()->entrypoint()->is_myself()) {
/* release Region_map_mmap::_lock during RPC */
_lock.unlock();
int socket = Linux_dataspace_client(ds_cap).fd().dst().socket;
Untyped_capability fd_cap = Linux_dataspace_client(ds_cap).fd();
int socket = Capability_space::ipc_cap_data(fd_cap).dst.socket;
_lock.lock();
return socket;
}
@ -223,7 +225,7 @@ int Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
* dataspace, the descriptor would unexpectedly be closed again.
*/
return core_env()->entrypoint()->apply(lx_ds_cap, [] (Linux_dataspace *ds) {
return ds ? lx_dup(ds->fd().dst().socket) : -1; });
return ds ? lx_dup(Capability_space::ipc_cap_data(ds->fd()).dst.socket) : -1; });
}

View File

@ -21,6 +21,9 @@
#include <ram_session_component.h>
#include <resource_path.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
/* Linux syscall bindings */
#include <core_linux_syscalls.h>
@ -55,7 +58,7 @@ void Ram_session_component::_export_ram_ds(Dataspace_component *ds)
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds)
{
int const fd = ds->fd().dst().socket;
int const fd = Capability_space::ipc_cap_data(ds->fd()).dst.socket;
if (fd != -1)
lx_close(fd);
}

View File

@ -24,6 +24,9 @@
#include <util/arg_string.h>
#include <root/root.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
/* local includes */
#include "rom_session_component.h"
@ -44,7 +47,7 @@ Rom_session_component::~Rom_session_component()
{
_ds_ep->dissolve(&_ds);
int const fd = _ds.fd().dst().socket;
int const fd = Capability_space::ipc_cap_data(_ds.fd()).dst.socket;
if (fd != -1)
lx_close(fd);
}

View File

@ -19,7 +19,8 @@ SRC_CC = main.cc \
dataspace_component.cc \
native_pd_component.cc \
native_cpu_component.cc \
rpc_cap_factory.cc \
capability_space.cc \
rpc_cap_factory_l4.cc \
core_rpc_cap_alloc.cc \
io_mem_session_component.cc \
signal_source_component.cc \
@ -47,7 +48,8 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath cpu_session_support.cc $(GEN_CORE_DIR)
vpath cpu_thread_component.cc $(GEN_CORE_DIR)
vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory.cc $(GEN_CORE_DIR)
vpath capability_space.cc $(GEN_CORE_DIR)
vpath rpc_cap_factory_l4.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)

View File

@ -14,15 +14,24 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__LOCAL_CAPABILITY_H_
#define _INCLUDE__BASE__LOCAL_CAPABILITY_H_
#ifndef _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_
#define _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_
#include <base/capability.h>
#include <base/internal/capability_space_tpl.h>
namespace Genode {
template <typename> class Local_capability;
/**
* Return true if argument is a local capability
*/
static inline bool local(Untyped_capability const &cap)
{
return Capability_space::ipc_cap_data(cap).dst.socket == -1;
}
}
/**
* Local capability referring to a specific RPC interface
*
@ -44,7 +53,9 @@ class Genode::Local_capability
* \return a capability that represents the local object.
*/
static Capability<RPC_INTERFACE> local_cap(RPC_INTERFACE* ptr) {
Untyped_capability cap(Cap_dst_policy::Dst(), (long)ptr);
Untyped_capability cap =
Capability_space::import(invalid_rpc_destination(),
Rpc_obj_key((long)ptr));
return reinterpret_cap_cast<RPC_INTERFACE>(cap); }
/**
@ -57,4 +68,4 @@ class Genode::Local_capability
return reinterpret_cast<RPC_INTERFACE*>(c.local_name()); }
};
#endif /* _INCLUDE__BASE__LOCAL_CAPABILITY_H_ */
#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ */

View File

@ -0,0 +1,41 @@
/*
* \brief RPC destination type
* \author Norman Feske
* \date 2016-03-11
*/
/*
* 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__BASE__INTERNAL__RPC_DESTINATION_H_
#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_
#include <base/output.h>
namespace Genode {
struct Rpc_destination
{
int socket = -1;
explicit Rpc_destination(int socket) : socket(socket) { }
Rpc_destination() { }
};
static inline Rpc_destination invalid_rpc_destination()
{
return Rpc_destination();
}
static void print(Output &out, Rpc_destination const &dst)
{
Genode::print(out, "socket=", dst.socket);
}
}
#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */

View File

@ -0,0 +1,31 @@
/*
* \brief Capability
* \author Norman Feske
* \date 2016-06-16
*/
/*
* 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 <base/log.h>
/* base-internal includes */
#include <base/internal/capability_space_tpl.h>
using namespace Genode;
Native_capability::Raw Native_capability::raw() const
{
/*
* On Linux, we don't pass information as a 'raw' representation to
* child components. So this function remains unused. We still need
* to provide it to prevent link errors of noux, which relies on this
* function for implementing 'fork' (not supported on base-linux).
*/
return { { 0, 0, 0, 0 } };
}

View File

@ -24,6 +24,7 @@
#include <base/internal/native_thread.h>
#include <base/internal/ipc_server.h>
#include <base/internal/server_socket_pair.h>
#include <base/internal/capability_space_tpl.h>
/* Linux includes */
#include <linux_syscalls.h>
@ -33,6 +34,19 @@
using namespace Genode;
namespace {
struct Pid
{
int value;
Pid() : value(lx_getpid()) { }
void print(Output &out) const { Genode::print(out, "[", value, "]"); }
};
}
/*
* The request message layout is:
*
@ -60,12 +74,21 @@ struct Protocol_header
/* badges of the transferred capability arguments */
unsigned long badges[Msgbuf_base::MAX_CAPS_PER_MSG];
enum { INVALID_BADGE = ~0UL };
enum { INVALID_BADGE = ~1UL };
void *msg_start() { return &protocol_word; }
};
/*
* The INVALID_BADGE must be different from the representation of an
* invalid RPC object key because this key value is used by manually
* created NON-RPC-object capabilities (client_sd, server_sd, dataspace fd).
*/
static_assert((int)Protocol_header::INVALID_BADGE != (int)Rpc_obj_key::INVALID,
"ambigious INVALID_BADGE");
/******************************
** File-descriptor registry **
******************************/
@ -242,8 +265,11 @@ static void insert_sds_into_message(Message &msg,
Native_capability const &cap = snd_msgbuf.cap(i);
if (cap.valid()) {
msg.marshal_socket(cap.dst().socket);
header.badges[i] = cap.local_name();
Capability_space::Ipc_cap_data cap_data =
Capability_space::ipc_cap_data(cap);
msg.marshal_socket(cap_data.dst.socket);
header.badges[i] = cap_data.rpc_obj_key.value();
} else {
header.badges[i] = Protocol_header::INVALID_BADGE;
}
@ -277,7 +303,8 @@ static void extract_sds_from_message(unsigned start_index,
int const associated_sd = Genode::ep_sd_registry()->try_associate(sd, id);
buf.insert(Native_capability(Cap_dst_policy::Dst(associated_sd), badge));
buf.insert(Capability_space::import(Rpc_destination(associated_sd),
Rpc_obj_key(badge)));
if ((associated_sd >= 0) && (associated_sd != sd)) {
@ -374,10 +401,13 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
/* marshal capabilities contained in 'snd_msgbuf' */
insert_sds_into_message(snd_msg, snd_header, snd_msgbuf);
int const send_ret = lx_sendmsg(dst.dst().socket, snd_msg.msg(), 0);
int const dst_socket = Capability_space::ipc_cap_data(dst).dst.socket;
int const send_ret = lx_sendmsg(dst_socket, snd_msg.msg(), 0);
if (send_ret < 0) {
PRAW("[%d] lx_sendmsg to sd %d failed with %d in lx_call()",
lx_getpid(), dst.dst().socket, send_ret);
raw(Pid(), " lx_sendmsg to sd ", dst_socket,
" failed with ", send_ret, " in lx_call()");
for (;;);
throw Genode::Ipc_error();
}
@ -414,7 +444,9 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst,
void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc,
Msgbuf_base &snd_msg)
{
try { lx_reply(caller.dst().socket, exc, snd_msg); } catch (Ipc_error) { }
int const reply_socket = Capability_space::ipc_cap_data(caller).dst.socket;
try { lx_reply(reply_socket, exc, snd_msg); } catch (Ipc_error) { }
}
@ -425,7 +457,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller,
{
/* when first called, there was no request yet */
if (last_caller.valid() && exc.value != Rpc_exception_code::INVALID_OBJECT)
lx_reply(last_caller.dst().socket, exc, reply_msg);
lx_reply(Capability_space::ipc_cap_data(last_caller).dst.socket, exc, reply_msg);
/*
* Block infinitely if called from the main thread. This may happen if the
@ -464,15 +496,15 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller,
/* start at offset 1 to skip the reply channel */
extract_sds_from_message(1, msg, header, request_msg);
typedef Native_capability::Dst Dst;
return Rpc_request(Native_capability(Dst(reply_socket), ~0UL), badge);
return Rpc_request(Capability_space::import(Rpc_destination(reply_socket),
Rpc_obj_key()), badge);
}
}
Ipc_server::Ipc_server()
:
Native_capability(Dst(-1), 0)
Native_capability(Capability_space::import(Rpc_destination(), Rpc_obj_key()))
{
/*
* If 'thread' is 0, the constructor was called by the main thread. By
@ -498,7 +530,8 @@ Ipc_server::Ipc_server()
/* override capability initialization */
*static_cast<Native_capability *>(this) =
Native_capability(Native_capability::Dst(socket_pair.client_sd), 0);
Capability_space::import(Rpc_destination(socket_pair.client_sd),
Rpc_obj_key());
}

View File

@ -22,6 +22,7 @@
#include <base/internal/native_thread.h>
#include <base/internal/globals.h>
#include <base/internal/parent_socket_handle.h>
#include <base/internal/capability_space_tpl.h>
using namespace Genode;
@ -32,16 +33,18 @@ using namespace Genode;
size_t Region_map_mmap::_dataspace_size(Dataspace_capability ds)
{
if (ds.valid())
if (local(ds))
return Local_capability<Dataspace>::deref(ds)->size();
return Dataspace_client(ds).size();
return Local_capability<Dataspace>::deref(ds)->size();
}
int Region_map_mmap::_dataspace_fd(Dataspace_capability ds)
{
return Linux_dataspace_client(ds).fd().dst().socket;
Untyped_capability fd_cap = Linux_dataspace_client(ds).fd();
return Capability_space::ipc_cap_data(fd_cap).dst.socket;
}
@ -126,12 +129,13 @@ static unsigned long get_env_ulong(const char *key)
static Parent_capability obtain_parent_cap()
{
long local_name = get_env_ulong("parent_local_name");
long const local_name = get_env_ulong("parent_local_name");
/* produce typed capability manually */
typedef Native_capability::Dst Dst;
Dst const dst(PARENT_SOCKET_HANDLE);
return reinterpret_cap_cast<Parent>(Native_capability(dst, local_name));
Untyped_capability parent_cap =
Capability_space::import(Rpc_destination(PARENT_SOCKET_HANDLE),
Rpc_obj_key(local_name));
return reinterpret_cap_cast<Parent>(parent_cap);
}
@ -178,8 +182,10 @@ namespace Genode {
Thread *thread = Thread::myself();
if (thread) {
socket_pair.server_sd = native_cpu.server_sd(thread->cap()).dst().socket;
socket_pair.client_sd = native_cpu.client_sd(thread->cap()).dst().socket;
Untyped_capability server_cap = native_cpu.server_sd(thread->cap());
Untyped_capability client_cap = native_cpu.client_sd(thread->cap());
socket_pair.server_sd = Capability_space::ipc_cap_data(server_cap).dst.socket;
socket_pair.client_sd = Capability_space::ipc_cap_data(client_cap).dst.socket;
thread->native_thread().socket_pair = socket_pair;
}
return socket_pair;

View File

@ -53,7 +53,7 @@ using namespace Genode;
static bool is_sub_rm_session(Dataspace_capability ds)
{
if (ds.valid())
if (ds.valid() && !local(ds))
return false;
return Local_capability<Dataspace>::deref(ds) != 0;

View File

@ -1,168 +0,0 @@
/*
* \brief Platform-specific capability type
* \author Norman Feske
* \author Alexander Boettcher
* \date 2009-10-02
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__NATIVE_CAPABILITY_H_
/* Genode includes */
#include <base/native_capability_tpl.h>
#include <base/stdint.h>
#include <base/cap_map.h>
/* NOVA includes */
#include <nova/syscalls.h>
namespace Genode {
class Native_capability
{
public:
typedef Nova::Obj_crd Dst;
struct Raw { };
private:
struct _Raw
{
Dst dst;
_Raw() : dst() { }
_Raw(addr_t sel, unsigned rights)
: dst(sel, 0, rights) { }
} _cap;
addr_t _rcv_window;
enum { INVALID_INDEX = ~0UL };
protected:
inline void _inc() const
{
Cap_index idx(cap_map()->find(local_name()));
idx.inc();
}
inline void _dec() const
{
Cap_index idx(cap_map()->find(local_name()));
idx.dec();
}
public:
/**
* Constructors
*/
Native_capability()
: _cap(), _rcv_window(INVALID_INDEX) {}
explicit
Native_capability(addr_t sel, unsigned rights = 0x1f)
{
if (sel == INVALID_INDEX)
_cap = _Raw();
else {
_cap = _Raw(sel, rights);
_inc();
}
_rcv_window = INVALID_INDEX;
}
Native_capability(const Native_capability &o)
: _cap(o._cap), _rcv_window(o._rcv_window)
{ if (valid()) _inc(); }
~Native_capability() { if (valid()) _dec(); }
/**
* Overloaded comparison operator
*/
bool operator==(const Native_capability &o) const {
return local_name() == o.local_name(); }
/**
* Copy constructor
*/
Native_capability& operator=
(const Native_capability &o)
{
if (this == &o)
return *this;
if (valid()) _dec();
_cap = o._cap;
_rcv_window = o._rcv_window;
if (valid()) _inc();
return *this;
}
/**
* Check whether the selector of the Native_cap and
* the capability type is valid.
*/
bool valid() const { return !_cap.dst.is_null(); }
Dst dst() const { return _cap.dst; }
/**
* Return the local_name. On NOVA it is the same as the
* destination value.
*/
addr_t local_name() const
{
if (valid())
return _cap.dst.base();
else
return INVALID_INDEX;
}
/**
* Set one specific cap selector index as receive
* window for the next IPC. This can be used to make
* sure that the to be received mapped capability will
* be placed at a specific index.
*/
void rcv_window(addr_t rcv) { _rcv_window = rcv; }
/**
* Return the selector of the rcv_window.
*/
addr_t rcv_window() const { return _rcv_window; }
/**
* Return an invalid Dst object
*/
static Dst invalid() { return Dst(); }
/**
* Return a invalid Native_capability
*/
static Native_capability invalid_cap()
{
return Native_capability();
}
Raw raw() const { return Raw(); }
};
}
#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */

View File

@ -3,6 +3,9 @@
* \author Alexander Boettcher
* \date 2013-08-26
*
* This header is public to allow user-level VMMs to manually allocate windows
* of consecutive selectors (for virtualization event portals) in the
* component's capability space.
*/
/*
@ -12,8 +15,8 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__CAP_MAP_H_
#define _INCLUDE__BASE__CAP_MAP_H_
#ifndef _INCLUDE__NOVA__CAP_MAP_H_
#define _INCLUDE__NOVA__CAP_MAP_H_
/* Genode includes */
#include <base/stdint.h>
@ -126,4 +129,4 @@ namespace Genode {
Capability_map *cap_map();
}
#endif /* _INCLUDE__BASE__CAP_MAP_H_ */
#endif /* _INCLUDE__NOVA__CAP_MAP_H_ */

View File

@ -0,0 +1,47 @@
/*
* \brief Capability helper
* \author Norman Feske
* \date 2016-06-27
*/
/*
* 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__CAPABILITY_SPACE_H_
#define _INCLUDE__NOVA__CAPABILITY_SPACE_H_
/* Genode includes */
#include <base/capability.h>
/* NOVA includes */
#include <nova/syscalls.h>
namespace Genode { namespace Capability_space {
enum { INVALID_INDEX = ~0UL };
typedef Nova::Crd Ipc_cap_data;
static inline Nova::Crd crd(Native_capability const &cap)
{
/*
* We store the 'Nova::Crd' value in place of the 'Data' pointer.
*/
addr_t value = (addr_t)cap.data();
Nova::Crd crd = *(Nova::Crd *)&value;
return crd;
}
static inline Native_capability import(addr_t sel, unsigned rights = 0x1f)
{
Nova::Obj_crd const crd = (sel == INVALID_INDEX)
? Nova::Obj_crd() : Nova::Obj_crd(sel, 0, rights);
return Native_capability(*(Native_capability::Data *)crd.value());
}
} }
#endif /* _INCLUDE__NOVA__CAPABILITY_SPACE_H_ */

View File

@ -34,7 +34,23 @@ struct Genode::Native_thread
addr_t initial_ip; /* initial IP of local thread */
/* receive window for capability selectors received at the server side */
Receive_window rcv_window;
Receive_window server_rcv_window;
/*
* Designated selector to populate with the result of an IPC call
*
* By default, the client-side receive window for delegated selectors
* is automatically allocated within the component's selector space.
* However, in special cases such as during the initialization of a
* user-level VMM (ports/include/vmm/vcpu_dispatcher.h), the targeted
* selector is defined manually. The 'client_rcv_sel' provides the
* hook for such a manual allocation. If it contains a valid selector
* value, the value is used as the basis of the receive window of an
* 'ipc_call'.
*/
addr_t client_rcv_sel = INVALID_INDEX;
void reset_client_rcv_sel() { client_rcv_sel = INVALID_INDEX; }
Native_capability pager_cap;

View File

@ -126,24 +126,12 @@ struct Genode::Receive_window
/**
* Return received portal-capability selector
*/
void rcv_pt_sel(Native_capability &cap)
{
if (_rcv_pt_sel_cnt >= _rcv_pt_sel_max) {
cap = Native_capability();
return;
}
/* return only received or translated caps */
cap = Native_capability(_rcv_pt_sel[_rcv_pt_sel_cnt++].sel);
}
void rcv_pt_sel(Native_capability &cap);
/**
* Return true if receive window must be re-initialized
*/
bool rcv_invalid() const
{
return _rcv_pt_base == INVALID_INDEX;
}
bool rcv_invalid() const;
unsigned num_received_caps() const { return _rcv_pt_sel_max; }
@ -167,56 +155,7 @@ struct Genode::Receive_window
* \result 'true' - receive window must be re-initialized
* 'false' - portal selectors has been kept
*/
bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS)
{
/* mark used mapped capabilities as used to prevent freeing */
bool reinit = false;
for (unsigned i = 0; i < _rcv_pt_sel_cnt; i++) {
if (!_rcv_pt_sel[i].del)
continue;
/* should never happen */
if (_rcv_pt_sel[i].sel < _rcv_pt_base ||
(_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS))
nova_die();
_rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP;
reinit = true;
}
/* if old receive window was smaller, we need to re-init */
for (unsigned i = 0; !reinit && i < new_max; i++)
if (_rcv_pt_cap_free[i] == FREE_INVALID)
reinit = true;
_rcv_pt_sel_cnt = 0;
_rcv_pt_sel_max = 0;
/* we can keep the cap selectors if none was used */
if (keep && !reinit) {
for (unsigned i = 0; i < MAX_CAP_ARGS; i++) {
/* revoke received caps which are unused */
if (_rcv_pt_cap_free[i] == UNUSED_CAP)
Nova::revoke(Nova::Obj_crd(_rcv_pt_base + i, 0), true);
/* free rest of indexes if new_max is smaller then last window */
if (i >= new_max && _rcv_pt_cap_free[i] == FREE_SEL)
cap_map()->remove(_rcv_pt_base + i, 0, false);
}
return false;
}
/* decrease ref count if valid selector */
for (unsigned i = 0; i < MAX_CAP_ARGS; i++) {
if (_rcv_pt_cap_free[i] == FREE_INVALID)
continue;
cap_map()->remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL);
}
return true;
}
bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS);
/**
* Initialize receive window for portal capability
@ -234,39 +173,7 @@ struct Genode::Receive_window
* fresh receive window and clears 'rcv_invalid'.
*/
bool prepare_rcv_window(Nova::Utcb &utcb,
addr_t rcv_window = INVALID_INDEX)
{
/* open maximal translate window */
utcb.crd_xlt = Nova::Obj_crd(0, ~0UL);
/* use receive window if specified */
if (rcv_window != INVALID_INDEX) {
/* cleanup if receive window already used */
if (!rcv_invalid()) rcv_cleanup(false);
_rcv_pt_base = rcv_window;
/* open receive window */
utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2);
return true;
}
/* allocate receive window if necessary, otherwise use old one */
if (rcv_invalid() || rcv_cleanup(true, 1U << _rcv_wnd_log2))
{
_rcv_pt_base = cap_map()->insert(_rcv_wnd_log2);
if (_rcv_pt_base == INVALID_INDEX) {
/* no mappings can be received */
utcb.crd_rcv = Nova::Obj_crd();
return false;
}
}
/* open receive window */
utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2);
return true;
}
addr_t rcv_window = INVALID_INDEX);
/**
* Post IPC processing.

View File

@ -31,6 +31,7 @@
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
#include <nova/capability_space.h>
namespace Genode {
@ -53,9 +54,9 @@ namespace Genode {
{
/* request mapping of semaphore capability selector */
Thread * myself = Thread::myself();
request_signal_sm_cap(Native_capability(myself->native_thread().ec_sel + 1),
request_signal_sm_cap(Capability_space::import(myself->native_thread().ec_sel + 1),
myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
_sem = Native_capability(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
_sem = Capability_space::import(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
call<Rpc_register_semaphore>(_sem);
}

View File

@ -12,3 +12,4 @@ SRC_CC += signal_submit.cc
SRC_CC += thread.cc thread_myself.cc
SRC_CC += stack.cc
SRC_CC += cap_map.cc
SRC_CC += capability.cc

View File

@ -0,0 +1,6 @@
SRC_CC += pager.cc
INC_DIR = $(REP_DIR)/src/core/include \
$(BASE_DIR)/src/core/include \
$(REP_DIR)/src/include \
$(BASE_DIR)/src/include

View File

@ -1,7 +1,3 @@
SRC_CC += pager.cc
INC_DIR = $(REP_DIR)/src/core/include \
$(BASE_DIR)/src/core/include \
$(BASE_DIR)/src/include
include $(REP_DIR)/lib/mk/core.inc
vpath %.cc $(REP_DIR)/src/core/spec/x86_32

View File

@ -1,6 +1,3 @@
SRC_CC += pager.cc
INC_DIR = $(REP_DIR)/src/core/include \
$(BASE_DIR)/src/include
include $(REP_DIR)/lib/mk/core.inc
vpath %.cc $(REP_DIR)/src/core/spec/x86_64

View File

@ -14,6 +14,9 @@
#ifndef _CORE__INCLUDE__IMPRINT_BADGE_H_
#define _CORE__INCLUDE__IMPRINT_BADGE_H_
/* NOVA includes */
#include <nova/syscalls.h>
static inline bool imprint_badge(unsigned long pt_sel, unsigned long badge)
{
using namespace Nova;

View File

@ -21,6 +21,9 @@
#include <cap_session/cap_session.h>
#include <pager/capability.h>
/* NOVA includes */
#include <nova/cap_map.h>
/* core-local includes */
#include <ipc_pager.h>
#include <rpc_cap_factory.h>

View File

@ -17,6 +17,9 @@
/* Genode includes */
#include <base/tslab.h>
/* NOVA includes */
#include <nova/capability_space.h>
/* core-local includes */
#include <signal_source_component.h>
#include <signal_source/capability.h>
@ -85,7 +88,7 @@ class Genode::Signal_broker
return Signal_context_capability();
}
Native_capability si(cap_map()->insert());
Native_capability si = Capability_space::import(cap_map()->insert());
Signal_context_capability cap = reinterpret_cap_cast<Signal_context>(si);
uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint,

View File

@ -29,6 +29,7 @@
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova_util.h> /* map_local */
#include <nova/capability_space.h>
static bool verbose_oom = false;
@ -126,7 +127,8 @@ void Pager_object::_page_fault_handler(addr_t pager_obj)
ret);
Native_capability pager_cap = obj->Object_pool<Pager_object>::Entry::cap();
revoke(pager_cap.dst());
revoke(Capability_space::crd(pager_cap).base());
revoke(Obj_crd(obj->exc_pt_sel_client(), NUM_INITIAL_PT_LOG2));
@ -917,7 +919,8 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
PWRN("invalid CPU parameter used in pager object");
return Pager_capability();
}
Native_capability pager_thread_cap(pager_threads[use_cpu]->native_thread().ec_sel);
Native_capability pager_thread_cap =
Capability_space::import(pager_threads[use_cpu]->native_thread().ec_sel);
/* request creation of portal bind to pager thread */
Native_capability cap_session =
@ -946,7 +949,7 @@ void Pager_entrypoint::dissolve(Pager_object *obj)
_cap_factory.free(pager_obj);
/* revoke cap selector locally */
revoke(pager_obj.dst(), true);
revoke(Capability_space::crd(pager_obj), true);
/* remove object from pool */
remove(obj);

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