From b32af4e0a4e07719ee16aa3e6f952f9e6c9da9ce Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Wed, 1 Apr 2015 10:23:38 +0200 Subject: [PATCH] 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 --- .../src/core/include/kernel/core_interface.h | 132 +++++++------ .../base-hw/src/core/include/kernel/thread.h | 6 +- repos/base-hw/src/core/include/platform_pd.h | 13 +- .../src/core/include/platform_thread.h | 7 +- .../arm_v7/trustzone/vm_session_component.h | 5 +- .../virtualization/vm_session_component.h | 5 +- repos/base-hw/src/core/kernel/kernel.cc | 2 +- repos/base-hw/src/core/kernel/thread.cc | 180 ++++-------------- repos/base-hw/src/core/kernel/vm_thread.cc | 2 +- repos/base-hw/src/core/platform.cc | 2 +- repos/base-hw/src/core/platform_pd.cc | 5 +- repos/base-hw/src/core/platform_thread.cc | 18 +- repos/base-hw/src/core/rm_session_support.cc | 5 +- .../src/core/signal_session_component.cc | 40 ++-- .../src/core/spec/arm/kernel/thread.cc | 3 +- .../src/core/spec/arm_v7/kernel/vm_thread.cc | 18 +- .../spec/arm_v7/trustzone/kernel/vm_thread.cc | 8 +- .../arm_v7/trustzone/vm_session_component.cc | 15 +- .../arm_v7/virtualization/kernel/vm_thread.cc | 8 +- .../virtualization/vm_session_component.cc | 17 +- .../core/spec/arm_v7/vm_session_component.cc | 6 +- 21 files changed, 203 insertions(+), 294 deletions(-) diff --git a/repos/base-hw/src/core/include/kernel/core_interface.h b/repos/base-hw/src/core/include/kernel/core_interface.h index decf50d3f1..d0c3a2dd1f 100644 --- a/repos/base-hw/src/core/include/kernel/core_interface.h +++ b/repos/base-hw/src/core/include/kernel/core_interface.h @@ -19,6 +19,12 @@ namespace Kernel { + class Pd; + class Thread; + class Signal_receiver; + class Signal_context; + class Vm; + addr_t mode_transition_base(); size_t mode_transition_size(); size_t thread_size(); @@ -55,10 +61,9 @@ namespace Kernel * \param dst appropriate memory donation for the kernel object * \param pd core local Platform_pd object * - * \retval >0 kernel name of the new domain - * \retval 0 failed + * \retval 0 when successful, otherwise !=0 */ - 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); } @@ -67,29 +72,26 @@ namespace Kernel /** * Destruct a domain * - * \param pd_id kernel name of the targeted domain - * - * \retval 0 succeeded - * \retval -1 failed + * \param pd pointer to pd kernel object */ - 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 * - * \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 * function ensures that the in-memory state of the targeted domain gets * 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 * - * \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 * - * \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 * - * \param thread_id kernel name of the targeted thread - * \param cpu_id kernel name of the targeted CPU - * \param pd_id kernel name of the targeted domain - * \param utcb core local pointer to userland thread-context + * \param thread pointer to thread kernel object + * \param cpu_id kernel name of the targeted CPU + * \param pd pointer to pd kernel object + * \param utcb core local pointer to userland thread-context * * \retval 0 suceeded * \retval !=0 failed */ - inline int start_thread(unsigned const thread_id, unsigned const cpu_id, - unsigned const pd_id, Native_utcb * const utcb) + inline int start_thread(Thread * const thread, unsigned const cpu_id, + Pd * const pd, Native_utcb * const utcb) { - return call(call_id_start_thread(), thread_id, cpu_id, pd_id, - (Call_arg)utcb); + return call(call_id_start_thread(), (Call_arg)thread, cpu_id, + (Call_arg)pd, (Call_arg)utcb); } /** * 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 */ - 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 * - * \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 signal_context_id kernel name of the handlers signal context * * \retval 0 succeeded * \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 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); } @@ -188,7 +190,7 @@ namespace Kernel /** * 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 writes amount of write 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 */ - inline unsigned access_thread_regs(unsigned const thread_id, + inline unsigned access_thread_regs(Thread * const thread, unsigned const reads, unsigned const writes, addr_t * const values) { - return call(call_id_access_thread_regs(), thread_id, reads, writes, - (Call_arg)values); + return call(call_id_access_thread_regs(), (Call_arg)thread, + reads, writes, (Call_arg)values); } @@ -245,45 +247,43 @@ namespace Kernel * Create a signal context and assign it to a signal receiver * * \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 * * \retval >0 kernel name of the new signal context * \retval 0 failed */ inline unsigned new_signal_context(addr_t const p, - unsigned const receiver, + Signal_receiver * const receiver, 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 * - * \param context kernel name of the targeted signal context - * - * \retval 0 suceeded - * \retval -1 failed + * \param context pointer to signal context kernel object */ - 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 * - * \param receiver kernel name of the targeted signal receiver + * \param receiver pointer to signal receiver kernel object * * \retval 0 suceeded * \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,14 +296,13 @@ namespace Kernel * \param table guest-physical to host-physical translation * table pointer * - * \retval >0 kernel name of the new VM - * \retval 0 failed + * \retval 0 when successful, otherwise !=0 * * Regaining of the supplied memory is not supported by now. */ - inline unsigned new_vm(void * const dst, void * const state, - unsigned const signal_context_id, - void * const table) + inline int new_vm(void * const dst, void * const state, + unsigned const signal_context_id, + void * const table) { return call(call_id_new_vm(), (Call_arg)dst, (Call_arg)state, (Call_arg)table, signal_context_id); @@ -313,42 +312,39 @@ namespace Kernel /** * 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 -1 failed + * \retval 0 when successful, otherwise !=0 */ - 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 * - * \param vm_id kernel name of the targeted VM + * \param vm pointer to vm kernel object * - * \retval 0 suceeded - * \retval -1 failed + * \retval 0 when successful, otherwise !=0 */ - 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 * - * \param vm_id kernel name of the targeted VM + * \param vm pointer to vm kernel object * - * \retval 0 suceeded - * \retval -1 failed + * \retval 0 when successful, otherwise !=0 */ - 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); } } diff --git a/repos/base-hw/src/core/include/kernel/thread.h b/repos/base-hw/src/core/include/kernel/thread.h index 685703454b..e7c1df3f86 100644 --- a/repos/base-hw/src/core/include/kernel/thread.h +++ b/repos/base-hw/src/core/include/kernel/thread.h @@ -309,10 +309,10 @@ class Kernel::Thread ** Accessors ** ***************/ - unsigned id() const { return Object::id(); } - char const * label() const { return _label; }; - unsigned pd_id() const; + unsigned id() const { return Object::id(); } + char const * label() const { return _label; } char const * pd_label() const; + Pd * const pd() const { return _pd; } }; #endif /* _KERNEL__THREAD_H_ */ diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index c02cb8fbf6..69748e886f 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -40,13 +40,13 @@ namespace Genode protected: Lock _lock; /* safeguard translation table and slab */ - unsigned _id; Native_capability _parent; Native_thread_id _main_thread; char const * const _label; Translation_table * _tt; /* translation table virtual 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 */ public: @@ -68,7 +68,8 @@ namespace Genode */ Platform_pd(Allocator * md_alloc, size_t ram_quota, char const *label) - : _main_thread(0), _label(label) + : _main_thread(0), _label(label), + _kernel_pd(reinterpret_cast(_kernel_pd_data)) { Lock::Guard guard(_lock); @@ -89,8 +90,7 @@ namespace Genode Kernel::mtc()->map(_tt, _pslab); /* create kernel object */ - _id = Kernel::new_pd(&_kernel_pd, this); - if (!_id) { + if (Kernel::new_pd(_kernel_pd, this)) { PERR("failed to create kernel object"); throw Root::Unavailable(); } @@ -146,13 +146,14 @@ namespace Genode ***************/ Lock * lock() { return &_lock; } - unsigned const id() { return _id; } char const * const label() { return _label; } Page_slab * page_slab() { return _pslab; } Translation_table * translation_table() { return _tt; } Translation_table * translation_table_phys() { return _tt_phys; } void page_slab(Page_slab *pslab) { _pslab = pslab; } + Kernel::Pd * kernel_pd() { return _kernel_pd; } + /***************************** ** Address-space interface ** diff --git a/repos/base-hw/src/core/include/platform_thread.h b/repos/base-hw/src/core/include/platform_thread.h index c4b829c4b9..bc1c2e2e2a 100644 --- a/repos/base-hw/src/core/include/platform_thread.h +++ b/repos/base-hw/src/core/include/platform_thread.h @@ -131,12 +131,12 @@ namespace Genode { /** * Pause this thread */ - void pause() { Kernel::pause_thread(_id); } + void pause() { Kernel::pause_thread(kernel_thread()); } /** * Resume this thread */ - void resume() { Kernel::resume_thread(_id); } + void resume() { Kernel::resume_thread(kernel_thread()); } /** * Cancel currently blocking operation @@ -191,6 +191,9 @@ namespace Genode { Native_thread_id id() const { return _id; } Ram_dataspace_capability utcb() const { return _utcb; } + + Kernel::Thread * const kernel_thread() { + return reinterpret_cast(_kernel_thread); } }; } diff --git a/repos/base-hw/src/core/include/spec/arm_v7/trustzone/vm_session_component.h b/repos/base-hw/src/core/include/spec/arm_v7/trustzone/vm_session_component.h index 0b600a1462..37bf6d10b1 100644 --- a/repos/base-hw/src/core/include/spec/arm_v7/trustzone/vm_session_component.h +++ b/repos/base-hw/src/core/include/spec/arm_v7/trustzone/vm_session_component.h @@ -35,11 +35,11 @@ class Genode::Vm_session_component : Rpc_entrypoint *_ds_ep; Range_allocator *_ram_alloc; - unsigned _vm_id; char _vm[sizeof(Kernel::Vm)]; Dataspace_component _ds; Dataspace_capability _ds_cap; addr_t _ds_addr; + bool _initialized = false; static size_t _ds_size() { return align_addr(sizeof(Cpu_state_modes), @@ -47,6 +47,9 @@ class Genode::Vm_session_component : addr_t _alloc_ds(size_t &ram_quota); + Kernel::Vm * _kernel_object() { + return reinterpret_cast(_vm); } + public: Vm_session_component(Rpc_entrypoint *ds_ep, diff --git a/repos/base-hw/src/core/include/spec/arm_v7/virtualization/vm_session_component.h b/repos/base-hw/src/core/include/spec/arm_v7/virtualization/vm_session_component.h index a36584339f..5fbafbd2c8 100644 --- a/repos/base-hw/src/core/include/spec/arm_v7/virtualization/vm_session_component.h +++ b/repos/base-hw/src/core/include/spec/arm_v7/virtualization/vm_session_component.h @@ -39,13 +39,13 @@ class Genode::Vm_session_component : Rpc_entrypoint *_ds_ep; Range_allocator *_ram_alloc; - unsigned _vm_id; char _vm[sizeof(Kernel::Vm)]; Dataspace_component _ds; Dataspace_capability _ds_cap; addr_t _ds_addr; Translation_table *_table; Page_slab *_pslab; + bool _initialized = false; static size_t _ds_size() { return align_addr(sizeof(Cpu_state_modes), @@ -54,6 +54,9 @@ class Genode::Vm_session_component : addr_t _alloc_ds(size_t &ram_quota); void _attach(addr_t phys_addr, addr_t vm_addr, size_t size); + Kernel::Vm * _kernel_object() { + return reinterpret_cast(_vm); } + public: Vm_session_component(Rpc_entrypoint *ds_ep, diff --git a/repos/base-hw/src/core/kernel/kernel.cc b/repos/base-hw/src/core/kernel/kernel.cc index a5591a35af..705c930904 100644 --- a/repos/base-hw/src/core/kernel/kernel.cc +++ b/repos/base-hw/src/core/kernel/kernel.cc @@ -119,7 +119,7 @@ namespace Kernel using namespace Genode; - Platform_pd::_id = Pd::id(); + Platform_pd::_kernel_pd = this; /* map exception vector for core */ Kernel::mtc()->map(table, slab); diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index eeb97560ca..7650767024 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -27,9 +27,7 @@ using namespace Kernel; typedef Genode::Thread_state Thread_state; -unsigned Thread::pd_id() const { return _pd ? _pd->id() : 0; } - -bool Thread::_core() const { return pd_id() == core_pd()->id(); } +bool Thread::_core() const { return pd() == core_pd(); } void Thread::_signal_context_kill_pending() { @@ -174,8 +172,8 @@ void Thread::init(Cpu * const cpu, Pd * const pd, /* print log message */ if (START_VERBOSE) { - Genode::printf("start thread %u '%s' in program %u '%s' ", - id(), label(), pd_id(), pd_label()); + Genode::printf("start thread %u '%s' in program '%s' ", + id(), label(), pd_label()); if (NR_OF_CPUS) { Genode::printf("on CPU %u/%u ", cpu->id(), NR_OF_CPUS); } Genode::printf("\n"); @@ -202,47 +200,30 @@ void Thread::_receive_yielded_cpu() void Thread::proceed(unsigned const cpu) { mtc()->switch_to_user(this, cpu); } -char const * Kernel::Thread::pd_label() const -{ - if (_core()) { return "core"; } - if (!_pd) { return "?"; } - return _pd->platform_pd()->label(); -} +char const * Kernel::Thread::pd_label() const { + return (_pd) ? _pd->platform_pd()->label() : "?"; } void Thread::_call_new_pd() { using namespace Genode; - /* create protection domain */ - void * p = (void *) user_arg_1(); - Platform_pd * ppd = (Platform_pd *) user_arg_2(); - Translation_table * tt = ppd->translation_table_phys(); - Pd * const pd = 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); + try { + /* create protection domain */ + void * p = (void *) user_arg_1(); + Platform_pd * ppd = (Platform_pd *) user_arg_2(); + Translation_table * tt = ppd->translation_table_phys(); + new (p) Pd(tt, ppd); + user_arg_0(0); return; - } - /* destruct protection domain */ - pd->~Pd(); - - /* clean up buffers of memory management */ - Cpu::flush_tlb_by_pid(pd->id()); - user_arg_0(0); + } catch(...) { } + user_arg_0(-1); } +void Thread::_call_delete_pd() { reinterpret_cast(user_arg_1())->~Pd(); } + + void Thread::_call_new_thread() { /* create new thread */ @@ -255,28 +236,12 @@ void Thread::_call_new_thread() } -void Thread::_call_delete_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_delete_thread() { + reinterpret_cast(user_arg_1())->~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 */ Cpu * const cpu = cpu_pool()->cpu(user_arg_2()); if (!cpu) { @@ -284,13 +249,10 @@ void Thread::_call_start_thread() user_arg_0(-2); return; } - /* lookup domain */ - Pd * const pd = Pd::pool()->object(user_arg_3()); - if (!pd) { - PWRN("failed to lookup domain"); - user_arg_0(-3); - return; - } + + Thread * const thread = (Thread*) user_arg_1(); + Pd * const pd = (Pd *) user_arg_3(); + /* start thread */ thread->init(cpu, pd, (Native_utcb *)user_arg_4(), 1); user_arg_0(0); @@ -300,38 +262,19 @@ void Thread::_call_start_thread() void Thread::_call_pause_current_thread() { _pause(); } -void Thread::_call_pause_thread() -{ - /* 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_pause_thread() { + reinterpret_cast(user_arg_1())->_pause(); } -void Thread::_call_resume_thread() -{ - /* 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_thread() { + user_arg_0(reinterpret_cast(user_arg_1())->_resume()); } void Thread::_call_resume_local_thread() { /* lookup thread */ 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"); user_arg_0(0); return; @@ -349,9 +292,7 @@ void Thread_event::_signal_acknowledged() Thread_event::Thread_event(Thread * const t) -: - _thread(t), _signal_context(0) -{ } +: _thread(t), _signal_context(0) { } void Thread_event::submit() @@ -415,17 +356,8 @@ void Thread::_call_send_reply_msg() 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 */ + Thread * const t = (Thread*) user_arg_1(); unsigned const event_id = user_arg_2(); unsigned const signal_context_id = user_arg_3(); 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() { /* get targeted thread */ - unsigned const thread_id = user_arg_1(); unsigned const reads = user_arg_2(); unsigned const writes = user_arg_3(); - Thread * const t = Thread::pool()->object(thread_id); + Thread * const t = (Thread*) user_arg_1(); if (!t) { PWRN("unknown thread"); user_arg_0(reads + writes); @@ -640,19 +571,11 @@ void Thread::_call_new_signal_receiver() 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*/ - void * const p = (void *)user_arg_1(); - unsigned const imprint = user_arg_3(); - Signal_context * const c = new (p) Signal_context(r, imprint); + void * const p = (void *)user_arg_1(); + Signal_receiver * const r = (Signal_receiver *) user_arg_2(); + unsigned const imprint = user_arg_3(); + Signal_context * const c = new (p) Signal_context(r, imprint); user_arg_0(c->id()); } @@ -757,37 +680,12 @@ void Thread::_call_kill_signal_context() } -void Thread::_call_delete_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_context() { + reinterpret_cast(user_arg_1())->~Signal_context(); } -void Thread::_call_delete_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); -} +void Thread::_call_delete_signal_receiver() { + reinterpret_cast(user_arg_1())->~Signal_receiver(); } int Thread::_read_reg(addr_t const id, addr_t & value) const diff --git a/repos/base-hw/src/core/kernel/vm_thread.cc b/repos/base-hw/src/core/kernel/vm_thread.cc index 82e45ade06..e22d83836c 100644 --- a/repos/base-hw/src/core/kernel/vm_thread.cc +++ b/repos/base-hw/src/core/kernel/vm_thread.cc @@ -14,7 +14,7 @@ /* core includes */ #include -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_run_vm() { user_arg_0(-1); } void Kernel::Thread::_call_pause_vm() { user_arg_0(-1); } diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index c3bb25f193..cff6c34a85 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -254,7 +254,7 @@ bool Genode::unmap_local(addr_t virt_addr, size_t num_pages) Kernel::core_pd()->platform_pd()->page_slab()); /* update translation caches of all CPUs */ - Kernel::update_pd(Kernel::core_pd()->id()); + Kernel::update_pd(Kernel::core_pd()); return true; } catch(...) { PERR("tried to remove invalid region!"); diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index 92feba4c94..58165cc763 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -21,10 +21,7 @@ Platform_pd::~Platform_pd() { Lock::Guard guard(_lock); - if (Kernel::delete_pd(_id)) { - PERR("failed to destruct protection domain at kernel"); - } - + Kernel::delete_pd(_kernel_pd); _tt->remove_translation(platform()->vm_start(), platform()->vm_size(), _pslab); diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 74d0fed25d..c1d95dab1a 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -74,7 +74,7 @@ Platform_thread::~Platform_thread() rm->remove_client(cap); } /* 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[1] = Reg_id::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"); return -1; } @@ -206,7 +206,8 @@ int Platform_thread::start(void * const ip, void * const sp) unsigned const cpu = _location.valid() ? _location.xpos() : Cpu::primary_id(); _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"); return -1; } @@ -220,7 +221,8 @@ void Platform_thread::pager(Pager_object * const pager) if (pager) { unsigned const sc_id = pager->signal_context_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(pager); return; } @@ -228,7 +230,7 @@ void Platform_thread::pager(Pager_object * const pager) PERR("failed to attach signal context to fault"); return; } 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; return; } @@ -259,7 +261,8 @@ Thread_state Platform_thread::state() Genode::memcpy(dst, src, size); Thread_state thread_state; Cpu_state * const cpu_state = static_cast(&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(); } return thread_state; @@ -274,7 +277,8 @@ void Platform_thread::state(Thread_state thread_state) void * dst = Thread_base::myself()->utcb()->base(); Genode::memcpy(dst, src, size); Cpu_state * const cpu_state = static_cast(&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(); } }; diff --git a/repos/base-hw/src/core/rm_session_support.cc b/repos/base-hw/src/core/rm_session_support.cc index 64b220204d..bbf264ddfe 100644 --- a/repos/base-hw/src/core/rm_session_support.cc +++ b/repos/base-hw/src/core/rm_session_support.cc @@ -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()); /* 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"); continue; } - unsigned const thread_id = pt->id(); typedef Kernel::Thread_reg_id Reg_id; static addr_t const read_regs[] = { 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(); memcpy(utcb, read_regs, sizeof(read_regs)); 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"); continue; } diff --git a/repos/base-hw/src/core/signal_session_component.cc b/repos/base-hw/src/core/signal_session_component.cc index 0a9400131d..008e2ca320 100644 --- a/repos/base-hw/src/core/signal_session_component.cc +++ b/repos/base-hw/src/core/signal_session_component.cc @@ -35,8 +35,7 @@ Signal_receiver_capability Signal_session_component::alloc_receiver() /* create kernel object for receiver */ addr_t donation = Receiver::kernel_donation(p); unsigned const id = Kernel::new_signal_receiver(donation); - if (!id) - { + if (!id) { /* clean up */ _receivers_slab.free(p, Receiver::size()); PERR("failed to create signal receiver"); @@ -67,9 +66,17 @@ void Signal_session_component::free_receiver(Signal_receiver_capability cap) Signal_context_capability -Signal_session_component::alloc_context(Signal_receiver_capability r, +Signal_session_component::alloc_context(Signal_receiver_capability src, 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 */ void * 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 */ addr_t donation = Context::kernel_donation(p); - unsigned const id = Kernel::new_signal_context(donation, r.dst(), imprint); - if (!id) - { + unsigned const id = Kernel::new_signal_context(donation, sr, imprint); + if (!id) { /* clean up */ _contexts_slab.free(p, Context::size()); 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) { /* release kernel resources */ - if (Kernel::delete_signal_context(c->id())) - { - /* clean-up */ - c->release(); - PERR("failed to kill signal context"); - throw Kill_context_failed(); - } + Kernel::Signal_context *sc = + (Kernel::Signal_context*) Context::kernel_donation(c); + Kernel::delete_signal_context(sc); + /* release core resources */ _contexts.remove_locked(c); 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) { /* release kernel resources */ - if (Kernel::delete_signal_receiver(r->id())) - { - /* clean-up */ - r->release(); - PERR("failed to kill signal receiver"); - throw Kill_receiver_failed(); - } + Kernel::Signal_receiver *sr = + (Kernel::Signal_receiver*) Receiver::kernel_donation(r); + Kernel::delete_signal_receiver(sr); + /* release core resources */ _receivers.remove_locked(r); r->~Signal_session_receiver(); diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread.cc b/repos/base-hw/src/core/spec/arm/kernel/thread.cc index daae32c133..c12cdcac8b 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread.cc @@ -126,5 +126,6 @@ void Thread::_mmu_exception() 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(); } } diff --git a/repos/base-hw/src/core/spec/arm_v7/kernel/vm_thread.cc b/repos/base-hw/src/core/spec/arm_v7/kernel/vm_thread.cc index ff73bb4d91..cf1a03bed5 100644 --- a/repos/base-hw/src/core/spec/arm_v7/kernel/vm_thread.cc +++ b/repos/base-hw/src/core/spec/arm_v7/kernel/vm_thread.cc @@ -17,22 +17,20 @@ void Kernel::Thread::_call_delete_vm() { - Vm * const vm = Vm::pool()->object(user_arg_1()); - if (vm) vm->~Vm(); - user_arg_0(vm ? 0 : -1); + reinterpret_cast(user_arg_1())->~Vm(); + user_arg_0(0); } -void Kernel::Thread::_call_run_vm() { - Vm * const vm = Vm::pool()->object(user_arg_1()); - if (vm) vm->run(); - user_arg_0(vm ? 0 : -1); +void Kernel::Thread::_call_run_vm() +{ + reinterpret_cast(user_arg_1())->run(); + user_arg_0(0); } void Kernel::Thread::_call_pause_vm() { - Vm * const vm = Vm::pool()->object(user_arg_1()); - if (vm) vm->pause(); - user_arg_0(vm ? 0 : -1); + reinterpret_cast(user_arg_1())->pause(); + user_arg_0(0); } diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm_thread.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm_thread.cc index d2fe2743e3..f28642dd92 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm_thread.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm_thread.cc @@ -21,7 +21,7 @@ void Kernel::Thread::_call_new_vm() auto const context = Signal_context::pool()->object(user_arg_4()); if (!context) { PWRN("failed to lookup signal context"); - user_arg_0(0); + user_arg_0(-1); return; } @@ -31,8 +31,6 @@ void Kernel::Thread::_call_new_vm() void * const table = reinterpret_cast(user_arg_3()); Cpu_state_modes * const state = reinterpret_cast(user_arg_2()); - Vm * const vm = new (allocator) Vm(state, context, table); - - /* return kernel name of virtual machine */ - user_arg_0(vm->id()); + new (allocator) Vm(state, context, table); + user_arg_0(0); } diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc index 0f2e007b4f..f22540cf78 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc @@ -20,18 +20,23 @@ using namespace Genode; void Vm_session_component::exception_handler(Signal_context_capability handler) { - if (_vm_id) { - PWRN("Cannot register exception_handler repeatedly"); + if (_initialized) { + PWRN("Cannot initialize kernel vm object twice!"); 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, size_t ram_quota) -: _ds_ep(ds_ep), _vm_id(0), - _ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0), +: _ds_ep(ds_ep), _ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0), _ds_cap(static_cap_cast(_ds_ep->manage(&_ds))) { _ds.assign_core_local_addr(core_env()->rm_session()->attach(_ds_cap)); diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm_thread.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm_thread.cc index 737e8d2cd6..ea2a2b0a93 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm_thread.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm_thread.cc @@ -20,7 +20,7 @@ void Kernel::Thread::_call_new_vm() auto const context = Signal_context::pool()->object(user_arg_4()); if (!context) { PWRN("failed to lookup signal context"); - user_arg_0(0); + user_arg_0(-1); return; } @@ -30,9 +30,7 @@ void Kernel::Thread::_call_new_vm() void * const table = reinterpret_cast(user_arg_3()); Cpu_state_modes * const state = reinterpret_cast(user_arg_2()); - Vm * const vm = new (allocator) Vm(state, context, table); - - /* return kernel name of virtual machine */ - user_arg_0(vm->id()); + new (allocator) Vm(state, context, table); + user_arg_0(0); } diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc index 0357b4d6a6..172bc5758d 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc @@ -25,14 +25,20 @@ using namespace Genode; void Vm_session_component::exception_handler(Signal_context_capability handler) { - if (_vm_id) { - PWRN("Cannot register exception_handler repeatedly"); + if (_initialized) { + PWRN("Cannot initialize kernel vm object twice!"); return; } + Core_mem_allocator * cma = static_cast(platform()->core_mem_alloc()); - _vm_id = Kernel::new_vm(&_vm, (void*)_ds.core_local_addr(), handler.dst(), - cma->phys_addr(_table)); + if (Kernel::new_vm(&_vm, (void*)_ds.core_local_addr(), handler.dst(), + 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, size_t ram_quota) -: _ds_ep(ds_ep), _vm_id(0), - _ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0), +: _ds_ep(ds_ep), _ds(_ds_size(), _alloc_ds(ram_quota), UNCACHED, true, 0), _ds_cap(static_cap_cast(_ds_ep->manage(&_ds))) { _ds.assign_core_local_addr(core_env()->rm_session()->attach(_ds_cap)); diff --git a/repos/base-hw/src/core/spec/arm_v7/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/vm_session_component.cc index 34088a3dc6..a941bcb06f 100644 --- a/repos/base-hw/src/core/spec/arm_v7/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/vm_session_component.cc @@ -32,14 +32,14 @@ addr_t Vm_session_component::_alloc_ds(size_t &ram_quota) 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?"); } 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?"); } @@ -49,7 +49,7 @@ Vm_session_component::~Vm_session_component() /* dissolve VM dataspace from service entry point */ _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 */ core_env()->rm_session()->detach(_ds.core_local_addr());