diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 83e48365a..627aa9d55 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -21,8 +21,6 @@ use crate::pci_segment::PciSegment; use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::serial_manager::{Error as SerialManagerError, SerialManager}; use crate::sigwinch_listener::start_sigwinch_listener; -#[cfg(target_arch = "aarch64")] -use crate::GuestMemoryMmap; use crate::GuestRegionMmap; use crate::PciDeviceInfo; use crate::{device_node, DEVICE_MANAGER_SNAPSHOT_ID}; @@ -51,7 +49,7 @@ use devices::legacy::Serial; use devices::{ interrupt_controller, interrupt_controller::InterruptController, AcpiNotificationFlags, }; -use hypervisor::{HypervisorType, HypervisorVmError, IoEventAddress}; +use hypervisor::{HypervisorType, IoEventAddress}; use libc::{ cfmakeraw, isatty, tcgetattr, tcsetattr, termios, MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE, TCSANOW, @@ -92,8 +90,6 @@ use vm_device::interrupt::{ }; use vm_device::{Bus, BusDevice, Resource}; use vm_memory::guest_memory::FileOffset; -#[cfg(target_arch = "aarch64")] -use vm_memory::GuestMemoryAtomic; use vm_memory::GuestMemoryRegion; use vm_memory::{Address, GuestAddress, GuestUsize, MmapRegion}; #[cfg(target_arch = "x86_64")] @@ -464,9 +460,6 @@ pub enum DeviceManagerError { /// Cannot hotplug device behind vIOMMU InvalidIommuHotplug, - /// Failed to create UEFI flash - CreateUefiFlash(HypervisorVmError), - /// Invalid identifier as it is not unique. IdentifierNotUnique(String), @@ -929,10 +922,6 @@ pub struct DeviceManager { // GPIO device for AArch64 gpio_device: Option>>, - #[cfg(target_arch = "aarch64")] - // Flash device for UEFI on AArch64 - uefi_flash: Option>, - // Flag to force setting the iommu on virtio devices force_iommu: bool, @@ -1089,8 +1078,6 @@ impl DeviceManager { virtio_mem_devices: Vec::new(), #[cfg(target_arch = "aarch64")] gpio_device: None, - #[cfg(target_arch = "aarch64")] - uefi_flash: None, force_iommu, restoring, io_uring_supported: None, @@ -1685,38 +1672,6 @@ impl DeviceManager { .unwrap() .insert(id.clone(), device_node!(id, gpio_device)); - // On AArch64, the UEFI binary requires a flash device at address 0. - // 4 MiB memory is mapped to simulate the flash. - let uefi_mem_slot = self.memory_manager.lock().unwrap().allocate_memory_slot(); - let uefi_region = GuestRegionMmap::new( - MmapRegion::new(arch::layout::UEFI_SIZE as usize).unwrap(), - arch::layout::UEFI_START, - ) - .unwrap(); - let uefi_mem_region = self - .memory_manager - .lock() - .unwrap() - .vm - .make_user_memory_region( - uefi_mem_slot, - uefi_region.start_addr().raw_value(), - uefi_region.len() as u64, - uefi_region.as_ptr() as u64, - false, - false, - ); - self.memory_manager - .lock() - .unwrap() - .vm - .create_user_memory_region(uefi_mem_region) - .map_err(DeviceManagerError::CreateUefiFlash)?; - - let uefi_flash = - GuestMemoryAtomic::new(GuestMemoryMmap::from_regions(vec![uefi_region]).unwrap()); - self.uefi_flash = Some(uefi_flash); - Ok(()) } @@ -4162,11 +4117,6 @@ impl DeviceManager { &self.iommu_attached_devices } - #[cfg(target_arch = "aarch64")] - pub fn uefi_flash(&self) -> GuestMemoryAtomic { - self.uefi_flash.as_ref().unwrap().clone() - } - fn validate_identifier(&self, id: &Option) -> DeviceManagerResult<()> { if let Some(id) = id { if id.starts_with("__") { diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index b6c6dab90..9e68d2d84 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -19,6 +19,8 @@ use arch::x86_64::{SgxEpcRegion, SgxEpcSection}; use arch::{layout, RegionType}; #[cfg(target_arch = "x86_64")] use devices::ioapic; +#[cfg(target_arch = "aarch64")] +use hypervisor::HypervisorVmError; #[cfg(target_arch = "x86_64")] use libc::{MAP_NORESERVE, MAP_POPULATE, MAP_SHARED, PROT_READ, PROT_WRITE}; use serde::{Deserialize, Serialize}; @@ -185,6 +187,8 @@ pub struct MemoryManager { guest_ram_mappings: Vec, pub acpi_address: Option, + #[cfg(target_arch = "aarch64")] + uefi_flash: Option>, } #[derive(Debug)] @@ -314,6 +318,10 @@ pub enum Error { /// Failed to allocate MMIO address AllocateMmioAddress, + + #[cfg(target_arch = "aarch64")] + /// Failed to create UEFI flash + CreateUefiFlash(HypervisorVmError), } const ENABLE_FLAG: usize = 0; @@ -825,6 +833,36 @@ impl MemoryManager { Ok(()) } + #[cfg(target_arch = "aarch64")] + fn add_uefi_flash(&mut self) -> Result<(), Error> { + // On AArch64, the UEFI binary requires a flash device at address 0. + // 4 MiB memory is mapped to simulate the flash. + let uefi_mem_slot = self.allocate_memory_slot(); + let uefi_region = GuestRegionMmap::new( + MmapRegion::new(arch::layout::UEFI_SIZE as usize).unwrap(), + arch::layout::UEFI_START, + ) + .unwrap(); + let uefi_mem_region = self.vm.make_user_memory_region( + uefi_mem_slot, + uefi_region.start_addr().raw_value(), + uefi_region.len() as u64, + uefi_region.as_ptr() as u64, + false, + false, + ); + self.vm + .create_user_memory_region(uefi_mem_region) + .map_err(Error::CreateUefiFlash)?; + + let uefi_flash = + GuestMemoryAtomic::new(GuestMemoryMmap::from_regions(vec![uefi_region]).unwrap()); + + self.uefi_flash = Some(uefi_flash); + + Ok(()) + } + #[allow(clippy::too_many_arguments)] pub fn new( vm: Arc, @@ -1081,9 +1119,15 @@ impl MemoryManager { arch_mem_regions, ram_allocator, dynamic, + #[cfg(target_arch = "aarch64")] + uefi_flash: None, }; memory_manager.allocate_address_space()?; + + #[cfg(target_arch = "aarch64")] + memory_manager.add_uefi_flash()?; + #[cfg(target_arch = "x86_64")] if let Some(sgx_epc_config) = sgx_epc_config { memory_manager.setup_sgx(sgx_epc_config)?; @@ -1857,6 +1901,11 @@ impl MemoryManager { self.guest_ram_mappings.len() as u32 } + #[cfg(target_arch = "aarch64")] + pub fn uefi_flash(&self) -> GuestMemoryAtomic { + self.uefi_flash.as_ref().unwrap().clone() + } + #[cfg(feature = "guest_debug")] pub fn coredump_memory_regions(&self, mem_offset: u64) -> CoredumpMemoryRegions { let mut mapping_sorted_by_gpa = self.guest_ram_mappings.clone(); diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 50a52ca58..dd54bd908 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -953,7 +953,7 @@ impl Vm { #[cfg(target_arch = "aarch64")] fn load_firmware(&self, mut firmware: &File) -> Result<()> { - let uefi_flash = self.device_manager.lock().as_ref().unwrap().uefi_flash(); + let uefi_flash = self.memory_manager.lock().as_ref().unwrap().uefi_flash(); let mem = uefi_flash.memory(); arch::aarch64::uefi::load_uefi(mem.deref(), arch::layout::UEFI_START, &mut firmware) .map_err(Error::UefiLoad)?;