From cda1ea53a56b30f77d5982c42ea170afd3e56f06 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Tue, 22 Jul 2025 01:20:31 +0000 Subject: [PATCH] vmm: acpi: Make 'create_acpi_tables' more flexible Now 'create_acpi_tables_internal()' can generate ACPI tables with different dsdt offset, so that it can be reused for generating ACPI tables for `fw_cfg`. Signed-off-by: Bo Chen Signed-off-by: Alex Orozco --- vmm/src/acpi.rs | 107 ++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index e59b63f58..27d52abeb 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -626,41 +626,32 @@ fn create_viot_table(iommu_bdf: &PciBdf, devices_bdf: &[PciBdf]) -> Sdt { viot } -pub fn create_acpi_tables( - guest_mem: &GuestMemoryMmap, +fn create_acpi_tables_internal( + dsdt_offset: GuestAddress, device_manager: &Arc>, cpu_manager: &Arc>, memory_manager: &Arc>, numa_nodes: &NumaNodes, tpm_enabled: bool, -) -> GuestAddress { - trace_scoped!("create_acpi_tables"); - - let start_time = Instant::now(); - let rsdp_offset = arch::layout::RSDP_POINTER; +) -> (Rsdp, Vec, Vec) { + // Generated bytes for ACPI tables + let mut tables_bytes: Vec = Vec::new(); let mut tables: Vec = Vec::new(); // DSDT let dsdt = create_dsdt_table(device_manager, cpu_manager, memory_manager); - let dsdt_offset = rsdp_offset.checked_add(Rsdp::len() as u64).unwrap(); - guest_mem - .write_slice(dsdt.as_slice(), dsdt_offset) - .expect("Error writing DSDT table"); + tables_bytes.extend_from_slice(dsdt.as_slice()); // FACP aka FADT let facp = create_facp_table(dsdt_offset, device_manager); let facp_offset = dsdt_offset.checked_add(dsdt.len() as u64).unwrap(); - guest_mem - .write_slice(facp.as_slice(), facp_offset) - .expect("Error writing FACP table"); + tables_bytes.extend_from_slice(facp.as_slice()); tables.push(facp_offset.0); // MADT let madt = cpu_manager.lock().unwrap().create_madt(); let madt_offset = facp_offset.checked_add(facp.len() as u64).unwrap(); - guest_mem - .write_slice(madt.as_slice(), madt_offset) - .expect("Error writing MADT table"); + tables_bytes.extend_from_slice(madt.as_slice()); tables.push(madt_offset.0); let mut prev_tbl_len = madt.len() as u64; let mut prev_tbl_off = madt_offset; @@ -670,9 +661,7 @@ pub fn create_acpi_tables( { let pptt = cpu_manager.lock().unwrap().create_pptt(); let pptt_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(pptt.as_slice(), pptt_offset) - .expect("Error writing PPTT table"); + tables_bytes.extend_from_slice(pptt.as_slice()); tables.push(pptt_offset.0); prev_tbl_len = pptt.len() as u64; prev_tbl_off = pptt_offset; @@ -683,9 +672,7 @@ pub fn create_acpi_tables( { let gtdt = create_gtdt_table(); let gtdt_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(gtdt.as_slice(), gtdt_offset) - .expect("Error writing GTDT table"); + tables_bytes.extend_from_slice(gtdt.as_slice()); tables.push(gtdt_offset.0); prev_tbl_len = gtdt.len() as u64; prev_tbl_off = gtdt_offset; @@ -694,9 +681,7 @@ pub fn create_acpi_tables( // MCFG let mcfg = create_mcfg_table(device_manager.lock().unwrap().pci_segments()); let mcfg_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(mcfg.as_slice(), mcfg_offset) - .expect("Error writing MCFG table"); + tables_bytes.extend_from_slice(mcfg.as_slice()); tables.push(mcfg_offset.0); prev_tbl_len = mcfg.len() as u64; prev_tbl_off = mcfg_offset; @@ -728,9 +713,7 @@ pub fn create_acpi_tables( // SPCR let spcr = create_spcr_table(serial_device_addr, serial_device_irq); let spcr_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(spcr.as_slice(), spcr_offset) - .expect("Error writing SPCR table"); + tables_bytes.extend_from_slice(spcr.as_slice()); tables.push(spcr_offset.0); prev_tbl_len = spcr.len() as u64; prev_tbl_off = spcr_offset; @@ -738,9 +721,7 @@ pub fn create_acpi_tables( // DBG2 let dbg2 = create_dbg2_table(serial_device_addr); let dbg2_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(dbg2.as_slice(), dbg2_offset) - .expect("Error writing DBG2 table"); + tables_bytes.extend_from_slice(dbg2.as_slice()); tables.push(dbg2_offset.0); prev_tbl_len = dbg2.len() as u64; prev_tbl_off = dbg2_offset; @@ -750,9 +731,7 @@ pub fn create_acpi_tables( // TPM2 Table let tpm2 = create_tpm2_table(); let tpm2_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(tpm2.as_slice(), tpm2_offset) - .expect("Error writing TPM2 table"); + tables_bytes.extend_from_slice(tpm2.as_slice()); tables.push(tpm2_offset.0); prev_tbl_len = tpm2.len() as u64; @@ -770,17 +749,13 @@ pub fn create_acpi_tables( topology, ); let srat_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(srat.as_slice(), srat_offset) - .expect("Error writing SRAT table"); + tables_bytes.extend_from_slice(srat.as_slice()); tables.push(srat_offset.0); // SLIT let slit = create_slit_table(numa_nodes); let slit_offset = srat_offset.checked_add(srat.len() as u64).unwrap(); - guest_mem - .write_slice(slit.as_slice(), slit_offset) - .expect("Error writing SLIT table"); + tables_bytes.extend_from_slice(slit.as_slice()); tables.push(slit_offset.0); prev_tbl_len = slit.len() as u64; @@ -791,9 +766,7 @@ pub fn create_acpi_tables( { let iort = create_iort_table(device_manager.lock().unwrap().pci_segments()); let iort_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(iort.as_slice(), iort_offset) - .expect("Error writing IORT table"); + tables_bytes.extend_from_slice(iort.as_slice()); tables.push(iort_offset.0); prev_tbl_len = iort.len() as u64; prev_tbl_off = iort_offset; @@ -805,9 +778,7 @@ pub fn create_acpi_tables( let viot = create_viot_table(iommu_bdf, devices_bdf); let viot_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(viot.as_slice(), viot_offset) - .expect("Error writing VIOT table"); + tables_bytes.extend_from_slice(viot.as_slice()); tables.push(viot_offset.0); prev_tbl_len = viot.len() as u64; prev_tbl_off = viot_offset; @@ -815,26 +786,56 @@ pub fn create_acpi_tables( // XSDT let mut xsdt = Sdt::new(*b"XSDT", 36, 1, *b"CLOUDH", *b"CHXSDT ", 1); - for table in tables { - xsdt.append(table); + for table in &tables { + xsdt.append(*table); } xsdt.update_checksum(); let xsdt_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); - guest_mem - .write_slice(xsdt.as_slice(), xsdt_offset) - .expect("Error writing XSDT table"); + tables_bytes.extend_from_slice(xsdt.as_slice()); // RSDP let rsdp = Rsdp::new(*b"CLOUDH", xsdt_offset.0); + + (rsdp, tables_bytes, tables) +} + +pub fn create_acpi_tables( + guest_mem: &GuestMemoryMmap, + device_manager: &Arc>, + cpu_manager: &Arc>, + memory_manager: &Arc>, + numa_nodes: &NumaNodes, + tpm_enabled: bool, +) -> GuestAddress { + trace_scoped!("create_acpi_tables"); + + let start_time = Instant::now(); + let rsdp_offset = arch::layout::RSDP_POINTER; + let dsdt_offset = rsdp_offset.checked_add(Rsdp::len() as u64).unwrap(); + + let (rsdp, tables_bytes, _tables_offset) = create_acpi_tables_internal( + dsdt_offset, + device_manager, + cpu_manager, + memory_manager, + numa_nodes, + tpm_enabled, + ); + guest_mem .write_slice(rsdp.as_bytes(), rsdp_offset) .expect("Error writing RSDP"); + guest_mem + .write_slice(tables_bytes.as_slice(), dsdt_offset) + .expect("Error writing ACPI tables"); + info!( "Generated ACPI tables: took {}µs size = {}", Instant::now().duration_since(start_time).as_micros(), - xsdt_offset.0 + xsdt.len() as u64 - rsdp_offset.0 + Rsdp::len() + tables_bytes.len(), ); + rsdp_offset }