mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
nova: add guarded access to MSRs
via Genode Pd::system_control interface Issue #5009
This commit is contained in:
parent
fe3a958dbf
commit
e36170c997
@ -287,6 +287,7 @@ namespace Nova {
|
||||
EC_TIME = 5U,
|
||||
EC_GET_VCPU_STATE = 6U,
|
||||
EC_SET_VCPU_STATE = 7U,
|
||||
EC_MSR_ACCESS = 8U
|
||||
};
|
||||
|
||||
enum Sc_op {
|
||||
@ -759,7 +760,7 @@ namespace Nova {
|
||||
* Calling this function has the side effect of removing all typed
|
||||
* message items from the message buffer.
|
||||
*/
|
||||
void set_msg_word(unsigned num) { items = num; }
|
||||
void set_msg_word(mword_t const num) { items = num; }
|
||||
|
||||
/**
|
||||
* Return current number of message word in UTCB
|
||||
|
@ -45,7 +45,7 @@ SRC_CC += stack_area.cc \
|
||||
vm_session_common.cc \
|
||||
heartbeat.cc
|
||||
|
||||
INC_DIR = $(REP_DIR)/src/core/include \
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(REP_DIR)/src/include \
|
||||
$(BASE_DIR)/src/include \
|
||||
$(GEN_CORE_DIR)/include
|
||||
|
@ -1,3 +1,5 @@
|
||||
SRC_CC += spec/x86_32/pager.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/x86_32
|
||||
|
||||
include $(REP_DIR)/lib/mk/core-nova.inc
|
||||
|
@ -1,3 +1,5 @@
|
||||
SRC_CC += spec/x86_64/pager.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include/spec/x86_64
|
||||
|
||||
include $(REP_DIR)/lib/mk/core-nova.inc
|
||||
|
@ -1 +1 @@
|
||||
3f6464b9126ffc77fdfd4b670ed7b4d3d3d0aff8
|
||||
e104241c249b88b6e0a4ff74bda67996dfa200c4
|
||||
|
@ -4,7 +4,7 @@ DOWNLOADS := nova.git
|
||||
|
||||
# r10 branch
|
||||
URL(nova) := https://github.com/alex-ab/NOVA.git
|
||||
REV(nova) := 89f714dcb32c7f4e97d29a8651e55862b8362df1
|
||||
REV(nova) := 3e34fa6c35c55566ae57a1fd654262964ffcf544
|
||||
DIR(nova) := src/kernel/nova
|
||||
|
||||
PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch))
|
||||
|
26
repos/base-nova/src/core/include/spec/x86_32/nova_msr.h
Normal file
26
repos/base-nova/src/core/include/spec/x86_32/nova_msr.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Guarded MSR access on NOVA
|
||||
* \author Alexander Boettcher
|
||||
* \date 2023-10-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__SPEC_X86_32__NOVA_MSR_H_
|
||||
#define _CORE__INCLUDE__SPEC_X86_32__NOVA_MSR_H_
|
||||
|
||||
#include <pd_session_component.h>
|
||||
|
||||
static Genode::Pd_session::Managing_system_state msr_access(Genode::Pd_session::Managing_system_state const &,
|
||||
Nova::Utcb &,
|
||||
Genode::addr_t const)
|
||||
{
|
||||
return { }; /* not supported for now on x86_32 */
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__SPEC_X86_32__NOVA_MSR_H_ */
|
55
repos/base-nova/src/core/include/spec/x86_64/nova_msr.h
Normal file
55
repos/base-nova/src/core/include/spec/x86_64/nova_msr.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* \brief Guarded MSR access on NOVA
|
||||
* \author Alexander Boettcher
|
||||
* \date 2023-10-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__SPEC_X86_64__NOVA_MSR_H_
|
||||
#define _CORE__INCLUDE__SPEC_X86_64__NOVA_MSR_H_
|
||||
|
||||
#include <pd_session_component.h>
|
||||
|
||||
static Genode::Pd_session::Managing_system_state msr_access(Genode::Pd_session::Managing_system_state const &state,
|
||||
Nova::Utcb &utcb,
|
||||
Genode::addr_t const msr_cap)
|
||||
{
|
||||
Genode::Pd_session::Managing_system_state result { };
|
||||
|
||||
utcb.set_msg_word(state.ip); /* count */
|
||||
utcb.msg()[0] = state.r8;
|
||||
utcb.msg()[1] = state.r9;
|
||||
utcb.msg()[2] = state.r10;
|
||||
utcb.msg()[3] = state.r11;
|
||||
utcb.msg()[4] = state.r12;
|
||||
utcb.msg()[5] = state.r13;
|
||||
utcb.msg()[6] = state.r14;
|
||||
utcb.msg()[7] = state.r15;
|
||||
|
||||
auto const res = Nova::ec_ctrl(Nova::Ec_op::EC_MSR_ACCESS, msr_cap);
|
||||
|
||||
result.trapno = (res == Nova::NOVA_OK) ? 1 : 0;
|
||||
|
||||
if (res != Nova::NOVA_OK)
|
||||
return result;
|
||||
|
||||
result.ip = utcb.msg_words(); /* bitmap about valid returned words */
|
||||
result.r8 = utcb.msg()[0];
|
||||
result.r9 = utcb.msg()[1];
|
||||
result.r10 = utcb.msg()[2];
|
||||
result.r11 = utcb.msg()[3];
|
||||
result.r12 = utcb.msg()[4];
|
||||
result.r13 = utcb.msg()[5];
|
||||
result.r14 = utcb.msg()[6];
|
||||
result.r15 = utcb.msg()[7];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__SPEC_X86_64__NOVA_MSR_H_ */
|
@ -16,22 +16,30 @@
|
||||
#include <assertion.h>
|
||||
|
||||
#include <nova_util.h> /* kernel_hip */
|
||||
#include <nova_msr.h>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
|
||||
bool Pd_session_component::assign_pci(addr_t pci_config_memory, uint16_t bdf)
|
||||
template <typename FUNC>
|
||||
inline Nova::uint8_t retry_syscall(addr_t pd_sel, FUNC func)
|
||||
{
|
||||
uint8_t res = Nova::NOVA_PD_OOM;
|
||||
Nova::uint8_t res;
|
||||
do {
|
||||
res = Nova::assign_pci(_pd->pd_sel(), pci_config_memory, bdf);
|
||||
res = func();
|
||||
} while (res == Nova::NOVA_PD_OOM &&
|
||||
Nova::NOVA_OK == Pager_object::handle_oom(Pager_object::SRC_CORE_PD,
|
||||
_pd->pd_sel(),
|
||||
pd_sel,
|
||||
"core", "ep",
|
||||
Pager_object::Policy::UPGRADE_CORE_TO_DST));
|
||||
|
||||
return res == Nova::NOVA_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Pd_session_component::assign_pci(addr_t pci_config_memory, uint16_t bdf)
|
||||
{
|
||||
return retry_syscall(_pd->pd_sel(), [&]() {
|
||||
return Nova::assign_pci(_pd->pd_sel(), pci_config_memory, bdf);
|
||||
}) == Nova::NOVA_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -45,8 +53,7 @@ void Pd_session_component::map(addr_t virt, addr_t size)
|
||||
auto map_memory = [&] (Mapping const &mapping)
|
||||
{
|
||||
/* asynchronously map memory */
|
||||
uint8_t err = Nova::NOVA_PD_OOM;
|
||||
do {
|
||||
uint8_t err = retry_syscall(_pd->pd_sel(), [&]() {
|
||||
utcb.set_msg_word(0);
|
||||
|
||||
bool res = utcb.append_item(nova_src_crd(mapping), 0, true, false,
|
||||
@ -57,13 +64,9 @@ void Pd_session_component::map(addr_t virt, addr_t size)
|
||||
/* one item ever fits on the UTCB */
|
||||
(void)res;
|
||||
|
||||
err = Nova::delegate(pd_core, pd_dst, nova_dst_crd(mapping));
|
||||
return Nova::delegate(pd_core, pd_dst, nova_dst_crd(mapping));
|
||||
});
|
||||
|
||||
} while (err == Nova::NOVA_PD_OOM &&
|
||||
Nova::NOVA_OK == Pager_object::handle_oom(Pager_object::SRC_CORE_PD,
|
||||
target_pd.pd_sel(),
|
||||
"core", "ep",
|
||||
Pager_object::Policy::UPGRADE_CORE_TO_DST));
|
||||
if (err != Nova::NOVA_OK) {
|
||||
error("could not eagerly map memory ",
|
||||
Hex_range<addr_t>(mapping.dst_addr, 1UL << mapping.size_log2) , " "
|
||||
@ -191,16 +194,9 @@ Capability<Pd_session::System_control> System_control_impl::control_cap(Affinity
|
||||
}
|
||||
|
||||
|
||||
State System_control_component::system_control(State const &request)
|
||||
static State acpi_suspend(State const &request)
|
||||
{
|
||||
bool const suspend = (request.trapno == State::ACPI_SUSPEND_REQUEST);
|
||||
State respond { };
|
||||
|
||||
if (!suspend) {
|
||||
/* report failed attempt */
|
||||
respond.trapno = 0;
|
||||
return respond;
|
||||
}
|
||||
State respond { .trapno = 0 };
|
||||
|
||||
/*
|
||||
* The trapno/ip/sp registers used below are just convention to transfer
|
||||
@ -224,3 +220,18 @@ State System_control_component::system_control(State const &request)
|
||||
|
||||
return respond;
|
||||
}
|
||||
|
||||
|
||||
State System_control_component::system_control(State const &request)
|
||||
{
|
||||
if (request.trapno == State::ACPI_SUSPEND_REQUEST)
|
||||
return acpi_suspend(request);
|
||||
|
||||
if (request.trapno == State::MSR_ACCESS) {
|
||||
auto const msr_cap = platform_specific().core_pd_sel() + 4;
|
||||
Nova::Utcb &utcb = *reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb());
|
||||
return msr_access(request, utcb, msr_cap);
|
||||
}
|
||||
|
||||
return State();
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ struct Genode::Cpu_state
|
||||
addr_t trapno = 0;
|
||||
|
||||
enum {
|
||||
ACPI_SUSPEND_REQUEST = 0x100, /* convention for managing_system() */
|
||||
ACPI_SUSPEND_REQUEST = 0x100, /* convention for system_control() */
|
||||
MSR_ACCESS = 0x101, /* convention for system_control() */
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -63,7 +63,8 @@ struct Genode::Cpu_state
|
||||
addr_t ss = 0;
|
||||
|
||||
enum {
|
||||
ACPI_SUSPEND_REQUEST = 0x100, /* convention for managing_system() */
|
||||
ACPI_SUSPEND_REQUEST = 0x100, /* convention for system_control() */
|
||||
MSR_ACCESS = 0x101, /* convention for system_control() */
|
||||
};
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user