Skip to content

Commit c042121

Browse files
committed
refactor: add top-level device manager
PCIe spec mandates that software can access the configuration space of PCIe devices both via MMIO and Port IO accesses. As a result, PCIe devices will need to register to both buses (on x86). Change the organization of devices, so that MMIO and PIO device managers do not own the buses. Instead, introduce a DeviceManager object which holds the buses, the resource allocator and includes also all types of device managers (at the moment MMIO, PIO and ACPI). Signed-off-by: Babis Chalios <bchalios@amazon.es>
1 parent 772d57d commit c042121

File tree

14 files changed

+859
-558
lines changed

14 files changed

+859
-558
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/vmm/src/acpi/mod.rs

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use crate::Vcpu;
1010
use crate::acpi::x86_64::{
1111
apic_addr, rsdp_addr, setup_arch_dsdt, setup_arch_fadt, setup_interrupt_controllers,
1212
};
13-
use crate::device_manager::acpi::ACPIDeviceManager;
14-
use crate::device_manager::mmio::MMIODeviceManager;
13+
use crate::device_manager::DeviceManager;
1514
use crate::device_manager::resources::ResourceAllocator;
1615
use crate::vstate::memory::{GuestAddress, GuestMemoryMmap};
1716

@@ -45,19 +44,22 @@ pub enum AcpiError {
4544
/// allocator for allocating space for the tables
4645
struct AcpiTableWriter<'a> {
4746
mem: &'a GuestMemoryMmap,
48-
resource_allocator: &'a mut ResourceAllocator,
4947
}
5048

5149
impl AcpiTableWriter<'_> {
5250
/// Write a table in guest memory
5351
///
5452
/// This will allocate enough space inside guest memory and write the table in the allocated
5553
/// buffer. It returns the address in which it wrote the table.
56-
fn write_acpi_table<S>(&mut self, table: &mut S) -> Result<u64, AcpiError>
54+
fn write_acpi_table<S>(
55+
&mut self,
56+
resource_allocator: &mut ResourceAllocator,
57+
table: &mut S,
58+
) -> Result<u64, AcpiError>
5759
where
5860
S: Sdt,
5961
{
60-
let addr = self.resource_allocator.allocate_system_memory(
62+
let addr = resource_allocator.allocate_system_memory(
6163
table.len().try_into().unwrap(),
6264
1,
6365
AllocPolicy::FirstMatch,
@@ -77,65 +79,76 @@ impl AcpiTableWriter<'_> {
7779
}
7880

7981
/// Build the DSDT table for the guest
80-
fn build_dsdt(
81-
&mut self,
82-
mmio_device_manager: &MMIODeviceManager,
83-
acpi_device_manager: &ACPIDeviceManager,
84-
) -> Result<u64, AcpiError> {
82+
fn build_dsdt(&mut self, device_manager: &mut DeviceManager) -> Result<u64, AcpiError> {
8583
let mut dsdt_data = Vec::new();
8684

8785
// Virtio-devices DSDT data
88-
dsdt_data.extend_from_slice(&mmio_device_manager.dsdt_data);
86+
dsdt_data.extend_from_slice(&device_manager.mmio_devices.dsdt_data);
8987

9088
// Add GED and VMGenID AML data.
91-
acpi_device_manager.append_aml_bytes(&mut dsdt_data)?;
89+
device_manager
90+
.acpi_devices
91+
.append_aml_bytes(&mut dsdt_data)?;
9292

9393
// Architecture specific DSDT data
9494
setup_arch_dsdt(&mut dsdt_data)?;
9595

9696
let mut dsdt = Dsdt::new(OEM_ID, *b"FCVMDSDT", OEM_REVISION, dsdt_data);
97-
self.write_acpi_table(&mut dsdt)
97+
self.write_acpi_table(&mut device_manager.resource_allocator, &mut dsdt)
9898
}
9999

100100
/// Build the FADT table for the guest
101101
///
102102
/// This includes a pointer with the location of the DSDT in guest memory
103-
fn build_fadt(&mut self, dsdt_addr: u64) -> Result<u64, AcpiError> {
103+
fn build_fadt(
104+
&mut self,
105+
resource_allocator: &mut ResourceAllocator,
106+
dsdt_addr: u64,
107+
) -> Result<u64, AcpiError> {
104108
let mut fadt = Fadt::new(OEM_ID, *b"FCVMFADT", OEM_REVISION);
105109
fadt.set_hypervisor_vendor_id(HYPERVISOR_VENDOR_ID);
106110
fadt.set_x_dsdt(dsdt_addr);
107111
fadt.set_flags(
108112
(1 << FADT_F_HW_REDUCED_ACPI) | (1 << FADT_F_PWR_BUTTON) | (1 << FADT_F_SLP_BUTTON),
109113
);
110114
setup_arch_fadt(&mut fadt);
111-
self.write_acpi_table(&mut fadt)
115+
self.write_acpi_table(resource_allocator, &mut fadt)
112116
}
113117

114118
/// Build the MADT table for the guest
115119
///
116120
/// This includes information about the interrupt controllers supported in the platform
117-
fn build_madt(&mut self, nr_vcpus: u8) -> Result<u64, AcpiError> {
121+
fn build_madt(
122+
&mut self,
123+
resource_allocator: &mut ResourceAllocator,
124+
nr_vcpus: u8,
125+
) -> Result<u64, AcpiError> {
118126
let mut madt = Madt::new(
119127
OEM_ID,
120128
*b"FCVMMADT",
121129
OEM_REVISION,
122130
apic_addr(),
123131
setup_interrupt_controllers(nr_vcpus),
124132
);
125-
self.write_acpi_table(&mut madt)
133+
self.write_acpi_table(resource_allocator, &mut madt)
126134
}
127135

128136
/// Build the XSDT table for the guest
129137
///
130138
/// Currently, we pass to the guest just FADT and MADT tables.
131-
fn build_xsdt(&mut self, fadt_addr: u64, madt_addr: u64) -> Result<u64, AcpiError> {
139+
fn build_xsdt(
140+
&mut self,
141+
resource_allocator: &mut ResourceAllocator,
142+
fadt_addr: u64,
143+
madt_addr: u64,
144+
) -> Result<u64, AcpiError> {
132145
let mut xsdt = Xsdt::new(
133146
OEM_ID,
134147
*b"FCMVXSDT",
135148
OEM_REVISION,
136149
vec![fadt_addr, madt_addr],
137150
);
138-
self.write_acpi_table(&mut xsdt)
151+
self.write_acpi_table(resource_allocator, &mut xsdt)
139152
}
140153

141154
/// Build the RSDP pointer for the guest.
@@ -163,20 +176,19 @@ impl AcpiTableWriter<'_> {
163176
/// such as interrupt controllers, vCPUs and VirtIO devices.
164177
pub(crate) fn create_acpi_tables(
165178
mem: &GuestMemoryMmap,
166-
resource_allocator: &mut ResourceAllocator,
167-
mmio_device_manager: &MMIODeviceManager,
168-
acpi_device_manager: &ACPIDeviceManager,
179+
device_manager: &mut DeviceManager,
169180
vcpus: &[Vcpu],
170181
) -> Result<(), AcpiError> {
171-
let mut writer = AcpiTableWriter {
172-
mem,
173-
resource_allocator,
174-
};
175-
176-
let dsdt_addr = writer.build_dsdt(mmio_device_manager, acpi_device_manager)?;
177-
let fadt_addr = writer.build_fadt(dsdt_addr)?;
178-
let madt_addr = writer.build_madt(vcpus.len().try_into().unwrap())?;
179-
let xsdt_addr = writer.build_xsdt(fadt_addr, madt_addr)?;
182+
let mut writer = AcpiTableWriter { mem };
183+
184+
let dsdt_addr = writer.build_dsdt(device_manager)?;
185+
let fadt_addr = writer.build_fadt(&mut device_manager.resource_allocator, dsdt_addr)?;
186+
let madt_addr = writer.build_madt(
187+
&mut device_manager.resource_allocator,
188+
vcpus.len().try_into().unwrap(),
189+
)?;
190+
let xsdt_addr =
191+
writer.build_xsdt(&mut device_manager.resource_allocator, fadt_addr, madt_addr)?;
180192
writer.build_rsdp(xsdt_addr)
181193
}
182194

@@ -218,17 +230,20 @@ mod tests {
218230
let mut vmm = default_vmm();
219231
let mut writer = AcpiTableWriter {
220232
mem: vmm.vm.guest_memory(),
221-
resource_allocator: &mut vmm.resource_allocator,
222233
};
223234

224235
// This should succeed
225236
let mut sdt = MockSdt(vec![0; 4096]);
226-
let addr = writer.write_acpi_table(&mut sdt).unwrap();
237+
let addr = writer
238+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
239+
.unwrap();
227240
assert_eq!(addr, SYSTEM_MEM_START);
228241

229242
// Let's try to write two 4K pages plus one byte
230243
let mut sdt = MockSdt(vec![0; usize::try_from(SYSTEM_MEM_SIZE + 1).unwrap()]);
231-
let err = writer.write_acpi_table(&mut sdt).unwrap_err();
244+
let err = writer
245+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
246+
.unwrap_err();
232247
assert!(
233248
matches!(
234249
err,
@@ -241,19 +256,29 @@ mod tests {
241256
// We are allocating memory for tables with alignment of 1 byte. All of these should
242257
// succeed.
243258
let mut sdt = MockSdt(vec![0; 5]);
244-
let addr = writer.write_acpi_table(&mut sdt).unwrap();
259+
let addr = writer
260+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
261+
.unwrap();
245262
assert_eq!(addr, SYSTEM_MEM_START + 4096);
246263
let mut sdt = MockSdt(vec![0; 2]);
247-
let addr = writer.write_acpi_table(&mut sdt).unwrap();
264+
let addr = writer
265+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
266+
.unwrap();
248267
assert_eq!(addr, SYSTEM_MEM_START + 4101);
249268
let mut sdt = MockSdt(vec![0; 4]);
250-
let addr = writer.write_acpi_table(&mut sdt).unwrap();
269+
let addr = writer
270+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
271+
.unwrap();
251272
assert_eq!(addr, SYSTEM_MEM_START + 4103);
252273
let mut sdt = MockSdt(vec![0; 8]);
253-
let addr = writer.write_acpi_table(&mut sdt).unwrap();
274+
let addr = writer
275+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
276+
.unwrap();
254277
assert_eq!(addr, SYSTEM_MEM_START + 4107);
255278
let mut sdt = MockSdt(vec![0; 16]);
256-
let addr = writer.write_acpi_table(&mut sdt).unwrap();
279+
let addr = writer
280+
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
281+
.unwrap();
257282
assert_eq!(addr, SYSTEM_MEM_START + 4115);
258283
}
259284

@@ -268,11 +293,13 @@ mod tests {
268293
let (_, vm) = setup_vm_with_memory(u64_to_usize(SYSTEM_MEM_START + SYSTEM_MEM_SIZE - 4096));
269294
let mut writer = AcpiTableWriter {
270295
mem: vm.guest_memory(),
271-
resource_allocator: &mut ResourceAllocator::new().unwrap(),
272296
};
297+
let mut resource_allocator = ResourceAllocator::new().unwrap();
273298

274299
let mut sdt = MockSdt(vec![0; usize::try_from(SYSTEM_MEM_SIZE).unwrap()]);
275-
let err = writer.write_acpi_table(&mut sdt).unwrap_err();
300+
let err = writer
301+
.write_acpi_table(&mut resource_allocator, &mut sdt)
302+
.unwrap_err();
276303
assert!(
277304
matches!(
278305
err,

0 commit comments

Comments
 (0)