nova: remove cap_sel - use cap_map

Fixes #905
This commit is contained in:
Alexander Boettcher 2013-09-11 10:45:23 +02:00 committed by Norman Feske
parent c139253439
commit 0d8abab3ee
17 changed files with 55 additions and 167 deletions

View File

@ -1,68 +0,0 @@
/*
* \brief Interface for process-local capability-selector allocation
* \author Norman Feske
* \date 2010-01-19
*
* This interface is NOVA-specific and not part of the Genode API. It should
* only be used internally by the framework or by NOVA-specific code. The
* implementation of the interface is part of the environment library.
*/
/*
* Copyright (C) 2010-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__CAP_SEL_ALLOC_H_
#define _INCLUDE__BASE__CAP_SEL_ALLOC_H_
#include <base/stdint.h>
#include <base/printf.h>
#include <base/bit_allocator.h>
namespace Genode {
class Cap_selector_allocator : public Bit_allocator<2 * 4096>
{
public:
/**
* Constructor
*/
Cap_selector_allocator();
/**
* Allocate range of capability selectors
*
* \param num_caps_log2 number of capability selectors specified as
* as the power of two. By default, the function
* returns a single capability selector.
* \return first capability selector of allocated range,
* or 0 if allocation failed
*
* The allocated range will be naturally aligned according to the
* specified 'num_cap_log2' value.
*/
addr_t alloc(size_t num_caps_log2 = 0);
/**
* Release range of capability selectors
*
* \param cap first capability selector of range
* \param num_caps_log2 number of capability selectors specified
* as the power of two
*/
void free(addr_t cap, size_t num_caps_log2);
};
/**
* Return singleton instance of 'Cap_selector_allocator'
*/
Cap_selector_allocator *cap_selector_allocator();
}
#endif /* _INCLUDE__BASE__CAP_SEL_ALLOC_H_ */

View File

@ -50,9 +50,6 @@ namespace Genode {
return;
Nova::sm_ctrl(block.local_name(), Nova::SEMAPHORE_DOWN);
Nova::revoke(Nova::Obj_crd(block.local_name(), 0));
cap_selector_allocator()->free(block.local_name(), 0);
}
void resume(Thread_capability thread) {

View File

@ -7,7 +7,7 @@
LIBS += base-common
SRC_CC += console/log_console.cc
SRC_CC += env/env.cc env/cap_sel_alloc.cc env/main_thread.cc \
SRC_CC += env/env.cc env/main_thread.cc \
env/context_area.cc env/reload_parent_cap
SRC_CC += thread/thread_nova.cc

View File

@ -13,12 +13,9 @@
*/
/* Genode includes */
#include <base/cap_sel_alloc.h>
#include <base/stdint.h>
#include <base/console.h>
/* NOVA includes */
#include <nova/syscalls.h>
/**
* Read byte from I/O port

View File

@ -14,7 +14,6 @@
*/
/* Genode includes */
#include <base/cap_sel_alloc.h>
#include <base/pager.h>
#include <base/sleep.h>
@ -337,8 +336,8 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location)
sizeof(_context->name) - 6);
addr_t pd_sel = __core_pd_sel;
_pt_cleanup = cap_selector_allocator()->alloc(1);
_client_exc_pt_sel = cap_selector_allocator()->alloc(NUM_INITIAL_PT_LOG2);
_pt_cleanup = cap_map()->insert(1);
_client_exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
_state._status = 0;
_state.sel_client_ec = Native_thread::INVALID_INDEX;
@ -440,10 +439,8 @@ Pager_object::~Pager_object()
/* revoke portal used for the cleanup call */
revoke(Obj_crd(_pt_cleanup, 0));
Native_capability pager_obj = ::Object_pool<Pager_object>::Entry::cap();
cap_selector_allocator()->free(_pt_cleanup, 1);
cap_selector_allocator()->free(pager_obj.local_name(), 0);
cap_selector_allocator()->free(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2);
cap_map()->remove(_pt_cleanup, 1, false);
cap_map()->remove(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2, false);
}

View File

@ -17,7 +17,6 @@
#include <base/printf.h>
#include <base/rpc_server.h>
#include <base/env.h>
#include <base/cap_sel_alloc.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -76,10 +75,6 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
/* wait until nobody is inside dispatch */
obj->acquire();
/* free cap selector */
/* XXX we need cap ref counting to avoid reuse bug which triggers */
//cap_selector_allocator()->free(obj->cap().local_name(), 0);
}
void Rpc_entrypoint::_activation_entry()
@ -99,13 +94,13 @@ void Rpc_entrypoint::_activation_entry()
ep->_delay_start.unlock();
}
/* required to decrease ref count of capability used during last reply */
ep->_snd_buf.snd_reset();
/* prepare ipc server object (copying utcb content to message buffer */
Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf);
ep->_rcv_buf.post_ipc(reinterpret_cast<Nova::Utcb *>(ep->utcb()));
/* destination of next reply - no effect on nova */
srv.dst(Native_capability(id_pt));
int opcode = 0;
srv >> IPC_WAIT >> opcode;
@ -255,7 +250,4 @@ Rpc_entrypoint::~Rpc_entrypoint()
/* de-announce object from cap_session */
_cap_session->free(_cap);
Nova::revoke(Nova::Obj_crd(_cap.local_name(), 0), true);
cap_selector_allocator()->free(_cap.local_name(), 0);
}

View File

@ -15,7 +15,6 @@
/* Genode includes */
#include <base/thread.h>
#include <base/cap_sel_alloc.h>
#include <base/printf.h>
#include <base/sleep.h>
#include <base/env.h>
@ -76,7 +75,7 @@ void Thread_base::_init_platform_thread()
* running semaphore and exception handler portals.
*/
_tid.ec_sel = Native_thread::INVALID_INDEX;
_tid.exc_pt_sel = cap_selector_allocator()->alloc(NUM_INITIAL_PT_LOG2);
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
if (_tid.exc_pt_sel == Native_thread::INVALID_INDEX)
throw Cpu_session::Thread_creation_failed();
@ -99,13 +98,13 @@ void Thread_base::_deinit_platform_thread()
{
using namespace Nova;
if (_tid.ec_sel != ~0UL) {
if (_tid.ec_sel != Native_thread::INVALID_INDEX) {
revoke(Obj_crd(_tid.ec_sel, 1));
cap_selector_allocator()->free(_tid.ec_sel, 1);
cap_map()->remove(_tid.ec_sel, 1, false);
}
revoke(Obj_crd(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2));
cap_selector_allocator()->free(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2);
cap_map()->remove(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2, false);
/* revoke utcb */
Rights rwx(true, true, true);
@ -113,17 +112,11 @@ void Thread_base::_deinit_platform_thread()
revoke(Mem_crd(utcb >> 12, 0, rwx));
/* de-announce thread */
if (_thread_cap.valid()) {
if (_thread_cap.valid())
env()->cpu_session()->kill_thread(_thread_cap);
revoke(_thread_cap.local_name(), 0);
cap_selector_allocator()->free(_thread_cap.local_name(), 0);
}
if (_pager_cap.valid()) {
if (_pager_cap.valid())
env()->rm_session()->remove_client(_pager_cap);
revoke(_pager_cap.local_name(), 0);
cap_selector_allocator()->free(_pager_cap.local_name(), 0);
}
}
@ -166,7 +159,7 @@ void Thread_base::start()
throw Cpu_session::Thread_creation_failed();
/* request native EC thread cap */
_tid.ec_sel = cap_selector_allocator()->alloc(1);
_tid.ec_sel = cap_map()->insert(1);
if (_tid.ec_sel == Native_thread::INVALID_INDEX)
throw Cpu_session::Thread_creation_failed();

View File

@ -12,9 +12,6 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/cap_sel_alloc.h>
/* Core includes */
#include <platform_pd.h>
@ -23,7 +20,7 @@
#include <nova_util.h>
enum {
ECHO_STACK_SIZE = 1024,
ECHO_STACK_SIZE = 512,
ECHO_GLOBAL = false,
ECHO_EXC_BASE = 0
};
@ -64,8 +61,8 @@ static void echo_reply()
Echo::Echo(Genode::addr_t utcb_addr)
:
_ec_sel(Genode::cap_selector_allocator()->alloc()),
_pt_sel(Genode::cap_selector_allocator()->alloc()),
_ec_sel(Genode::cap_map()->insert()),
_pt_sel(Genode::cap_map()->insert()),
_utcb((Nova::Utcb *)utcb_addr)
{
using namespace Nova;
@ -77,11 +74,11 @@ Echo::Echo(Genode::addr_t utcb_addr)
ECHO_EXC_BASE, ECHO_GLOBAL);
/* make error condition visible by raising an unhandled page fault */
if (res) { ((void (*)())(res*0x10000UL))(); }
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
/* set up echo portal to ourself */
res = create_pt(_pt_sel, pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply);
if (res) { ((void (*)())(res*0x10001UL))(); }
if (res != Nova::NOVA_OK) { *reinterpret_cast<unsigned *>(0) = 0xdead; }
revoke(Obj_crd(_pt_sel, 0, Obj_crd::RIGHT_PT_CTRL));
/* echo thread doesn't receive anything, it transfers items during reply */

View File

@ -29,9 +29,11 @@ namespace Genode {
static long _unique_id_cnt;
struct Cap_object : Native_capability, List<Cap_object>::Element
struct Cap_object : List<Cap_object>::Element
{
Cap_object(addr_t cap_sel) : Native_capability(cap_sel) {}
Genode::addr_t _cap_sel;
Cap_object(addr_t cap_sel) : _cap_sel(cap_sel) {}
};
Tslab<Cap_object, 128> _cap_slab;
@ -54,8 +56,9 @@ namespace Genode {
Lock::Guard cap_lock(_cap_lock);
for (Cap_object *obj; (obj = _cap_list.first()); ) {
Nova::revoke(Nova::Obj_crd(obj->local_name(), 0));
/* XXX cap_selector free up */
Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0));
cap_map()->remove(obj->_cap_sel, 0, false);
_cap_list.remove(obj);
destroy(&_cap_slab, obj);
}
@ -64,7 +67,7 @@ namespace Genode {
Native_capability alloc(Native_capability ep, addr_t entry,
addr_t mtd)
{
addr_t pt_sel = cap_selector_allocator()->alloc(0);
addr_t pt_sel = cap_map()->insert();
addr_t pd_sel = Platform_pd::pd_core_sel();
addr_t ec_sel = ep.local_name();
@ -94,9 +97,7 @@ namespace Genode {
destroy(&_cap_slab, pt_cap);
/* cleanup unused selectors */
cap_selector_allocator()->free(pt_sel, 0);
/* XXX revoke ec_sel if it was mapped !!!! */
cap_map()->remove(pt_sel, 0, false);
return Native_capability::invalid_cap();
}
@ -108,9 +109,10 @@ namespace Genode {
Lock::Guard cap_lock(_cap_lock);
for (Cap_object *obj = _cap_list.first(); obj ; obj = obj->next()) {
if (cap.local_name() == obj->local_name()) {
Nova::revoke(Nova::Obj_crd(obj->local_name(), 0));
/* XXX cap_selector free up */
if (cap.local_name() == obj->_cap_sel) {
Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0));
cap_map()->remove(obj->_cap_sel, 0, false);
_cap_list.remove(obj);
destroy(&_cap_slab, obj);
return;

View File

@ -97,7 +97,7 @@ class Irq_thread : public Thread_base
utcb_obj->crd_xlt = Obj_crd();
/* create SC */
unsigned sc_sel = cap_selector_allocator()->alloc();
unsigned sc_sel = cap_map()->insert();
res = create_sc(sc_sel, pd_sel, _tid.ec_sel, Qpd());
if (res != NOVA_OK) {
PERR("%p - create_sc returned returned %d", this, res);
@ -122,7 +122,7 @@ class Genode::Irq_proxy_component : public Irq_proxy<Irq_thread>
bool _associate()
{
/* alloc slector where IRQ will be mapped */
_irq_sel = cap_selector_allocator()->alloc();
_irq_sel = cap_map()->insert();
/* since we run in APIC mode translate IRQ 0 (PIT) to 2 */
if (!_irq_number)

View File

@ -257,7 +257,7 @@ static void init_core_page_fault_handler()
EXC_BASE = 0
};
addr_t ec_sel = cap_selector_allocator()->alloc();
addr_t ec_sel = cap_map()->insert();
uint8_t ret = create_ec(ec_sel, __core_pd_sel, boot_cpu(),
CORE_PAGER_UTCB_ADDR, core_pager_stack_top(),

View File

@ -13,7 +13,6 @@
/* Genode includes */
#include <base/printf.h>
#include <base/cap_sel_alloc.h>
/* core includes */
#include <platform_pd.h>
@ -57,5 +56,5 @@ Platform_pd::~Platform_pd()
/* Revoke and free cap, pd is gone */
Nova::revoke(Nova::Obj_crd(_pd_sel, 0));
cap_selector_allocator()->free(_pd_sel, 0);
cap_map()->remove(_pd_sel, 0, false);
}

View File

@ -15,7 +15,6 @@
/* Genode includes */
#include <base/printf.h>
#include <base/cap_sel_alloc.h>
#include <base/ipc_pager.h>
/* core includes */
@ -129,7 +128,7 @@ int Platform_thread::start(void *ip, void *sp)
return -6;
}
pd_sel = cap_selector_allocator()->alloc();
pd_sel = cap_map()->insert();
/* create task */
res = create_pd(pd_sel, pd_core_sel, initial_pts);
@ -180,7 +179,7 @@ int Platform_thread::start(void *ip, void *sp)
cleanup_pd:
revoke(Obj_crd(pd_sel, 0));
cap_selector_allocator()->free(pd_sel, 0);
cap_map()->remove(pd_sel, 0, false);
return -7;
}
@ -287,7 +286,7 @@ Weak_ptr<Address_space> Platform_thread::address_space()
Platform_thread::Platform_thread(const char *name, unsigned, int thread_id)
:
_pd(0), _pager(0), _id_base(cap_selector_allocator()->alloc(1)),
_pd(0), _pager(0), _id_base(cap_map()->insert(1)),
_sel_exc_base(Native_thread::INVALID_INDEX), _location(boot_cpu(), 0),
_features(0)
{
@ -301,5 +300,5 @@ Platform_thread::~Platform_thread()
/* free ec and sc caps */
revoke(Obj_crd(_id_base, 1));
cap_selector_allocator()->free(_id_base, 1);
cap_map()->remove(_id_base, 1, false);
}

View File

@ -14,7 +14,6 @@
/* Genode includes */
#include <base/ipc.h>
#include <base/printf.h>
#include <base/cap_sel_alloc.h>
/* core includes */
#include <signal_session_component.h>

View File

@ -27,7 +27,6 @@ SRC_CC = main.cc \
signal_source_component.cc \
trace_session_component.cc \
core_rm_session.cc \
cap_sel_alloc.cc \
main_thread.cc \
context_area.cc \
echo.cc \
@ -60,6 +59,5 @@ vpath platform_services.cc $(GEN_CORE_DIR)/x86
vpath context_area.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath %.cc $(REP_DIR)/src/core
vpath cap_sel_alloc.cc $(REP_DIR)/src/base/env
vpath main_thread.cc $(REP_DIR)/src/base/env
vpath pager.cc $(REP_DIR)/src/base/pager

View File

@ -15,10 +15,7 @@
/* Genode includes */
#include <base/thread.h>
#include <base/cap_sel_alloc.h>
#include <base/printf.h>
#include <base/sleep.h>
#include <base/env.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -39,8 +36,8 @@ void Thread_base::_init_platform_thread()
*/
using namespace Nova;
_tid.ec_sel = cap_selector_allocator()->alloc(1);
_tid.exc_pt_sel = cap_selector_allocator()->alloc(NUM_INITIAL_PT_LOG2);
_tid.ec_sel = cap_map()->insert(1);
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
addr_t pd_sel = Platform_pd::pd_core_sel();
/* create running semaphore required for locking */
@ -58,9 +55,8 @@ void Thread_base::_deinit_platform_thread()
unmap_local(Nova::Obj_crd(_tid.ec_sel, 1));
unmap_local(Nova::Obj_crd(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
cap_selector_allocator()->free(_tid.ec_sel, 1);
cap_selector_allocator()->free(_tid.exc_pt_sel,
Nova::NUM_INITIAL_PT_LOG2);
cap_map()->remove(_tid.ec_sel, 1, false);
cap_map()->remove(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2, false);
/* revoke utcb */
Nova::Rights rwx(true, true, true);
@ -78,7 +74,7 @@ void Thread_base::start()
using namespace Nova;
addr_t sp = reinterpret_cast<addr_t>(&_context->stack[-4]);
sp &= ~0xf; /* align initial stack to 16 byte boundary */
sp &= ~0xFUL; /* align initial stack to 16 byte boundary */
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_context->utcb);
addr_t pd_sel = Platform_pd::pd_core_sel();

View File

@ -35,7 +35,6 @@
#include <util/touch.h>
#include <base/printf.h>
#include <base/sleep.h>
#include <base/cap_sel_alloc.h>
#include <base/thread.h>
#include <base/rpc_server.h>
#include <base/native_types.h>
@ -279,14 +278,13 @@ class Vcpu_thread : Genode::Thread<STACK_SIZE>
Vcpu_thread(char const * name) : Thread(name)
{
using namespace Genode;
/* release pre-allocated selectors of Thread */
Genode::cap_selector_allocator()->
free(tid().exc_pt_sel,
Nova::NUM_INITIAL_PT_LOG2);
cap_map()->remove(tid().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
/* allocate correct number of selectors */
tid().exc_pt_sel = Genode::cap_selector_allocator()->
alloc(VCPU_EXC_BASE_LOG2);
tid().exc_pt_sel = cap_map()->insert(VCPU_EXC_BASE_LOG2);
/* tell generic thread code that this becomes a vCPU */
tid().is_vcpu = true;
@ -295,15 +293,13 @@ class Vcpu_thread : Genode::Thread<STACK_SIZE>
~Vcpu_thread()
{
using namespace Nova;
using namespace Genode;
revoke(Obj_crd(tid().exc_pt_sel, VCPU_EXC_BASE_LOG2));
Genode::cap_selector_allocator()->
free(tid().exc_pt_sel, VCPU_EXC_BASE_LOG2);
Nova::revoke(Nova::Obj_crd(tid().exc_pt_sel, VCPU_EXC_BASE_LOG2));
cap_map()->remove(tid().exc_pt_sel, VCPU_EXC_BASE_LOG2, false);
/* allocate selectors for ~Thread */
tid().exc_pt_sel = Genode::cap_selector_allocator()->
alloc(NUM_INITIAL_PT_LOG2);
tid().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_PT_LOG2);
}
Genode::addr_t exc_base() { return tid().exc_pt_sel; }
@ -354,12 +350,6 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
** Shortcuts **
***************/
static Nova::mword_t _alloc_sel(Genode::size_t num_caps_log2 = 0) {
return Genode::cap_selector_allocator()->alloc(num_caps_log2); }
static void _free_sel(Nova::mword_t sel, Genode::size_t num_caps_log2 = 0) {
Genode::cap_selector_allocator()->free(sel, num_caps_log2); }
static ::Utcb *_utcb_of_myself() {
return (::Utcb *)Genode::Thread_base::myself()->utcb(); }