base-hw: separate variants of Kernel_object(...)

For the constructor of Kernel_object<T> there are two variants. One for the
case that it is called from Core where the kernel object (type T) must be
created via a syscall and one when it is called from within the kernel and the
kernel object can be created directly. Selecting one of these variants was done
using a bool argument to the constructor. However, this implies that the
constructor of Kernel_object<T> and that of T have the same signature in the
variadic arguments, even in the syscall case, although technically it would
then not be necessary.

This becomes a problem as soon as kernel objects created by Core shall receive
additional arguments from the kernel, for instance a reference to the global
CPU pool, and therefore stands in the way when wanting to get rid of global
statics in the kernel. Therefore, this commit introduces two constructors that
are selected through enum arguments:

! Kernel_object(Called_from_kernel, ...);
! Kernel_object(Called_from_core, ...);

Ref #4217
This commit is contained in:
Martin Stein 2021-07-09 12:09:31 +02:00 committed by Norman Feske
parent 6e4ef43bf0
commit 8b69bc96f9
5 changed files with 31 additions and 13 deletions

View File

@ -44,19 +44,29 @@ class Genode::Kernel_object : public Genode::Constructible<Kernel::Core_object<T
public:
enum Called_from_core { CALLED_FROM_CORE };
enum Called_from_kernel { CALLED_FROM_KERNEL };
Kernel_object() {}
/**
* Creates a kernel object either via a syscall or directly
* Creates a kernel object via a syscall
*/
template <typename... ARGS>
Kernel_object(bool syscall, ARGS &&... args)
Kernel_object(Called_from_core, ARGS &&... args)
:
_cap(Capability_space::import(syscall ? T::syscall_create(*this, args...)
: Kernel::cap_id_invalid()))
_cap(Capability_space::import(T::syscall_create(*this, args...)))
{ }
/**
* Creates a kernel object directly
*/
template <typename... ARGS>
Kernel_object(Called_from_kernel, ARGS &&... args)
:
_cap(Capability_space::import(Kernel::cap_id_invalid()))
{
if (!syscall)
Genode::Constructible<Kernel::Core_object<T>>::construct(args...);
Genode::Constructible<Kernel::Core_object<T>>::construct(args...);
}
~Kernel_object()

View File

@ -110,7 +110,8 @@ Pager_entrypoint::Pager_entrypoint(Rpc_cap_factory &)
:
Thread(Weight::DEFAULT_WEIGHT, "pager_ep", PAGER_EP_STACK_SIZE,
Type::NORMAL),
_kobj(true)
_kobj(_kobj.CALLED_FROM_CORE)
{
start();
}

View File

@ -96,7 +96,9 @@ Hw::Address_space::Address_space(Page_table & tt,
_tt(tt),
_tt_phys(Platform::core_page_table()),
_tt_alloc(tt_alloc),
_kobj(false, *(Page_table*)translation_table_phys(), pd)
_kobj(_kobj.CALLED_FROM_KERNEL,
*(Page_table*)translation_table_phys(),
pd)
{ }
@ -107,7 +109,9 @@ Hw::Address_space::Address_space(Platform_pd & pd)
_tt_array(new (_cma()) Array([] (void * virt) {
return (addr_t)_cma().phys_addr(virt);})),
_tt_alloc(_tt_array->alloc()),
_kobj(true, *(Page_table*)translation_table_phys(), pd)
_kobj(_kobj.CALLED_FROM_CORE,
*(Page_table*)translation_table_phys(),
pd)
{ }

View File

@ -68,7 +68,7 @@ Platform_thread::Platform_thread(Label const &label, Native_utcb &utcb)
_utcb_pd_addr(&utcb),
_main_thread(false),
_location(Affinity::Location()),
_kobj(true, _label.string())
_kobj(_kobj.CALLED_FROM_CORE, _label.string())
{
/* create UTCB for a core thread */
void *utcb_phys;
@ -95,7 +95,7 @@ Platform_thread::Platform_thread(size_t const quota,
_quota(quota),
_main_thread(false),
_location(location),
_kobj(true, _priority, _quota, _label.string())
_kobj(_kobj.CALLED_FROM_CORE, _priority, _quota, _label.string())
{
try {
_utcb = core_env().pd_session()->alloc(sizeof(Native_utcb), CACHED);

View File

@ -56,7 +56,7 @@ struct Genode::Signal_source_component : private Kernel_object<Kernel::Signal_re
Signal_source_component()
:
Kernel_object<Kernel::Signal_receiver>(true),
Kernel_object<Kernel::Signal_receiver>(CALLED_FROM_CORE),
Signal_source_pool::Entry(Kernel_object<Kernel::Signal_receiver>::cap())
{ }
@ -70,7 +70,10 @@ struct Genode::Signal_source_component : private Kernel_object<Kernel::Signal_re
Genode::Signal_context_component::Signal_context_component(Signal_source_component &s,
addr_t const imprint)
:
Kernel_object<Kernel::Signal_context>(true, s.signal_receiver(), imprint),
Kernel_object<Kernel::Signal_context>(CALLED_FROM_CORE,
s.signal_receiver(),
imprint),
Signal_context_pool::Entry(Kernel_object<Kernel::Signal_context>::_cap)
{ }