hw: move physical VMCB address out of the VMCB

The physical address of the memory used for the guest VMCB is already
present in Vcpu_data. Use the information there instead of storing the
physical address in the host data area, thereby freeing up 8 bytes for
a bigger Mmio class.

Issue #4081
This commit is contained in:
Benjamin Lamowski 2024-01-24 16:04:13 +01:00 committed by Christian Helmuth
parent cec7847502
commit 69b76ba9ed
6 changed files with 18 additions and 14 deletions

View File

@ -14,9 +14,9 @@
#ifndef _INCLUDE__SPEC__PC__VM_STATE_H_
#define _INCLUDE__SPEC__PC__VM_STATE_H_
#include <base/internal/page_size.h>
/* x86 CPU state */
#include <cpu/vcpu_state.h>
#include <virtualization/svm.h>
namespace Genode {
@ -28,7 +28,8 @@ namespace Genode {
struct Genode::Vm_data
{
Board::Vmcb vmcb;
alignas(Genode::get_page_size())
uint8_t vmcb[get_page_size()];
Genode::addr_t vmcb_phys_addr;
Genode::Vcpu_state * vcpu_state;
};

View File

@ -61,8 +61,7 @@ namespace Kernel {
struct Board::Vcpu_context
{
Vcpu_context(unsigned id, void *vcpu_data_ptr,
Genode::addr_t context_phys_addr);
Vcpu_context(unsigned id, void *vcpu_data_ptr);
void initialize_svm(Kernel::Cpu &cpu, void *table);
void read_vcpu_state(Genode::Vcpu_state &state);
void write_vcpu_state(Genode::Vcpu_state &state);

View File

@ -24,14 +24,13 @@ using Kernel::Vm;
using Board::Vmcb;
Vmcb::Vmcb(Genode::uint32_t id, Genode::addr_t addr)
Vmcb::Vmcb(Genode::uint32_t id)
:
Mmio((Genode::addr_t)this)
{
write<Guest_asid>(id);
write<Msrpm_base_pa>(dummy_msrpm());
write<Iopm_base_pa>(dummy_iopm());
phys_addr = addr;
/*
* Set the guest PAT register to the default value.

View File

@ -47,7 +47,7 @@ Vm::Vm(Irq::Pool & user_irq_pool,
_state(*data.vcpu_state),
_context(context),
_id(id),
_vcpu_context(id.id, &data.vmcb, data.vmcb_phys_addr)
_vcpu_context(id.id, data.vmcb)
{
affinity(cpu);
}
@ -78,7 +78,7 @@ void Vm::proceed(Cpu & cpu)
* we can pop it later
*/
_vcpu_context.regs->trapno = _vcpu_context.vmcb.root_vmcb_phys;
Hypervisor::switch_world(_vcpu_context.vmcb.phys_addr,
Hypervisor::switch_world(_vcpu_context.vmcb.vm_data()->vmcb_phys_addr,
(addr_t) &_vcpu_context.regs->r8,
_vcpu_context.regs->fpu_context());
/*
@ -175,10 +175,9 @@ void Vm::_sync_from_vmm()
}
Board::Vcpu_context::Vcpu_context(unsigned id, void *vcpu_data_ptr,
Genode::addr_t context_phys_addr)
Board::Vcpu_context::Vcpu_context(unsigned id, void *vcpu_data_ptr)
:
vmcb(*Genode::construct_at<Vmcb>(vcpu_data_ptr, id, context_phys_addr)),
vmcb(*Genode::construct_at<Vmcb>(vcpu_data_ptr, id)),
regs(1)
{
regs->trapno = TRAP_VMEXIT;

View File

@ -17,6 +17,7 @@
#include <base/internal/page_size.h>
#include <base/stdint.h>
#include <cpu/vcpu_state.h>
#include <cpu/vcpu_state_virtualization.h>
#include <util/mmio.h>
#include <util/string.h>
@ -76,7 +77,7 @@ struct Board::Vmcb_control_area
struct Board::Vmcb_reserved_for_host
{
/* 64bit used by the inherited Mmio class here */
Genode::addr_t phys_addr = 0U;
Genode::uint64_t _reserved[1];
Genode::addr_t root_vmcb_phys = 0U;
};
static_assert(Board::Vmcb_control_area::total_size -
@ -143,7 +144,7 @@ struct alignas(Genode::get_page_size()) Board::Vmcb
Asid_host = 0,
};
Vmcb(Genode::uint32_t id, Genode::addr_t addr = 0);
Vmcb(Genode::uint32_t id);
void init(Genode::size_t cpu_id, void * table_ptr);
static Vmcb & host_vmcb(Genode::size_t cpu_id);
static Genode::addr_t dummy_msrpm();
@ -154,6 +155,11 @@ struct alignas(Genode::get_page_size()) Board::Vmcb
sizeof(Board::Vmcb_state_save_area) -
Board::Vmcb_control_area::total_size];
Genode::Vm_data * vm_data()
{
return reinterpret_cast<Genode::Vm_data *>(this);
}
/*
* AMD Manual Vol. 2, Table B-1: VMCB Layout, Control Area
*/

View File

@ -116,7 +116,7 @@ Genode::addr_t Vm_session_component::_alloc_vm_data(Genode::addr_t ds_addr)
Genode::Vm_data* vm_data = (Genode::Vm_data *) vm_data_ptr;
vm_data->vcpu_state = (Genode::Vcpu_state *) ds_addr;
vm_data->vmcb_phys_addr = (addr_t)cma().phys_addr(&vm_data->vmcb);
vm_data->vmcb_phys_addr = (addr_t)cma().phys_addr(vm_data->vmcb);
return (Genode::addr_t) vm_data_ptr;
}