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_ #ifndef _INCLUDE__SPEC__PC__VM_STATE_H_
#define _INCLUDE__SPEC__PC__VM_STATE_H_ #define _INCLUDE__SPEC__PC__VM_STATE_H_
#include <base/internal/page_size.h>
/* x86 CPU state */ /* x86 CPU state */
#include <cpu/vcpu_state.h> #include <cpu/vcpu_state.h>
#include <virtualization/svm.h>
namespace Genode { namespace Genode {
@ -28,7 +28,8 @@ namespace Genode {
struct Genode::Vm_data 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::addr_t vmcb_phys_addr;
Genode::Vcpu_state * vcpu_state; Genode::Vcpu_state * vcpu_state;
}; };

View File

@ -61,8 +61,7 @@ namespace Kernel {
struct Board::Vcpu_context struct Board::Vcpu_context
{ {
Vcpu_context(unsigned id, void *vcpu_data_ptr, Vcpu_context(unsigned id, void *vcpu_data_ptr);
Genode::addr_t context_phys_addr);
void initialize_svm(Kernel::Cpu &cpu, void *table); void initialize_svm(Kernel::Cpu &cpu, void *table);
void read_vcpu_state(Genode::Vcpu_state &state); void read_vcpu_state(Genode::Vcpu_state &state);
void write_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; using Board::Vmcb;
Vmcb::Vmcb(Genode::uint32_t id, Genode::addr_t addr) Vmcb::Vmcb(Genode::uint32_t id)
: :
Mmio((Genode::addr_t)this) Mmio((Genode::addr_t)this)
{ {
write<Guest_asid>(id); write<Guest_asid>(id);
write<Msrpm_base_pa>(dummy_msrpm()); write<Msrpm_base_pa>(dummy_msrpm());
write<Iopm_base_pa>(dummy_iopm()); write<Iopm_base_pa>(dummy_iopm());
phys_addr = addr;
/* /*
* Set the guest PAT register to the default value. * 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), _state(*data.vcpu_state),
_context(context), _context(context),
_id(id), _id(id),
_vcpu_context(id.id, &data.vmcb, data.vmcb_phys_addr) _vcpu_context(id.id, data.vmcb)
{ {
affinity(cpu); affinity(cpu);
} }
@ -78,7 +78,7 @@ void Vm::proceed(Cpu & cpu)
* we can pop it later * we can pop it later
*/ */
_vcpu_context.regs->trapno = _vcpu_context.vmcb.root_vmcb_phys; _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, (addr_t) &_vcpu_context.regs->r8,
_vcpu_context.regs->fpu_context()); _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, Board::Vcpu_context::Vcpu_context(unsigned id, void *vcpu_data_ptr)
Genode::addr_t context_phys_addr)
: :
vmcb(*Genode::construct_at<Vmcb>(vcpu_data_ptr, id, context_phys_addr)), vmcb(*Genode::construct_at<Vmcb>(vcpu_data_ptr, id)),
regs(1) regs(1)
{ {
regs->trapno = TRAP_VMEXIT; regs->trapno = TRAP_VMEXIT;

View File

@ -17,6 +17,7 @@
#include <base/internal/page_size.h> #include <base/internal/page_size.h>
#include <base/stdint.h> #include <base/stdint.h>
#include <cpu/vcpu_state.h> #include <cpu/vcpu_state.h>
#include <cpu/vcpu_state_virtualization.h>
#include <util/mmio.h> #include <util/mmio.h>
#include <util/string.h> #include <util/string.h>
@ -76,7 +77,7 @@ struct Board::Vmcb_control_area
struct Board::Vmcb_reserved_for_host struct Board::Vmcb_reserved_for_host
{ {
/* 64bit used by the inherited Mmio class here */ /* 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; Genode::addr_t root_vmcb_phys = 0U;
}; };
static_assert(Board::Vmcb_control_area::total_size - static_assert(Board::Vmcb_control_area::total_size -
@ -143,7 +144,7 @@ struct alignas(Genode::get_page_size()) Board::Vmcb
Asid_host = 0, 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); void init(Genode::size_t cpu_id, void * table_ptr);
static Vmcb & host_vmcb(Genode::size_t cpu_id); static Vmcb & host_vmcb(Genode::size_t cpu_id);
static Genode::addr_t dummy_msrpm(); static Genode::addr_t dummy_msrpm();
@ -154,6 +155,11 @@ struct alignas(Genode::get_page_size()) Board::Vmcb
sizeof(Board::Vmcb_state_save_area) - sizeof(Board::Vmcb_state_save_area) -
Board::Vmcb_control_area::total_size]; 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 * 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; Genode::Vm_data* vm_data = (Genode::Vm_data *) vm_data_ptr;
vm_data->vcpu_state = (Genode::Vcpu_state *) ds_addr; 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; return (Genode::addr_t) vm_data_ptr;
} }