hw: turn Kernel_object into Genode::Constructible

Fix #3531
This commit is contained in:
Stefan Kalkowski 2019-10-16 15:07:11 +02:00 committed by Christian Helmuth
parent 3e3fb63863
commit f6435d91fc
30 changed files with 304 additions and 327 deletions

View File

@ -18,7 +18,6 @@
/* core includes */ /* core includes */
#include <kernel/irq.h> #include <kernel/irq.h>
#include <irq_root.h> #include <irq_root.h>
#include <irq_args.h>
#include <core_env.h> #include <core_env.h>
/* base-internal includes */ /* base-internal includes */
@ -35,10 +34,7 @@ unsigned Irq_session_component::_find_irq_number(const char * const args)
void Irq_session_component::ack_irq() void Irq_session_component::ack_irq()
{ {
using Kernel::User_irq; if (_kobj.constructed()) Kernel::ack_irq(*_kobj);
if (!_sig_cap.valid()) { return; }
User_irq * const kirq = reinterpret_cast<User_irq*>(&_kernel_object);
Kernel::ack_irq(kirq);
} }
@ -51,8 +47,8 @@ void Irq_session_component::sigh(Signal_context_capability cap)
_sig_cap = cap; _sig_cap = cap;
if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number, if (!_kobj.create(_irq_number, _irq_args.trigger(), _irq_args.polarity(),
Capability_space::capid(_sig_cap))) Capability_space::capid(_sig_cap)))
warning("invalid signal handler for IRQ ", _irq_number); warning("invalid signal handler for IRQ ", _irq_number);
} }
@ -61,18 +57,16 @@ Irq_session_component::~Irq_session_component()
{ {
using namespace Kernel; using namespace Kernel;
User_irq * kirq = reinterpret_cast<User_irq*>(&_kernel_object);
_irq_alloc.free((void *)(addr_t)_irq_number); _irq_alloc.free((void *)(addr_t)_irq_number);
if (_sig_cap.valid())
Kernel::delete_irq(kirq);
} }
Irq_session_component::Irq_session_component(Range_allocator &irq_alloc, Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
const char * const args) const char * const args)
: : _irq_args(args),
_irq_number(Platform::irq(_find_irq_number(args))), _irq_alloc(irq_alloc), _irq_number(Platform::irq(_irq_args.irq_number())),
_is_msi(false), _address(0), _value(0) _irq_alloc(irq_alloc),
_kobj(), _is_msi(false), _address(0), _value(0)
{ {
const long mmconf = const long mmconf =
Arg_string::find_arg(args, "device_config_phys").long_value(0); Arg_string::find_arg(args, "device_config_phys").long_value(0);
@ -89,8 +83,4 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
error("unavailable interrupt ", _irq_number, " requested"); error("unavailable interrupt ", _irq_number, " requested");
throw Service_denied(); throw Service_denied();
} }
Irq_args const irq_args(args);
Kernel::irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity());
} }

View File

@ -19,6 +19,8 @@
#include <util/list.h> #include <util/list.h>
#include <irq_session/capability.h> #include <irq_session/capability.h>
#include <irq_args.h>
#include <object.h>
#include <kernel/irq.h> #include <kernel/irq.h>
namespace Genode { class Irq_session_component; } namespace Genode { class Irq_session_component; }
@ -31,13 +33,13 @@ class Genode::Irq_session_component : public Rpc_object<Irq_session>,
friend class List<Irq_session_component>; friend class List<Irq_session_component>;
unsigned _irq_number; Irq_args const _irq_args;
Range_allocator &_irq_alloc; unsigned _irq_number;
Genode::uint8_t _kernel_object[sizeof(Kernel::User_irq)]; Range_allocator & _irq_alloc;
bool _is_msi; Kernel_object<Kernel::User_irq> _kobj;
addr_t _address, _value; bool _is_msi;
addr_t _address, _value;
Signal_context_capability _sig_cap { }; Signal_context_capability _sig_cap { };
unsigned _find_irq_number(const char * const args); unsigned _find_irq_number(const char * const args);

View File

@ -31,6 +31,7 @@ namespace Kernel
class Vm; class Vm;
class User_irq; class User_irq;
using Native_utcb = Genode::Native_utcb; using Native_utcb = Genode::Native_utcb;
template <typename T> class Core_object_identity;
/** /**
* Kernel names of the kernel calls * Kernel names of the kernel calls
@ -60,15 +61,14 @@ namespace Kernel
constexpr Call_arg call_id_delete_obj() { return 122; } constexpr Call_arg call_id_delete_obj() { return 122; }
constexpr Call_arg call_id_cancel_thread_blocking() { return 123; } constexpr Call_arg call_id_cancel_thread_blocking() { return 123; }
constexpr Call_arg call_id_new_core_thread() { return 124; } constexpr Call_arg call_id_new_core_thread() { return 124; }
constexpr Call_arg call_id_irq_mode() { return 125; }
/** /**
* Invalidate TLB entries for the `pd` in region `addr`, `sz` * Invalidate TLB entries for the `pd` in region `addr`, `sz`
*/ */
inline void invalidate_tlb(Pd * const pd, addr_t const addr, inline void invalidate_tlb(Pd & pd, addr_t const addr,
size_t const sz) size_t const sz)
{ {
call(call_id_invalidate_tlb(), (Call_arg)pd, (Call_arg)addr, call(call_id_invalidate_tlb(), (Call_arg)&pd, (Call_arg)addr,
(Call_arg)sz); (Call_arg)sz);
} }
@ -79,9 +79,9 @@ namespace Kernel
* \param thread kernel object of the targeted thread * \param thread kernel object of the targeted thread
* \param quota new CPU quota value * \param quota new CPU quota value
*/ */
inline void thread_quota(Kernel::Thread * const thread, size_t const quota) inline void thread_quota(Kernel::Thread & thread, size_t const quota)
{ {
call(call_id_thread_quota(), (Call_arg)thread, (Call_arg)quota); call(call_id_thread_quota(), (Call_arg)&thread, (Call_arg)quota);
} }
@ -104,9 +104,9 @@ namespace Kernel
* continue the execution of a thread no matter what state the thread is * continue the execution of a thread no matter what state the thread is
* in. * in.
*/ */
inline void pause_thread(Thread * const thread) inline void pause_thread(Thread & thread)
{ {
call(call_id_pause_thread(), (Call_arg)thread); call(call_id_pause_thread(), (Call_arg)&thread);
} }
@ -115,9 +115,9 @@ namespace Kernel
* *
* \param thread pointer to thread kernel object * \param thread pointer to thread kernel object
*/ */
inline void resume_thread(Thread * const thread) inline void resume_thread(Thread & thread)
{ {
call(call_id_resume_thread(), (Call_arg)thread); call(call_id_resume_thread(), (Call_arg)&thread);
} }
@ -132,11 +132,11 @@ namespace Kernel
* \retval 0 suceeded * \retval 0 suceeded
* \retval !=0 failed * \retval !=0 failed
*/ */
inline int start_thread(Thread * const thread, unsigned const cpu_id, inline int start_thread(Thread & thread, unsigned const cpu_id,
Pd * const pd, Native_utcb * const utcb) Pd & pd, Native_utcb & utcb)
{ {
return call(call_id_start_thread(), (Call_arg)thread, cpu_id, return call(call_id_start_thread(), (Call_arg)&thread, cpu_id,
(Call_arg)pd, (Call_arg)utcb); (Call_arg)&pd, (Call_arg)&utcb);
} }
@ -155,9 +155,9 @@ namespace Kernel
* limit the time a parent waits for a server when closing a session * limit the time a parent waits for a server when closing a session
* of one of its children. * of one of its children.
*/ */
inline void cancel_thread_blocking(Thread * const thread) inline void cancel_thread_blocking(Thread & thread)
{ {
call(call_id_cancel_thread_blocking(), (Call_arg)thread); call(call_id_cancel_thread_blocking(), (Call_arg)&thread);
} }
@ -167,10 +167,10 @@ namespace Kernel
* \param thread pointer to thread kernel object * \param thread pointer to thread kernel object
* \param signal_context_id capability id of the page-fault handler * \param signal_context_id capability id of the page-fault handler
*/ */
inline void thread_pager(Thread * const thread, inline void thread_pager(Thread & thread,
capid_t const signal_context_id) capid_t const signal_context_id)
{ {
call(call_id_thread_pager(), (Call_arg)thread, signal_context_id); call(call_id_thread_pager(), (Call_arg)&thread, signal_context_id);
} }
@ -179,9 +179,9 @@ namespace Kernel
* *
* \param vm pointer to vm kernel object * \param vm pointer to vm kernel object
*/ */
inline void run_vm(Vm * const vm) inline void run_vm(Vm & vm)
{ {
call(call_id_run_vm(), (Call_arg) vm); call(call_id_run_vm(), (Call_arg) &vm);
} }
@ -190,33 +190,9 @@ namespace Kernel
* *
* \param vm pointer to vm kernel object * \param vm pointer to vm kernel object
*/ */
inline void pause_vm(Vm * const vm) inline void pause_vm(Vm & vm)
{ {
call(call_id_pause_vm(), (Call_arg) vm); call(call_id_pause_vm(), (Call_arg) &vm);
}
/**
* Create an interrupt object
*
* \param p memory donation for the irq object
* \param irq_nr interrupt number
* \param signal_context_id capability id of the signal context
*/
inline int new_irq(addr_t const p, unsigned irq_nr,
capid_t signal_context_id)
{
return call(call_id_new_irq(), (Call_arg) p, irq_nr, signal_context_id);
}
/**
* Set trigger/polaruty of IRQ
* \param irq_nr interrupt number
* \param trigger low or edge
* \param polarity low or high
*/
inline void irq_mode(unsigned irq_nr, unsigned trigger, unsigned polarity)
{
call(call_id_irq_mode(), irq_nr, trigger, polarity);
} }
/** /**
@ -224,40 +200,9 @@ namespace Kernel
* *
* \param irq pointer to interrupt kernel object * \param irq pointer to interrupt kernel object
*/ */
inline void ack_irq(User_irq * const irq) inline void ack_irq(User_irq & irq)
{ {
call(call_id_ack_irq(), (Call_arg) irq); call(call_id_ack_irq(), (Call_arg) &irq);
}
/**
* Destruct an interrupt object
*
* \param irq pointer to interrupt kernel object
*/
inline void delete_irq(User_irq * const irq)
{
call(call_id_delete_irq(), (Call_arg) irq);
}
/**
* Create a new object identity for a thread
*
* \param dst memory donation for the new object
* \param cap capability id of the targeted thread
*/
inline capid_t new_obj(void * const dst, capid_t const cap)
{
return call(call_id_new_obj(), (Call_arg)dst, (Call_arg)cap);
}
/**
* Destroy an object identity
*
* \param dst pointer to the object identity object
*/
inline void delete_obj(void * const dst)
{
call(call_id_delete_obj(), (Call_arg)dst);
} }
} }

View File

@ -15,9 +15,6 @@
#ifndef _CORE__KERNEL__IPC_NODE_H_ #ifndef _CORE__KERNEL__IPC_NODE_H_
#define _CORE__KERNEL__IPC_NODE_H_ #define _CORE__KERNEL__IPC_NODE_H_
/* Genode includes */
#include <util/construct_at.h>
/* base-local includes */ /* base-local includes */
#include <base/internal/native_utcb.h> #include <base/internal/native_utcb.h>

View File

@ -30,3 +30,14 @@ Kernel::Irq::Pool &Kernel::User_irq::_pool()
static Irq::Pool p; static Irq::Pool p;
return p; return p;
} }
Kernel::User_irq::User_irq(unsigned const irq,
Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
Signal_context & context)
: Irq(irq, _pool()), _context(context)
{
disable();
cpu_pool().executing_cpu().pic().irq_mode(_irq_nr, trigger, polarity);
}

View File

@ -135,8 +135,10 @@ class Kernel::User_irq : public Kernel::Irq, public Kernel::Object
/** /**
* Construct object that signals interrupt 'irq' via signal 'context' * Construct object that signals interrupt 'irq' via signal 'context'
*/ */
User_irq(unsigned const irq, Signal_context &context) User_irq(unsigned const irq,
: Irq(irq, _pool()), _context(context) { disable(); } Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
Signal_context & context);
/** /**
* Destructor * Destructor
@ -157,6 +159,33 @@ class Kernel::User_irq : public Kernel::Irq, public Kernel::Object
*/ */
static User_irq * object(unsigned const irq) { static User_irq * object(unsigned const irq) {
return dynamic_cast<User_irq*>(_pool().object(irq)); } return dynamic_cast<User_irq*>(_pool().object(irq)); }
/**
* Syscall to create user irq object
*
* \param irq reference to constructible object
* \param nr interrupt number
* \param trigger level or edge
* \param polarity low or high
* \param sig capability of signal context
*/
static capid_t syscall_create(Genode::Kernel_object<User_irq> & irq,
unsigned nr,
Genode::Irq_session::Trigger trigger,
Genode::Irq_session::Polarity polarity,
capid_t sig)
{
return call(call_id_new_irq(), (Call_arg)&irq, nr,
(trigger << 2) | polarity, sig);
}
/**
* Syscall to delete user irq object
*
* \param irq reference to constructible object
*/
static void syscall_destroy(Genode::Kernel_object<User_irq> &irq) {
call(call_id_delete_irq(), (Call_arg) &irq); }
}; };
#endif /* _CORE__KERNEL__IRQ_H_ */ #endif /* _CORE__KERNEL__IRQ_H_ */

View File

@ -18,8 +18,10 @@
#include <util/avl_tree.h> #include <util/avl_tree.h>
#include <util/bit_allocator.h> #include <util/bit_allocator.h>
#include <util/list.h> #include <util/list.h>
#include <util/reconstructible.h>
/* core includes */ /* core includes */
#include <kernel/core_interface.h>
#include <kernel/interface.h> #include <kernel/interface.h>
#include <kernel/kernel.h> #include <kernel/kernel.h>
@ -192,6 +194,13 @@ class Kernel::Core_object_identity : public Object_identity,
Object_identity_reference(this, core_pd()) { } Object_identity_reference(this, core_pd()) { }
capid_t core_capid() { return capid(); } capid_t core_capid() { return capid(); }
static capid_t syscall_create(Genode::Constructible<Core_object_identity<T>> & t,
capid_t const cap) {
return call(call_id_new_obj(), (Call_arg)&t, (Call_arg)cap); }
static void syscall_destroy(Genode::Constructible<Core_object_identity<T>> & t) {
call(call_id_delete_obj(), (Call_arg)&t); }
}; };

View File

@ -19,9 +19,11 @@
#include <hw/assert.h> #include <hw/assert.h>
#include <cpu.h> #include <cpu.h>
#include <kernel/core_interface.h> #include <kernel/core_interface.h>
#include <kernel/object.h> #include <object.h>
#include <translation_table.h> #include <translation_table.h>
#include <util/reconstructible.h>
namespace Genode { namespace Genode {
class Platform_pd; class Platform_pd;
} }
@ -51,6 +53,7 @@ class Kernel::Pd : public Kernel::Object
Genode::Platform_pd &_platform_pd; Genode::Platform_pd &_platform_pd;
Capid_allocator _capid_alloc { }; Capid_allocator _capid_alloc { };
Object_identity_reference_tree _cap_tree { }; Object_identity_reference_tree _cap_tree { };
bool _core_pd { false };
public: public:
@ -69,6 +72,12 @@ class Kernel::Pd : public Kernel::Object
{ {
capid_t invalid = _capid_alloc.alloc(); capid_t invalid = _capid_alloc.alloc();
assert(invalid == cap_id_invalid()); assert(invalid == cap_id_invalid());
static bool first_pd = true;
if (first_pd) {
_core_pd = true;
first_pd = false;
}
} }
~Pd() ~Pd()
@ -77,16 +86,16 @@ class Kernel::Pd : public Kernel::Object
oir->~Object_identity_reference(); oir->~Object_identity_reference();
} }
static capid_t syscall_create(void * const dst, static capid_t syscall_create(Genode::Kernel_object<Pd> & p,
Hw::Page_table &tt, Hw::Page_table & tt,
Genode::Platform_pd &pd) Genode::Platform_pd & pd)
{ {
return call(call_id_new_pd(), (Call_arg)dst, return call(call_id_new_pd(), (Call_arg)&p,
(Call_arg)&tt, (Call_arg)&pd); (Call_arg)&tt, (Call_arg)&pd);
} }
static void syscall_destroy(Pd * const pd) { static void syscall_destroy(Genode::Kernel_object<Pd> & p) {
call(call_id_delete_pd(), (Call_arg)pd); } call(call_id_delete_pd(), (Call_arg)&p); }
/** /**
* Check whether the given 'cpu' needs to do some maintainance * Check whether the given 'cpu' needs to do some maintainance
@ -103,6 +112,13 @@ class Kernel::Pd : public Kernel::Object
Hw::Page_table &translation_table() { return _table; } Hw::Page_table &translation_table() { return _table; }
Capid_allocator &capid_alloc() { return _capid_alloc; } Capid_allocator &capid_alloc() { return _capid_alloc; }
Object_identity_reference_tree &cap_tree() { return _cap_tree; } Object_identity_reference_tree &cap_tree() { return _cap_tree; }
bool core_pd() const { return _core_pd; }
}; };
template<>
inline Kernel::Core_object_identity<Kernel::Pd>::Core_object_identity(Kernel::Pd & pd)
: Object_identity(pd),
Object_identity_reference(this, pd.core_pd() ? pd : core_pd()) { }
#endif /* _CORE__KERNEL__PD_H_ */ #endif /* _CORE__KERNEL__PD_H_ */

View File

@ -55,7 +55,7 @@ Signal_context_killer::~Signal_context_killer() { cancel_waiting(); }
void Signal_context::_deliverable() void Signal_context::_deliverable()
{ {
if (_submits) { _receiver->_add_deliverable(this); } if (_submits) { _receiver._add_deliverable(this); }
} }
@ -118,16 +118,15 @@ int Signal_context::kill(Signal_context_killer * const k)
Signal_context::~Signal_context() Signal_context::~Signal_context()
{ {
if (_killer) { _killer->_signal_context_kill_failed(); } if (_killer) { _killer->_signal_context_kill_failed(); }
_receiver->_context_destructed(this); _receiver._context_destructed(this);
} }
Signal_context::Signal_context(Signal_receiver * const r, addr_t const imprint) Signal_context::Signal_context(Signal_receiver & r, addr_t const imprint)
: : _receiver(r),
_receiver(r), _imprint(imprint)
_imprint(imprint)
{ {
r->_add_context(this); r._add_context(this);
} }
@ -164,7 +163,7 @@ void Signal_receiver::_listen()
/* communicate signal data to handler */ /* communicate signal data to handler */
_handlers.dequeue([&] (Signal_handler::Fifo_element &elem) { _handlers.dequeue([&] (Signal_handler::Fifo_element &elem) {
auto const handler = &elem.object(); auto const handler = &elem.object();
handler->_receiver = 0; handler->_receiver = nullptr;
handler->_receive_signal(&data, sizeof(data)); handler->_receive_signal(&data, sizeof(data));
}); });
context->_delivered(); context->_delivered();

View File

@ -16,9 +16,10 @@
/* Genode includes */ /* Genode includes */
#include <base/signal.h> #include <base/signal.h>
#include <util/reconstructible.h>
#include <kernel/core_interface.h> #include <kernel/core_interface.h>
#include <kernel/object.h> #include <object.h>
namespace Kernel namespace Kernel
{ {
@ -160,7 +161,7 @@ class Kernel::Signal_context : public Kernel::Object
Fifo_element _deliver_fe { *this }; Fifo_element _deliver_fe { *this };
Fifo_element _contexts_fe { *this }; Fifo_element _contexts_fe { *this };
Signal_receiver * const _receiver; Signal_receiver & _receiver;
addr_t const _imprint; addr_t const _imprint;
Signal_context_killer * _killer { nullptr }; Signal_context_killer * _killer { nullptr };
unsigned _submits { 0 }; unsigned _submits { 0 };
@ -197,7 +198,7 @@ class Kernel::Signal_context : public Kernel::Object
* *
* \throw Assign_to_receiver_failed * \throw Assign_to_receiver_failed
*/ */
Signal_context(Signal_receiver * const r, addr_t const imprint); Signal_context(Signal_receiver & r, addr_t const imprint);
/** /**
* Submit the signal * Submit the signal
@ -233,12 +234,12 @@ class Kernel::Signal_context : public Kernel::Object
* *
* \retval capability id of the new kernel object * \retval capability id of the new kernel object
*/ */
static capid_t syscall_create(void * p, static capid_t syscall_create(Genode::Kernel_object<Signal_context> &c,
Signal_receiver * const receiver, Signal_receiver & receiver,
addr_t const imprint) addr_t const imprint)
{ {
return call(call_id_new_signal_context(), (Call_arg)p, return call(call_id_new_signal_context(), (Call_arg)&c,
(Call_arg)receiver, (Call_arg)imprint); (Call_arg)&receiver, (Call_arg)imprint);
} }
/** /**
@ -246,8 +247,8 @@ class Kernel::Signal_context : public Kernel::Object
* *
* \param context pointer to signal context kernel object * \param context pointer to signal context kernel object
*/ */
static void syscall_destroy(Signal_context * const context) { static void syscall_destroy(Genode::Kernel_object<Signal_context> &c) {
call(call_id_delete_signal_context(), (Call_arg)context); } call(call_id_delete_signal_context(), (Call_arg)&c); }
}; };
class Kernel::Signal_receiver : public Kernel::Object class Kernel::Signal_receiver : public Kernel::Object
@ -311,16 +312,16 @@ class Kernel::Signal_receiver : public Kernel::Object
* *
* \retval capability id of the new kernel object * \retval capability id of the new kernel object
*/ */
static capid_t syscall_create(void * p) { static capid_t syscall_create(Genode::Kernel_object<Signal_receiver> &r) {
return call(call_id_new_signal_receiver(), (Call_arg)p); } return call(call_id_new_signal_receiver(), (Call_arg)&r); }
/** /**
* Syscall to destruct a signal receiver * Syscall to destruct a signal receiver
* *
* \param receiver pointer to signal receiver kernel object * \param receiver pointer to signal receiver kernel object
*/ */
static void syscall_destroy(Signal_receiver * const receiver) { static void syscall_destroy(Genode::Kernel_object<Signal_receiver> &r) {
call(call_id_delete_signal_receiver(), (Call_arg)receiver); } call(call_id_delete_signal_receiver(), (Call_arg)&r); }
}; };
#endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */ #endif /* _CORE__KERNEL__SIGNAL_RECEIVER_H_ */

View File

@ -15,7 +15,6 @@
/* Genode includes */ /* Genode includes */
#include <base/thread_state.h> #include <base/thread_state.h>
#include <cpu_session/cpu_session.h> #include <cpu_session/cpu_session.h>
#include <util/construct_at.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/unmanaged_singleton.h> #include <base/internal/unmanaged_singleton.h>
@ -47,17 +46,17 @@ Thread::Tlb_invalidation::Tlb_invalidation(Thread & caller, Pd & pd,
} }
Thread::Destroy::Destroy(Thread & caller, Thread & to_delete) Thread::Destroy::Destroy(Thread & caller, Genode::Kernel_object<Thread> & to_delete)
: caller(caller), thread_to_destroy(to_delete) : caller(caller), thread_to_destroy(to_delete)
{ {
thread_to_destroy._cpu->work_list().insert(&_le); thread_to_destroy->_cpu->work_list().insert(&_le);
caller._become_inactive(AWAITS_RESTART); caller._become_inactive(AWAITS_RESTART);
} }
void Thread::Destroy::execute() void Thread::Destroy::execute()
{ {
thread_to_destroy.~Thread(); thread_to_destroy.destruct();
cpu_pool().executing_cpu().work_list().remove(&_le); cpu_pool().executing_cpu().work_list().remove(&_le);
caller._restart(); caller._restart();
} }
@ -193,28 +192,6 @@ size_t Thread::_core_to_kernel_quota(size_t const quota) const
} }
void Thread::_call_new_thread()
{
void * const p = (void *)user_arg_1();
unsigned const priority = user_arg_2();
unsigned const quota = _core_to_kernel_quota(user_arg_3());
char const * const label = (char *)user_arg_4();
Core_object<Thread> * co =
Genode::construct_at<Core_object<Thread> >(p, priority, quota, label);
user_arg_0(co->core_capid());
}
void Thread::_call_new_core_thread()
{
void * const p = (void *)user_arg_1();
char const * const label = (char *)user_arg_2();
Core_object<Thread> * co =
Genode::construct_at<Core_object<Thread> >(p, label);
user_arg_0(co->core_capid());
}
void Thread::_call_thread_quota() void Thread::_call_thread_quota()
{ {
Thread * const thread = (Thread *)user_arg_1(); Thread * const thread = (Thread *)user_arg_1();
@ -227,7 +204,7 @@ void Thread::_call_start_thread()
/* lookup CPU */ /* lookup CPU */
Cpu & cpu = cpu_pool().cpu(user_arg_2()); Cpu & cpu = cpu_pool().cpu(user_arg_2());
user_arg_0(0); user_arg_0(0);
Thread &thread = *(Thread *)user_arg_1(); Thread &thread = *(Thread*)user_arg_1();
assert(thread._state == AWAITS_START); assert(thread._state == AWAITS_START);
@ -338,7 +315,8 @@ void Thread::_call_yield_thread()
void Thread::_call_delete_thread() void Thread::_call_delete_thread()
{ {
Thread * to_delete = reinterpret_cast<Thread*>(user_arg_1()); Genode::Kernel_object<Thread> & to_delete =
*(Genode::Kernel_object<Thread>*)user_arg_1();
/** /**
* Delete a thread immediately if it has no cpu assigned yet, * Delete a thread immediately if it has no cpu assigned yet,
@ -346,7 +324,7 @@ void Thread::_call_delete_thread()
*/ */
if (!to_delete->_cpu || if (!to_delete->_cpu ||
(to_delete->_cpu->id() == Cpu::executing_id() || (to_delete->_cpu->id() == Cpu::executing_id() ||
&to_delete->_cpu->scheduled_job() != to_delete)) { &to_delete->_cpu->scheduled_job() != &*to_delete)) {
_call_delete<Thread>(); _call_delete<Thread>();
return; return;
} }
@ -354,7 +332,7 @@ void Thread::_call_delete_thread()
/** /**
* Construct a cross-cpu work item and send an IPI * Construct a cross-cpu work item and send an IPI
*/ */
_destroy.construct(*this, *to_delete); _destroy.construct(*this, to_delete);
to_delete->_cpu->trigger_ip_interrupt(); to_delete->_cpu->trigger_ip_interrupt();
} }
@ -566,21 +544,19 @@ void Thread::_call_kill_signal_context()
void Thread::_call_new_irq() void Thread::_call_new_irq()
{ {
Signal_context * const c = pd().cap_tree().find<Signal_context>(user_arg_3()); Signal_context * const c = pd().cap_tree().find<Signal_context>(user_arg_4());
if (!c) { if (!c) {
Genode::raw(*this, ": invalid signal context for interrupt"); Genode::raw(*this, ": invalid signal context for interrupt");
user_arg_0(-1); user_arg_0(-1);
return; return;
} }
new ((void *)user_arg_1()) User_irq(user_arg_2(), *c); Genode::Irq_session::Trigger trigger =
user_arg_0(0); (Genode::Irq_session::Trigger) (user_arg_3() & 0b1100);
} Genode::Irq_session::Polarity polarity =
(Genode::Irq_session::Polarity) (user_arg_3() & 0b11);
void Thread::_call_irq_mode() _call_new<User_irq>((unsigned)user_arg_2(), trigger, polarity, *c);
{
cpu_pool().executing_cpu().pic().irq_mode(user_arg_1(), user_arg_2(),
user_arg_3());
} }
@ -601,17 +577,18 @@ void Thread::_call_new_obj()
return; return;
} }
using Thread_identity = Core_object_identity<Thread>; using Thread_identity = Genode::Constructible<Core_object_identity<Thread>>;
Thread_identity * coi = Thread_identity & coi = *(Thread_identity*)user_arg_1();
Genode::construct_at<Thread_identity>((void *)user_arg_1(), *thread); coi.construct(*thread);
user_arg_0(coi->core_capid()); user_arg_0(coi->core_capid());
} }
void Thread::_call_delete_obj() void Thread::_call_delete_obj()
{ {
using Object = Core_object_identity<Thread>; using Thread_identity = Genode::Constructible<Core_object_identity<Thread>>;
reinterpret_cast<Object*>(user_arg_1())->~Object(); Thread_identity & coi = *(Thread_identity*)user_arg_1();
coi.destruct();
} }
@ -686,8 +663,14 @@ void Thread::_call()
} }
/* switch over kernel calls that are restricted to core */ /* switch over kernel calls that are restricted to core */
switch (call_id) { switch (call_id) {
case call_id_new_thread(): _call_new_thread(); return; case call_id_new_thread():
case call_id_new_core_thread(): _call_new_core_thread(); return; _call_new<Thread>((unsigned) user_arg_2(),
(unsigned) _core_to_kernel_quota(user_arg_3()),
(char const *) user_arg_4());
return;
case call_id_new_core_thread():
_call_new<Thread>((char const *) user_arg_2());
return;
case call_id_thread_quota(): _call_thread_quota(); return; case call_id_thread_quota(): _call_thread_quota(); return;
case call_id_delete_thread(): _call_delete_thread(); return; case call_id_delete_thread(): _call_delete_thread(); return;
case call_id_start_thread(): _call_start_thread(); return; case call_id_start_thread(): _call_start_thread(); return;
@ -702,7 +685,7 @@ void Thread::_call()
case call_id_delete_pd(): _call_delete<Pd>(); return; case call_id_delete_pd(): _call_delete<Pd>(); return;
case call_id_new_signal_receiver(): _call_new<Signal_receiver>(); return; case call_id_new_signal_receiver(): _call_new<Signal_receiver>(); return;
case call_id_new_signal_context(): case call_id_new_signal_context():
_call_new<Signal_context>((Signal_receiver*) user_arg_2(), user_arg_3()); _call_new<Signal_context>(*(Signal_receiver*) user_arg_2(), user_arg_3());
return; return;
case call_id_delete_signal_context(): _call_delete<Signal_context>(); return; case call_id_delete_signal_context(): _call_delete<Signal_context>(); return;
case call_id_delete_signal_receiver(): _call_delete<Signal_receiver>(); return; case call_id_delete_signal_receiver(): _call_delete<Signal_receiver>(); return;
@ -712,7 +695,6 @@ void Thread::_call()
case call_id_pause_vm(): _call_pause_vm(); return; case call_id_pause_vm(): _call_pause_vm(); return;
case call_id_pause_thread(): _call_pause_thread(); return; case call_id_pause_thread(): _call_pause_thread(); return;
case call_id_new_irq(): _call_new_irq(); return; case call_id_new_irq(): _call_new_irq(); return;
case call_id_irq_mode(): _call_irq_mode(); return;
case call_id_delete_irq(): _call_delete<Irq>(); return; case call_id_delete_irq(): _call_delete<Irq>(); return;
case call_id_ack_irq(): _call_ack_irq(); return; case call_id_ack_irq(): _call_ack_irq(); return;
case call_id_new_obj(): _call_new_obj(); return; case call_id_new_obj(): _call_new_obj(); return;

View File

@ -23,7 +23,7 @@
#include <kernel/inter_processor_work.h> #include <kernel/inter_processor_work.h>
#include <kernel/signal_receiver.h> #include <kernel/signal_receiver.h>
#include <kernel/ipc_node.h> #include <kernel/ipc_node.h>
#include <kernel/object.h> #include <object.h>
namespace Kernel namespace Kernel
{ {
@ -89,10 +89,12 @@ class Kernel::Thread
*/ */
struct Destroy : Inter_processor_work struct Destroy : Inter_processor_work
{ {
Thread & caller; /* the caller gets blocked till the end */ using Kthread = Genode::Kernel_object<Thread>;
Thread & thread_to_destroy; /* thread to be destroyed */
Destroy(Thread & caller, Thread & to_destroy); Thread & caller; /* the caller gets blocked till the end */
Kthread & thread_to_destroy; /* thread to be destroyed */
Destroy(Thread & caller, Kthread & to_destroy);
/************************************ /************************************
** Inter_processor_work interface ** ** Inter_processor_work interface **
@ -241,18 +243,19 @@ class Kernel::Thread
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
void _call_new(ARGS &&... args) void _call_new(ARGS &&... args)
{ {
using Object = Core_object<T>; Genode::Kernel_object<T> & kobj =
void * dst = (void *)user_arg_1(); *(Genode::Kernel_object<T>*)user_arg_1();
Object * o = Genode::construct_at<Object>(dst, args...); kobj.construct(args...);
user_arg_0(o->core_capid()); user_arg_0(kobj->core_capid());
} }
template <typename T> template <typename T>
void _call_delete() void _call_delete()
{ {
using Object = Core_object<T>; Genode::Kernel_object<T> & kobj =
reinterpret_cast<Object*>(user_arg_1())->~Object(); *(Genode::Kernel_object<T>*)user_arg_1();
kobj.destruct();
} }
@ -334,11 +337,12 @@ class Kernel::Thread
* *
* \retval capability id of the new kernel object * \retval capability id of the new kernel object
*/ */
static capid_t syscall_create(void * const p, unsigned const priority, static capid_t syscall_create(Genode::Kernel_object<Thread> & t,
size_t const quota, unsigned const priority,
char const * const label) size_t const quota,
char const * const label)
{ {
return call(call_id_new_thread(), (Call_arg)p, (Call_arg)priority, return call(call_id_new_thread(), (Call_arg)&t, (Call_arg)priority,
(Call_arg)quota, (Call_arg)label); (Call_arg)quota, (Call_arg)label);
} }
@ -350,9 +354,10 @@ class Kernel::Thread
* *
* \retval capability id of the new kernel object * \retval capability id of the new kernel object
*/ */
static capid_t syscall_create(void * const p, char const * const label) static capid_t syscall_create(Genode::Kernel_object<Thread> & t,
char const * const label)
{ {
return call(call_id_new_core_thread(), (Call_arg)p, return call(call_id_new_core_thread(), (Call_arg)&t,
(Call_arg)label); (Call_arg)label);
} }
@ -361,8 +366,8 @@ class Kernel::Thread
* *
* \param thread pointer to thread kernel object * \param thread pointer to thread kernel object
*/ */
static void syscall_destroy(Thread * thread) { static void syscall_destroy(Genode::Kernel_object<Thread> & t) {
call(call_id_delete_thread(), (Call_arg)thread); } call(call_id_delete_thread(), (Call_arg)&t); }
void print(Genode::Output &out) const; void print(Genode::Output &out) const;

View File

@ -84,11 +84,12 @@ class Kernel::Vm : public Cpu_job,
* *
* \retval cap id when successful, otherwise invalid cap id * \retval cap id when successful, otherwise invalid cap id
*/ */
static capid_t syscall_create(void * const dst, void * const state, static capid_t syscall_create(Genode::Kernel_object<Vm> & vm,
capid_t const signal_context_id, void * const state,
void * const table) capid_t const signal_context_id,
void * const table)
{ {
return call(call_id_new_vm(), (Call_arg)dst, (Call_arg)state, return call(call_id_new_vm(), (Call_arg)&vm, (Call_arg)state,
(Call_arg)table, signal_context_id); (Call_arg)table, signal_context_id);
} }
@ -99,8 +100,8 @@ class Kernel::Vm : public Cpu_job,
* *
* \retval 0 when successful, otherwise !=0 * \retval 0 when successful, otherwise !=0
*/ */
static void syscall_destroy(Vm * const vm) { static void syscall_destroy(Genode::Kernel_object<Vm> & vm) {
call(call_id_delete_vm(), (Call_arg) vm); } call(call_id_delete_vm(), (Call_arg) &vm); }
/**************** /****************

View File

@ -15,7 +15,7 @@
#define _CORE__OBJECT_H_ #define _CORE__OBJECT_H_
/* Genode includes */ /* Genode includes */
#include <util/construct_at.h> #include <util/reconstructible.h>
/* base-internal includes */ /* base-internal includes */
#include <base/internal/capability_space.h> #include <base/internal/capability_space.h>
@ -35,13 +35,8 @@ namespace Genode {
template <typename T> template <typename T>
class Genode::Kernel_object class Genode::Kernel_object : public Genode::Constructible<Kernel::Core_object<T>>
{ {
private:
uint8_t _data[sizeof(Kernel::Core_object<T>)]
__attribute__((aligned(sizeof(addr_t))));
protected: protected:
Untyped_capability _cap { }; Untyped_capability _cap { };
@ -55,15 +50,17 @@ class Genode::Kernel_object
*/ */
template <typename... ARGS> template <typename... ARGS>
Kernel_object(bool syscall, ARGS &&... args) Kernel_object(bool syscall, ARGS &&... args)
: _cap(Capability_space::import(syscall ? T::syscall_create(&_data, args...) : _cap(Capability_space::import(syscall ? T::syscall_create(*this, args...)
: Kernel::cap_id_invalid())) : Kernel::cap_id_invalid()))
{ {
if (!syscall) construct_at<T>(&_data, args...); if (!syscall) Genode::Constructible<Kernel::Core_object<T>>::construct(args...);
} }
~Kernel_object() { T::syscall_destroy(kernel_object()); } ~Kernel_object()
{
T * kernel_object() { return reinterpret_cast<T*>(_data); } if (Genode::Constructible<Kernel::Core_object<T>>::constructed())
T::syscall_destroy(*this);
}
Untyped_capability cap() { return _cap; } Untyped_capability cap() { return _cap; }
@ -73,8 +70,10 @@ class Genode::Kernel_object
template <typename... ARGS> template <typename... ARGS>
bool create(ARGS &&... args) bool create(ARGS &&... args)
{ {
if (_cap.valid()) return false; if (Genode::Constructible<Kernel::Core_object<T>>::constructed())
_cap = Capability_space::import(T::syscall_create(&_data, args...)); return false;
_cap = Capability_space::import(T::syscall_create(*this, args...));
return _cap.valid(); return _cap.valid();
} }
}; };

View File

@ -53,12 +53,12 @@ void Pager_object::wake_up()
if (pt) pt->restart(); if (pt) pt->restart();
} }
void Pager_object::start_paging(Kernel::Signal_receiver * receiver) void Pager_object::start_paging(Kernel_object<Kernel::Signal_receiver> & receiver)
{ {
using Object = Kernel_object<Kernel::Signal_context>; using Object = Kernel_object<Kernel::Signal_context>;
using Entry = Object_pool<Pager_object>::Entry; using Entry = Object_pool<Pager_object>::Entry;
create(receiver, (unsigned long)this); create(*receiver, (unsigned long)this);
Entry::cap(Object::_cap); Entry::cap(Object::_cap);
} }
@ -103,13 +103,13 @@ void Pager_entrypoint::dissolve(Pager_object &o)
Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &) Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &)
: Thread_deprecated<PAGER_EP_STACK_SIZE>("pager_ep"), : Thread_deprecated<PAGER_EP_STACK_SIZE>("pager_ep"),
Kernel_object<Kernel::Signal_receiver>(true) _kobj(true)
{ start(); } { start(); }
Pager_capability Pager_entrypoint::manage(Pager_object &o) Pager_capability Pager_entrypoint::manage(Pager_object &o)
{ {
o.start_paging(kernel_object()); o.start_paging(_kobj);
insert(&o); insert(&o);
return reinterpret_cap_cast<Pager_object>(o.cap()); return reinterpret_cap_cast<Pager_object>(o.cap());
} }

View File

@ -157,7 +157,7 @@ class Genode::Pager_object : private Object_pool<Pager_object>::Entry,
* *
* \param receiver signal receiver that receives the page faults * \param receiver signal receiver that receives the page faults
*/ */
void start_paging(Kernel::Signal_receiver * receiver); void start_paging(Kernel_object<Kernel::Signal_receiver> & receiver);
/** /**
* Called when a page-fault finally could not be resolved * Called when a page-fault finally could not be resolved
@ -195,9 +195,12 @@ class Genode::Pager_object : private Object_pool<Pager_object>::Entry,
class Genode::Pager_entrypoint : public Object_pool<Pager_object>, class Genode::Pager_entrypoint : public Object_pool<Pager_object>,
public Thread_deprecated<PAGER_EP_STACK_SIZE>, public Thread_deprecated<PAGER_EP_STACK_SIZE>,
private Kernel_object<Kernel::Signal_receiver>,
private Ipc_pager private Ipc_pager
{ {
private:
Kernel_object<Kernel::Signal_receiver> _kobj;
public: public:
/** /**

View File

@ -69,26 +69,29 @@ void Hw::Address_space::flush(addr_t virt, size_t size, Core_local_addr)
try { try {
_tt.remove_translation(virt, size, _tt_alloc); _tt.remove_translation(virt, size, _tt_alloc);
Kernel::invalidate_tlb(&_kernel_pd, virt, size); Kernel::invalidate_tlb(*_kobj, virt, size);
} catch(...) { } catch(...) {
error("tried to remove invalid region!"); error("tried to remove invalid region!");
} }
} }
Hw::Address_space::Address_space(Kernel::Pd & pd, Page_table & tt, Hw::Address_space::Address_space(Page_table & tt,
Page_table::Allocator & tt_alloc) Page_table::Allocator & tt_alloc,
: _tt(tt), _tt_phys(Platform::core_page_table()), Platform_pd & pd)
_tt_alloc(tt_alloc), _kernel_pd(pd) { } : _tt(tt),
_tt_phys(Platform::core_page_table()),
_tt_alloc(tt_alloc),
_kobj(false, *(Page_table*)translation_table_phys(), pd) {}
Hw::Address_space::Address_space(Kernel::Pd & pd) Hw::Address_space::Address_space(Platform_pd & pd)
: _tt(*construct_at<Page_table>(_table_alloc(), *((Page_table*)Hw::Mm::core_page_tables().base))), : _tt(*construct_at<Page_table>(_table_alloc(), *((Page_table*)Hw::Mm::core_page_tables().base))),
_tt_phys((addr_t)_cma().phys_addr(&_tt)), _tt_phys((addr_t)_cma().phys_addr(&_tt)),
_tt_array(new (_cma()) Array([this] (void * virt) { _tt_array(new (_cma()) Array([this] (void * virt) {
return (addr_t)_cma().phys_addr(virt);})), return (addr_t)_cma().phys_addr(virt);})),
_tt_alloc(_tt_array->alloc()), _tt_alloc(_tt_array->alloc()),
_kernel_pd(pd) { } _kobj(true, *(Page_table*)translation_table_phys(), pd) { }
Hw::Address_space::~Address_space() Hw::Address_space::~Address_space()
@ -142,20 +145,13 @@ void Platform_pd::assign_parent(Native_capability parent)
Platform_pd::Platform_pd(Page_table & tt, Platform_pd::Platform_pd(Page_table & tt,
Page_table::Allocator & alloc) Page_table::Allocator & alloc)
: : Hw::Address_space(tt, alloc, *this), _label("core") { }
Hw::Address_space(*kernel_object(), tt, alloc),
Kernel_object<Kernel::Pd>(false, *(Page_table*)translation_table_phys(), *this),
_label("core")
{ }
Platform_pd::Platform_pd(Allocator &, char const *label) Platform_pd::Platform_pd(Allocator &, char const *label)
: : Hw::Address_space(*this), _label(label)
Hw::Address_space(*kernel_object()),
Kernel_object<Kernel::Pd>(true, *(Page_table*)translation_table_phys(), *this),
_label(label)
{ {
if (!_cap.valid()) { if (!_kobj.cap().valid()) {
error("failed to create kernel object"); error("failed to create kernel object");
throw Service_denied(); throw Service_denied();
} }

View File

@ -72,12 +72,11 @@ class Hw::Address_space : public Genode::Address_space
using Table = Hw::Page_table; using Table = Hw::Page_table;
using Array = Table::Allocator::Array<DEFAULT_TRANSLATION_TABLE_MAX>; using Array = Table::Allocator::Array<DEFAULT_TRANSLATION_TABLE_MAX>;
Genode::Lock _lock { }; /* table lock */ Genode::Lock _lock { }; /* table lock */
Table & _tt; /* table virt addr */ Table & _tt; /* table virt addr */
Genode::addr_t _tt_phys; /* table phys addr */ Genode::addr_t _tt_phys; /* table phys addr */
Array * _tt_array = nullptr; Array * _tt_array = nullptr;
Table::Allocator & _tt_alloc; /* table allocator */ Table::Allocator & _tt_alloc; /* table allocator */
Kernel::Pd & _kernel_pd;
static inline Genode::Core_mem_allocator &_cma(); static inline Genode::Core_mem_allocator &_cma();
@ -85,25 +84,27 @@ class Hw::Address_space : public Genode::Address_space
protected: protected:
Kernel_object<Kernel::Pd> _kobj;
/** /**
* Core-specific constructor * Core-specific constructor
* *
* \param pd pointer to kernel's pd object * \param tt reference to translation table
* \param tt pointer to translation table * \param tt_alloc reference to translation table allocator
* \param tt_alloc pointer to translation table allocator * \param pd reference to platform pd object
*/ */
Address_space(Kernel::Pd & pd, Address_space(Hw::Page_table & tt,
Hw::Page_table & tt, Hw::Page_table::Allocator & tt_alloc,
Hw::Page_table::Allocator & tt_alloc); Platform_pd & pd);
public: public:
/** /**
* Constructor * Constructor
* *
* \param pd pointer to kernel's pd object * \param pd reference to platform pd object
*/ */
Address_space(Kernel::Pd & pd); Address_space(Platform_pd & pd);
~Address_space(); ~Address_space();
@ -132,9 +133,9 @@ class Hw::Address_space : public Genode::Address_space
** Accessors ** ** Accessors **
***************/ ***************/
Kernel::Pd & kernel_pd() { return _kernel_pd; } Kernel::Pd & kernel_pd() { return *_kobj; }
Hw::Page_table & translation_table() { return _tt; } Hw::Page_table & translation_table() { return _tt; }
Genode::addr_t translation_table_phys() { return _tt_phys; } Genode::addr_t translation_table_phys() { return _tt_phys; }
}; };
@ -161,8 +162,7 @@ class Genode::Cap_space
class Genode::Platform_pd : public Hw::Address_space, class Genode::Platform_pd : public Hw::Address_space,
private Cap_space, private Cap_space
private Kernel_object<Kernel::Pd>
{ {
private: private:

View File

@ -54,7 +54,7 @@ Platform_thread::~Platform_thread()
void Platform_thread::quota(size_t const quota) void Platform_thread::quota(size_t const quota)
{ {
_quota = quota; _quota = quota;
Kernel::thread_quota(_kobj.kernel_object(), quota); Kernel::thread_quota(*_kobj, quota);
} }
@ -158,8 +158,8 @@ int Platform_thread::start(void * const ip, void * const sp)
} }
/* initialize thread registers */ /* initialize thread registers */
_kobj.kernel_object()->regs->ip = reinterpret_cast<addr_t>(ip); _kobj->regs->ip = reinterpret_cast<addr_t>(ip);
_kobj.kernel_object()->regs->sp = reinterpret_cast<addr_t>(sp); _kobj->regs->sp = reinterpret_cast<addr_t>(sp);
/* start executing new thread */ /* start executing new thread */
if (!_pd) { if (!_pd) {
@ -179,8 +179,7 @@ int Platform_thread::start(void * const ip, void * const sp)
utcb.cap_add(Capability_space::capid(_pd->parent())); utcb.cap_add(Capability_space::capid(_pd->parent()));
utcb.cap_add(Capability_space::capid(_utcb)); utcb.cap_add(Capability_space::capid(_utcb));
} }
Kernel::start_thread(_kobj.kernel_object(), cpu, &_pd->kernel_pd(), Kernel::start_thread(*_kobj, cpu, _pd->kernel_pd(), *_utcb_core_addr);
_utcb_core_addr);
return 0; return 0;
} }
@ -189,7 +188,7 @@ void Platform_thread::pager(Pager_object &pager)
{ {
using namespace Kernel; using namespace Kernel;
thread_pager(_kobj.kernel_object(), Capability_space::capid(pager.cap())); thread_pager(*_kobj, Capability_space::capid(pager.cap()));
_pager = &pager; _pager = &pager;
} }
@ -205,14 +204,14 @@ Genode::Pager_object &Platform_thread::pager()
Thread_state Platform_thread::state() Thread_state Platform_thread::state()
{ {
Thread_state bstate(*_kobj.kernel_object()->regs); Thread_state bstate(*_kobj->regs);
return Thread_state(bstate); return Thread_state(bstate);
} }
void Platform_thread::state(Thread_state thread_state) void Platform_thread::state(Thread_state thread_state)
{ {
Cpu_state * cstate = static_cast<Cpu_state *>(&*_kobj.kernel_object()->regs); Cpu_state * cstate = static_cast<Cpu_state *>(&*_kobj->regs);
*cstate = static_cast<Cpu_state>(thread_state); *cstate = static_cast<Cpu_state>(thread_state);
} }

View File

@ -122,7 +122,7 @@ namespace Genode {
/** /**
* Return information about current fault * Return information about current fault
*/ */
Kernel::Thread_fault fault_info() { return _kobj.kernel_object()->fault(); } Kernel::Thread_fault fault_info() { return _kobj->fault(); }
/** /**
* Join a protection domain * Join a protection domain
@ -150,7 +150,7 @@ namespace Genode {
/** /**
* Pause this thread * Pause this thread
*/ */
void pause() { Kernel::pause_thread(_kobj.kernel_object()); } void pause() { Kernel::pause_thread(*_kobj); }
/** /**
* Enable/disable single stepping * Enable/disable single stepping
@ -160,13 +160,13 @@ namespace Genode {
/** /**
* Resume this thread * Resume this thread
*/ */
void resume() { Kernel::resume_thread(_kobj.kernel_object()); } void resume() { Kernel::resume_thread(*_kobj); }
/** /**
* Cancel currently blocking operation * Cancel currently blocking operation
*/ */
void cancel_blocking() { void cancel_blocking() {
Kernel::cancel_thread_blocking(_kobj.kernel_object()); } Kernel::cancel_thread_blocking(*_kobj); }
/** /**
* Set CPU quota of the thread to 'quota' * Set CPU quota of the thread to 'quota'

View File

@ -36,7 +36,7 @@ void Pager_entrypoint::entry()
if (cap.valid()) Kernel::ack_signal(Capability_space::capid(cap)); if (cap.valid()) Kernel::ack_signal(Capability_space::capid(cap));
/* receive fault */ /* receive fault */
if (Kernel::await_signal(Capability_space::capid(_cap))) continue; if (Kernel::await_signal(Capability_space::capid(_kobj.cap()))) continue;
Pager_object *po = *(Pager_object**)Thread::myself()->utcb()->data(); Pager_object *po = *(Pager_object**)Thread::myself()->utcb()->data();
cap = po->cap(); cap = po->cap();

View File

@ -39,14 +39,18 @@ class Genode::Rpc_cap_factory
/** /**
* Kernel object placeholder held in a list * Kernel object placeholder held in a list
*/ */
struct Kobject : List<Kobject>::Element struct Kobject
: List<Kobject>::Element
{ {
using Identity = Kernel::Core_object_identity<Kernel::Thread>; using O = Kernel::Core_object_identity<Kernel::Thread>;
Native_capability cap { }; Constructible<O> kobj {};
Native_capability cap;
uint8_t data[sizeof(Identity)] Kobject(Native_capability ep)
__attribute__((aligned(sizeof(addr_t)))); : cap(Capability_space::import(O::syscall_create(kobj, Capability_space::capid(ep)))) {}
void destruct() { O::syscall_destroy(kobj); }
}; };
using Slab = Tslab<Kobject, get_page_size()>; using Slab = Tslab<Kobject, get_page_size()>;
@ -68,7 +72,6 @@ class Genode::Rpc_cap_factory
Lock::Guard guard(_lock); Lock::Guard guard(_lock);
while (Kobject * obj = _list.first()) { while (Kobject * obj = _list.first()) {
Kernel::delete_obj(obj->data);
_list.remove(obj); _list.remove(obj);
destroy(&_slab, obj); destroy(&_slab, obj);
} }
@ -87,11 +90,8 @@ class Genode::Rpc_cap_factory
Kobject * obj; Kobject * obj;
if (!_slab.alloc(sizeof(Kobject), (void**)&obj)) if (!_slab.alloc(sizeof(Kobject), (void**)&obj))
throw Allocator::Out_of_memory(); throw Allocator::Out_of_memory();
construct_at<Kobject>(obj); construct_at<Kobject>(obj, ep);
/* create kernel object via syscall */
Kernel::capid_t capid = Kernel::new_obj(obj->data, Capability_space::capid(ep));
obj->cap = Capability_space::import(capid);
if (!obj->cap.valid()) { if (!obj->cap.valid()) {
raw("Invalid entrypoint ", (addr_t)Capability_space::capid(ep), raw("Invalid entrypoint ", (addr_t)Capability_space::capid(ep),
" for allocating a capability!"); " for allocating a capability!");
@ -110,7 +110,7 @@ class Genode::Rpc_cap_factory
for (Kobject * obj = _list.first(); obj; obj = obj->next()) { for (Kobject * obj = _list.first(); obj; obj = obj->next()) {
if (obj->cap.data() == cap.data()) { if (obj->cap.data() == cap.data()) {
Kernel::delete_obj(obj->data); obj->destruct();
_list.remove(obj); _list.remove(obj);
destroy(&_slab, obj); destroy(&_slab, obj);
return; return;

View File

@ -55,19 +55,21 @@ struct Genode::Signal_source_component : private Kernel_object<Kernel::Signal_re
using Signal_source_pool::Entry::cap; using Signal_source_pool::Entry::cap;
Signal_source_component() Signal_source_component()
: : Kernel_object<Kernel::Signal_receiver>(true),
Kernel_object<Kernel::Signal_receiver>(true), Signal_source_pool::Entry(Kernel_object<Kernel::Signal_receiver>::cap())
Signal_source_pool::Entry(Kernel_object<Kernel::Signal_receiver>::_cap)
{ } { }
void submit(Signal_context_component *, unsigned long) { ASSERT_NEVER_CALLED; } void submit(Signal_context_component *, unsigned long) { ASSERT_NEVER_CALLED; }
Kernel::Signal_receiver & signal_receiver() {
return **static_cast<Kernel_object<Kernel::Signal_receiver>*>(this); }
}; };
Genode::Signal_context_component::Signal_context_component(Signal_source_component &s, Genode::Signal_context_component::Signal_context_component(Signal_source_component &s,
addr_t const imprint) addr_t const imprint)
: :
Kernel_object<Kernel::Signal_context>(true, s.kernel_object(), imprint), Kernel_object<Kernel::Signal_context>(true, s.signal_receiver(), imprint),
Signal_context_pool::Entry(Kernel_object<Kernel::Signal_context>::_cap) Signal_context_pool::Entry(Kernel_object<Kernel::Signal_context>::_cap)
{ } { }

View File

@ -44,6 +44,7 @@ void Vm::exception(Cpu & cpu)
return; return;
case Genode::Cpu_state::DATA_ABORT: case Genode::Cpu_state::DATA_ABORT:
_state->dfar = Cpu::Dfar::read(); _state->dfar = Cpu::Dfar::read();
[[fallthrough]];
default: default:
pause(); pause();
_context->submit(1); _context->submit(1);

View File

@ -20,8 +20,7 @@ using namespace Genode;
void Vm_session_component::_exception_handler(Signal_context_capability handler, Vcpu_id) void Vm_session_component::_exception_handler(Signal_context_capability handler, Vcpu_id)
{ {
if (!create(_ds_addr, Capability_space::capid(handler), nullptr)) if (!_kobj.create(_ds_addr, Capability_space::capid(handler), nullptr)) {
{
warning("Cannot instantiate vm kernel object twice," warning("Cannot instantiate vm kernel object twice,"
"or invalid signal context?"); "or invalid signal context?");
} }

View File

@ -33,8 +33,7 @@ class Genode::Vm_session_component
: :
private Ram_quota_guard, private Ram_quota_guard,
private Cap_quota_guard, private Cap_quota_guard,
public Rpc_object<Vm_session, Vm_session_component>, public Rpc_object<Vm_session, Vm_session_component>
private Kernel_object<Kernel::Vm>
{ {
private: private:
@ -49,6 +48,7 @@ class Genode::Vm_session_component
Region_map &_region_map; Region_map &_region_map;
Ram_dataspace_capability _ds_cap { }; Ram_dataspace_capability _ds_cap { };
Region_map::Local_addr _ds_addr { 0 }; Region_map::Local_addr _ds_addr { 0 };
Kernel_object<Kernel::Vm> _kobj {};
static size_t _ds_size() { static size_t _ds_size() {
return align_addr(sizeof(Cpu_state_modes), return align_addr(sizeof(Cpu_state_modes),

View File

@ -28,8 +28,8 @@ static Core_mem_allocator & cma() {
void Vm_session_component::_exception_handler(Signal_context_capability handler, Vcpu_id) void Vm_session_component::_exception_handler(Signal_context_capability handler, Vcpu_id)
{ {
if (!create(_ds_addr, Capability_space::capid(handler), if (!_kobj.create(_ds_addr, Capability_space::capid(handler),
cma().phys_addr(&_table))) cma().phys_addr(&_table)))
Genode::warning("Cannot instantiate vm kernel object, invalid signal context?"); Genode::warning("Cannot instantiate vm kernel object, invalid signal context?");
} }
@ -95,16 +95,15 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep,
Region_map &region_map, Region_map &region_map,
unsigned, unsigned,
Trace::Source_registry &) Trace::Source_registry &)
: : Ram_quota_guard(resources.ram_quota),
Ram_quota_guard(resources.ram_quota), Cap_quota_guard(resources.cap_quota),
Cap_quota_guard(resources.cap_quota), _ep(ds_ep),
_ep(ds_ep), _constrained_md_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
_constrained_md_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()), _sliced_heap(_constrained_md_ram_alloc, region_map),
_sliced_heap(_constrained_md_ram_alloc, region_map), _region_map(region_map),
_region_map(region_map), _table(*construct_at<Table>(_alloc_table())),
_table(*construct_at<Table>(_alloc_table())), _table_array(*(new (cma()) Array([this] (void * virt) {
_table_array(*(new (cma()) Array([this] (void * virt) { return (addr_t)cma().phys_addr(virt);})))
return (addr_t)cma().phys_addr(virt);})))
{ {
_ds_cap = _constrained_md_ram_alloc.alloc(_ds_size(), Genode::Cache_attribute::UNCACHED); _ds_cap = _constrained_md_ram_alloc.alloc(_ds_size(), Genode::Cache_attribute::UNCACHED);

View File

@ -39,8 +39,7 @@ class Genode::Vm_session_component
private Ram_quota_guard, private Ram_quota_guard,
private Cap_quota_guard, private Cap_quota_guard,
public Rpc_object<Vm_session, Vm_session_component>, public Rpc_object<Vm_session, Vm_session_component>,
public Region_map_detach, public Region_map_detach
private Kernel_object<Kernel::Vm>
{ {
private: private:
@ -64,6 +63,7 @@ class Genode::Vm_session_component
Region_map::Local_addr _ds_addr { 0 }; Region_map::Local_addr _ds_addr { 0 };
Table &_table; Table &_table;
Array &_table_array; Array &_table_array;
Kernel_object<Kernel::Vm> _kobj {};
static size_t _ds_size() { static size_t _ds_size() {
return align_addr(sizeof(Cpu_state_modes), return align_addr(sizeof(Cpu_state_modes),

View File

@ -30,13 +30,11 @@ addr_t Vm_session_component::_alloc_ds()
void Vm_session_component::_run(Vcpu_id) void Vm_session_component::_run(Vcpu_id)
{ {
if (Kernel_object<Kernel::Vm>::_cap.valid()) if (_kobj.constructed()) Kernel::run_vm(*_kobj);
Kernel::run_vm(kernel_object());
} }
void Vm_session_component::_pause(Vcpu_id) void Vm_session_component::_pause(Vcpu_id)
{ {
if (Kernel_object<Kernel::Vm>::_cap.valid()) if (_kobj.constructed()) Kernel::pause_vm(*_kobj);
Kernel::pause_vm(kernel_object());
} }

View File

@ -35,12 +35,12 @@ class Genode::Vm_session_component
: :
private Ram_quota_guard, private Ram_quota_guard,
private Cap_quota_guard, private Cap_quota_guard,
public Rpc_object<Vm_session, Vm_session_component>, public Rpc_object<Vm_session, Vm_session_component>
private Kernel_object<Kernel::Vm>
{ {
private: private:
Vm_state _state; Kernel_object<Kernel::Vm> _kobj {};
Vm_state _state;
public: public:
@ -68,22 +68,16 @@ class Genode::Vm_session_component
void _exception_handler(Signal_context_capability handler, Vcpu_id) void _exception_handler(Signal_context_capability handler, Vcpu_id)
{ {
if (!create(&_state, Capability_space::capid(handler), nullptr)) if (!_kobj.create(&_state, Capability_space::capid(handler), nullptr))
warning("Cannot instantiate vm kernel object, " warning("Cannot instantiate vm kernel object, "
"invalid signal context?"); "invalid signal context?");
} }
void _run(Vcpu_id) void _run(Vcpu_id) {
{ if (_kobj.constructed()) Kernel::run_vm(*_kobj); }
if (Kernel_object<Kernel::Vm>::_cap.valid())
Kernel::run_vm(kernel_object());
}
void _pause(Vcpu_id) void _pause(Vcpu_id) {
{ if (_kobj.constructed()) Kernel::pause_vm(*_kobj); }
if (Kernel_object<Kernel::Vm>::_cap.valid())
Kernel::pause_vm(kernel_object());
}
void attach(Dataspace_capability, addr_t, Attach_attr) override { } void attach(Dataspace_capability, addr_t, Attach_attr) override { }
void attach_pic(addr_t) override { } void attach_pic(addr_t) override { }