mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-21 19:02:30 +00:00
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:
parent
5343b0ac18
commit
e9488846f1
@ -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);
|
||||
|
@ -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,
|
||||
));
|
||||
|
||||
|
@ -7,3 +7,4 @@ edition = "2018"
|
||||
[dependencies]
|
||||
libc = "0.2.71"
|
||||
vm-memory = "0.2.1"
|
||||
arch = { path = "../arch" }
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user