hw: extend "hw: explicit cpu state argument in kernel entry" for VMX

The work in #5425 missed an adaption for setting up the stack pointer
and pushing the appropriate TRAP_VMEXIT exception value before jumping
to `_kernel_entry` after returning from `vmlaunch`.

Adapt the VMX implementation and remove a now superfluous argument from
the initialization method.

Issue #5474
This commit is contained in:
Benjamin Lamowski 2025-03-06 20:45:30 +01:00 committed by Norman Feske
parent aa0927b194
commit 71e9b603a7
6 changed files with 25 additions and 14 deletions

View File

@ -67,8 +67,7 @@ Vmcb_buf &Vmcb::host_vmcb(size_t cpu_id)
return *host_vmcb[cpu_id];
}
void Vmcb::initialize(Kernel::Cpu &cpu, addr_t page_table_phys_addr,
Core::Cpu::Context &)
void Vmcb::initialize(Kernel::Cpu &cpu, addr_t page_table_phys_addr)
{
using Cpu = Hw::X86_64_cpu;

View File

@ -266,5 +266,5 @@ void Board::Vcpu_context::write_vcpu_state(Vcpu_state &state)
void Board::Vcpu_context::initialize(Kernel::Cpu &cpu, addr_t table_phys_addr)
{
virt.initialize(cpu, table_phys_addr, *regs);
virt.initialize(cpu, table_phys_addr);
}

View File

@ -53,6 +53,21 @@ extern int __idt;
Vmcs * current_vmcs[Hw::Pc_board::NR_OF_CPUS] = { nullptr };
/*
* We need to push the artifical TRAP_VMEXIT value
* to trapno after returning from vmlauch and before
* jumping to _kernel_entry
*/
void kernel_entry_push_trap()
{
asm volatile(
"pushq %[trap_val];" /* make the stack point to trapno, the right place */
"jmp _kernel_entry;"
:
: [trap_val] "i"(Board::TRAP_VMEXIT)
: "memory");
}
Vmcs_buf::Vmcs_buf(Genode::uint32_t system_rev)
{
Genode::memset((void *) this, 0, sizeof(Vmcs_buf));
@ -233,8 +248,7 @@ void Vmcs::setup_vmx_info()
cr4_mask = ~cr4_fixed1 | cr4_fixed0;
}
void Vmcs::initialize(Kernel::Cpu &cpu, Genode::addr_t page_table_phys,
Core::Cpu::Context &regs)
void Vmcs::initialize(Kernel::Cpu &cpu, Genode::addr_t page_table_phys)
{
using Cpu = Hw::X86_64_cpu;
@ -346,14 +360,14 @@ void Vmcs::initialize(Kernel::Cpu &cpu, Genode::addr_t page_table_phys,
write(E_HOST_IA32_SYSENTER_ESP, reinterpret_cast<Genode::addr_t>(&(cpu.tss.rsp[0])));
write(E_HOST_IA32_SYSENTER_CS, 0x8);
write(E_HOST_IA32_SYSENTER_EIP, reinterpret_cast<Genode::uint64_t>(&_kernel_entry));
write(E_HOST_IA32_SYSENTER_EIP, reinterpret_cast<Genode::uint64_t>(&kernel_entry_push_trap));
/*
* Set the RSP to trapno, so that _kernel_entry will save the registers
* into the right fields.
*/
write(E_HOST_RSP, reinterpret_cast<Genode::uint64_t>(&(regs.trapno)));
write(E_HOST_RIP, reinterpret_cast<Genode::uint64_t>(&_kernel_entry));
write(E_HOST_RSP, cpu.stack_start() - 568);
write(E_HOST_RIP, reinterpret_cast<Genode::uint64_t>(&kernel_entry_push_trap));
}

View File

@ -332,8 +332,7 @@ struct Board::Vmcb
void enforce_intercepts(uint32_t desired_primary = 0U,
uint32_t desired_secondary = 0U);
void initialize(Kernel::Cpu &cpu,
addr_t page_table_phys_addr,
Core::Cpu::Context &) override;
addr_t page_table_phys_addr) override;
void write_vcpu_state(Vcpu_state &state) override;
void read_vcpu_state(Vcpu_state &state) override;
void switch_world(Core::Cpu::Context &regs, addr_t) override;

View File

@ -38,8 +38,8 @@ struct Virt_interface
Genode::Vcpu_data &vcpu_data;
virtual void initialize(Kernel::Cpu &cpu,
addr_t page_table_phys_addr,
Core::Cpu::Context &regs) = 0;
addr_t page_table_phys_addr)
= 0;
virtual void write_vcpu_state(Vcpu_state &state) = 0;
virtual void read_vcpu_state(Vcpu_state &state) = 0;
virtual void switch_world(Core::Cpu::Context &regs, addr_t) = 0;

View File

@ -382,8 +382,7 @@ Board::Vmcs
return ((ar >> 4) & 0x1F00) | (ar & 0xFF);
}
void initialize(Kernel::Cpu &cpu, addr_t page_table_phys,
Core::Cpu::Context &regs) override;
void initialize(Kernel::Cpu &cpu, addr_t page_table_phys) override;
void write_vcpu_state(Genode::Vcpu_state &state) override;
void read_vcpu_state(Genode::Vcpu_state &state) override;
void switch_world(Core::Cpu::Context &regs, addr_t) override;