vm-allocator: Introduce an MMIO hole address allocator

With this new AddressAllocator as part of the SystemAllocator, the
VMM can now decide with finer granularity where to place memory.

By allocating the RAM and the hole into the MMIO address space, we
ensure that no memory will be allocated by accident where the RAM or
where the hole is.
And by creating the new MMIO hole address space, we create a subset
of the entire MMIO address space where we can place 32 bits BARs for
example.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-07-17 09:54:11 -07:00
parent a761b820c7
commit f98a69f42e
5 changed files with 133 additions and 16 deletions

View file

@ -31,6 +31,7 @@ fn pagesize() -> usize {
/// let mut allocator = SystemAllocator::new(
/// GuestAddress(0x1000), 0x10000,
/// GuestAddress(0x10000000), 0x10000000,
/// GuestAddress(0x20000000), 0x100000,
/// vec![GsiApic::new(5, 19)]).unwrap();
/// assert_eq!(allocator.allocate_irq(), Some(5));
/// assert_eq!(allocator.allocate_irq(), Some(6));
@ -40,6 +41,7 @@ fn pagesize() -> usize {
pub struct SystemAllocator {
io_address_space: AddressAllocator,
mmio_address_space: AddressAllocator,
mmio_hole_address_space: AddressAllocator,
gsi_allocator: GsiAllocator,
}
@ -57,11 +59,14 @@ impl SystemAllocator {
io_size: GuestUsize,
mmio_base: GuestAddress,
mmio_size: GuestUsize,
mmio_hole_base: GuestAddress,
mmio_hole_size: GuestUsize,
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)?,
gsi_allocator: GsiAllocator::new(apics),
})
}
@ -101,6 +106,20 @@ impl SystemAllocator {
)
}
/// Reserves a section of `size` bytes of MMIO address space.
pub fn allocate_mmio_hole_addresses(
&mut self,
address: Option<GuestAddress>,
size: GuestUsize,
align_size: Option<GuestUsize>,
) -> Option<GuestAddress> {
self.mmio_hole_address_space.allocate(
address,
size,
Some(align_size.unwrap_or(pagesize() as u64)),
)
}
/// Free an IO address range.
/// We can only free a range if it matches exactly an already allocated range.
pub fn free_io_addresses(&mut self, address: GuestAddress, size: GuestUsize) {