mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
vmm, vm-allocator: Introduce an allocator for platform devices
This allocator allocates 64-bit MMIO addresses for use with platform devices e.g. ACPI control devices and ensures there is no overlap with PCI address space ranges which can cause issues with PCI device remapping. Use this allocator the ACPI platform devices. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
9d1a7e43a7
commit
def98faf37
@ -47,13 +47,13 @@ fn pagesize() -> usize {
|
|||||||
/// assert_eq!(allocator.allocate_irq(), Some(6));
|
/// assert_eq!(allocator.allocate_irq(), Some(6));
|
||||||
/// #[cfg(target_arch = "aarch64")]
|
/// #[cfg(target_arch = "aarch64")]
|
||||||
/// assert_eq!(allocator.allocate_irq(), Some(33));
|
/// assert_eq!(allocator.allocate_irq(), Some(33));
|
||||||
/// assert_eq!(allocator.allocate_mmio_addresses(None, 0x1000, Some(0x1000)), Some(GuestAddress(0x1fff_f000)));
|
/// assert_eq!(allocator.allocate_platform_mmio_addresses(None, 0x1000, Some(0x1000)), Some(GuestAddress(0x1fff_f000)));
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub struct SystemAllocator {
|
pub struct SystemAllocator {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
io_address_space: AddressAllocator,
|
io_address_space: AddressAllocator,
|
||||||
mmio_address_space: AddressAllocator,
|
platform_mmio_address_space: AddressAllocator,
|
||||||
mmio_hole_address_space: AddressAllocator,
|
mmio_hole_address_space: AddressAllocator,
|
||||||
gsi_allocator: GsiAllocator,
|
gsi_allocator: GsiAllocator,
|
||||||
}
|
}
|
||||||
@ -64,8 +64,8 @@ impl SystemAllocator {
|
|||||||
///
|
///
|
||||||
/// * `io_base` - (X86) The starting address of IO memory.
|
/// * `io_base` - (X86) The starting address of IO memory.
|
||||||
/// * `io_size` - (X86) The size of IO memory.
|
/// * `io_size` - (X86) The size of IO memory.
|
||||||
/// * `mmio_base` - The starting address of MMIO memory.
|
/// * `platform_mmio_base` - The starting address of platform MMIO memory.
|
||||||
/// * `mmio_size` - The size of MMIO memory.
|
/// * `platform_mmio_size` - The size of platform MMIO memory.
|
||||||
/// * `mmio_hole_base` - The starting address of MMIO memory in 32-bit address space.
|
/// * `mmio_hole_base` - The starting address of MMIO memory in 32-bit address space.
|
||||||
/// * `mmio_hole_size` - The size of MMIO memory in 32-bit address space.
|
/// * `mmio_hole_size` - The size of MMIO memory in 32-bit address space.
|
||||||
/// * `apics` - (X86) Vector of APIC's.
|
/// * `apics` - (X86) Vector of APIC's.
|
||||||
@ -73,8 +73,8 @@ impl SystemAllocator {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
#[cfg(target_arch = "x86_64")] io_base: GuestAddress,
|
#[cfg(target_arch = "x86_64")] io_base: GuestAddress,
|
||||||
#[cfg(target_arch = "x86_64")] io_size: GuestUsize,
|
#[cfg(target_arch = "x86_64")] io_size: GuestUsize,
|
||||||
mmio_base: GuestAddress,
|
platform_mmio_base: GuestAddress,
|
||||||
mmio_size: GuestUsize,
|
platform_mmio_size: GuestUsize,
|
||||||
mmio_hole_base: GuestAddress,
|
mmio_hole_base: GuestAddress,
|
||||||
mmio_hole_size: GuestUsize,
|
mmio_hole_size: GuestUsize,
|
||||||
#[cfg(target_arch = "x86_64")] apics: Vec<GsiApic>,
|
#[cfg(target_arch = "x86_64")] apics: Vec<GsiApic>,
|
||||||
@ -82,7 +82,10 @@ impl SystemAllocator {
|
|||||||
Some(SystemAllocator {
|
Some(SystemAllocator {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
io_address_space: AddressAllocator::new(io_base, io_size)?,
|
io_address_space: AddressAllocator::new(io_base, io_size)?,
|
||||||
mmio_address_space: AddressAllocator::new(mmio_base, mmio_size)?,
|
platform_mmio_address_space: AddressAllocator::new(
|
||||||
|
platform_mmio_base,
|
||||||
|
platform_mmio_size,
|
||||||
|
)?,
|
||||||
mmio_hole_address_space: AddressAllocator::new(mmio_hole_base, mmio_hole_size)?,
|
mmio_hole_address_space: AddressAllocator::new(mmio_hole_base, mmio_hole_size)?,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
gsi_allocator: GsiAllocator::new(apics),
|
gsi_allocator: GsiAllocator::new(apics),
|
||||||
@ -113,14 +116,14 @@ impl SystemAllocator {
|
|||||||
.allocate(address, size, Some(align_size.unwrap_or(0x1)))
|
.allocate(address, size, Some(align_size.unwrap_or(0x1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserves a section of `size` bytes of MMIO address space.
|
/// Reserves a section of `size` bytes of platform MMIO address space.
|
||||||
pub fn allocate_mmio_addresses(
|
pub fn allocate_platform_mmio_addresses(
|
||||||
&mut self,
|
&mut self,
|
||||||
address: Option<GuestAddress>,
|
address: Option<GuestAddress>,
|
||||||
size: GuestUsize,
|
size: GuestUsize,
|
||||||
align_size: Option<GuestUsize>,
|
align_size: Option<GuestUsize>,
|
||||||
) -> Option<GuestAddress> {
|
) -> Option<GuestAddress> {
|
||||||
self.mmio_address_space.allocate(
|
self.platform_mmio_address_space.allocate(
|
||||||
address,
|
address,
|
||||||
size,
|
size,
|
||||||
Some(align_size.unwrap_or(pagesize() as u64)),
|
Some(align_size.unwrap_or(pagesize() as u64)),
|
||||||
@ -148,10 +151,10 @@ impl SystemAllocator {
|
|||||||
self.io_address_space.free(address, size)
|
self.io_address_space.free(address, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free an MMIO address range.
|
/// Free a platform MMIO address range.
|
||||||
/// We can only free a range if it matches exactly an already allocated range.
|
/// We can only free a range if it matches exactly an already allocated range.
|
||||||
pub fn free_mmio_addresses(&mut self, address: GuestAddress, size: GuestUsize) {
|
pub fn free_platform_mmio_addresses(&mut self, address: GuestAddress, size: GuestUsize) {
|
||||||
self.mmio_address_space.free(address, size)
|
self.platform_mmio_address_space.free(address, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free an MMIO address range from the 32 bits hole.
|
/// Free an MMIO address range from the 32 bits hole.
|
||||||
|
@ -575,7 +575,7 @@ impl CpuManager {
|
|||||||
.allocator()
|
.allocator()
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_mmio_addresses(None, CPU_MANAGER_ACPI_SIZE as u64, None)
|
.allocate_platform_mmio_addresses(None, CPU_MANAGER_ACPI_SIZE as u64, None)
|
||||||
.ok_or(Error::AllocateMmmioAddress)?;
|
.ok_or(Error::AllocateMmmioAddress)?;
|
||||||
|
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
|
@ -975,7 +975,7 @@ impl DeviceManager {
|
|||||||
.allocator
|
.allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_mmio_addresses(None, DEVICE_MANAGER_ACPI_SIZE as u64, None)
|
.allocate_platform_mmio_addresses(None, DEVICE_MANAGER_ACPI_SIZE as u64, None)
|
||||||
.ok_or(DeviceManagerError::AllocateIoPort)?;
|
.ok_or(DeviceManagerError::AllocateIoPort)?;
|
||||||
|
|
||||||
let mut pci_irq_slots = [0; 32];
|
let mut pci_irq_slots = [0; 32];
|
||||||
@ -1366,7 +1366,11 @@ impl DeviceManager {
|
|||||||
.allocator
|
.allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_mmio_addresses(None, devices::acpi::GED_DEVICE_ACPI_SIZE as u64, None)
|
.allocate_platform_mmio_addresses(
|
||||||
|
None,
|
||||||
|
devices::acpi::GED_DEVICE_ACPI_SIZE as u64,
|
||||||
|
None,
|
||||||
|
)
|
||||||
.ok_or(DeviceManagerError::AllocateMmioAddress)?;
|
.ok_or(DeviceManagerError::AllocateMmioAddress)?;
|
||||||
let ged_device = Arc::new(Mutex::new(devices::AcpiGedDevice::new(
|
let ged_device = Arc::new(Mutex::new(devices::AcpiGedDevice::new(
|
||||||
interrupt_group,
|
interrupt_group,
|
||||||
|
@ -63,6 +63,9 @@ const MPOL_BIND: u32 = 2;
|
|||||||
const MPOL_MF_STRICT: u32 = 1;
|
const MPOL_MF_STRICT: u32 = 1;
|
||||||
const MPOL_MF_MOVE: u32 = 1 << 1;
|
const MPOL_MF_MOVE: u32 = 1 << 1;
|
||||||
|
|
||||||
|
// Reserve 1 MiB for platform MMIO devices (e.g. ACPI control devices)
|
||||||
|
const PLATFORM_DEVICE_AREA_SIZE: u64 = 1 << 20;
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, Versionize)]
|
#[derive(Clone, Default, Serialize, Deserialize, Versionize)]
|
||||||
struct HotPlugState {
|
struct HotPlugState {
|
||||||
base: u64,
|
base: u64,
|
||||||
@ -827,7 +830,9 @@ impl MemoryManager {
|
|||||||
(((mmio_address_space_size) >> 16) << 16),
|
(((mmio_address_space_size) >> 16) << 16),
|
||||||
mmio_address_space_size
|
mmio_address_space_size
|
||||||
);
|
);
|
||||||
let end_of_device_area = GuestAddress(mmio_address_space_size - 1);
|
let start_of_platform_device_area =
|
||||||
|
GuestAddress(mmio_address_space_size - PLATFORM_DEVICE_AREA_SIZE);
|
||||||
|
let end_of_device_area = start_of_platform_device_area.unchecked_sub(1);
|
||||||
|
|
||||||
let (ram_size, zones, allow_mem_hotplug) =
|
let (ram_size, zones, allow_mem_hotplug) =
|
||||||
Self::validate_memory_config(config, user_provided_zones)?;
|
Self::validate_memory_config(config, user_provided_zones)?;
|
||||||
@ -989,8 +994,8 @@ impl MemoryManager {
|
|||||||
{
|
{
|
||||||
1 << 16
|
1 << 16
|
||||||
},
|
},
|
||||||
GuestAddress(0),
|
start_of_platform_device_area,
|
||||||
mmio_address_space_size,
|
PLATFORM_DEVICE_AREA_SIZE,
|
||||||
layout::MEM_32BIT_DEVICES_START,
|
layout::MEM_32BIT_DEVICES_START,
|
||||||
layout::MEM_32BIT_DEVICES_SIZE,
|
layout::MEM_32BIT_DEVICES_SIZE,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -1006,7 +1011,7 @@ impl MemoryManager {
|
|||||||
let acpi_address = allocator
|
let acpi_address = allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate_mmio_addresses(None, MEMORY_MANAGER_ACPI_SIZE as u64, None)
|
.allocate_platform_mmio_addresses(None, MEMORY_MANAGER_ACPI_SIZE as u64, None)
|
||||||
.ok_or(Error::AllocateMmioAddress)?;
|
.ok_or(Error::AllocateMmioAddress)?;
|
||||||
|
|
||||||
#[cfg(not(feature = "tdx"))]
|
#[cfg(not(feature = "tdx"))]
|
||||||
|
Loading…
Reference in New Issue
Block a user