From daafe3f4e29c57c71f48e7e0867568e528b42c94 Mon Sep 17 00:00:00 2001 From: Benjamin Lamowski Date: Tue, 6 Jun 2023 15:57:38 +0200 Subject: [PATCH] base: rework vmm library API The new API emphasizes control over the vCPU data by granting access through the Vcpu::with_state() method, which makes sure that the vCPU is stopped, invokes the supplied function with a reference to the VM state and resumes the vCPU if the function returns true. The old Vcpu::run(), Vcpu::pause() and Vcpu::state() methods are removed in favor of the new API. Execution of the vCPU is now interrupted by sending a native Genode Signal to its Vcpu_handler, which will run the VMM's exit handling method. When this method retrieves the vCPU state by calling Vcpu::with_state(), the outside interruption is detected and on x86 a recall exit is injected into the state to signal the vCPU interruption / pause request to the VMM's vCPU handler. Ref #4968 --- repos/base/include/vm_session/connection.h | 29 +++++++++++++++++++--- repos/base/lib/symbols/ld | 4 +-- repos/base/src/lib/base/vm.cc | 18 +++----------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/repos/base/include/vm_session/connection.h b/repos/base/include/vm_session/connection.h index 080582b078..d6975312ae 100644 --- a/repos/base/include/vm_session/connection.h +++ b/repos/base/include/vm_session/connection.h @@ -2,6 +2,7 @@ * \brief Connection to a VM service * \author Stefan Kalkowski * \author Christian Helmuth + * \author Benjamin Lamowski * \date 2012-10-02 * * The VM connection is the API for VM and vCPU handling and implemented @@ -22,6 +23,7 @@ #include #include #include +#include #include #include @@ -47,6 +49,12 @@ struct Genode::Vm_connection : Connection, Rpc_client /* for example OMIT_FPU_ON_IRQ */ }; + + struct Call_with_state : Genode::Interface + { + virtual bool call_with_state(Vcpu_state &) = 0; + }; + /** * Virtual CPU * @@ -55,13 +63,28 @@ struct Genode::Vm_connection : Connection, Rpc_client */ struct Vcpu : Genode::Noncopyable { + void _with_state(Call_with_state &); + Native_vcpu &_native_vcpu; Vcpu(Vm_connection &, Allocator &, Vcpu_handler_base &, Exit_config const &); - void run(); - void pause(); - Vcpu_state & state(); + template + void with_state(FN const &fn) + { + struct Untyped_fn : Call_with_state + { + FN const &_fn; + Untyped_fn(FN const &fn) : _fn(fn) {} + + bool call_with_state(Vcpu_state &state) override + { + return _fn(state); + } + } untyped_fn(fn); + + _with_state(untyped_fn); + } }; friend class Vcpu; diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld index 7b57c08b93..406dc0362f 100644 --- a/repos/base/lib/symbols/ld +++ b/repos/base/lib/symbols/ld @@ -92,9 +92,7 @@ _ZN6Genode13Shared_objectC1ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T _ZN6Genode13Shared_objectC2ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T _ZN6Genode13Shared_objectD1Ev T _ZN6Genode13Shared_objectD2Ev T -_ZN6Genode13Vm_connection4Vcpu3runEv T -_ZN6Genode13Vm_connection4Vcpu5pauseEv T -_ZN6Genode13Vm_connection4Vcpu5stateEv T +_ZN6Genode13Vm_connection4Vcpu11_with_stateERNS0_15Call_with_stateE T _ZN6Genode13Vm_connection4VcpuC1ERS0_RNS_9AllocatorERNS_17Vcpu_handler_baseERKNS0_11Exit_configE T _ZN6Genode13Vm_connection4VcpuC2ERS0_RNS_9AllocatorERNS_17Vcpu_handler_baseERKNS0_11Exit_configE T _ZN6Genode13Xml_generator4NodeC1ERS0_PKcRKNS1_3_FnE T diff --git a/repos/base/src/lib/base/vm.cc b/repos/base/src/lib/base/vm.cc index 1e2aa96a66..fa2c76f49d 100644 --- a/repos/base/src/lib/base/vm.cc +++ b/repos/base/src/lib/base/vm.cc @@ -2,11 +2,12 @@ * \brief Generic VM-connection implementation * \author Alexander Boettcher * \author Christian Helmuth + * \author Benjamin Lamowski * \date 2018-08-27 */ /* - * Copyright (C) 2018-2021 Genode Labs GmbH + * Copyright (C) 2018-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. @@ -21,22 +22,9 @@ struct Vm_session::Native_vcpu { }; static Vm_session::Native_vcpu dummy; - -void Vm_connection::Vcpu::run() { } - - -void Vm_connection::Vcpu::pause() { } - - struct Genode::Vcpu_state { }; -Vcpu_state & Vm_connection::Vcpu::state() -{ - static char dummy[sizeof(Vcpu_state)]; - - return *(Vcpu_state *)dummy; -} - +void Vm_connection::Vcpu::_with_state(Call_with_state &) {}; Vm_connection::Vcpu::Vcpu(Vm_connection &, Allocator &, Vcpu_handler_base &, Exit_config const &)