diff --git a/repos/base-hw/src/core/kernel/vm.h b/repos/base-hw/src/core/kernel/vm.h index 7b82c81803..6259d0bba5 100644 --- a/repos/base-hw/src/core/kernel/vm.h +++ b/repos/base-hw/src/core/kernel/vm.h @@ -132,12 +132,7 @@ class Kernel::Vm : private Kernel::Object, public Cpu_context ** Vm_session ** ****************/ - void run() - { - _sync_from_vmm(); - if (_scheduled != ACTIVE) Cpu_context::_activate(); - _scheduled = ACTIVE; - } + void run(); void pause() { diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc index 54256ead92..9f22a485b7 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc @@ -84,6 +84,14 @@ void Vm::proceed() } +void Vm::run() +{ + _sync_from_vmm(); + if (_scheduled != ACTIVE) Cpu_context::_activate(); + _scheduled = ACTIVE; +} + + void Vm::_sync_to_vmm() {} diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc index e533e62257..bc9d712dfe 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc @@ -205,6 +205,14 @@ void Kernel::Vm::proceed() } +void Vm::run() +{ + _sync_from_vmm(); + if (_scheduled != ACTIVE) Cpu_context::_activate(); + _scheduled = ACTIVE; +} + + void Vm::_sync_to_vmm() {} diff --git a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc index fe5176cffb..51777e0fa8 100644 --- a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc @@ -212,6 +212,14 @@ void Vm::proceed() } +void Vm::run() +{ + _sync_from_vmm(); + if (_scheduled != ACTIVE) Cpu_context::_activate(); + _scheduled = ACTIVE; +} + + void Vm::_sync_to_vmm() {} diff --git a/repos/base-hw/src/core/spec/x86_64/virtualization/board.h b/repos/base-hw/src/core/spec/x86_64/virtualization/board.h index 82bae483b7..a821d15eaa 100644 --- a/repos/base-hw/src/core/spec/x86_64/virtualization/board.h +++ b/repos/base-hw/src/core/spec/x86_64/virtualization/board.h @@ -35,14 +35,12 @@ namespace Board { enum Platform_exitcodes : uint64_t { EXIT_NPF = 0xfc, - EXIT_INIT = 0xfd, EXIT_STARTUP = 0xfe, EXIT_PAUSED = 0xff, }; enum Custom_trapnos : uint64_t { TRAP_VMEXIT = 256, - TRAP_VMSKIP = 257, }; }; @@ -55,6 +53,12 @@ namespace Kernel { struct Board::Vcpu_context { + enum class Init_state { + CREATED, + INITIALIZING, + STARTED + }; + Vcpu_context(unsigned id, Vcpu_data &vcpu_data); void initialize(Kernel::Cpu &cpu, addr_t table_phys_addr); void read_vcpu_state(Vcpu_state &state); @@ -66,7 +70,10 @@ struct Board::Vcpu_context uint64_t tsc_aux_host = 0U; uint64_t tsc_aux_guest = 0U; - uint64_t exit_reason = EXIT_INIT; + uint64_t exit_reason = EXIT_PAUSED; + + Init_state init_state { Init_state::CREATED }; + static Virt_interface &detect_virtualization(Vcpu_data &vcpu_data, unsigned id) diff --git a/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/vm.cc index 3b26635afd..73253e78bb 100644 --- a/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/x86_64/virtualization/kernel/vm.cc @@ -54,16 +54,31 @@ Vm::~Vm() } +void Vm::run() +{ + if (_vcpu_context.init_state == Board::Vcpu_context::Init_state::CREATED) { + _vcpu_context.exit_reason = Board::EXIT_STARTUP; + _vcpu_context.init_state = Board::Vcpu_context::Init_state::INITIALIZING; + _context.submit(1); + return; + } + + _sync_from_vmm(); + if (_scheduled != ACTIVE) Cpu_context::_activate(); + _scheduled = ACTIVE; +} + + void Vm::proceed() { using namespace Board; _cpu().switch_to(*_vcpu_context.regs); - if (_vcpu_context.exit_reason == EXIT_INIT) { - _vcpu_context.regs->trapno = TRAP_VMSKIP; - Hypervisor::restore_state_for_entry((addr_t)&_vcpu_context.regs->r8, - _vcpu_context.regs->fpu_context()); - /* jumps to _kernel_entry */ + + if (_vcpu_context.init_state == Board::Vcpu_context::Init_state::INITIALIZING) { + _vcpu_context.initialize(_cpu(), + reinterpret_cast(_id.table)); + _vcpu_context.tsc_aux_host = _cpu().id(); } Cpu::Ia32_tsc_aux::write( @@ -125,18 +140,6 @@ void Vm::exception() case Cpu_state::INTERRUPTS_START ... Cpu_state::INTERRUPTS_END: _interrupt(_user_irq_pool); break; - case TRAP_VMSKIP: - /* vCPU is running for the first time */ - _vcpu_context.initialize(_cpu(), - reinterpret_cast(_id.table)); - _vcpu_context.tsc_aux_host = _cpu().id(); - /* - * We set the artificial startup exit code, stop the - * vCPU thread and ask the VMM to handle it. - */ - _vcpu_context.exit_reason = EXIT_STARTUP; - pause = true; - break; default: error("VM: triggered unknown exception ", _vcpu_context.regs->trapno, @@ -169,13 +172,10 @@ void Vm::_sync_to_vmm() void Vm::_sync_from_vmm() { - /* first run() will skip through to issue startup exit */ - if (_vcpu_context.exit_reason == Board::EXIT_INIT) - return; - _vcpu_context.read_vcpu_state(_state); } + Board::Vcpu_context::Vcpu_context(unsigned id, Vcpu_data &vcpu_data) : regs(1),