Skip to content

Commit 971a28d

Browse files
committed
refactor: prepare ResourceAllocator for PCIe devices
PCIe devices need some times to relocate themselves in memory. To do so, they need to keep an (atomic) reference to a type that implements `DeviceRelocation` trait. The logic for relocation involves removing the device from the bus it has been registered to, allocate a new address range for it and reinsert it. Instead of creating a new type for it, reuse `ResourceAllocator`. This means that we need to move the buses from the `DeviceManager` inside `ResourceAllocator`. Signed-off-by: Babis Chalios <[email protected]>
1 parent 6a56cd6 commit 971a28d

File tree

11 files changed

+153
-149
lines changed

11 files changed

+153
-149
lines changed

Cargo.lock

Lines changed: 7 additions & 0 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: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl AcpiTableWriter<'_> {
5353
/// buffer. It returns the address in which it wrote the table.
5454
fn write_acpi_table<S>(
5555
&mut self,
56-
resource_allocator: &mut ResourceAllocator,
56+
resource_allocator: &ResourceAllocator,
5757
table: &mut S,
5858
) -> Result<u64, AcpiError>
5959
where
@@ -94,15 +94,15 @@ impl AcpiTableWriter<'_> {
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 device_manager.resource_allocator, &mut dsdt)
97+
self.write_acpi_table(&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
103103
fn build_fadt(
104104
&mut self,
105-
resource_allocator: &mut ResourceAllocator,
105+
resource_allocator: &ResourceAllocator,
106106
dsdt_addr: u64,
107107
) -> Result<u64, AcpiError> {
108108
let mut fadt = Fadt::new(OEM_ID, *b"FCVMFADT", OEM_REVISION);
@@ -120,7 +120,7 @@ impl AcpiTableWriter<'_> {
120120
/// This includes information about the interrupt controllers supported in the platform
121121
fn build_madt(
122122
&mut self,
123-
resource_allocator: &mut ResourceAllocator,
123+
resource_allocator: &ResourceAllocator,
124124
nr_vcpus: u8,
125125
) -> Result<u64, AcpiError> {
126126
let mut madt = Madt::new(
@@ -138,7 +138,7 @@ impl AcpiTableWriter<'_> {
138138
/// Currently, we pass to the guest just FADT and MADT tables.
139139
fn build_xsdt(
140140
&mut self,
141-
resource_allocator: &mut ResourceAllocator,
141+
resource_allocator: &ResourceAllocator,
142142
fadt_addr: u64,
143143
madt_addr: u64,
144144
) -> Result<u64, AcpiError> {
@@ -180,15 +180,14 @@ pub(crate) fn create_acpi_tables(
180180
vcpus: &[Vcpu],
181181
) -> Result<(), AcpiError> {
182182
let mut writer = AcpiTableWriter { mem };
183-
184183
let dsdt_addr = writer.build_dsdt(device_manager)?;
185-
let fadt_addr = writer.build_fadt(&mut device_manager.resource_allocator, dsdt_addr)?;
184+
185+
let fadt_addr = writer.build_fadt(&device_manager.resource_allocator, dsdt_addr)?;
186186
let madt_addr = writer.build_madt(
187-
&mut device_manager.resource_allocator,
187+
&device_manager.resource_allocator,
188188
vcpus.len().try_into().unwrap(),
189189
)?;
190-
let xsdt_addr =
191-
writer.build_xsdt(&mut device_manager.resource_allocator, fadt_addr, madt_addr)?;
190+
let xsdt_addr = writer.build_xsdt(&device_manager.resource_allocator, fadt_addr, madt_addr)?;
192191
writer.build_rsdp(xsdt_addr)
193192
}
194193

@@ -227,22 +226,22 @@ mod tests {
227226
#[test]
228227
fn test_write_acpi_table_memory_allocation() {
229228
// A mocke Vmm object with 128MBs of memory
230-
let mut vmm = default_vmm();
229+
let vmm = default_vmm();
231230
let mut writer = AcpiTableWriter {
232231
mem: vmm.vm.guest_memory(),
233232
};
234233

235234
// This should succeed
236235
let mut sdt = MockSdt(vec![0; 4096]);
237236
let addr = writer
238-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
237+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
239238
.unwrap();
240239
assert_eq!(addr, SYSTEM_MEM_START);
241240

242241
// Let's try to write two 4K pages plus one byte
243242
let mut sdt = MockSdt(vec![0; usize::try_from(SYSTEM_MEM_SIZE + 1).unwrap()]);
244243
let err = writer
245-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
244+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
246245
.unwrap_err();
247246
assert!(
248247
matches!(
@@ -257,27 +256,27 @@ mod tests {
257256
// succeed.
258257
let mut sdt = MockSdt(vec![0; 5]);
259258
let addr = writer
260-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
259+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
261260
.unwrap();
262261
assert_eq!(addr, SYSTEM_MEM_START + 4096);
263262
let mut sdt = MockSdt(vec![0; 2]);
264263
let addr = writer
265-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
264+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
266265
.unwrap();
267266
assert_eq!(addr, SYSTEM_MEM_START + 4101);
268267
let mut sdt = MockSdt(vec![0; 4]);
269268
let addr = writer
270-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
269+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
271270
.unwrap();
272271
assert_eq!(addr, SYSTEM_MEM_START + 4103);
273272
let mut sdt = MockSdt(vec![0; 8]);
274273
let addr = writer
275-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
274+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
276275
.unwrap();
277276
assert_eq!(addr, SYSTEM_MEM_START + 4107);
278277
let mut sdt = MockSdt(vec![0; 16]);
279278
let addr = writer
280-
.write_acpi_table(&mut vmm.device_manager.resource_allocator, &mut sdt)
279+
.write_acpi_table(&vmm.device_manager.resource_allocator, &mut sdt)
281280
.unwrap();
282281
assert_eq!(addr, SYSTEM_MEM_START + 4115);
283282
}
@@ -294,11 +293,11 @@ mod tests {
294293
let mut writer = AcpiTableWriter {
295294
mem: vm.guest_memory(),
296295
};
297-
let mut resource_allocator = ResourceAllocator::new().unwrap();
296+
let resource_allocator = ResourceAllocator::new().unwrap();
298297

299298
let mut sdt = MockSdt(vec![0; usize::try_from(SYSTEM_MEM_SIZE).unwrap()]);
300299
let err = writer
301-
.write_acpi_table(&mut resource_allocator, &mut sdt)
300+
.write_acpi_table(&resource_allocator, &mut sdt)
302301
.unwrap_err();
303302
assert!(
304303
matches!(

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ mod tests {
477477
.register_virtio_test_device(
478478
&vm,
479479
mem.clone(),
480-
&mut device_manager.resource_allocator,
480+
&device_manager.resource_allocator,
481481
dummy,
482482
&mut cmdline,
483483
"dummy",

src/vmm/src/arch/x86_64/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ pub fn configure_system_for_boot(
213213
// Note that this puts the mptable at the last 1k of Linux's 640k base RAM
214214
mptable::setup_mptable(
215215
vmm.vm.guest_memory(),
216-
&mut vmm.device_manager.resource_allocator,
216+
&vmm.device_manager.resource_allocator,
217217
vcpu_config.vcpu_count,
218218
)
219219
.map_err(ConfigurationError::MpTableSetup)?;
@@ -598,8 +598,8 @@ mod tests {
598598
fn test_system_configuration() {
599599
let no_vcpus = 4;
600600
let gm = single_region_mem(0x10000);
601-
let mut resource_allocator = ResourceAllocator::new().unwrap();
602-
let err = mptable::setup_mptable(&gm, &mut resource_allocator, 1);
601+
let resource_allocator = ResourceAllocator::new().unwrap();
602+
let err = mptable::setup_mptable(&gm, &resource_allocator, 1);
603603
assert!(matches!(
604604
err.unwrap_err(),
605605
mptable::MptableError::NotEnoughMemory
@@ -608,24 +608,24 @@ mod tests {
608608
// Now assigning some memory that falls before the 32bit memory hole.
609609
let mem_size = mib_to_bytes(128);
610610
let gm = arch_mem(mem_size);
611-
let mut resource_allocator = ResourceAllocator::new().unwrap();
612-
mptable::setup_mptable(&gm, &mut resource_allocator, no_vcpus).unwrap();
611+
let resource_allocator = ResourceAllocator::new().unwrap();
612+
mptable::setup_mptable(&gm, &resource_allocator, no_vcpus).unwrap();
613613
configure_64bit_boot(&gm, GuestAddress(0), 0, &None).unwrap();
614614
configure_pvh(&gm, GuestAddress(0), &None).unwrap();
615615

616616
// Now assigning some memory that is equal to the start of the 32bit memory hole.
617617
let mem_size = mib_to_bytes(3328);
618618
let gm = arch_mem(mem_size);
619-
let mut resource_allocator = ResourceAllocator::new().unwrap();
620-
mptable::setup_mptable(&gm, &mut resource_allocator, no_vcpus).unwrap();
619+
let resource_allocator = ResourceAllocator::new().unwrap();
620+
mptable::setup_mptable(&gm, &resource_allocator, no_vcpus).unwrap();
621621
configure_64bit_boot(&gm, GuestAddress(0), 0, &None).unwrap();
622622
configure_pvh(&gm, GuestAddress(0), &None).unwrap();
623623

624624
// Now assigning some memory that falls after the 32bit memory hole.
625625
let mem_size = mib_to_bytes(3330);
626626
let gm = arch_mem(mem_size);
627-
let mut resource_allocator = ResourceAllocator::new().unwrap();
628-
mptable::setup_mptable(&gm, &mut resource_allocator, no_vcpus).unwrap();
627+
let resource_allocator = ResourceAllocator::new().unwrap();
628+
mptable::setup_mptable(&gm, &resource_allocator, no_vcpus).unwrap();
629629
configure_64bit_boot(&gm, GuestAddress(0), 0, &None).unwrap();
630630
configure_pvh(&gm, GuestAddress(0), &None).unwrap();
631631
}

src/vmm/src/arch/x86_64/mptable.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ fn compute_mp_size(num_cpus: u8) -> usize {
116116
/// Performs setup of the MP table for the given `num_cpus`.
117117
pub fn setup_mptable(
118118
mem: &GuestMemoryMmap,
119-
resource_allocator: &mut ResourceAllocator,
119+
resource_allocator: &ResourceAllocator,
120120
num_cpus: u8,
121121
) -> Result<(), MptableError> {
122122
if num_cpus > MAX_SUPPORTED_CPUS {
@@ -334,27 +334,27 @@ mod tests {
334334
fn bounds_check() {
335335
let num_cpus = 4;
336336
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(num_cpus));
337-
let mut resource_allocator = ResourceAllocator::new().unwrap();
337+
let resource_allocator = ResourceAllocator::new().unwrap();
338338

339-
setup_mptable(&mem, &mut resource_allocator, num_cpus).unwrap();
339+
setup_mptable(&mem, &resource_allocator, num_cpus).unwrap();
340340
}
341341

342342
#[test]
343343
fn bounds_check_fails() {
344344
let num_cpus = 4;
345345
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(num_cpus) - 1);
346-
let mut resource_allocator = ResourceAllocator::new().unwrap();
346+
let resource_allocator = ResourceAllocator::new().unwrap();
347347

348-
setup_mptable(&mem, &mut resource_allocator, num_cpus).unwrap_err();
348+
setup_mptable(&mem, &resource_allocator, num_cpus).unwrap_err();
349349
}
350350

351351
#[test]
352352
fn mpf_intel_checksum() {
353353
let num_cpus = 1;
354354
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(num_cpus));
355-
let mut resource_allocator = ResourceAllocator::new().unwrap();
355+
let resource_allocator = ResourceAllocator::new().unwrap();
356356

357-
setup_mptable(&mem, &mut resource_allocator, num_cpus).unwrap();
357+
setup_mptable(&mem, &resource_allocator, num_cpus).unwrap();
358358

359359
let mpf_intel: mpspec::mpf_intel = mem.read_obj(GuestAddress(SYSTEM_MEM_START)).unwrap();
360360

@@ -365,9 +365,9 @@ mod tests {
365365
fn mpc_table_checksum() {
366366
let num_cpus = 4;
367367
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(num_cpus));
368-
let mut resource_allocator = ResourceAllocator::new().unwrap();
368+
let resource_allocator = ResourceAllocator::new().unwrap();
369369

370-
setup_mptable(&mem, &mut resource_allocator, num_cpus).unwrap();
370+
setup_mptable(&mem, &resource_allocator, num_cpus).unwrap();
371371

372372
let mpf_intel: mpspec::mpf_intel = mem.read_obj(GuestAddress(SYSTEM_MEM_START)).unwrap();
373373
let mpc_offset = GuestAddress(u64::from(mpf_intel.physptr));
@@ -388,9 +388,9 @@ mod tests {
388388
fn mpc_entry_count() {
389389
let num_cpus = 1;
390390
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(num_cpus));
391-
let mut resource_allocator = ResourceAllocator::new().unwrap();
391+
let resource_allocator = ResourceAllocator::new().unwrap();
392392

393-
setup_mptable(&mem, &mut resource_allocator, num_cpus).unwrap();
393+
setup_mptable(&mem, &resource_allocator, num_cpus).unwrap();
394394

395395
let mpf_intel: mpspec::mpf_intel = mem.read_obj(GuestAddress(SYSTEM_MEM_START)).unwrap();
396396
let mpc_offset = GuestAddress(u64::from(mpf_intel.physptr));
@@ -419,8 +419,8 @@ mod tests {
419419
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(MAX_SUPPORTED_CPUS));
420420

421421
for i in 0..MAX_SUPPORTED_CPUS {
422-
let mut resource_allocator = ResourceAllocator::new().unwrap();
423-
setup_mptable(&mem, &mut resource_allocator, i).unwrap();
422+
let resource_allocator = ResourceAllocator::new().unwrap();
423+
setup_mptable(&mem, &resource_allocator, i).unwrap();
424424

425425
let mpf_intel: mpspec::mpf_intel =
426426
mem.read_obj(GuestAddress(SYSTEM_MEM_START)).unwrap();
@@ -450,9 +450,9 @@ mod tests {
450450
fn cpu_entry_count_max() {
451451
let cpus = MAX_SUPPORTED_CPUS + 1;
452452
let mem = single_region_mem_at(SYSTEM_MEM_START, compute_mp_size(cpus));
453-
let mut resource_allocator = ResourceAllocator::new().unwrap();
453+
let resource_allocator = ResourceAllocator::new().unwrap();
454454

455-
let result = setup_mptable(&mem, &mut resource_allocator, cpus).unwrap_err();
455+
let result = setup_mptable(&mem, &resource_allocator, cpus).unwrap_err();
456456
assert_eq!(result, MptableError::TooManyCpus);
457457
}
458458
}

0 commit comments

Comments
 (0)