Fiasco.OC: keep reference to capabilities in use.

Due to recently introduces smart-pointers to Cap_index objects it's
necessary to always keep at least one reference as long as a corresponding
slot in the capability-space of a process is in use. This is especially
important for L4Linux that uses cap-slots directly without the given
abstractions of Genode.
This commit is contained in:
Stefan Kalkowski 2012-05-03 12:09:23 +02:00 committed by Norman Feske
parent a4282e2033
commit ac1ff2f5f8
7 changed files with 36 additions and 23 deletions

View File

@ -66,6 +66,12 @@ Genode::Native_capability Genode::Cpu_session_component::alloc_irq()
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, i->kcap());
if (l4_error(res))
PWRN("Allocation of irq object failed!");
/*
* Increment reference-counter, because we don't hold any
* reference to IRQ object by now
*/
i->inc();
return Genode::Native_capability(i);
}

View File

@ -96,7 +96,7 @@ namespace {
Genode::size_t _blk_size;
Genode::size_t _blk_cnt;
Block::Session::Operations _blk_ops;
Fiasco::l4_cap_idx_t _irq_cap;
Genode::Native_capability _irq_cap;
Genode::Signal_context _tx;
char _name[32];
@ -105,21 +105,21 @@ namespace {
Block_device(const char *label)
: _alloc(Genode::env()->heap()),
_session(&_alloc, TX_BUF_SIZE, label),
_irq_cap(L4lx::vcpu_connection()->alloc_irq().dst())
_irq_cap(L4lx::vcpu_connection()->alloc_irq())
{
_session.info(&_blk_cnt, &_blk_size, &_blk_ops);
Genode::strncpy(_name, label, sizeof(_name));
}
Req_cache *cache() { return &_cache; }
Block::Connection *session() { return &_session; }
Fiasco::l4_cap_idx_t irq_cap() { return _irq_cap; }
Genode::Signal_context *context() { return &_tx; }
Genode::size_t block_size() { return _blk_size; }
Genode::size_t block_count() { return _blk_cnt; }
Req_cache *cache() { return &_cache; }
Block::Connection *session() { return &_session; }
Fiasco::l4_cap_idx_t irq_cap() { return _irq_cap.dst(); }
Genode::Signal_context *context() { return &_tx; }
Genode::size_t block_size() { return _blk_size; }
Genode::size_t block_count() { return _blk_cnt; }
bool writeable() {
return _blk_ops.supported(Block::Packet_descriptor::WRITE); }
const char *name() { return _name; }
const char *name() { return _name; }
};

View File

@ -153,9 +153,9 @@ extern "C" {
l4_cap_idx_t genode_net_irq_cap()
{
static l4_cap_idx_t cap = L4lx::vcpu_connection()->alloc_irq().dst();
static Signal_thread th(cap);
return cap;
static Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq();
static Signal_thread th(cap.dst());
return cap.dst();
}

View File

@ -95,10 +95,10 @@ extern "C" {
l4_cap_idx_t genode_terminal_irq(unsigned idx) {
static l4_cap_idx_t cap = L4lx::vcpu_connection()->alloc_irq().dst();
static Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq();
if (!signal_thread)
signal_thread = new (Genode::env()->heap()) Signal_thread(cap);
return cap;
signal_thread = new (Genode::env()->heap()) Signal_thread(cap.dst());
return cap.dst();
}

View File

@ -88,10 +88,16 @@ namespace L4lx {
_tid = state.kcap;
_context->utcb = state.utcb;
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
l4_utcb_tcr_u(state.utcb)->user[0] = state.kcap; /* L4X_UTCB_TCR_ID */
cap_map()->insert(state.id, state.kcap);
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);
}
/* register initial IP and SP at core */
addr_t stack = (addr_t)&_context->stack[-4];

View File

@ -71,8 +71,8 @@ static unsigned int startup_timer(struct l4x_irq_desc_private *p)
Genode::snprintf(name, sizeof(name), "timer.i%d", TIMER_IRQ);
Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq();
p->irq_cap = cap.dst();
static Genode::Native_capability timer_cap = L4lx::vcpu_connection()->alloc_irq();
p->irq_cap = timer_cap.dst();
p->cpu = 0;
l4lx_thread_create(timer_irq_thread, cpu, 0, 0, 0, 0, 0, name);

View File

@ -103,7 +103,8 @@ static void prepare_l4re_env()
using namespace Fiasco;
Genode::Foc_cpu_connection cpu;
static Genode::Native_capability main_thread_cap
= cpu.native_cap(Genode::env()->cpu_session()->first());
l4re_env_t *env = l4re_env();
env->first_free_utcb = (l4_addr_t)l4_utcb() + L4_UTCB_OFFSET;
env->utcb_area = l4_fpage((l4_addr_t)l4_utcb(),
@ -113,7 +114,7 @@ static void prepare_l4re_env()
env->scheduler = L4_BASE_SCHEDULER_CAP;
env->mem_alloc = L4_INVALID_CAP;
env->log = L4_INVALID_CAP;
env->main_thread = cpu.native_cap(Genode::env()->cpu_session()->first()).dst();
env->main_thread = main_thread_cap.dst();
env->rm = Fiasco::THREADS_BASE_CAP + Fiasco::THREAD_PAGER_CAP;
}