1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //! Manages system resources that can be allocated to VMs and their devices.
6
7 use std::ops::RangeInclusive;
8
9 use remain::sorted;
10 use serde::{Deserialize, Serialize};
11 use thiserror::Error;
12
13 pub use crate::system_allocator::{MemRegion, MmioType, SystemAllocator, SystemAllocatorConfig};
14
15 pub mod address_allocator;
16 mod system_allocator;
17
18 /// Used to tag SystemAllocator allocations.
19 #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, Serialize, Deserialize)]
20 pub enum Alloc {
21 /// An anonymous resource allocation.
22 /// Should only be instantiated through `SystemAllocator::get_anon_alloc()`.
23 /// Avoid using these. Instead, use / create a more descriptive Alloc variant.
24 Anon(usize),
25 /// A PCI BAR region with associated bus, device, function and bar numbers.
26 PciBar { bus: u8, dev: u8, func: u8, bar: u8 },
27 /// GPU render node region.
28 GpuRenderNode,
29 /// Pmem device region with associated device index.
30 PmemDevice(usize),
31 /// pstore region.
32 Pstore,
33 /// A PCI bridge window with associated bus, dev, function.
34 PciBridgeWindow { bus: u8, dev: u8, func: u8 },
35 /// A PCI bridge prefetch window with associated bus, dev, function.
36 PciBridgePrefetchWindow { bus: u8, dev: u8, func: u8 },
37 /// File-backed memory mapping.
38 FileBacked(u64),
39 /// virtio vhost user queue with queue id
40 VvuQueue(u8),
41 }
42
43 #[sorted]
44 #[derive(Error, Debug, Eq, PartialEq)]
45 pub enum Error {
46 #[error("Allocation cannot have size of 0")]
47 AllocSizeZero,
48 #[error("Pool alignment must be a power of 2")]
49 BadAlignment,
50 #[error("Alloc does not exist: {0:?}")]
51 BadAlloc(Alloc),
52 #[error("Alloc already exists: {0:?}")]
53 ExistingAlloc(Alloc),
54 #[error("Invalid Alloc: {0:?}")]
55 InvalidAlloc(Alloc),
56 #[error("IO port out of range: base:{0} size:{1}")]
57 IOPortOutOfRange(u64, u64),
58 #[error("Platform MMIO address range not specified")]
59 MissingPlatformMMIOAddresses,
60 #[error("No IO address range specified")]
61 NoIoAllocator,
62 #[error("Out of bounds")]
63 OutOfBounds,
64 #[error("Out of space")]
65 OutOfSpace,
66 #[error("base={base} + size={size} overflows")]
67 PoolOverflow { base: u64, size: u64 },
68 #[error("Pool cannot have size of 0")]
69 PoolSizeZero,
70 #[error("Overlapping region base={base} size={size}")]
71 RegionOverlap { base: u64, size: u64 },
72 }
73
74 pub type Result<T> = std::result::Result<T, Error>;
75
76 /// Computes the length of a RangeInclusive value. Returns None
77 /// if the range is 0..=u64::MAX.
range_inclusive_len(r: &RangeInclusive<u64>) -> Option<u64>78 pub fn range_inclusive_len(r: &RangeInclusive<u64>) -> Option<u64> {
79 (r.end() - r.start()).checked_add(1)
80 }
81