diff --git a/repos/ports/src/virtualbox6/sup_vcpu.cc b/repos/ports/src/virtualbox6/sup_vcpu.cc index f1196b3b27..cff44179bb 100644 --- a/repos/ports/src/virtualbox6/sup_vcpu.cc +++ b/repos/ports/src/virtualbox6/sup_vcpu.cc @@ -3,10 +3,11 @@ * \author Alexander Boettcher * \author Norman Feske * \author Christian Helmuth + * \author Benjamin Lamowski */ /* - * Copyright (C) 2013-2021 Genode Labs GmbH + * Copyright (C) 2013-2023 Genode Labs GmbH * * This file is distributed under the terms of the GNU General Public License * version 2. @@ -90,6 +91,10 @@ namespace Sup { template class Sup::Vcpu_impl : public Sup::Vcpu, Genode::Noncopyable { + public: + + struct State_container { Vcpu_state &ref; }; + private: Pthread::Emt &_emt; @@ -98,6 +103,8 @@ class Sup::Vcpu_impl : public Sup::Vcpu, Genode::Noncopyable VMCPU &_vmcpu; Libc::Allocator _alloc; + Genode::Constructible _state; + /* exit handler run in vCPU mode - switches to EMT */ void _handle_exit(); @@ -160,15 +167,18 @@ class Sup::Vcpu_impl : public Sup::Vcpu, Genode::Noncopyable template void Sup::Vcpu_impl::_handle_exit() { - _emt.switch_to_emt(); - - _vcpu.run(); + _vcpu.with_state([this](Genode::Vcpu_state &state) { + _state.construct(state); + _emt.switch_to_emt(); + _state.destruct(); + return true; + }); } template void Sup::Vcpu_impl::_transfer_state_to_vcpu(CPUMCTX const &ctx) { - Vcpu_state &state { _vcpu.state() }; + Vcpu_state &state { _state->ref }; /* transfer defaults and cached state */ state.ctrl_primary.charge(_cached_state.ctrl_primary); /* XXX always updates ctrls */ @@ -257,7 +267,8 @@ template void Sup::Vcpu_impl::_transfer_state_to_vcpu(CPUM /* export FPU state */ AssertCompile(sizeof(Vcpu_state::Fpu::State) >= sizeof(X86FXSTATE)); - _vcpu.state().fpu.charge([&] (Vcpu_state::Fpu::State &fpu) { + + _state->ref.fpu.charge([&](Vcpu_state::Fpu::State &fpu) { ::memcpy(fpu._buffer, ctx.pXStateR3, sizeof(fpu)); }); @@ -311,7 +322,7 @@ static void handle_intr_state(PVMCPUCC pVCpu, CPUMCTX &ctx, Vcpu_state &state) template void Sup::Vcpu_impl::_transfer_state_to_vbox(CPUMCTX &ctx) { - Vcpu_state const &state { _vcpu.state() }; + Vcpu_state const &state { _state->ref }; ctx.rip = state.ip.value(); ctx.rsp = state.sp.value(); @@ -394,7 +405,7 @@ template void Sup::Vcpu_impl::_transfer_state_to_vbox(CPUM _cached_state.ctrl_secondary = state.ctrl_secondary.value(); /* handle guest interrupt state */ - handle_intr_state(pVCpu, ctx, _vcpu.state()); + handle_intr_state(pVCpu, ctx, _state->ref); VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3); @@ -403,8 +414,9 @@ template void Sup::Vcpu_impl::_transfer_state_to_vbox(CPUM APICSetTpr(pVCpu, tpr); /* import FPU state */ - _vcpu.state().fpu.with_state([&] (Vcpu_state::Fpu::State const &fpu) { + _state->ref.fpu.with_state([&](Vcpu_state::Fpu::State const &fpu) { ::memcpy(ctx.pXStateR3, fpu._buffer, sizeof(X86FXSTATE)); + return true; }); /* do SVM/VMX-specific transfers */ @@ -427,7 +439,7 @@ template bool Sup::Vcpu_impl::_check_and_request_irq_window() VMCPU_FF_INTERRUPT_PIC))) return false; - _vcpu.state().inj_info.charge(REQ_IRQ_WINDOW_EXIT); + _state->ref.inj_info.charge(REQ_IRQ_WINDOW_EXIT); return true; } @@ -491,7 +503,7 @@ typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_npt_ept(VBO { rc = VINF_EM_RAW_EMULATE_INSTR; - RTGCPHYS const GCPhys = PAGE_ADDRESS(_vcpu.state().qual_secondary.value()); + RTGCPHYS const GCPhys = PAGE_ADDRESS(_state->ref.qual_secondary.value()); PPGMRAMRANGE const pRam = pgmPhysGetRangeAtOrAbove(&_vm, GCPhys); if (!pRam) @@ -515,7 +527,7 @@ typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_npt_ept(VBO template typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_paused() { - Vcpu_state &state { _vcpu.state() }; + Vcpu_state &state { _state->ref }; Assert(state.actv_state.value() == VMX_VMCS_GUEST_ACTIVITY_ACTIVE); @@ -557,7 +569,7 @@ typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_startup() template typename Sup::Vcpu_impl::Current_state Sup::Vcpu_impl::_handle_irq_window() { - Vcpu_state &state { _vcpu.state() }; + Vcpu_state &state { _state->ref }; PVMCPU pVCpu = &_vmcpu; @@ -680,10 +692,10 @@ template VBOXSTRICTRC Sup::Vcpu_impl::_switch_to_hw() /* run vCPU until next exit */ _emt.switch_to_vcpu(); - result = VIRT::handle_exit(_vcpu.state()); + result = VIRT::handle_exit(_state->ref); /* discharge by default */ - _vcpu.state().discharge(); + _state->ref.discharge(); switch (result.state) { @@ -743,7 +755,7 @@ template void Sup::Vcpu_impl::pause() VMCPUSTATE enmState = pVCpu->enmState; if (enmState == VMCPUSTATE_STARTED_EXEC_NEM) - _vcpu.pause(); + _handler.local_submit(); else _check_force_flags = true; } @@ -777,7 +789,7 @@ template VBOXSTRICTRC Sup::Vcpu_impl::run() _transfer_state_to_vbox(ctx); - Assert(_vcpu.state().actv_state.value() == VMX_VMCS_GUEST_ACTIVITY_ACTIVE); + Assert(_state->ref.actv_state.value() == VMX_VMCS_GUEST_ACTIVITY_ACTIVE); /* see hmR0VmxExitToRing3 - sync recompiler state */ CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_SYSENTER_MSR | @@ -821,7 +833,6 @@ Sup::Vcpu_impl::Vcpu_impl(Env &env, VM &vm, Vm_connection &vm_con, RTSemEventMultiCreate(&_halt_semevent); /* run vCPU until initial startup exception */ - _vcpu.run(); _switch_to_hw(); }