hw: directly reference kernel objects from core

Instead of handing over object ids to the kernel, which has to find them
in object pools then, core can simply use object pointers to reference
kernel objects.

Ref #1443
This commit is contained in:
Stefan Kalkowski 2015-04-01 10:23:38 +02:00 committed by Christian Helmuth
parent c850462f43
commit b32af4e0a4
21 changed files with 203 additions and 294 deletions

View File

@ -19,6 +19,12 @@
namespace Kernel namespace Kernel
{ {
class Pd;
class Thread;
class Signal_receiver;
class Signal_context;
class Vm;
addr_t mode_transition_base(); addr_t mode_transition_base();
size_t mode_transition_size(); size_t mode_transition_size();
size_t thread_size(); size_t thread_size();
@ -55,10 +61,9 @@ namespace Kernel
* \param dst appropriate memory donation for the kernel object * \param dst appropriate memory donation for the kernel object
* \param pd core local Platform_pd object * \param pd core local Platform_pd object
* *
* \retval >0 kernel name of the new domain * \retval 0 when successful, otherwise !=0
* \retval 0 failed
*/ */
inline unsigned long new_pd(void * const dst, Platform_pd * const pd) inline int long new_pd(void * const dst, Platform_pd * const pd)
{ {
return call(call_id_new_pd(), (Call_arg)dst, (Call_arg)pd); return call(call_id_new_pd(), (Call_arg)dst, (Call_arg)pd);
} }
@ -67,29 +72,26 @@ namespace Kernel
/** /**
* Destruct a domain * Destruct a domain
* *
* \param pd_id kernel name of the targeted domain * \param pd pointer to pd kernel object
*
* \retval 0 succeeded
* \retval -1 failed
*/ */
inline int delete_pd(unsigned const pd_id) inline void delete_pd(Pd * const pd)
{ {
return call(call_id_delete_pd(), pd_id); call(call_id_delete_pd(), (Call_arg)pd);
} }
/** /**
* Update locally effective domain configuration to in-memory state * Update locally effective domain configuration to in-memory state
* *
* \param pd_id kernel name of the targeted domain * \param pd pointer to pd kernel object
* *
* Kernel and/or hardware may cache parts of a domain configuration. This * Kernel and/or hardware may cache parts of a domain configuration. This
* function ensures that the in-memory state of the targeted domain gets * function ensures that the in-memory state of the targeted domain gets
* CPU-locally effective. * CPU-locally effective.
*/ */
inline void update_pd(unsigned const pd_id) inline void update_pd(Pd * const pd)
{ {
call(call_id_update_pd(), pd_id); call(call_id_update_pd(), (Call_arg)pd);
} }
@ -115,72 +117,72 @@ namespace Kernel
/** /**
* Pause execution of a specific thread * Pause execution of a specific thread
* *
* \param thread_id kernel name of the targeted thread * \param thread pointer to thread kernel object
*/ */
inline void pause_thread(unsigned const thread_id) inline void pause_thread(Thread * const thread)
{ {
call(call_id_pause_thread(), thread_id); call(call_id_pause_thread(), (Call_arg)thread);
} }
/** /**
* Destruct a thread * Destruct a thread
* *
* \param thread_id kernel name of the targeted thread * \param thread pointer to thread kernel object
*/ */
inline void delete_thread(unsigned const thread_id) inline void delete_thread(Thread * const thread)
{ {
call(call_id_delete_thread(), thread_id); call(call_id_delete_thread(), (Call_arg)thread);
} }
/** /**
* Start execution of a thread * Start execution of a thread
* *
* \param thread_id kernel name of the targeted thread * \param thread pointer to thread kernel object
* \param cpu_id kernel name of the targeted CPU * \param cpu_id kernel name of the targeted CPU
* \param pd_id kernel name of the targeted domain * \param pd pointer to pd kernel object
* \param utcb core local pointer to userland thread-context * \param utcb core local pointer to userland thread-context
* *
* \retval 0 suceeded * \retval 0 suceeded
* \retval !=0 failed * \retval !=0 failed
*/ */
inline int start_thread(unsigned const thread_id, unsigned const cpu_id, inline int start_thread(Thread * const thread, unsigned const cpu_id,
unsigned const pd_id, Native_utcb * const utcb) Pd * const pd, Native_utcb * const utcb)
{ {
return call(call_id_start_thread(), thread_id, cpu_id, pd_id, return call(call_id_start_thread(), (Call_arg)thread, cpu_id,
(Call_arg)utcb); (Call_arg)pd, (Call_arg)utcb);
} }
/** /**
* Cancel blocking of a thread if possible * Cancel blocking of a thread if possible
* *
* \param thread_id kernel name of the targeted thread * \param thread pointer to thread kernel object
* *
* \return wether thread was in a cancelable blocking beforehand * \return wether thread was in a cancelable blocking beforehand
*/ */
inline bool resume_thread(unsigned const thread_id) inline bool resume_thread(Thread * const thread)
{ {
return call(call_id_resume_thread(), thread_id); return call(call_id_resume_thread(), (Call_arg)thread);
} }
/** /**
* Set or unset the handler of an event that can be triggered by a thread * Set or unset the handler of an event that can be triggered by a thread
* *
* \param thread_id kernel name of the targeted thread * \param thread pointer to thread kernel object
* \param event_id kernel name of the targeted thread event * \param event_id kernel name of the targeted thread event
* \param signal_context_id kernel name of the handlers signal context * \param signal_context_id kernel name of the handlers signal context
* *
* \retval 0 succeeded * \retval 0 succeeded
* \retval -1 failed * \retval -1 failed
*/ */
inline int route_thread_event(unsigned const thread_id, inline int route_thread_event(Thread * const thread,
unsigned const event_id, unsigned const event_id,
unsigned const signal_context_id) unsigned const signal_context_id)
{ {
return call(call_id_route_thread_event(), thread_id, return call(call_id_route_thread_event(), (Call_arg)thread,
event_id, signal_context_id); event_id, signal_context_id);
} }
@ -188,7 +190,7 @@ namespace Kernel
/** /**
* Access plain member variables of a kernel thread-object * Access plain member variables of a kernel thread-object
* *
* \param thread_id kernel name of the targeted thread * \param thread pointer to thread kernel object
* \param reads amount of read operations * \param reads amount of read operations
* \param writes amount of write operations * \param writes amount of write operations
* \param values base of the value buffer for all operations * \param values base of the value buffer for all operations
@ -217,13 +219,13 @@ namespace Kernel
* ... ... * ... ...
* (reads + writes - 1) * sizeof(addr_t): write value #writes * (reads + writes - 1) * sizeof(addr_t): write value #writes
*/ */
inline unsigned access_thread_regs(unsigned const thread_id, inline unsigned access_thread_regs(Thread * const thread,
unsigned const reads, unsigned const reads,
unsigned const writes, unsigned const writes,
addr_t * const values) addr_t * const values)
{ {
return call(call_id_access_thread_regs(), thread_id, reads, writes, return call(call_id_access_thread_regs(), (Call_arg)thread,
(Call_arg)values); reads, writes, (Call_arg)values);
} }
@ -245,45 +247,43 @@ namespace Kernel
* Create a signal context and assign it to a signal receiver * Create a signal context and assign it to a signal receiver
* *
* \param p memory donation for the kernel signal-context object * \param p memory donation for the kernel signal-context object
* \param receiver kernel name of targeted signal receiver * \param receiver pointer to signal receiver kernel object
* \param imprint user label of the signal context * \param imprint user label of the signal context
* *
* \retval >0 kernel name of the new signal context * \retval >0 kernel name of the new signal context
* \retval 0 failed * \retval 0 failed
*/ */
inline unsigned new_signal_context(addr_t const p, inline unsigned new_signal_context(addr_t const p,
unsigned const receiver, Signal_receiver * const receiver,
unsigned const imprint) unsigned const imprint)
{ {
return call(call_id_new_signal_context(), p, receiver, imprint); return call(call_id_new_signal_context(), p,
(Call_arg)receiver, imprint);
} }
/** /**
* Destruct a signal context * Destruct a signal context
* *
* \param context kernel name of the targeted signal context * \param context pointer to signal context kernel object
*
* \retval 0 suceeded
* \retval -1 failed
*/ */
inline int delete_signal_context(unsigned const context) inline void delete_signal_context(Signal_context * const context)
{ {
return call(call_id_delete_signal_context(), context); call(call_id_delete_signal_context(), (Call_arg)context);
} }
/** /**
* Destruct a signal receiver * Destruct a signal receiver
* *
* \param receiver kernel name of the targeted signal receiver * \param receiver pointer to signal receiver kernel object
* *
* \retval 0 suceeded * \retval 0 suceeded
* \retval -1 failed * \retval -1 failed
*/ */
inline int delete_signal_receiver(unsigned const receiver) inline void delete_signal_receiver(Signal_receiver * const receiver)
{ {
return call(call_id_delete_signal_receiver(), receiver); call(call_id_delete_signal_receiver(), (Call_arg)receiver);
} }
@ -296,12 +296,11 @@ namespace Kernel
* \param table guest-physical to host-physical translation * \param table guest-physical to host-physical translation
* table pointer * table pointer
* *
* \retval >0 kernel name of the new VM * \retval 0 when successful, otherwise !=0
* \retval 0 failed
* *
* Regaining of the supplied memory is not supported by now. * Regaining of the supplied memory is not supported by now.
*/ */
inline unsigned new_vm(void * const dst, void * const state, inline int new_vm(void * const dst, void * const state,
unsigned const signal_context_id, unsigned const signal_context_id,
void * const table) void * const table)
{ {
@ -313,42 +312,39 @@ namespace Kernel
/** /**
* Execute a virtual-machine (again) * Execute a virtual-machine (again)
* *
* \param vm_id kernel name of the targeted VM * \param vm pointer to vm kernel object
* *
* \retval 0 suceeded * \retval 0 when successful, otherwise !=0
* \retval -1 failed
*/ */
inline int run_vm(unsigned const vm_id) inline int run_vm(Vm * const vm)
{ {
return call(call_id_run_vm(), vm_id); return call(call_id_run_vm(), (Call_arg) vm);
} }
/** /**
* Destruct a virtual-machine * Destruct a virtual-machine
* *
* \param vm_id kernel name of the targeted VM * \param vm pointer to vm kernel object
* *
* \retval 0 suceeded * \retval 0 when successful, otherwise !=0
* \retval -1 failed
*/ */
inline int delete_vm(unsigned const vm_id) inline int delete_vm(Vm * const vm)
{ {
return call(call_id_delete_vm(), vm_id); return call(call_id_delete_vm(), (Call_arg) vm);
} }
/** /**
* Stop execution of a virtual-machine * Stop execution of a virtual-machine
* *
* \param vm_id kernel name of the targeted VM * \param vm pointer to vm kernel object
* *
* \retval 0 suceeded * \retval 0 when successful, otherwise !=0
* \retval -1 failed
*/ */
inline int pause_vm(unsigned const vm_id) inline int pause_vm(Vm * const vm)
{ {
return call(call_id_pause_vm(), vm_id); return call(call_id_pause_vm(), (Call_arg) vm);
} }
} }

View File

@ -310,9 +310,9 @@ class Kernel::Thread
***************/ ***************/
unsigned id() const { return Object::id(); } unsigned id() const { return Object::id(); }
char const * label() const { return _label; }; char const * label() const { return _label; }
unsigned pd_id() const;
char const * pd_label() const; char const * pd_label() const;
Pd * const pd() const { return _pd; }
}; };
#endif /* _KERNEL__THREAD_H_ */ #endif /* _KERNEL__THREAD_H_ */

View File

@ -40,13 +40,13 @@ namespace Genode
protected: protected:
Lock _lock; /* safeguard translation table and slab */ Lock _lock; /* safeguard translation table and slab */
unsigned _id;
Native_capability _parent; Native_capability _parent;
Native_thread_id _main_thread; Native_thread_id _main_thread;
char const * const _label; char const * const _label;
Translation_table * _tt; /* translation table virtual addr. */ Translation_table * _tt; /* translation table virtual addr. */
Translation_table * _tt_phys; /* translation table physical addr. */ Translation_table * _tt_phys; /* translation table physical addr. */
uint8_t _kernel_pd[sizeof(Kernel::Pd)]; uint8_t _kernel_pd_data[sizeof(Kernel::Pd)];
Kernel::Pd * _kernel_pd;
Page_slab * _pslab; /* page table allocator */ Page_slab * _pslab; /* page table allocator */
public: public:
@ -68,7 +68,8 @@ namespace Genode
*/ */
Platform_pd(Allocator * md_alloc, size_t ram_quota, Platform_pd(Allocator * md_alloc, size_t ram_quota,
char const *label) char const *label)
: _main_thread(0), _label(label) : _main_thread(0), _label(label),
_kernel_pd(reinterpret_cast<Kernel::Pd*>(_kernel_pd_data))
{ {
Lock::Guard guard(_lock); Lock::Guard guard(_lock);
@ -89,8 +90,7 @@ namespace Genode
Kernel::mtc()->map(_tt, _pslab); Kernel::mtc()->map(_tt, _pslab);
/* create kernel object */ /* create kernel object */
_id = Kernel::new_pd(&_kernel_pd, this); if (Kernel::new_pd(_kernel_pd, this)) {
if (!_id) {
PERR("failed to create kernel object"); PERR("failed to create kernel object");
throw Root::Unavailable(); throw Root::Unavailable();
} }
@ -146,13 +146,14 @@ namespace Genode
***************/ ***************/
Lock * lock() { return &_lock; } Lock * lock() { return &_lock; }
unsigned const id() { return _id; }
char const * const label() { return _label; } char const * const label() { return _label; }
Page_slab * page_slab() { return _pslab; } Page_slab * page_slab() { return _pslab; }
Translation_table * translation_table() { return _tt; } Translation_table * translation_table() { return _tt; }
Translation_table * translation_table_phys() { return _tt_phys; } Translation_table * translation_table_phys() { return _tt_phys; }
void page_slab(Page_slab *pslab) { _pslab = pslab; } void page_slab(Page_slab *pslab) { _pslab = pslab; }
Kernel::Pd * kernel_pd() { return _kernel_pd; }
/***************************** /*****************************
** Address-space interface ** ** Address-space interface **

View File

@ -131,12 +131,12 @@ namespace Genode {
/** /**
* Pause this thread * Pause this thread
*/ */
void pause() { Kernel::pause_thread(_id); } void pause() { Kernel::pause_thread(kernel_thread()); }
/** /**
* Resume this thread * Resume this thread
*/ */
void resume() { Kernel::resume_thread(_id); } void resume() { Kernel::resume_thread(kernel_thread()); }
/** /**
* Cancel currently blocking operation * Cancel currently blocking operation
@ -191,6 +191,9 @@ namespace Genode {
Native_thread_id id() const { return _id; } Native_thread_id id() const { return _id; }
Ram_dataspace_capability utcb() const { return _utcb; } Ram_dataspace_capability utcb() const { return _utcb; }
Kernel::Thread * const kernel_thread() {
return reinterpret_cast<Kernel::Thread*>(_kernel_thread); }
}; };
} }

View File

@ -35,11 +35,11 @@ class Genode::Vm_session_component :
Rpc_entrypoint *_ds_ep; Rpc_entrypoint *_ds_ep;
Range_allocator *_ram_alloc; Range_allocator *_ram_alloc;
unsigned _vm_id;
char _vm[sizeof(Kernel::Vm)]; char _vm[sizeof(Kernel::Vm)];
Dataspace_component _ds; Dataspace_component _ds;
Dataspace_capability _ds_cap; Dataspace_capability _ds_cap;
addr_t _ds_addr; addr_t _ds_addr;
bool _initialized = false;
static size_t _ds_size() { static size_t _ds_size() {
return align_addr(sizeof(Cpu_state_modes), return align_addr(sizeof(Cpu_state_modes),
@ -47,6 +47,9 @@ class Genode::Vm_session_component :
addr_t _alloc_ds(size_t &ram_quota); addr_t _alloc_ds(size_t &ram_quota);
Kernel::Vm * _kernel_object() {
return reinterpret_cast<Kernel::Vm*>(_vm); }
public: public:
Vm_session_component(Rpc_entrypoint *ds_ep, Vm_session_component(Rpc_entrypoint *ds_ep,

View File

@ -39,13 +39,13 @@ class Genode::Vm_session_component :
Rpc_entrypoint *_ds_ep; Rpc_entrypoint *_ds_ep;
Range_allocator *_ram_alloc; Range_allocator *_ram_alloc;
unsigned _vm_id;
char _vm[sizeof(Kernel::Vm)]; char _vm[sizeof(Kernel::Vm)];
Dataspace_component _ds; Dataspace_component _ds;
Dataspace_capability _ds_cap; Dataspace_capability _ds_cap;
addr_t _ds_addr; addr_t _ds_addr;
Translation_table *_table; Translation_table *_table;
Page_slab *_pslab; Page_slab *_pslab;
bool _initialized = false;
static size_t _ds_size() { static size_t _ds_size() {
return align_addr(sizeof(Cpu_state_modes), return align_addr(sizeof(Cpu_state_modes),
@ -54,6 +54,9 @@ class Genode::Vm_session_component :
addr_t _alloc_ds(size_t &ram_quota); addr_t _alloc_ds(size_t &ram_quota);
void _attach(addr_t phys_addr, addr_t vm_addr, size_t size); void _attach(addr_t phys_addr, addr_t vm_addr, size_t size);
Kernel::Vm * _kernel_object() {
return reinterpret_cast<Kernel::Vm*>(_vm); }
public: public:
Vm_session_component(Rpc_entrypoint *ds_ep, Vm_session_component(Rpc_entrypoint *ds_ep,

View File

@ -119,7 +119,7 @@ namespace Kernel
using namespace Genode; using namespace Genode;
Platform_pd::_id = Pd::id(); Platform_pd::_kernel_pd = this;
/* map exception vector for core */ /* map exception vector for core */
Kernel::mtc()->map(table, slab); Kernel::mtc()->map(table, slab);

View File

@ -27,9 +27,7 @@ using namespace Kernel;
typedef Genode::Thread_state Thread_state; typedef Genode::Thread_state Thread_state;
unsigned Thread::pd_id() const { return _pd ? _pd->id() : 0; } bool Thread::_core() const { return pd() == core_pd(); }
bool Thread::_core() const { return pd_id() == core_pd()->id(); }
void Thread::_signal_context_kill_pending() void Thread::_signal_context_kill_pending()
{ {
@ -174,8 +172,8 @@ void Thread::init(Cpu * const cpu, Pd * const pd,
/* print log message */ /* print log message */
if (START_VERBOSE) { if (START_VERBOSE) {
Genode::printf("start thread %u '%s' in program %u '%s' ", Genode::printf("start thread %u '%s' in program '%s' ",
id(), label(), pd_id(), pd_label()); id(), label(), pd_label());
if (NR_OF_CPUS) { if (NR_OF_CPUS) {
Genode::printf("on CPU %u/%u ", cpu->id(), NR_OF_CPUS); } Genode::printf("on CPU %u/%u ", cpu->id(), NR_OF_CPUS); }
Genode::printf("\n"); Genode::printf("\n");
@ -202,47 +200,30 @@ void Thread::_receive_yielded_cpu()
void Thread::proceed(unsigned const cpu) { mtc()->switch_to_user(this, cpu); } void Thread::proceed(unsigned const cpu) { mtc()->switch_to_user(this, cpu); }
char const * Kernel::Thread::pd_label() const char const * Kernel::Thread::pd_label() const {
{ return (_pd) ? _pd->platform_pd()->label() : "?"; }
if (_core()) { return "core"; }
if (!_pd) { return "?"; }
return _pd->platform_pd()->label();
}
void Thread::_call_new_pd() void Thread::_call_new_pd()
{ {
using namespace Genode; using namespace Genode;
try {
/* create protection domain */ /* create protection domain */
void * p = (void *) user_arg_1(); void * p = (void *) user_arg_1();
Platform_pd * ppd = (Platform_pd *) user_arg_2(); Platform_pd * ppd = (Platform_pd *) user_arg_2();
Translation_table * tt = ppd->translation_table_phys(); Translation_table * tt = ppd->translation_table_phys();
Pd * const pd = new (p) Pd(tt, ppd); new (p) Pd(tt, ppd);
user_arg_0(pd->id());
}
void Thread::_call_delete_pd()
{
/* lookup protection domain */
unsigned id = user_arg_1();
Pd * const pd = Pd::pool()->object(id);
if (!pd) {
PWRN("%s -> %s: cannot destroy unknown protection domain %u",
pd_label(), label(), id);
user_arg_0(-1);
return;
}
/* destruct protection domain */
pd->~Pd();
/* clean up buffers of memory management */
Cpu::flush_tlb_by_pid(pd->id());
user_arg_0(0); user_arg_0(0);
return;
} catch(...) { }
user_arg_0(-1);
} }
void Thread::_call_delete_pd() { reinterpret_cast<Pd*>(user_arg_1())->~Pd(); }
void Thread::_call_new_thread() void Thread::_call_new_thread()
{ {
/* create new thread */ /* create new thread */
@ -255,28 +236,12 @@ void Thread::_call_new_thread()
} }
void Thread::_call_delete_thread() void Thread::_call_delete_thread() {
{ reinterpret_cast<Thread*>(user_arg_1())->~Thread(); }
/* lookup thread */
Thread * const thread = Thread::pool()->object(user_arg_1());
if (!thread) {
PWRN("failed to lookup thread");
return;
}
/* destroy thread */
thread->~Thread();
}
void Thread::_call_start_thread() void Thread::_call_start_thread()
{ {
/* lookup thread */
Thread * const thread = Thread::pool()->object(user_arg_1());
if (!thread) {
PWRN("failed to lookup thread");
user_arg_0(-1);
return;
}
/* lookup CPU */ /* lookup CPU */
Cpu * const cpu = cpu_pool()->cpu(user_arg_2()); Cpu * const cpu = cpu_pool()->cpu(user_arg_2());
if (!cpu) { if (!cpu) {
@ -284,13 +249,10 @@ void Thread::_call_start_thread()
user_arg_0(-2); user_arg_0(-2);
return; return;
} }
/* lookup domain */
Pd * const pd = Pd::pool()->object(user_arg_3()); Thread * const thread = (Thread*) user_arg_1();
if (!pd) { Pd * const pd = (Pd *) user_arg_3();
PWRN("failed to lookup domain");
user_arg_0(-3);
return;
}
/* start thread */ /* start thread */
thread->init(cpu, pd, (Native_utcb *)user_arg_4(), 1); thread->init(cpu, pd, (Native_utcb *)user_arg_4(), 1);
user_arg_0(0); user_arg_0(0);
@ -300,38 +262,19 @@ void Thread::_call_start_thread()
void Thread::_call_pause_current_thread() { _pause(); } void Thread::_call_pause_current_thread() { _pause(); }
void Thread::_call_pause_thread() void Thread::_call_pause_thread() {
{ reinterpret_cast<Thread*>(user_arg_1())->_pause(); }
/* lookup thread */
Thread * const thread = Thread::pool()->object(user_arg_1());
if (!thread) {
PWRN("failed to lookup thread");
return;
}
/* pause thread */
thread->_pause();
}
void Thread::_call_resume_thread() void Thread::_call_resume_thread() {
{ user_arg_0(reinterpret_cast<Thread*>(user_arg_1())->_resume()); }
/* lookup thread */
Thread * const thread = Thread::pool()->object(user_arg_1());
if (!thread) {
PWRN("failed to lookup thread");
user_arg_0(false);
return;
}
/* resume thread */
user_arg_0(thread->_resume());
}
void Thread::_call_resume_local_thread() void Thread::_call_resume_local_thread()
{ {
/* lookup thread */ /* lookup thread */
Thread * const thread = Thread::pool()->object(user_arg_1()); Thread * const thread = Thread::pool()->object(user_arg_1());
if (!thread || pd_id() != thread->pd_id()) { if (!thread || pd() != thread->pd()) {
PWRN("failed to lookup thread"); PWRN("failed to lookup thread");
user_arg_0(0); user_arg_0(0);
return; return;
@ -349,9 +292,7 @@ void Thread_event::_signal_acknowledged()
Thread_event::Thread_event(Thread * const t) Thread_event::Thread_event(Thread * const t)
: : _thread(t), _signal_context(0) { }
_thread(t), _signal_context(0)
{ }
void Thread_event::submit() void Thread_event::submit()
@ -415,17 +356,8 @@ void Thread::_call_send_reply_msg()
void Thread::_call_route_thread_event() void Thread::_call_route_thread_event()
{ {
/* get targeted thread */
unsigned const thread_id = user_arg_1();
Thread * const t = Thread::pool()->object(thread_id);
if (!t) {
PWRN("%s -> %s: cannot route event to unknown thread %u",
pd_label(), label(), thread_id);
user_arg_0(-1);
return;
}
/* override event route */ /* override event route */
Thread * const t = (Thread*) user_arg_1();
unsigned const event_id = user_arg_2(); unsigned const event_id = user_arg_2();
unsigned const signal_context_id = user_arg_3(); unsigned const signal_context_id = user_arg_3();
if (t->_route_event(event_id, signal_context_id)) { user_arg_0(-1); } if (t->_route_event(event_id, signal_context_id)) { user_arg_0(-1); }
@ -473,10 +405,9 @@ unsigned Thread_event::signal_context_id() const
void Thread::_call_access_thread_regs() void Thread::_call_access_thread_regs()
{ {
/* get targeted thread */ /* get targeted thread */
unsigned const thread_id = user_arg_1();
unsigned const reads = user_arg_2(); unsigned const reads = user_arg_2();
unsigned const writes = user_arg_3(); unsigned const writes = user_arg_3();
Thread * const t = Thread::pool()->object(thread_id); Thread * const t = (Thread*) user_arg_1();
if (!t) { if (!t) {
PWRN("unknown thread"); PWRN("unknown thread");
user_arg_0(reads + writes); user_arg_0(reads + writes);
@ -640,17 +571,9 @@ void Thread::_call_new_signal_receiver()
void Thread::_call_new_signal_context() void Thread::_call_new_signal_context()
{ {
/* lookup receiver */
unsigned const id = user_arg_2();
Signal_receiver * const r = Signal_receiver::pool()->object(id);
if (!r) {
PWRN("%s -> %s: no context construction, unknown signal receiver %u",
pd_label(), label(), id);
user_arg_0(0);
return;
}
/* create and assign context*/ /* create and assign context*/
void * const p = (void *)user_arg_1(); void * const p = (void *)user_arg_1();
Signal_receiver * const r = (Signal_receiver *) user_arg_2();
unsigned const imprint = user_arg_3(); unsigned const imprint = user_arg_3();
Signal_context * const c = new (p) Signal_context(r, imprint); Signal_context * const c = new (p) Signal_context(r, imprint);
user_arg_0(c->id()); user_arg_0(c->id());
@ -757,37 +680,12 @@ void Thread::_call_kill_signal_context()
} }
void Thread::_call_delete_signal_context() void Thread::_call_delete_signal_context() {
{ reinterpret_cast<Signal_context*>(user_arg_1())->~Signal_context(); }
/* lookup signal context */
unsigned const id = user_arg_1();
Signal_context * const c = Signal_context::pool()->object(id);
if (!c) {
PWRN("%s -> %s: cannot destroy unknown signal context %u",
pd_label(), label(), id);
user_arg_0(0);
return;
}
/* destruct signal context */
c->~Signal_context();
user_arg_0(0);
}
void Thread::_call_delete_signal_receiver() void Thread::_call_delete_signal_receiver() {
{ reinterpret_cast<Signal_receiver*>(user_arg_1())->~Signal_receiver(); }
/* lookup signal receiver */
unsigned const id = user_arg_1();
Signal_receiver * const r = Signal_receiver::pool()->object(id);
if (!r) {
PWRN("%s -> %s: cannot destroy unknown signal receiver %u",
pd_label(), label(), id);
user_arg_0(0);
return;
}
r->~Signal_receiver();
user_arg_0(0);
}
int Thread::_read_reg(addr_t const id, addr_t & value) const int Thread::_read_reg(addr_t const id, addr_t & value) const

View File

@ -14,7 +14,7 @@
/* core includes */ /* core includes */
#include <kernel/thread.h> #include <kernel/thread.h>
void Kernel::Thread::_call_new_vm() { user_arg_0(0); } void Kernel::Thread::_call_new_vm() { user_arg_0(-1); }
void Kernel::Thread::_call_delete_vm() { user_arg_0(-1); } void Kernel::Thread::_call_delete_vm() { user_arg_0(-1); }
void Kernel::Thread::_call_run_vm() { user_arg_0(-1); } void Kernel::Thread::_call_run_vm() { user_arg_0(-1); }
void Kernel::Thread::_call_pause_vm() { user_arg_0(-1); } void Kernel::Thread::_call_pause_vm() { user_arg_0(-1); }

View File

@ -254,7 +254,7 @@ bool Genode::unmap_local(addr_t virt_addr, size_t num_pages)
Kernel::core_pd()->platform_pd()->page_slab()); Kernel::core_pd()->platform_pd()->page_slab());
/* update translation caches of all CPUs */ /* update translation caches of all CPUs */
Kernel::update_pd(Kernel::core_pd()->id()); Kernel::update_pd(Kernel::core_pd());
return true; return true;
} catch(...) { } catch(...) {
PERR("tried to remove invalid region!"); PERR("tried to remove invalid region!");

View File

@ -21,10 +21,7 @@ Platform_pd::~Platform_pd()
{ {
Lock::Guard guard(_lock); Lock::Guard guard(_lock);
if (Kernel::delete_pd(_id)) { Kernel::delete_pd(_kernel_pd);
PERR("failed to destruct protection domain at kernel");
}
_tt->remove_translation(platform()->vm_start(), platform()->vm_size(), _tt->remove_translation(platform()->vm_start(), platform()->vm_size(),
_pslab); _pslab);

View File

@ -74,7 +74,7 @@ Platform_thread::~Platform_thread()
rm->remove_client(cap); rm->remove_client(cap);
} }
/* destroy object at the kernel */ /* destroy object at the kernel */
Kernel::delete_thread(_id); Kernel::delete_thread(kernel_thread());
} }
@ -197,7 +197,7 @@ int Platform_thread::start(void * const ip, void * const sp)
write_regs[0] = Reg_id::IP; write_regs[0] = Reg_id::IP;
write_regs[1] = Reg_id::SP; write_regs[1] = Reg_id::SP;
addr_t values[] = { (addr_t)ip, (addr_t)sp }; addr_t values[] = { (addr_t)ip, (addr_t)sp };
if (Kernel::access_thread_regs(id(), 0, WRITES, values)) { if (Kernel::access_thread_regs(kernel_thread(), 0, WRITES, values)) {
PERR("failed to initialize thread registers"); PERR("failed to initialize thread registers");
return -1; return -1;
} }
@ -206,7 +206,8 @@ int Platform_thread::start(void * const ip, void * const sp)
unsigned const cpu = unsigned const cpu =
_location.valid() ? _location.xpos() : Cpu::primary_id(); _location.valid() ? _location.xpos() : Cpu::primary_id();
_utcb_core_addr->start_info()->init(_id, _utcb); _utcb_core_addr->start_info()->init(_id, _utcb);
if (Kernel::start_thread(_id, cpu, _pd->id(), _utcb_core_addr)) { if (Kernel::start_thread(kernel_thread(), cpu, _pd->kernel_pd(),
_utcb_core_addr)) {
PERR("failed to start thread"); PERR("failed to start thread");
return -1; return -1;
} }
@ -220,7 +221,8 @@ void Platform_thread::pager(Pager_object * const pager)
if (pager) { if (pager) {
unsigned const sc_id = pager->signal_context_id(); unsigned const sc_id = pager->signal_context_id();
if (sc_id) { if (sc_id) {
if (!Kernel::route_thread_event(id(), Event_id::FAULT, sc_id)) { if (!Kernel::route_thread_event(kernel_thread(), Event_id::FAULT,
sc_id)) {
_rm_client = dynamic_cast<Rm_client *>(pager); _rm_client = dynamic_cast<Rm_client *>(pager);
return; return;
} }
@ -228,7 +230,7 @@ void Platform_thread::pager(Pager_object * const pager)
PERR("failed to attach signal context to fault"); PERR("failed to attach signal context to fault");
return; return;
} else { } else {
if (!Kernel::route_thread_event(id(), Event_id::FAULT, 0)) { if (!Kernel::route_thread_event(kernel_thread(), Event_id::FAULT, 0)) {
_rm_client = 0; _rm_client = 0;
return; return;
} }
@ -259,7 +261,8 @@ Thread_state Platform_thread::state()
Genode::memcpy(dst, src, size); Genode::memcpy(dst, src, size);
Thread_state thread_state; Thread_state thread_state;
Cpu_state * const cpu_state = static_cast<Cpu_state *>(&thread_state); Cpu_state * const cpu_state = static_cast<Cpu_state *>(&thread_state);
if (Kernel::access_thread_regs(id(), length, 0, (addr_t *)cpu_state)) { if (Kernel::access_thread_regs(kernel_thread(), length, 0,
(addr_t *)cpu_state)) {
throw Cpu_session::State_access_failed(); throw Cpu_session::State_access_failed();
} }
return thread_state; return thread_state;
@ -274,7 +277,8 @@ void Platform_thread::state(Thread_state thread_state)
void * dst = Thread_base::myself()->utcb()->base(); void * dst = Thread_base::myself()->utcb()->base();
Genode::memcpy(dst, src, size); Genode::memcpy(dst, src, size);
Cpu_state * const cpu_state = static_cast<Cpu_state *>(&thread_state); Cpu_state * const cpu_state = static_cast<Cpu_state *>(&thread_state);
if (Kernel::access_thread_regs(id(), 0, length, (addr_t *)cpu_state)) { if (Kernel::access_thread_regs(kernel_thread(), 0, length,
(addr_t *)cpu_state)) {
throw Cpu_session::State_access_failed(); throw Cpu_session::State_access_failed();
} }
}; };

View File

@ -53,7 +53,7 @@ void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
tt->remove_translation(virt_base, size, pd->page_slab()); tt->remove_translation(virt_base, size, pd->page_slab());
/* update translation caches */ /* update translation caches */
Kernel::update_pd(pd->id()); Kernel::update_pd(pd->kernel_pd());
} }
@ -128,7 +128,6 @@ void Pager_activation_base::entry()
PWRN("failed to get platform thread of faulter"); PWRN("failed to get platform thread of faulter");
continue; continue;
} }
unsigned const thread_id = pt->id();
typedef Kernel::Thread_reg_id Reg_id; typedef Kernel::Thread_reg_id Reg_id;
static addr_t const read_regs[] = { static addr_t const read_regs[] = {
Reg_id::FAULT_TLB, Reg_id::IP, Reg_id::FAULT_ADDR, Reg_id::FAULT_TLB, Reg_id::IP, Reg_id::FAULT_ADDR,
@ -137,7 +136,7 @@ void Pager_activation_base::entry()
void * const utcb = Thread_base::myself()->utcb()->base(); void * const utcb = Thread_base::myself()->utcb()->base();
memcpy(utcb, read_regs, sizeof(read_regs)); memcpy(utcb, read_regs, sizeof(read_regs));
addr_t * const values = (addr_t *)&_fault; addr_t * const values = (addr_t *)&_fault;
if (Kernel::access_thread_regs(thread_id, READS, 0, values)) { if (Kernel::access_thread_regs(pt->kernel_thread(), READS, 0, values)) {
PWRN("failed to read fault data"); PWRN("failed to read fault data");
continue; continue;
} }

View File

@ -35,8 +35,7 @@ Signal_receiver_capability Signal_session_component::alloc_receiver()
/* create kernel object for receiver */ /* create kernel object for receiver */
addr_t donation = Receiver::kernel_donation(p); addr_t donation = Receiver::kernel_donation(p);
unsigned const id = Kernel::new_signal_receiver(donation); unsigned const id = Kernel::new_signal_receiver(donation);
if (!id) if (!id) {
{
/* clean up */ /* clean up */
_receivers_slab.free(p, Receiver::size()); _receivers_slab.free(p, Receiver::size());
PERR("failed to create signal receiver"); PERR("failed to create signal receiver");
@ -67,9 +66,17 @@ void Signal_session_component::free_receiver(Signal_receiver_capability cap)
Signal_context_capability Signal_context_capability
Signal_session_component::alloc_context(Signal_receiver_capability r, Signal_session_component::alloc_context(Signal_receiver_capability src,
unsigned const imprint) unsigned const imprint)
{ {
/* look up ressource info */
Receiver::Pool::Guard r(_receivers.lookup_and_lock(src));
if (!r) {
PERR("unknown signal receiver");
throw Create_context_failed();
}
Kernel::Signal_receiver *sr =
(Kernel::Signal_receiver*) Receiver::kernel_donation(r);
/* allocate resources for context */ /* allocate resources for context */
void * p; void * p;
if (!_contexts_slab.alloc(Context::size(), &p)) { if (!_contexts_slab.alloc(Context::size(), &p)) {
@ -78,9 +85,8 @@ Signal_session_component::alloc_context(Signal_receiver_capability r,
} }
/* create kernel object for context */ /* create kernel object for context */
addr_t donation = Context::kernel_donation(p); addr_t donation = Context::kernel_donation(p);
unsigned const id = Kernel::new_signal_context(donation, r.dst(), imprint); unsigned const id = Kernel::new_signal_context(donation, sr, imprint);
if (!id) if (!id) {
{
/* clean up */ /* clean up */
_contexts_slab.free(p, Context::size()); _contexts_slab.free(p, Context::size());
PERR("failed to create signal context"); PERR("failed to create signal context");
@ -112,13 +118,10 @@ void Signal_session_component::free_context(Signal_context_capability cap)
void Signal_session_component::_destruct_context(Context * const c) void Signal_session_component::_destruct_context(Context * const c)
{ {
/* release kernel resources */ /* release kernel resources */
if (Kernel::delete_signal_context(c->id())) Kernel::Signal_context *sc =
{ (Kernel::Signal_context*) Context::kernel_donation(c);
/* clean-up */ Kernel::delete_signal_context(sc);
c->release();
PERR("failed to kill signal context");
throw Kill_context_failed();
}
/* release core resources */ /* release core resources */
_contexts.remove_locked(c); _contexts.remove_locked(c);
c->~Signal_session_context(); c->~Signal_session_context();
@ -128,13 +131,10 @@ void Signal_session_component::_destruct_context(Context * const c)
void Signal_session_component::_destruct_receiver(Receiver * const r) void Signal_session_component::_destruct_receiver(Receiver * const r)
{ {
/* release kernel resources */ /* release kernel resources */
if (Kernel::delete_signal_receiver(r->id())) Kernel::Signal_receiver *sr =
{ (Kernel::Signal_receiver*) Receiver::kernel_donation(r);
/* clean-up */ Kernel::delete_signal_receiver(sr);
r->release();
PERR("failed to kill signal receiver");
throw Kill_receiver_failed();
}
/* release core resources */ /* release core resources */
_receivers.remove_locked(r); _receivers.remove_locked(r);
r->~Signal_session_receiver(); r->~Signal_session_receiver();

View File

@ -126,5 +126,6 @@ void Thread::_mmu_exception()
void Thread::_call_update_pd() void Thread::_call_update_pd()
{ {
if (Cpu_domain_update::_do_global(user_arg_1())) { _pause(); } Pd * const pd = (Pd *) user_arg_1();
if (Cpu_domain_update::_do_global(pd->asid)) { _pause(); }
} }

View File

@ -17,22 +17,20 @@
void Kernel::Thread::_call_delete_vm() void Kernel::Thread::_call_delete_vm()
{ {
Vm * const vm = Vm::pool()->object(user_arg_1()); reinterpret_cast<Vm*>(user_arg_1())->~Vm();
if (vm) vm->~Vm(); user_arg_0(0);
user_arg_0(vm ? 0 : -1);
} }
void Kernel::Thread::_call_run_vm() { void Kernel::Thread::_call_run_vm()
Vm * const vm = Vm::pool()->object(user_arg_1()); {
if (vm) vm->run(); reinterpret_cast<Vm*>(user_arg_1())->run();
user_arg_0(vm ? 0 : -1); user_arg_0(0);
} }
void Kernel::Thread::_call_pause_vm() void Kernel::Thread::_call_pause_vm()
{ {
Vm * const vm = Vm::pool()->object(user_arg_1()); reinterpret_cast<Vm*>(user_arg_1())->pause();
if (vm) vm->pause(); user_arg_0(0);
user_arg_0(vm ? 0 : -1);
} }

View File

@ -21,7 +21,7 @@ void Kernel::Thread::_call_new_vm()
auto const context = Signal_context::pool()->object(user_arg_4()); auto const context = Signal_context::pool()->object(user_arg_4());
if (!context) { if (!context) {
PWRN("failed to lookup signal context"); PWRN("failed to lookup signal context");
user_arg_0(0); user_arg_0(-1);
return; return;
} }
@ -31,8 +31,6 @@ void Kernel::Thread::_call_new_vm()
void * const table = reinterpret_cast<void *>(user_arg_3()); void * const table = reinterpret_cast<void *>(user_arg_3());
Cpu_state_modes * const state = Cpu_state_modes * const state =
reinterpret_cast<Cpu_state_modes *>(user_arg_2()); reinterpret_cast<Cpu_state_modes *>(user_arg_2());
Vm * const vm = new (allocator) Vm(state, context, table); new (allocator) Vm(state, context, table);
user_arg_0(0);
/* return kernel name of virtual machine */
user_arg_0(vm->id());
} }

View File

@ -20,18 +20,23 @@ using namespace Genode;
void Vm_session_component::exception_handler(Signal_context_capability handler) void Vm_session_component::exception_handler(Signal_context_capability handler)
{ {
if (_vm_id) { if (_initialized) {
PWRN("Cannot register exception_handler repeatedly"); PWRN("Cannot initialize kernel vm object twice!");
return; return;
} }
_vm_id = Kernel::new_vm(&_vm, (void*)_ds.core_local_addr(), handler.dst(), 0);
if (Kernel::new_vm(&_vm, (void*)_ds.core_local_addr(), handler.dst(), 0)) {
PWRN("Cannot instantiate vm kernel object, invalid signal context?");
return;
}
_initialized = true;
} }
Vm_session_component::Vm_session_component(Rpc_entrypoint *ds_ep, Vm_session_component::Vm_session_component(Rpc_entrypoint *ds_ep,
size_t ram_quota) size_t ram_quota)
: _ds_ep(ds_ep), _vm_id(0), : _ds_ep(ds_ep), _ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0),
_ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0),
_ds_cap(static_cap_cast<Dataspace>(_ds_ep->manage(&_ds))) _ds_cap(static_cap_cast<Dataspace>(_ds_ep->manage(&_ds)))
{ {
_ds.assign_core_local_addr(core_env()->rm_session()->attach(_ds_cap)); _ds.assign_core_local_addr(core_env()->rm_session()->attach(_ds_cap));

View File

@ -20,7 +20,7 @@ void Kernel::Thread::_call_new_vm()
auto const context = Signal_context::pool()->object(user_arg_4()); auto const context = Signal_context::pool()->object(user_arg_4());
if (!context) { if (!context) {
PWRN("failed to lookup signal context"); PWRN("failed to lookup signal context");
user_arg_0(0); user_arg_0(-1);
return; return;
} }
@ -30,9 +30,7 @@ void Kernel::Thread::_call_new_vm()
void * const table = reinterpret_cast<void *>(user_arg_3()); void * const table = reinterpret_cast<void *>(user_arg_3());
Cpu_state_modes * const state = Cpu_state_modes * const state =
reinterpret_cast<Cpu_state_modes *>(user_arg_2()); reinterpret_cast<Cpu_state_modes *>(user_arg_2());
Vm * const vm = new (allocator) Vm(state, context, table); new (allocator) Vm(state, context, table);
user_arg_0(0);
/* return kernel name of virtual machine */
user_arg_0(vm->id());
} }

View File

@ -25,14 +25,20 @@ using namespace Genode;
void Vm_session_component::exception_handler(Signal_context_capability handler) void Vm_session_component::exception_handler(Signal_context_capability handler)
{ {
if (_vm_id) { if (_initialized) {
PWRN("Cannot register exception_handler repeatedly"); PWRN("Cannot initialize kernel vm object twice!");
return; return;
} }
Core_mem_allocator * cma = Core_mem_allocator * cma =
static_cast<Core_mem_allocator*>(platform()->core_mem_alloc()); static_cast<Core_mem_allocator*>(platform()->core_mem_alloc());
_vm_id = Kernel::new_vm(&_vm, (void*)_ds.core_local_addr(), handler.dst(), if (Kernel::new_vm(&_vm, (void*)_ds.core_local_addr(), handler.dst(),
cma->phys_addr(_table)); cma->phys_addr(_table))) {
PWRN("Cannot instantiate vm kernel object, invalid signal context?");
return;
}
_initialized = true;
} }
@ -80,8 +86,7 @@ void Vm_session_component::detach(addr_t vm_addr, size_t size) {
Vm_session_component::Vm_session_component(Rpc_entrypoint *ds_ep, Vm_session_component::Vm_session_component(Rpc_entrypoint *ds_ep,
size_t ram_quota) size_t ram_quota)
: _ds_ep(ds_ep), _vm_id(0), : _ds_ep(ds_ep), _ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0),
_ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0),
_ds_cap(static_cap_cast<Dataspace>(_ds_ep->manage(&_ds))) _ds_cap(static_cap_cast<Dataspace>(_ds_ep->manage(&_ds)))
{ {
_ds.assign_core_local_addr(core_env()->rm_session()->attach(_ds_cap)); _ds.assign_core_local_addr(core_env()->rm_session()->attach(_ds_cap));

View File

@ -32,14 +32,14 @@ addr_t Vm_session_component::_alloc_ds(size_t &ram_quota)
void Vm_session_component::run(void) void Vm_session_component::run(void)
{ {
if (!_vm_id || Kernel::run_vm(_vm_id)) if (!_initialized || Kernel::run_vm(_kernel_object()))
PWRN("Unknown VM: is the exception handler registered?"); PWRN("Unknown VM: is the exception handler registered?");
} }
void Vm_session_component::pause(void) void Vm_session_component::pause(void)
{ {
if (!_vm_id || Kernel::pause_vm(_vm_id)) if (!_initialized || Kernel::pause_vm(_kernel_object()))
PWRN("Unknown VM: is the exception handler registered?"); PWRN("Unknown VM: is the exception handler registered?");
} }
@ -49,7 +49,7 @@ Vm_session_component::~Vm_session_component()
/* dissolve VM dataspace from service entry point */ /* dissolve VM dataspace from service entry point */
_ds_ep->dissolve(&_ds); _ds_ep->dissolve(&_ds);
if (Kernel::delete_vm(_vm_id)) PERR("Cannot destruct unknown VM"); if (Kernel::delete_vm(_kernel_object())) PERR("Cannot destruct unknown VM");
/* free region in allocator */ /* free region in allocator */
core_env()->rm_session()->detach(_ds.core_local_addr()); core_env()->rm_session()->detach(_ds.core_local_addr());