mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 11:55:24 +00:00
Fiasco.OC: several capability ref-counter fixes.
This commit fixes several issues that were triggered e.g. by the 'noux_tool_chain' run-script (fix #208 in part). The following problems are tackled: * Don't reference count capability selectors within a task that are actually controlled by core (all beneath 0x200000), because it's undecideable which "version" of a capability selector we currently use, e.g. a thread gets destroyed and a new one gets created immediately some other thread might have a Native_capability pointing to the already destroyed thread's gate capability-slot, that is now a new valid one (the one of the new thread) * In core we cannot invalidate and remove a capability from the so called Cap_map before each reference to it is destroyed, so don't do this in Cap_session_component::free, but only reference-decrement within there, the actual removal can only be done in Cap_map::remove. Because core also has to invalidate a capability to be removed in all protection-domains we have to implement a core specific Cap_map::remove method * When a capability gets inserted into the Cap_map, and we detect an old invalid entry with the dame id in the tree, don't just overmap that invalid entry (as there exist remaining references to it), but just remove it from the tree and allocate an new entry. * Use the Cap_session_component interface to free a Pager_object when it gets dissolved, as its also used for allocation
This commit is contained in:
parent
b71c1649d6
commit
a5ea6765d1
@ -58,7 +58,7 @@ namespace Genode {
|
||||
** Cap_index_allocator interface **
|
||||
***********************************/
|
||||
|
||||
Cap_index* alloc(size_t cnt)
|
||||
Cap_index* alloc_range(size_t cnt)
|
||||
{
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Genode {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Cap_index* alloc(addr_t addr, size_t cnt)
|
||||
Cap_index* alloc(addr_t addr)
|
||||
{
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
@ -89,17 +89,11 @@ namespace Genode {
|
||||
* address in capability space
|
||||
*/
|
||||
T* obj = reinterpret_cast<T*>(kcap_to_idx(addr));
|
||||
T* ret = obj;
|
||||
|
||||
/* check whether the consecutive entries are in range and unused */
|
||||
for (size_t i = 0; i < cnt; i++, obj++) {
|
||||
if (obj < &_indices[0] || obj >= &_indices[SZ])
|
||||
throw Index_out_of_bounds();
|
||||
if (obj->used())
|
||||
throw Region_conflict();
|
||||
new (obj) T();
|
||||
}
|
||||
return ret;
|
||||
if (obj < &_indices[0] || obj >= &_indices[SZ])
|
||||
throw Index_out_of_bounds();
|
||||
|
||||
return new (obj) T();
|
||||
}
|
||||
|
||||
void free(Cap_index* idx, size_t cnt)
|
||||
@ -121,6 +115,9 @@ namespace Genode {
|
||||
|
||||
Cap_index* kcap_to_idx(addr_t kcap) {
|
||||
return &_indices[kcap >> Fiasco::L4_CAP_SHIFT]; }
|
||||
|
||||
bool static_idx(Cap_index *idx) {
|
||||
return ((T*)idx) < &_indices[START_IDX]; }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -103,20 +103,17 @@ namespace Genode
|
||||
* \return pointer to first allocated object, or zero if
|
||||
* out of entries
|
||||
*/
|
||||
virtual Cap_index* alloc(size_t cnt) = 0;
|
||||
virtual Cap_index* alloc_range(size_t cnt) = 0;
|
||||
|
||||
/**
|
||||
* Allocate a range of Cap_index objects at a specific
|
||||
* Allocate a Cap_index object at a specific
|
||||
* point in the capability space
|
||||
*
|
||||
* \param kcap address in capability space
|
||||
* \param cnt number of objects to allocate
|
||||
* \throw Index_out_of_bounds if address is out of scope
|
||||
* \throw Region_conflict if capability space entry is used
|
||||
* \return pointer to first allocated object,
|
||||
* or zero if out of entries
|
||||
* \return pointer to allocated object
|
||||
*/
|
||||
virtual Cap_index* alloc(addr_t kcap, size_t cnt) = 0;
|
||||
virtual Cap_index* alloc(addr_t kcap) = 0;
|
||||
|
||||
/**
|
||||
* Free a range of Cap_index objects
|
||||
@ -141,6 +138,14 @@ namespace Genode
|
||||
* \param kcap the address in the capability space
|
||||
*/
|
||||
virtual Cap_index* kcap_to_idx(addr_t kcap) = 0;
|
||||
|
||||
/**
|
||||
* Returns whether a Cap_index object is from the region
|
||||
* controlled by core, or not.
|
||||
*
|
||||
* \param idx pointer to the Cap_index object in question
|
||||
*/
|
||||
virtual bool static_idx(Cap_index *idx) = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -226,9 +231,7 @@ namespace Genode
|
||||
* Create and insert a new Cap_index with a specific capability id,
|
||||
* and location in capability space
|
||||
*
|
||||
* Allocation of the Cap_index is done via the global
|
||||
* Cap_index_allocator, which might throw exceptions that aren't
|
||||
* caught by this method
|
||||
* A previously existent entry with the same id gets removed!
|
||||
*
|
||||
* \param id the global capability id
|
||||
* \param kcap address in capability space
|
||||
@ -239,7 +242,10 @@ namespace Genode
|
||||
|
||||
/**
|
||||
* Create and insert a new Cap_index with a specific capability id
|
||||
* and map from given kcap to newly allocated one
|
||||
* and map from given kcap to newly allocated one,
|
||||
* if the an entry with the same id exists already,
|
||||
* it is returned if it points to the same kernel-object,
|
||||
* or gets overridden if it's already invalid.
|
||||
*
|
||||
* Allocation of the Cap_index is done via the global
|
||||
* Cap_index_allocator, which might throw exceptions that aren't
|
||||
@ -247,12 +253,14 @@ namespace Genode
|
||||
*
|
||||
* \param id the global capability id
|
||||
* \return pointer to the new Cap_index object, or zero
|
||||
* when allocation failed
|
||||
* when allocation failed, or when a valid entry
|
||||
* with the same id exists and it's kernel-object
|
||||
* differs to the one given by kcap
|
||||
*/
|
||||
Cap_index* insert_map(int id, addr_t kcap);
|
||||
|
||||
/**
|
||||
* Remove a Cap_index object
|
||||
* Remove (resp. invalidate) a Cap_index object
|
||||
*
|
||||
* \param i pointer to Cap_index object to remove
|
||||
*/
|
||||
|
@ -68,7 +68,7 @@ namespace Genode {
|
||||
* Constructor
|
||||
*/
|
||||
Msgbuf_base()
|
||||
: _rcv_idx_base(cap_idx_alloc()->alloc(MAX_CAP_ARGS)), _label(0)
|
||||
: _rcv_idx_base(cap_idx_alloc()->alloc_range(MAX_CAP_ARGS)), _label(0)
|
||||
{
|
||||
rcv_reset();
|
||||
snd_reset();
|
||||
|
@ -1,11 +1,12 @@
|
||||
SRC_CC = env.cc context_area.cc cap_map.cc cap_alloc.cc \
|
||||
reload_parent_cap.cc spin_lock.cc
|
||||
reload_parent_cap.cc spin_lock.cc cap_map_remove.cc
|
||||
LIBS = ipc heap log_console lock
|
||||
INC_DIR += $(REP_DIR)/src/base/lock $(BASE_DIR)/src/base/lock
|
||||
|
||||
vpath env.cc $(BASE_DIR)/src/base/env
|
||||
vpath context_area.cc $(BASE_DIR)/src/base/env
|
||||
vpath cap_map.cc $(REP_DIR)/src/base/env
|
||||
vpath cap_map_remove.cc $(REP_DIR)/src/base/env
|
||||
vpath cap_alloc.cc $(REP_DIR)/src/base/env
|
||||
vpath spin_lock.cc $(REP_DIR)/src/base/env
|
||||
vpath reload_parent_cap.cc $(BASE_DIR)/src/base/env
|
||||
|
66
base-foc/src/base/env/cap_map.cc
vendored
66
base-foc/src/base/env/cap_map.cc
vendored
@ -54,6 +54,10 @@ Genode::addr_t Genode::Cap_index::kcap() {
|
||||
|
||||
Genode::uint8_t Genode::Cap_index::inc()
|
||||
{
|
||||
/* con't ref-count index that are controlled by core */
|
||||
if (cap_idx_alloc()->static_idx(this))
|
||||
return 1;
|
||||
|
||||
spinlock_lock(&_cap_index_spinlock);
|
||||
Genode::uint8_t ret = ++_ref_cnt;
|
||||
spinlock_unlock(&_cap_index_spinlock);
|
||||
@ -63,6 +67,10 @@ Genode::uint8_t Genode::Cap_index::inc()
|
||||
|
||||
Genode::uint8_t Genode::Cap_index::dec()
|
||||
{
|
||||
/* con't ref-count index that are controlled by core */
|
||||
if (cap_idx_alloc()->static_idx(this))
|
||||
return 1;
|
||||
|
||||
spinlock_lock(&_cap_index_spinlock);
|
||||
Genode::uint8_t ret = --_ref_cnt;
|
||||
spinlock_unlock(&_cap_index_spinlock);
|
||||
@ -76,14 +84,9 @@ Genode::uint8_t Genode::Cap_index::dec()
|
||||
|
||||
Genode::Cap_index* Genode::Capability_map::find(int id)
|
||||
{
|
||||
using namespace Genode;
|
||||
Genode::Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
Cap_index* i = 0;
|
||||
if (_tree.first())
|
||||
i = _tree.first()->find_by_id(id);
|
||||
return i;
|
||||
return _tree.first() ? _tree.first()->find_by_id(id) : 0;
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +99,7 @@ Genode::Cap_index* Genode::Capability_map::insert(int id)
|
||||
ASSERT(!_tree.first() || !_tree.first()->find_by_id(id),
|
||||
"Double insertion in cap_map()!");
|
||||
|
||||
Cap_index *i = cap_idx_alloc()->alloc(1);
|
||||
Cap_index *i = cap_idx_alloc()->alloc_range(1);
|
||||
if (i) {
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
@ -111,10 +114,12 @@ Genode::Cap_index* Genode::Capability_map::insert(int id, addr_t kcap)
|
||||
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
ASSERT(!_tree.first() || !_tree.first()->find_by_id(id),
|
||||
"Double insertion in cap_map()!");
|
||||
/* remove potentially existent entry */
|
||||
Cap_index *i = _tree.first() ? _tree.first()->find_by_id(id) : 0;
|
||||
if (i)
|
||||
_tree.remove(i);
|
||||
|
||||
Cap_index *i = cap_idx_alloc()->alloc(kcap, 1);
|
||||
i = cap_idx_alloc()->alloc(kcap);
|
||||
if (i) {
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
@ -130,11 +135,8 @@ Genode::Cap_index* Genode::Capability_map::insert_map(int id, addr_t kcap)
|
||||
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
Cap_index* i = 0;
|
||||
|
||||
/* check whether capability id exists */
|
||||
if (_tree.first())
|
||||
i = _tree.first()->find_by_id(id);
|
||||
Cap_index *i = _tree.first() ? _tree.first()->find_by_id(id) : 0;
|
||||
|
||||
/* if we own the capability already check whether it's the same */
|
||||
if (i) {
|
||||
@ -147,18 +149,23 @@ Genode::Cap_index* Genode::Capability_map::insert_map(int id, addr_t kcap)
|
||||
tag = l4_task_cap_valid(L4_BASE_TASK_CAP, i->kcap());
|
||||
if (l4_msgtag_label(tag))
|
||||
return 0;
|
||||
else
|
||||
/* it's invalid so remove it from the tree */
|
||||
_tree.remove(i);
|
||||
} else
|
||||
/* they are equal so just return the one in the map */
|
||||
return i;
|
||||
} else {
|
||||
/* the capability doesn't exists in the map so allocate a new one */
|
||||
i = cap_idx_alloc()->alloc(1);
|
||||
if (!i)
|
||||
return 0;
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
}
|
||||
|
||||
/* the capability doesn't exists in the map so allocate a new one */
|
||||
i = cap_idx_alloc()->alloc_range(1);
|
||||
if (!i)
|
||||
return 0;
|
||||
|
||||
/* set it's id and insert it into the tree */
|
||||
i->id(id);
|
||||
_tree.insert(i);
|
||||
|
||||
/* map the given cap to our registry entry */
|
||||
l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP,
|
||||
l4_obj_fpage(kcap, 0, L4_FPAGE_RWX),
|
||||
@ -167,21 +174,6 @@ Genode::Cap_index* Genode::Capability_map::insert_map(int id, addr_t kcap)
|
||||
}
|
||||
|
||||
|
||||
void Genode::Capability_map::remove(Genode::Cap_index* i)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
if (i) {
|
||||
Cap_index* e = _tree.first() ? _tree.first()->find_by_id(i->id()) : 0;
|
||||
if (e == i)
|
||||
_tree.remove(i);
|
||||
cap_idx_alloc()->free(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Genode::Capability_map* Genode::cap_map()
|
||||
{
|
||||
static Genode::Capability_map map;
|
||||
|
30
base-foc/src/base/env/cap_map_remove.cc
vendored
Normal file
30
base-foc/src/base/env/cap_map_remove.cc
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Mapping of Genode's capability names to kernel capabilities.
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2010-12-06
|
||||
*
|
||||
* This is a Fiasco.OC-specific addition to the process enviroment.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2012 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/cap_map.h>
|
||||
|
||||
void Genode::Capability_map::remove(Genode::Cap_index* i)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
if (i) {
|
||||
Cap_index* e = _tree.first() ? _tree.first()->find_by_id(i->id()) : 0;
|
||||
if (e == i)
|
||||
_tree.remove(i);
|
||||
cap_idx_alloc()->free(i, 1);
|
||||
}
|
||||
}
|
@ -192,7 +192,7 @@ void Ipc_istream::_wait()
|
||||
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
|
||||
:
|
||||
Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()),
|
||||
Native_capability(cap_map()->find(Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE])),
|
||||
Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]),
|
||||
_rcv_msg(rcv_msg)
|
||||
{
|
||||
_read_offset = sizeof(l4_mword_t);
|
||||
|
@ -113,5 +113,6 @@ void Ipc_pager::acknowledge_wakeup()
|
||||
|
||||
|
||||
Ipc_pager::Ipc_pager()
|
||||
: Native_capability(cap_map()->find(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) { }
|
||||
|
||||
|
@ -160,7 +160,13 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session,
|
||||
}
|
||||
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj) { remove(obj); }
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
{
|
||||
/* cleanup at cap session */
|
||||
_cap_session->free(obj->Object_pool<Pager_object>::Entry::cap());
|
||||
|
||||
remove(obj);
|
||||
}
|
||||
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object *obj)
|
||||
|
@ -29,9 +29,9 @@ void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
int id = l4_utcb_tcr_u(_context->utcb)->user[UTCB_TCR_BADGE];
|
||||
Cap_index *i = (Cap_index*)l4_utcb_tcr_u(_context->utcb)->user[UTCB_TCR_BADGE];
|
||||
cap_map()->remove(i);
|
||||
env()->cpu_session()->kill_thread(_thread_cap);
|
||||
cap_map()->remove(cap_map()->find(id));
|
||||
}
|
||||
|
||||
|
||||
@ -57,18 +57,9 @@ void Thread_base::start()
|
||||
_tid = state.kcap;
|
||||
_context->utcb = state.utcb;
|
||||
|
||||
try {
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
|
||||
/* there might be leaks in the application */
|
||||
cap_map()->remove(cap_map()->find(state.id));
|
||||
|
||||
/* we need to manually increase the reference counter here */
|
||||
cap_map()->insert(state.id, state.kcap)->inc();
|
||||
} catch(Cap_index_allocator::Region_conflict) {
|
||||
PERR("could not insert id %x", state.id);
|
||||
}
|
||||
Cap_index *i = cap_map()->insert(state.id, state.kcap);
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
|
||||
/* register initial IP and SP at core */
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
|
@ -71,21 +71,6 @@ void Cap_mapping::map(Native_thread_id task)
|
||||
}
|
||||
|
||||
|
||||
void Cap_mapping::unmap()
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
if (!local)
|
||||
return;
|
||||
|
||||
l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
|
||||
l4_obj_fpage(local->kcap(), 0, L4_FPAGE_RWX),
|
||||
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
|
||||
if (l4_msgtag_has_error(tag))
|
||||
PERR("unmapping cap failed");
|
||||
}
|
||||
|
||||
|
||||
Cap_mapping::Cap_mapping(bool alloc, Native_thread_id r)
|
||||
: local(alloc ? _get_cap() : 0), remote(r)
|
||||
{
|
||||
@ -105,7 +90,6 @@ Cap_mapping::Cap_mapping(Core_cap_index* i, Native_thread_id r)
|
||||
Cap_mapping::~Cap_mapping()
|
||||
{
|
||||
if (local) {
|
||||
unmap();
|
||||
cap_map()->remove(local);
|
||||
}
|
||||
}
|
||||
@ -164,6 +148,7 @@ Native_capability Cap_session_component::alloc(Cap_session_component *session,
|
||||
} catch (Cap_id_allocator::Out_of_ids) {
|
||||
PERR("Out of IDs");
|
||||
}
|
||||
|
||||
return cap;
|
||||
}
|
||||
|
||||
@ -189,15 +174,7 @@ void Cap_session_component::free(Native_capability cap)
|
||||
if (idx->session() != this)
|
||||
return;
|
||||
|
||||
l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
|
||||
l4_obj_fpage(idx->kcap(), 0, L4_FPAGE_RWX),
|
||||
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
|
||||
if (l4_msgtag_has_error(tag))
|
||||
PERR("destruction of ipc-gate %lx failed!", (unsigned long) idx->kcap());
|
||||
|
||||
unsigned long id = idx->id();
|
||||
cap_map()->remove(idx);
|
||||
platform_specific()->cap_id_alloc()->free(id);
|
||||
idx->dec();
|
||||
}
|
||||
|
||||
|
||||
@ -232,6 +209,32 @@ void Cap_id_allocator::free(unsigned long id)
|
||||
}
|
||||
|
||||
|
||||
void Genode::Capability_map::remove(Genode::Cap_index* i)
|
||||
{
|
||||
using namespace Genode;
|
||||
using namespace Fiasco;
|
||||
|
||||
Lock_guard<Spin_lock> guard(_lock);
|
||||
|
||||
if (i) {
|
||||
Core_cap_index* e = static_cast<Core_cap_index*>(_tree.first() ? _tree.first()->find_by_id(i->id()) : 0);
|
||||
if (e == i) {
|
||||
|
||||
l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
|
||||
l4_obj_fpage(i->kcap(), 0, L4_FPAGE_RWX),
|
||||
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
|
||||
if (l4_msgtag_has_error(tag))
|
||||
PERR("destruction of ipc-gate %lx failed!", (unsigned long) i->kcap());
|
||||
|
||||
|
||||
platform_specific()->cap_id_alloc()->free(i->id());
|
||||
_tree.remove(i);
|
||||
}
|
||||
cap_idx_alloc()->free(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Genode::Cap_index_allocator* cap_idx_alloc()
|
||||
{
|
||||
static Genode::Cap_index_allocator_tpl<Core_cap_index, 20*1024> _alloc;
|
||||
|
@ -55,11 +55,6 @@ namespace Genode {
|
||||
* \param task capability of task to map to
|
||||
*/
|
||||
void map(Native_task task);
|
||||
|
||||
/**
|
||||
* Unmap all child mappings
|
||||
*/
|
||||
void unmap();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ void Thread_base::start()
|
||||
pt->pager(platform_specific()->core_pager());
|
||||
|
||||
_context->utcb = pt->utcb();
|
||||
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_BADGE] = pt->gate().local->id();
|
||||
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local;
|
||||
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
|
||||
pt->start((void *)_thread_start, _context->stack);
|
||||
|
@ -28,19 +28,10 @@ enum { MAIN_THREAD_CAP_ID = 1 };
|
||||
static void main_thread_bootstrap() {
|
||||
using namespace Genode;
|
||||
|
||||
/**
|
||||
* Unfortunately ldso calls this function twice. So the second time when
|
||||
* inserting the main thread's gate-capability an exception would be raised.
|
||||
* At least on ARM we got problems when raising an exception that early,
|
||||
* that's why we first check if the cap is already registered before
|
||||
* inserting it.
|
||||
*/
|
||||
Cap_index *idx = cap_map()->find(MAIN_THREAD_CAP_ID);
|
||||
if (!idx) {
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = MAIN_THREAD_CAP_ID;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
|
||||
cap_map()->insert(MAIN_THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP)->inc();
|
||||
}
|
||||
Cap_index *i
|
||||
= cap_map()->insert(MAIN_THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP);
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = (unsigned long) i;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ int main(int argc, char **argv)
|
||||
|
||||
enum { COUNT = 1000 };
|
||||
|
||||
Cap_index* idx = cap_idx_alloc()->alloc(COUNT);
|
||||
Cap_index* idx = cap_idx_alloc()->alloc_range(COUNT);
|
||||
Native_thread_id tid = env()->ram_session_cap().dst();
|
||||
|
||||
/* try the first 1000 local name IDs */
|
||||
|
@ -50,7 +50,7 @@ namespace L4lx {
|
||||
Genode::size_t size,
|
||||
Genode::Dataspace_capability ds)
|
||||
: _name(name), _size(size), _cap(ds),
|
||||
_ref(Genode::cap_idx_alloc()->alloc(1)->kcap()) {}
|
||||
_ref(Genode::cap_idx_alloc()->alloc_range(1)->kcap()) {}
|
||||
|
||||
|
||||
/***************
|
||||
|
@ -88,16 +88,10 @@ namespace L4lx {
|
||||
_tid = state.kcap;
|
||||
_context->utcb = state.utcb;
|
||||
|
||||
try {
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
l4_utcb_tcr_u(state.utcb)->user[0] = state.kcap; /* L4X_UTCB_TCR_ID */
|
||||
|
||||
/* we need to manually increase the reference counter here */
|
||||
cap_map()->insert(state.id, state.kcap)->inc();
|
||||
} catch(Cap_index_allocator::Region_conflict) {
|
||||
PERR("could not insert id %x", state.id);
|
||||
}
|
||||
Cap_index *i = cap_map()->insert(state.id, state.kcap);
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;
|
||||
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
|
||||
l4_utcb_tcr_u(state.utcb)->user[0] = state.kcap; /* L4X_UTCB_TCR_ID */
|
||||
|
||||
/* register initial IP and SP at core */
|
||||
addr_t stack = (addr_t)&_context->stack[-4];
|
||||
|
@ -28,7 +28,7 @@ extern "C" {
|
||||
|
||||
l4_cap_idx_t l4re_util_cap_alloc(void)
|
||||
{
|
||||
l4_cap_idx_t ret = Genode::cap_idx_alloc()->alloc(1)->kcap();
|
||||
l4_cap_idx_t ret = Genode::cap_idx_alloc()->alloc_range(1)->kcap();
|
||||
|
||||
if (DEBUG)
|
||||
PDBG("ret=%lx", ret);
|
||||
|
@ -85,7 +85,7 @@ int l4lx_task_number_free(l4_cap_idx_t task)
|
||||
int l4lx_task_get_new_task(l4_cap_idx_t parent_id,
|
||||
l4_cap_idx_t *id)
|
||||
{
|
||||
*id = Genode::cap_idx_alloc()->alloc(1)->kcap();
|
||||
*id = Genode::cap_idx_alloc()->alloc_range(1)->kcap();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user