From c7b22156da355dbfb3570d65402fe65df3cf5f58 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 1 Dec 2022 14:05:37 +0000 Subject: [PATCH] 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 --- arch/src/aarch64/mod.rs | 6 +++--- arch/src/x86_64/mod.rs | 7 +++---- vmm/src/cpu.rs | 32 ++++++++++---------------------- vmm/src/vm.rs | 4 +++- 4 files changed, 19 insertions(+), 30 deletions(-) diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 93ea987a0..afc051489 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -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, id: u8, - kernel_entry_point: Option, + boot_setup: Option<(EntryPoint, &GuestMemoryAtomic)>, ) -> super::Result { - 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(), diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 8dceb2664..0789db72b 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -742,8 +742,7 @@ pub fn generate_common_cpuid( pub fn configure_vcpu( vcpu: &Arc, id: u8, - kernel_entry_point: Option, - vm_memory: &GuestMemoryAtomic, + boot_setup: Option<(EntryPoint, &GuestMemoryAtomic)>, cpuid: Vec, 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()))?; diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 58049dd38..d9d31dbdc 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -329,28 +329,20 @@ impl Vcpu { pub fn configure( &mut self, #[cfg(target_arch = "aarch64")] vm: &Arc, - kernel_entry_point: Option, - #[cfg(target_arch = "x86_64")] guest_memory: &GuestMemoryAtomic, + boot_setup: Option<(EntryPoint, &GuestMemoryAtomic)>, #[cfg(target_arch = "x86_64")] cpuid: Vec, #[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>>, - #[cfg_attr(target_arch = "aarch64", allow(dead_code))] + #[cfg(feature = "guest_debug")] guest_memory: GuestMemoryAtomic, #[cfg(target_arch = "x86_64")] cpuid: Vec, @@ -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>, - entry_point: Option, + boot_setup: Option<(EntryPoint, &GuestMemoryAtomic)>, ) -> 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(()) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index cf6416eed..114ba5da8 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -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)?; }