mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 02:40:08 +00:00
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:
parent
ffc25fde53
commit
916bd88e5e
@ -19,20 +19,47 @@ using namespace Core;
|
||||
using State = Genode::Pd_session::Managing_system_state;
|
||||
|
||||
|
||||
State Pd_session_component::managing_system(State const & s)
|
||||
class System_control_component : public Genode::Rpc_object<Pd_session::System_control>,
|
||||
public Core::System_control
|
||||
{
|
||||
static constexpr addr_t SMCCC_NOT_SUPPORTED = 0xffffffffUL;
|
||||
public:
|
||||
|
||||
State system_control(State const &) override;
|
||||
|
||||
Capability<Pd_session::System_control> control_cap(Affinity::Location const) const override;
|
||||
};
|
||||
|
||||
|
||||
State System_control_component::system_control(State const &s)
|
||||
{
|
||||
State ret;
|
||||
|
||||
ret.r[0] = (_managing_system == Managing_system::DENIED)
|
||||
? SMCCC_NOT_SUPPORTED
|
||||
: Hw::Psci_smc_functor::call(s.r[0], s.r[1], s.r[2], s.r[3]);
|
||||
ret.r[0] = Hw::Psci_smc_functor::call(s.r[0], s.r[1], s.r[2], s.r[3]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static System_control_component &system_instance()
|
||||
{
|
||||
static System_control_component system_component { };
|
||||
return system_component;
|
||||
}
|
||||
|
||||
|
||||
System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &ep)
|
||||
{
|
||||
ep.manage(&system_instance());
|
||||
return system_instance();
|
||||
}
|
||||
|
||||
|
||||
Capability<Pd_session::System_control> System_control_component::control_cap(Affinity::Location const) const
|
||||
{
|
||||
return system_instance().cap();
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** Dummy implementations **
|
||||
***************************/
|
||||
|
@ -18,10 +18,20 @@ using namespace Core;
|
||||
using State = Genode::Pd_session::Managing_system_state;
|
||||
|
||||
|
||||
State Pd_session_component::managing_system(State const &request)
|
||||
class System_control_component : public Genode::Rpc_object<Pd_session::System_control>,
|
||||
public Core::System_control
|
||||
{
|
||||
bool const suspend = (_managing_system == Managing_system::PERMITTED) &&
|
||||
(request.trapno == State::ACPI_SUSPEND_REQUEST);
|
||||
public:
|
||||
|
||||
State system_control(State const &) override;
|
||||
|
||||
Capability<Pd_session::System_control> control_cap(Affinity::Location const) const override;
|
||||
};
|
||||
|
||||
|
||||
State System_control_component::system_control(State const &request)
|
||||
{
|
||||
bool const suspend = (request.trapno == State::ACPI_SUSPEND_REQUEST);
|
||||
State respond { };
|
||||
|
||||
if (!suspend) {
|
||||
@ -49,6 +59,26 @@ State Pd_session_component::managing_system(State const &request)
|
||||
}
|
||||
|
||||
|
||||
static System_control_component &system_instance()
|
||||
{
|
||||
static System_control_component system_component { };
|
||||
return system_component;
|
||||
}
|
||||
|
||||
|
||||
System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &ep)
|
||||
{
|
||||
ep.manage(&system_instance());
|
||||
return system_instance();
|
||||
}
|
||||
|
||||
|
||||
Capability<Pd_session::System_control> System_control_component::control_cap(Affinity::Location const) const
|
||||
{
|
||||
return system_instance().cap();
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** Dummy implementations **
|
||||
***************************/
|
||||
@ -57,4 +87,3 @@ bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; }
|
||||
|
||||
|
||||
void Pd_session_component::map(addr_t, addr_t) { }
|
||||
|
||||
|
@ -101,10 +101,41 @@ void Pd_session_component::map(addr_t virt, addr_t size)
|
||||
|
||||
using State = Genode::Pd_session::Managing_system_state;
|
||||
|
||||
State Pd_session_component::managing_system(State const &request)
|
||||
|
||||
class System_control_component : public Genode::Rpc_object<Pd_session::System_control>,
|
||||
public Core::System_control
|
||||
{
|
||||
bool const suspend = (_managing_system == Managing_system::PERMITTED) &&
|
||||
(request.trapno == State::ACPI_SUSPEND_REQUEST);
|
||||
public:
|
||||
|
||||
State system_control(State const &) override;
|
||||
|
||||
Capability<Pd_session::System_control> control_cap(Affinity::Location const) const override;
|
||||
};
|
||||
|
||||
|
||||
static System_control_component &system_instance()
|
||||
{
|
||||
static System_control_component system_component { };
|
||||
return system_component;
|
||||
}
|
||||
|
||||
|
||||
System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &ep)
|
||||
{
|
||||
ep.manage(&system_instance());
|
||||
return system_instance();
|
||||
}
|
||||
|
||||
|
||||
Capability<Pd_session::System_control> System_control_component::control_cap(Affinity::Location const) const
|
||||
{
|
||||
return system_instance().cap();
|
||||
}
|
||||
|
||||
|
||||
State System_control_component::system_control(State const &request)
|
||||
{
|
||||
bool const suspend = (request.trapno == State::ACPI_SUSPEND_REQUEST);
|
||||
State respond { };
|
||||
|
||||
if (!suspend) {
|
||||
|
@ -93,8 +93,8 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
|
||||
|
||||
Capability<Native_pd> native_pd() override { return call<Rpc_native_pd>(); }
|
||||
|
||||
Managing_system_state managing_system(Managing_system_state const & state) override {
|
||||
return call<Rpc_managing_system>(state); }
|
||||
Capability<System_control> system_control_cap(Affinity::Location const location) override {
|
||||
return call<Rpc_system_control_cap>(location); }
|
||||
|
||||
addr_t dma_addr(Ram_dataspace_capability ds) override { return call<Rpc_dma_addr>(ds); }
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define _INCLUDE__PD_SESSION__PD_SESSION_H_
|
||||
|
||||
#include <util/attempt.h>
|
||||
#include <base/affinity.h>
|
||||
#include <base/exception.h>
|
||||
#include <cpu/cpu_state.h>
|
||||
#include <session/session.h>
|
||||
@ -305,12 +306,26 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
** Access to system management interface **
|
||||
*******************************************/
|
||||
|
||||
struct System_control : Interface
|
||||
{
|
||||
using System_control_state = Cpu_state;
|
||||
|
||||
virtual System_control_state system_control(System_control_state const &) = 0;
|
||||
|
||||
GENODE_RPC(Rpc_system_control, System_control_state, system_control,
|
||||
System_control_state const &);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_system_control);
|
||||
};
|
||||
|
||||
|
||||
using Managing_system_state = Cpu_state;
|
||||
|
||||
/**
|
||||
* Call privileged system management functionality of kernel or firmware
|
||||
* Call privileged system control functionality of kernel or firmware
|
||||
*/
|
||||
virtual Managing_system_state managing_system(Managing_system_state const &) = 0;
|
||||
|
||||
virtual Capability<System_control> system_control_cap(Affinity::Location const) = 0;
|
||||
|
||||
|
||||
/*******************************************
|
||||
@ -391,8 +406,9 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
|
||||
GENODE_RPC(Rpc_native_pd, Capability<Native_pd>, native_pd);
|
||||
|
||||
GENODE_RPC(Rpc_managing_system, Managing_system_state, managing_system,
|
||||
Managing_system_state const &);
|
||||
GENODE_RPC(Rpc_system_control_cap, Capability<System_control>,
|
||||
system_control_cap, Affinity::Location);
|
||||
|
||||
GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, Ram_dataspace_capability);
|
||||
GENODE_RPC(Rpc_attach_dma, Attach_dma_result, attach_dma,
|
||||
Dataspace_capability, addr_t);
|
||||
@ -405,7 +421,7 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
Rpc_transfer_cap_quota, Rpc_cap_quota, Rpc_used_caps,
|
||||
Rpc_try_alloc, Rpc_free,
|
||||
Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram,
|
||||
Rpc_native_pd, Rpc_managing_system,
|
||||
Rpc_native_pd, Rpc_system_control_cap,
|
||||
Rpc_dma_addr, Rpc_attach_dma);
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -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 { };
|
||||
}
|
||||
|
||||
|
||||
/*******************************************
|
||||
|
36
repos/base/src/core/include/system_control.h
Normal file
36
repos/base/src/core/include/system_control.h
Normal 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_ */
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -34,6 +34,17 @@ class Suspend
|
||||
uint8_t s3_sleep_typeb { };
|
||||
bool s3_sleep_valid { };
|
||||
|
||||
Capability<Pd_session::System_control> _control_cap { _env.pd().system_control_cap(Affinity::Location()) };
|
||||
|
||||
struct Client: Genode::Rpc_client<Pd_session::System_control>
|
||||
{
|
||||
explicit Client(Genode::Capability<Pd_session::System_control> cap)
|
||||
: Rpc_client<Pd_session::System_control>(cap) { }
|
||||
|
||||
Pd_session::Managing_system_state system_control(Pd_session::Managing_system_state const &state) override {
|
||||
return call<Rpc_system_control>(state); }
|
||||
} _system_control { _control_cap };
|
||||
|
||||
void suspend()
|
||||
{
|
||||
/*
|
||||
@ -58,7 +69,7 @@ class Suspend
|
||||
in.ip = s3_sleep_typea;
|
||||
in.sp = s3_sleep_typeb;
|
||||
|
||||
out = _env.pd().managing_system (in);
|
||||
out = _system_control.system_control (in);
|
||||
|
||||
if (!out.trapno)
|
||||
log("suspend failed");
|
||||
|
@ -267,8 +267,8 @@ struct Monitor::Inferior_pd : Monitored_pd_session
|
||||
Capability<Native_pd> native_pd() override {
|
||||
return _real.call<Rpc_native_pd>(); }
|
||||
|
||||
Managing_system_state managing_system(Managing_system_state const & state) override {
|
||||
return _real.call<Rpc_managing_system>(state); }
|
||||
Capability<System_control> system_control_cap(Affinity::Location const location) override {
|
||||
return _real.call<Rpc_system_control_cap>(location); }
|
||||
|
||||
addr_t dma_addr(Ram_dataspace_capability ds) override {
|
||||
return _real.call<Rpc_dma_addr>(ds); }
|
||||
|
@ -39,6 +39,7 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics
|
||||
using Sig_ctx_cap = Signal_context_capability;
|
||||
using Ram_ds_cap = Ram_dataspace_capability;
|
||||
using Mng_sys_state = Managing_system_state;
|
||||
using Control_cap = Capability<System_control>;
|
||||
|
||||
void assign_parent(Capability<Parent>) override { never_called(__func__); };
|
||||
bool assign_pci(addr_t, uint16_t) override { never_called(__func__); };
|
||||
@ -61,7 +62,7 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics
|
||||
Ram_quota ram_quota() const override { never_called(__func__); };
|
||||
Ram_quota used_ram() const override { never_called(__func__); };
|
||||
Capability<Native_pd> native_pd() override { never_called(__func__); };
|
||||
Mng_sys_state managing_system(Mng_sys_state const &) override { never_called(__func__); };
|
||||
Control_cap system_control_cap(Affinity::Location) override { never_called(__func__); };
|
||||
addr_t dma_addr(Ram_ds_cap) override { never_called(__func__); };
|
||||
Attach_dma_result attach_dma(Dataspace_capability, addr_t) override { never_called(__func__); };
|
||||
|
||||
|
@ -145,9 +145,8 @@ class Gdb_monitor::Pd_session_component : public Rpc_object<Pd_session>
|
||||
Capability<Native_pd> native_pd() override {
|
||||
return _pd.native_pd(); }
|
||||
|
||||
Managing_system_state
|
||||
managing_system(Managing_system_state const & state) override {
|
||||
return _pd.managing_system(state); }
|
||||
Capability<System_control> system_control_cap(Affinity::Location const location) override {
|
||||
return _pd.system_control_cap(location); }
|
||||
|
||||
addr_t dma_addr(Ram_dataspace_capability ds) override {
|
||||
return _pd.dma_addr(ds); }
|
||||
|
Loading…
Reference in New Issue
Block a user