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
{
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);
}
}

View File

@ -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_ */

View File

@ -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*>(_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 **

View File

@ -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*>(_kernel_thread); }
};
}

View File

@ -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<Kernel::Vm*>(_vm); }
public:
Vm_session_component(Rpc_entrypoint *ds_ep,

View File

@ -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<Kernel::Vm*>(_vm); }
public:
Vm_session_component(Rpc_entrypoint *ds_ep,

View File

@ -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);

View File

@ -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<Pd*>(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<Thread*>(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<Thread*>(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<Thread*>(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<Signal_context*>(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<Signal_receiver*>(user_arg_1())->~Signal_receiver(); }
int Thread::_read_reg(addr_t const id, addr_t & value) const

View File

@ -14,7 +14,7 @@
/* core includes */
#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_run_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());
/* 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!");

View File

@ -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);

View File

@ -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<Rm_client *>(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<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();
}
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<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();
}
};

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());
/* 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;
}

View File

@ -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();

View File

@ -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(); }
}

View File

@ -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<Vm*>(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<Vm*>(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<Vm*>(user_arg_1())->pause();
user_arg_0(0);
}

View File

@ -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<void *>(user_arg_3());
Cpu_state_modes * const state =
reinterpret_cast<Cpu_state_modes *>(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);
}

View File

@ -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<Dataspace>(_ds_ep->manage(&_ds)))
{
_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());
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<void *>(user_arg_3());
Cpu_state_modes * const state =
reinterpret_cast<Cpu_state_modes *>(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);
}

View File

@ -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<Core_mem_allocator*>(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<Dataspace>(_ds_ep->manage(&_ds)))
{
_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)
{
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());