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 <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao
2020-06-09 12:04:40 +08:00
committed by Rob Bradford
parent 5343b0ac18
commit e9488846f1
7 changed files with 53 additions and 33 deletions

View File

@@ -56,8 +56,8 @@ pub const LEGACY_RTC_MAPPED_IO_START: u64 = 0x0901_0000;
pub const LEGACY_DEVICES_MAPPED_IO_SIZE: u64 = 0x0700_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 /// 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 MEM_32BIT_DEVICES_START: GuestAddress = GuestAddress(0x1000_0000);
pub const PCI_DEVICES_MAPPED_IO_SIZE: u64 = 0x3000_0000; pub const MEM_32BIT_DEVICES_SIZE: u64 = 0x3000_0000;
/// PCI MMCONFIG space (start: after the device space at 1 GiB, length: 256MiB) /// PCI MMCONFIG space (start: after the device space at 1 GiB, length: 256MiB)
pub const PCI_MMCONFIG_START: GuestAddress = GuestAddress(0x4000_0000); pub const PCI_MMCONFIG_START: GuestAddress = GuestAddress(0x4000_0000);

View File

@@ -63,14 +63,14 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
// 0 ~ 256 MiB: Reserved // 0 ~ 256 MiB: Reserved
regions.push(( regions.push((
GuestAddress(0), GuestAddress(0),
layout::PCI_DEVICES_MAPPED_IO_START as usize, layout::MEM_32BIT_DEVICES_START.0 as usize,
RegionType::Reserved, RegionType::Reserved,
)); ));
// 256 MiB ~ 1 G: MMIO space // 256 MiB ~ 1 G: MMIO space
regions.push(( regions.push((
GuestAddress(layout::PCI_DEVICES_MAPPED_IO_START), layout::MEM_32BIT_DEVICES_START,
layout::PCI_DEVICES_MAPPED_IO_SIZE as usize, layout::MEM_32BIT_DEVICES_SIZE as usize,
RegionType::SubRegion, RegionType::SubRegion,
)); ));

View File

@@ -7,3 +7,4 @@ edition = "2018"
[dependencies] [dependencies]
libc = "0.2.71" libc = "0.2.71"
vm-memory = "0.2.1" vm-memory = "0.2.1"
arch = { path = "../arch" }

View File

@@ -2,6 +2,9 @@
// //
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause // 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::collections::btree_map::BTreeMap;
use std::result; use std::result;
@@ -13,12 +16,14 @@ pub enum Error {
pub type Result<T> = result::Result<T, Error>; pub type Result<T> = result::Result<T, Error>;
/// GsiApic /// GsiApic
#[cfg(target_arch = "x86_64")]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct GsiApic { pub struct GsiApic {
base: u32, base: u32,
irqs: u32, irqs: u32,
} }
#[cfg(target_arch = "x86_64")]
impl GsiApic { impl GsiApic {
/// New GSI APIC /// New GSI APIC
pub fn new(base: u32, irqs: u32) -> Self { pub fn new(base: u32, irqs: u32) -> Self {
@@ -28,12 +33,14 @@ impl GsiApic {
/// GsiAllocator /// GsiAllocator
pub struct GsiAllocator { pub struct GsiAllocator {
#[cfg(target_arch = "x86_64")]
apics: BTreeMap<u32, u32>, apics: BTreeMap<u32, u32>,
next_irq: u32, next_irq: u32,
next_gsi: u32, next_gsi: u32,
} }
impl GsiAllocator { impl GsiAllocator {
#[cfg(target_arch = "x86_64")]
/// New GSI allocator /// New GSI allocator
pub fn new(apics: Vec<GsiApic>) -> Self { pub fn new(apics: Vec<GsiApic>) -> Self {
let mut allocator = GsiAllocator { let mut allocator = GsiAllocator {
@@ -57,13 +64,23 @@ impl GsiAllocator {
allocator allocator
} }
/// Allocate a GSI #[cfg(target_arch = "aarch64")]
pub fn allocate_gsi(&mut self) -> Result<u32> { /// New GSI allocator
self.next_gsi = self.next_gsi.checked_add(1).ok_or(Error::Overflow)?; pub fn new() -> Self {
GsiAllocator {
Ok(self.next_gsi - 1) next_irq: arch::IRQ_BASE,
next_gsi: arch::IRQ_BASE,
}
} }
/// Allocate a GSI
pub fn allocate_gsi(&mut self) -> Result<u32> {
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 /// Allocate an IRQ
pub fn allocate_irq(&mut self) -> Result<u32> { pub fn allocate_irq(&mut self) -> Result<u32> {
let mut irq: u32 = 0; let mut irq: u32 = 0;
@@ -81,4 +98,12 @@ impl GsiAllocator {
Ok(irq) Ok(irq)
} }
#[cfg(target_arch = "aarch64")]
/// Allocate an IRQ
pub fn allocate_irq(&mut self) -> Result<u32> {
let irq = self.next_irq;
self.next_irq = self.next_irq.checked_add(1).ok_or(Error::Overflow)?;
Ok(irq)
}
} }

View File

@@ -18,5 +18,7 @@ mod gsi;
mod system; mod system;
pub use crate::address::AddressAllocator; 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; pub use crate::system::SystemAllocator;

View File

@@ -10,7 +10,9 @@
use vm_memory::{GuestAddress, GuestUsize}; use vm_memory::{GuestAddress, GuestUsize};
use crate::address::AddressAllocator; 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}; use libc::{sysconf, _SC_PAGESIZE};
@@ -53,7 +55,10 @@ impl SystemAllocator {
/// * `io_size` - The size of IO memory. /// * `io_size` - The size of IO memory.
/// * `mmio_base` - The starting address of MMIO memory. /// * `mmio_base` - The starting address of MMIO memory.
/// * `mmio_size` - The size 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( pub fn new(
io_base: GuestAddress, io_base: GuestAddress,
io_size: GuestUsize, io_size: GuestUsize,
@@ -61,13 +66,16 @@ impl SystemAllocator {
mmio_size: GuestUsize, mmio_size: GuestUsize,
mmio_hole_base: GuestAddress, mmio_hole_base: GuestAddress,
mmio_hole_size: GuestUsize, mmio_hole_size: GuestUsize,
apics: Vec<GsiApic>, #[cfg(target_arch = "x86_64")] apics: Vec<GsiApic>,
) -> Option<Self> { ) -> Option<Self> {
Some(SystemAllocator { Some(SystemAllocator {
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)?, mmio_address_space: AddressAllocator::new(mmio_base, 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")]
gsi_allocator: GsiAllocator::new(apics), gsi_allocator: GsiAllocator::new(apics),
#[cfg(target_arch = "aarch64")]
gsi_allocator: GsiAllocator::new(),
}) })
} }

View File

@@ -8,9 +8,7 @@ use crate::MEMORY_MANAGER_SNAPSHOT_ID;
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]
use acpi_tables::{aml, aml::Aml}; use acpi_tables::{aml, aml::Aml};
use anyhow::anyhow; use anyhow::anyhow;
#[cfg(target_arch = "x86_64")] use arch::{get_host_cpu_phys_bits, layout, RegionType};
use arch::layout;
use arch::{get_host_cpu_phys_bits, RegionType};
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use devices::ioapic; use devices::ioapic;
use devices::BusDevice; use devices::BusDevice;
@@ -301,7 +299,6 @@ impl MemoryManager {
let mut hotplug_slots = Vec::with_capacity(HOTPLUG_COUNT); let mut hotplug_slots = Vec::with_capacity(HOTPLUG_COUNT);
hotplug_slots.resize_with(HOTPLUG_COUNT, HotPlugState::default); hotplug_slots.resize_with(HOTPLUG_COUNT, HotPlugState::default);
#[cfg(target_arch = "x86_64")]
// Both MMIO and PIO address spaces start at address 0. // Both MMIO and PIO address spaces start at address 0.
let allocator = Arc::new(Mutex::new( let allocator = Arc::new(Mutex::new(
SystemAllocator::new( SystemAllocator::new(
@@ -309,8 +306,9 @@ impl MemoryManager {
1 << 16 as GuestUsize, 1 << 16 as GuestUsize,
GuestAddress(0), GuestAddress(0),
mmio_address_space_size(), mmio_address_space_size(),
layout::MEM_32BIT_RESERVED_START, layout::MEM_32BIT_DEVICES_START,
layout::MEM_32BIT_DEVICES_SIZE, layout::MEM_32BIT_DEVICES_SIZE,
#[cfg(target_arch = "x86_64")]
vec![GsiApic::new( vec![GsiApic::new(
X86_64_IRQ_BASE, X86_64_IRQ_BASE,
ioapic::NUM_IOAPIC_PINS as u32 - X86_64_IRQ_BASE, ioapic::NUM_IOAPIC_PINS as u32 - X86_64_IRQ_BASE,
@@ -319,20 +317,6 @@ impl MemoryManager {
.ok_or(Error::CreateSystemAllocator)?, .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 { let memory_manager = Arc::new(Mutex::new(MemoryManager {
guest_memory: guest_memory.clone(), guest_memory: guest_memory.clone(),
next_kvm_memory_slot: 0, next_kvm_memory_slot: 0,