mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-14 08:16:28 +00:00
hw: x86_64: clean up vCPU startup
- and store the vCPU startup state in a dedicated enum - return the STARTUP exit from Vm::run() - initialize the vCPU from Vm::proceed() instead of Vm::exception() Fix genodelabs/genode#5450
This commit is contained in:
parent
faa5b9ca40
commit
759bfec3a9
@ -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()
|
||||
{
|
||||
|
@ -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()
|
||||
{}
|
||||
|
||||
|
@ -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()
|
||||
{}
|
||||
|
||||
|
@ -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()
|
||||
{}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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<addr_t>(_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<addr_t>(_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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user