base: extend PD session by system_control_cap

Per Affinity::Location a system control cap can be requested. The capability
provides an RPC interface to request and set Cpu_state, as provided by the
former Pd::managing_system(Cpu_state) method. Invocation of those system
control capabilities then *can* (see below) be executed on the desired CPU
as described by Affinity::Location.

The system control cap will be invalid for kernels that don't support
system_control/managing_system functionality at all.

The system control cap will be ever by the same, e.g. ignoring the
Affinity::Location parameter, if the used kernel doesn't support or doesn't
require the feature to execute the system control per CPU.

The commit is a preparation step to add guarded and selective x86 MSR
access per CPU.

Fixes #5009
This commit is contained in:
Alexander Boettcher
2023-09-26 10:55:06 +02:00
committed by Christian Helmuth
parent ffc25fde53
commit 916bd88e5e
15 changed files with 220 additions and 38 deletions

View File

@ -75,7 +75,8 @@ class Core::Core_env : public Noncopyable
_region_map,
*((Pager_entrypoint *)nullptr),
"" /* args to native PD */,
platform_specific().core_mem_alloc())
platform_specific().core_mem_alloc(),
*((Core::System_control *)nullptr))
{
_pd_session.init_cap_and_ram_accounts();
}

View File

@ -33,6 +33,7 @@ class Core::Pd_root : public Root_component<Pd_session_component>
Range_allocator &_phys_alloc;
Region_map &_local_rm;
Range_allocator &_core_mem;
System_control &_system_control;
/**
* The RAM allocations of system management components are getting
@ -91,7 +92,7 @@ class Core::Pd_root : public Root_component<Pd_session_component>
_virt_range_from_args(args),
_managing_system(args),
_local_rm, _pager_ep, args,
_core_mem);
_core_mem, _system_control);
}
void _upgrade_session(Pd_session_component *pd, const char *args) override
@ -111,11 +112,13 @@ class Core::Pd_root : public Root_component<Pd_session_component>
Range_allocator &phys_alloc,
Region_map &local_rm,
Allocator &md_alloc,
Range_allocator &core_mem)
Range_allocator &core_mem,
System_control &system_control)
:
Root_component<Pd_session_component>(&ep, &md_alloc),
_ep(ep), _signal_ep(signal_ep), _pager_ep(pager_ep),
_phys_alloc(phys_alloc), _local_rm(local_rm), _core_mem(core_mem)
_phys_alloc(phys_alloc), _local_rm(local_rm), _core_mem(core_mem),
_system_control(system_control)
{ }
};

View File

@ -30,6 +30,7 @@
#include <constrained_core_ram.h>
#include <platform_pd.h>
#include <signal_broker.h>
#include <system_control.h>
#include <rpc_cap_factory.h>
#include <ram_dataspace_factory.h>
#include <native_pd_component.h>
@ -52,6 +53,7 @@ class Core::Pd_session_component : public Session_object<Pd_session>
Constructible<Account<Ram_quota> > _ram_account { };
Rpc_entrypoint &_ep;
Core::System_control &_system_control;
Constrained_ram_allocator _constrained_md_ram_alloc;
Constrained_core_ram _constrained_core_ram_alloc;
Sliced_heap _sliced_heap;
@ -131,10 +133,12 @@ class Core::Pd_session_component : public Session_object<Pd_session>
Region_map &local_rm,
Pager_entrypoint &pager_ep,
char const *args,
Range_allocator &core_mem)
Range_allocator &core_mem,
Core::System_control &system_control)
:
Session_object(ep, resources, label, diag),
_ep(ep),
_system_control(system_control),
_constrained_md_ram_alloc(*this, _ram_quota_guard(), _cap_quota_guard()),
_constrained_core_ram_alloc(_ram_quota_guard(), _cap_quota_guard(), core_mem),
_sliced_heap(_constrained_md_ram_alloc, local_rm),
@ -329,11 +333,17 @@ class Core::Pd_session_component : public Session_object<Pd_session>
Capability<Native_pd> native_pd() override { return _native_pd.cap(); }
/*******************************
** Managing system interface **
*******************************/
/******************************
** System control interface **
******************************/
Managing_system_state managing_system(Managing_system_state const &) override;
Capability<System_control> system_control_cap(Affinity::Location const location) override
{
if (_managing_system == Managing_system::PERMITTED)
return _system_control.control_cap(location);
return { };
}
/*******************************************

View File

@ -0,0 +1,36 @@
/*
* \brief Interface to get access to privileged system control capability
* \author Alexander Boettcher
* \date 2023-09-25
*/
/*
* Copyright (C) 2023 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CORE__INCLUDE__SYSTEM_CONTROL_H_
#define _CORE__INCLUDE__SYSTEM_CONTROL_H_
#include <base/rpc_server.h>
namespace Core {
class System_control;
System_control & init_system_control(Allocator &, Rpc_entrypoint &);
}
class Core::System_control : Interface
{
public:
virtual Capability<Pd_session::System_control> control_cap(Affinity::Location) const = 0;
};
#endif /* _CORE__INCLUDE__SYSTEM_CONTROL_H_ */

View File

@ -29,6 +29,7 @@
#include <core_env.h>
#include <core_service.h>
#include <signal_transmitter.h>
#include <system_control.h>
#include <rom_root.h>
#include <rm_root.h>
#include <cpu_root.h>
@ -255,6 +256,8 @@ void Genode::bootstrap_component(Genode::Platform &)
using Trace_root = Core::Trace::Root;
using Trace_session_component = Core::Trace::Session_component;
static Core::System_control &system_control = init_system_control(sliced_heap, ep);
static Rom_root rom_root (ep, ep, platform().rom_fs(), sliced_heap);
static Rm_root rm_root (ep, sliced_heap, core_ram_alloc, local_rm, pager_ep);
static Cpu_root cpu_root (core_ram_alloc, local_rm, ep, ep, pager_ep,
@ -262,7 +265,8 @@ void Genode::bootstrap_component(Genode::Platform &)
static Pd_root pd_root (ep, core_env().signal_ep(), pager_ep,
platform().ram_alloc(),
local_rm, sliced_heap,
platform_specific().core_mem_alloc());
platform_specific().core_mem_alloc(),
system_control);
static Log_root log_root (ep, sliced_heap);
static Io_mem_root io_mem_root (ep, ep, platform().io_mem_alloc(),
platform().ram_alloc(), sliced_heap);

View File

@ -22,6 +22,20 @@ bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; }
void Pd_session_component::map(addr_t, addr_t) { }
using State = Genode::Pd_session::Managing_system_state;
State Pd_session_component::managing_system(State const &) { return State(); }
class System_control_dummy : public System_control
{
public:
Capability<Pd_session::System_control> control_cap(Affinity::Location) const override
{
return { };
}
};
System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &)
{
static System_control_dummy dummy { };
return dummy;
}