mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-03 20:15:45 +00:00
vmm:AArch64: move uefi_flash to memory manager
uefi_flash is used when load firmware, that is load payload depends on device manager. move uefi_flash to memory manager can eliminate the dependency. Signed-off-by: Jianyong Wu <jianyong.wu@arm.com> Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
parent
9b1452f258
commit
b65639fad3
@ -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<Arc<Mutex<devices::legacy::Gpio>>>,
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
// Flash device for UEFI on AArch64
|
||||
uefi_flash: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
|
||||
// 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<GuestMemoryMmap> {
|
||||
self.uefi_flash.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
fn validate_identifier(&self, id: &Option<String>) -> DeviceManagerResult<()> {
|
||||
if let Some(id) = id {
|
||||
if id.starts_with("__") {
|
||||
|
@ -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<GuestRamMapping>,
|
||||
|
||||
pub acpi_address: Option<GuestAddress>,
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
uefi_flash: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
}
|
||||
|
||||
#[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<dyn hypervisor::Vm>,
|
||||
@ -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<GuestMemoryMmap> {
|
||||
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();
|
||||
|
@ -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)?;
|
||||
|
Loading…
Reference in New Issue
Block a user