aarch, vmm: Reduce requirement for guest memory to vCPU boot only

When configuring the vCPUs it is only necessary to provide the guest
memory when booting fresh (for populating the guest memory). As such
refactor the vCPU configuration to remove the use of the
GuestMemoryMmap stored on the CpuManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-12-01 14:05:37 +00:00
parent e5e5a89e65
commit c7b22156da
4 changed files with 19 additions and 30 deletions

View File

@ -19,7 +19,7 @@ use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt::Debug;
use std::sync::{Arc, Mutex};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestUsize};
use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryAtomic, GuestUsize};
/// Errors thrown while configuring aarch64 system.
#[derive(Debug)]
@ -64,9 +64,9 @@ pub struct EntryPoint {
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> super::Result<u64> {
if let Some(kernel_entry_point) = kernel_entry_point {
if let Some((kernel_entry_point, _guest_memory)) = boot_setup {
vcpu.setup_regs(
id,
kernel_entry_point.entry_addr.raw_value(),

View File

@ -742,8 +742,7 @@ pub fn generate_common_cpuid(
pub fn configure_vcpu(
vcpu: &Arc<dyn hypervisor::Vcpu>,
id: u8,
kernel_entry_point: Option<EntryPoint>,
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
cpuid: Vec<CpuIdEntry>,
kvm_hyperv: bool,
) -> super::Result<()> {
@ -760,12 +759,12 @@ pub fn configure_vcpu(
}
regs::setup_msrs(vcpu).map_err(Error::MsrsConfiguration)?;
if let Some(kernel_entry_point) = kernel_entry_point {
if let Some((kernel_entry_point, guest_memory)) = boot_setup {
if let Some(entry_addr) = kernel_entry_point.entry_addr {
// Safe to unwrap because this method is called after the VM is configured
regs::setup_regs(vcpu, entry_addr.raw_value()).map_err(Error::RegsConfiguration)?;
regs::setup_fpu(vcpu).map_err(Error::FpuConfiguration)?;
regs::setup_sregs(&vm_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
regs::setup_sregs(&guest_memory.memory(), vcpu).map_err(Error::SregsConfiguration)?;
}
}
interrupts::set_lint(vcpu).map_err(|e| Error::LocalIntConfiguration(e.into()))?;

View File

@ -329,28 +329,20 @@ impl Vcpu {
pub fn configure(
&mut self,
#[cfg(target_arch = "aarch64")] vm: &Arc<dyn hypervisor::Vm>,
kernel_entry_point: Option<EntryPoint>,
#[cfg(target_arch = "x86_64")] guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
#[cfg(target_arch = "x86_64")] cpuid: Vec<CpuIdEntry>,
#[cfg(target_arch = "x86_64")] kvm_hyperv: bool,
) -> Result<()> {
#[cfg(target_arch = "aarch64")]
{
self.init(vm)?;
self.mpidr = arch::configure_vcpu(&self.vcpu, self.id, kernel_entry_point)
self.mpidr = arch::configure_vcpu(&self.vcpu, self.id, boot_setup)
.map_err(Error::VcpuConfiguration)?;
}
info!("Configuring vCPU: cpu_id = {}", self.id);
#[cfg(target_arch = "x86_64")]
arch::configure_vcpu(
&self.vcpu,
self.id,
kernel_entry_point,
guest_memory,
cpuid,
kvm_hyperv,
)
.map_err(Error::VcpuConfiguration)?;
arch::configure_vcpu(&self.vcpu, self.id, boot_setup, cpuid, kvm_hyperv)
.map_err(Error::VcpuConfiguration)?;
Ok(())
}
@ -426,7 +418,7 @@ pub struct CpuManager {
config: CpusConfig,
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>,
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
#[cfg(feature = "guest_debug")]
guest_memory: GuestMemoryAtomic<GuestMemoryMmap>,
#[cfg(target_arch = "x86_64")]
cpuid: Vec<CpuIdEntry>,
@ -688,6 +680,7 @@ impl CpuManager {
hypervisor_type,
config: config.clone(),
interrupt_controller: None,
#[cfg(feature = "guest_debug")]
guest_memory,
#[cfg(target_arch = "x86_64")]
cpuid,
@ -741,21 +734,16 @@ impl CpuManager {
pub fn configure_vcpu(
&self,
vcpu: Arc<Mutex<Vcpu>>,
entry_point: Option<EntryPoint>,
boot_setup: Option<(EntryPoint, &GuestMemoryAtomic<GuestMemoryMmap>)>,
) -> Result<()> {
let mut vcpu = vcpu.lock().unwrap();
#[cfg(target_arch = "x86_64")]
vcpu.configure(
entry_point,
&self.guest_memory,
self.cpuid.clone(),
self.config.kvm_hyperv,
)
.expect("Failed to configure vCPU");
vcpu.configure(boot_setup, self.cpuid.clone(), self.config.kvm_hyperv)
.expect("Failed to configure vCPU");
#[cfg(target_arch = "aarch64")]
vcpu.configure(&self.vm, entry_point)
vcpu.configure(&self.vm, boot_setup)
.expect("Failed to configure vCPU");
Ok(())

View File

@ -2058,10 +2058,12 @@ impl Vm {
// Configure the vcpus that have been created
let vcpus = self.cpu_manager.lock().unwrap().vcpus();
for vcpu in vcpus {
let guest_memory = &self.memory_manager.lock().as_ref().unwrap().guest_memory();
let boot_setup = entry_point.map(|e| (e, guest_memory));
self.cpu_manager
.lock()
.unwrap()
.configure_vcpu(vcpu, entry_point)
.configure_vcpu(vcpu, boot_setup)
.map_err(Error::CpuManager)?;
}