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;
/// 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);

View File

@ -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,
));

View File

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

View File

@ -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<T> = result::Result<T, Error>;
/// 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<u32, u32>,
next_irq: u32,
next_gsi: u32,
}
impl GsiAllocator {
#[cfg(target_arch = "x86_64")]
/// New GSI allocator
pub fn new(apics: Vec<GsiApic>) -> Self {
let mut allocator = GsiAllocator {
@ -57,13 +64,23 @@ impl GsiAllocator {
allocator
}
/// Allocate a GSI
pub fn allocate_gsi(&mut self) -> Result<u32> {
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<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
pub fn allocate_irq(&mut self) -> Result<u32> {
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<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;
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;

View File

@ -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<GsiApic>,
#[cfg(target_arch = "x86_64")] apics: Vec<GsiApic>,
) -> Option<Self> {
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(),
})
}

View File

@ -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,