From e9488846f1d3ce17fde603adc8f9bb2abb8a5a8d Mon Sep 17 00:00:00 2001 From: Michael Zhao Date: Tue, 9 Jun 2020 12:04:40 +0800 Subject: [PATCH] vm-allocator: Enable vm-allocator for AArch64 Implemented GSI allocator and system allocator for AArch64. Renamed some layout definitions to align more code between architectures. Signed-off-by: Michael Zhao --- arch/src/aarch64/layout.rs | 4 ++-- arch/src/aarch64/mod.rs | 6 +++--- vm-allocator/Cargo.toml | 1 + vm-allocator/src/gsi.rs | 35 ++++++++++++++++++++++++++++++----- vm-allocator/src/lib.rs | 4 +++- vm-allocator/src/system.rs | 14 +++++++++++--- vmm/src/memory_manager.rs | 22 +++------------------- 7 files changed, 53 insertions(+), 33 deletions(-) diff --git a/arch/src/aarch64/layout.rs b/arch/src/aarch64/layout.rs index 715894e9f..aae867634 100644 --- a/arch/src/aarch64/layout.rs +++ b/arch/src/aarch64/layout.rs @@ -56,8 +56,8 @@ pub const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000; pub const LEGACY_DEVICES_MAPPED_IO_SIZE: u64 = 0x0700_0000; /// Starting from 0x1000_0000 (256MiB), the 768MiB (ends at 1 GiB) is used for PCIE MMIO -pub const PCI_DEVICES_MAPPED_IO_START: u64 = 0x1000_0000; -pub const PCI_DEVICES_MAPPED_IO_SIZE: u64 = 0x3000_0000; +pub const MEM_32BIT_DEVICES_START: GuestAddress = GuestAddress(0x1000_0000); +pub const MEM_32BIT_DEVICES_SIZE: u64 = 0x3000_0000; /// PCI MMCONFIG space (start: after the device space at 1 GiB, length: 256MiB) pub const PCI_MMCONFIG_START: GuestAddress = GuestAddress(0x4000_0000); diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 508dcbed4..3c76757b7 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -63,14 +63,14 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region // 0 ~ 256 MiB: Reserved regions.push(( GuestAddress(0), - layout::PCI_DEVICES_MAPPED_IO_START as usize, + layout::MEM_32BIT_DEVICES_START.0 as usize, RegionType::Reserved, )); // 256 MiB ~ 1 G: MMIO space regions.push(( - GuestAddress(layout::PCI_DEVICES_MAPPED_IO_START), - layout::PCI_DEVICES_MAPPED_IO_SIZE as usize, + layout::MEM_32BIT_DEVICES_START, + layout::MEM_32BIT_DEVICES_SIZE as usize, RegionType::SubRegion, )); diff --git a/vm-allocator/Cargo.toml b/vm-allocator/Cargo.toml index e785de228..28336d7b3 100644 --- a/vm-allocator/Cargo.toml +++ b/vm-allocator/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" [dependencies] libc = "0.2.71" vm-memory = "0.2.1" +arch = { path = "../arch" } diff --git a/vm-allocator/src/gsi.rs b/vm-allocator/src/gsi.rs index 88e05bf8e..f650506c8 100644 --- a/vm-allocator/src/gsi.rs +++ b/vm-allocator/src/gsi.rs @@ -2,6 +2,9 @@ // // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause +#[cfg(target_arch = "aarch64")] +use arch; +#[cfg(target_arch = "x86_64")] use std::collections::btree_map::BTreeMap; use std::result; @@ -13,12 +16,14 @@ pub enum Error { pub type Result = result::Result; /// GsiApic +#[cfg(target_arch = "x86_64")] #[derive(Copy, Clone)] pub struct GsiApic { base: u32, irqs: u32, } +#[cfg(target_arch = "x86_64")] impl GsiApic { /// New GSI APIC pub fn new(base: u32, irqs: u32) -> Self { @@ -28,12 +33,14 @@ impl GsiApic { /// GsiAllocator pub struct GsiAllocator { + #[cfg(target_arch = "x86_64")] apics: BTreeMap, next_irq: u32, next_gsi: u32, } impl GsiAllocator { + #[cfg(target_arch = "x86_64")] /// New GSI allocator pub fn new(apics: Vec) -> Self { let mut allocator = GsiAllocator { @@ -57,13 +64,23 @@ impl GsiAllocator { allocator } - /// Allocate a GSI - pub fn allocate_gsi(&mut self) -> Result { - self.next_gsi = self.next_gsi.checked_add(1).ok_or(Error::Overflow)?; - - Ok(self.next_gsi - 1) + #[cfg(target_arch = "aarch64")] + /// New GSI allocator + pub fn new() -> Self { + GsiAllocator { + next_irq: arch::IRQ_BASE, + next_gsi: arch::IRQ_BASE, + } } + /// Allocate a GSI + pub fn allocate_gsi(&mut self) -> Result { + let gsi = self.next_gsi; + self.next_gsi = self.next_gsi.checked_add(1).ok_or(Error::Overflow)?; + Ok(gsi) + } + + #[cfg(target_arch = "x86_64")] /// Allocate an IRQ pub fn allocate_irq(&mut self) -> Result { let mut irq: u32 = 0; @@ -81,4 +98,12 @@ impl GsiAllocator { Ok(irq) } + + #[cfg(target_arch = "aarch64")] + /// Allocate an IRQ + pub fn allocate_irq(&mut self) -> Result { + let irq = self.next_irq; + self.next_irq = self.next_irq.checked_add(1).ok_or(Error::Overflow)?; + Ok(irq) + } } diff --git a/vm-allocator/src/lib.rs b/vm-allocator/src/lib.rs index 15d431ce5..484b6e338 100644 --- a/vm-allocator/src/lib.rs +++ b/vm-allocator/src/lib.rs @@ -18,5 +18,7 @@ mod gsi; mod system; pub use crate::address::AddressAllocator; -pub use crate::gsi::{GsiAllocator, GsiApic}; +pub use crate::gsi::GsiAllocator; +#[cfg(target_arch = "x86_64")] +pub use crate::gsi::GsiApic; pub use crate::system::SystemAllocator; diff --git a/vm-allocator/src/system.rs b/vm-allocator/src/system.rs index 8cb4eccd8..811e79b31 100644 --- a/vm-allocator/src/system.rs +++ b/vm-allocator/src/system.rs @@ -10,7 +10,9 @@ use vm_memory::{GuestAddress, GuestUsize}; use crate::address::AddressAllocator; -use crate::gsi::{GsiAllocator, GsiApic}; +use crate::gsi::GsiAllocator; +#[cfg(target_arch = "x86_64")] +use crate::gsi::GsiApic; use libc::{sysconf, _SC_PAGESIZE}; @@ -53,7 +55,10 @@ impl SystemAllocator { /// * `io_size` - The size of IO memory. /// * `mmio_base` - The starting address of MMIO memory. /// * `mmio_size` - The size of MMIO memory. - /// * `first_irq` - The first irq number to give out. + /// * `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. + /// * `apics` - (X86) Vector of APIC's. + /// pub fn new( io_base: GuestAddress, io_size: GuestUsize, @@ -61,13 +66,16 @@ impl SystemAllocator { mmio_size: GuestUsize, mmio_hole_base: GuestAddress, mmio_hole_size: GuestUsize, - apics: Vec, + #[cfg(target_arch = "x86_64")] apics: Vec, ) -> Option { Some(SystemAllocator { io_address_space: AddressAllocator::new(io_base, io_size)?, mmio_address_space: AddressAllocator::new(mmio_base, mmio_size)?, mmio_hole_address_space: AddressAllocator::new(mmio_hole_base, mmio_hole_size)?, + #[cfg(target_arch = "x86_64")] gsi_allocator: GsiAllocator::new(apics), + #[cfg(target_arch = "aarch64")] + gsi_allocator: GsiAllocator::new(), }) } diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 463e9798f..c2885e0b1 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -8,9 +8,7 @@ use crate::MEMORY_MANAGER_SNAPSHOT_ID; #[cfg(feature = "acpi")] use acpi_tables::{aml, aml::Aml}; use anyhow::anyhow; -#[cfg(target_arch = "x86_64")] -use arch::layout; -use arch::{get_host_cpu_phys_bits, RegionType}; +use arch::{get_host_cpu_phys_bits, layout, RegionType}; #[cfg(target_arch = "x86_64")] use devices::ioapic; use devices::BusDevice; @@ -301,7 +299,6 @@ impl MemoryManager { let mut hotplug_slots = Vec::with_capacity(HOTPLUG_COUNT); hotplug_slots.resize_with(HOTPLUG_COUNT, HotPlugState::default); - #[cfg(target_arch = "x86_64")] // Both MMIO and PIO address spaces start at address 0. let allocator = Arc::new(Mutex::new( SystemAllocator::new( @@ -309,8 +306,9 @@ impl MemoryManager { 1 << 16 as GuestUsize, GuestAddress(0), mmio_address_space_size(), - layout::MEM_32BIT_RESERVED_START, + layout::MEM_32BIT_DEVICES_START, layout::MEM_32BIT_DEVICES_SIZE, + #[cfg(target_arch = "x86_64")] vec![GsiApic::new( X86_64_IRQ_BASE, ioapic::NUM_IOAPIC_PINS as u32 - X86_64_IRQ_BASE, @@ -319,20 +317,6 @@ impl MemoryManager { .ok_or(Error::CreateSystemAllocator)?, )); - #[cfg(target_arch = "aarch64")] - let allocator = Arc::new(Mutex::new( - SystemAllocator::new( - GuestAddress(0), - 0, - GuestAddress(0), - 0, - GuestAddress(0), - 0, - vec![], - ) - .ok_or(Error::CreateSystemAllocator)?, - )); - let memory_manager = Arc::new(Mutex::new(MemoryManager { guest_memory: guest_memory.clone(), next_kvm_memory_slot: 0,