From af261f231ca86c9c3c430a2fad58f95455796741 Mon Sep 17 00:00:00 2001 From: Praveen K Paladugu Date: Fri, 12 Aug 2022 20:28:04 +0000 Subject: [PATCH] vmm: Add required acpi entries for vtpm device Add an TPM2 entry to DSDT ACPI table. Add a TPM2 table to guest's ACPI. Signed-off-by: Praveen K Paladugu Co-authored-by: Sean Yoo --- vmm/src/acpi.rs | 25 +++++++++++++++++++++++++ vmm/src/device_manager.rs | 30 ++++++++++++++++++++++++++++++ vmm/src/vm.rs | 4 ++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index 2527af7d1..5ae1fd1fb 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -264,6 +264,18 @@ fn create_mcfg_table(pci_segments: &[PciSegment]) -> Sdt { mcfg } +fn create_tpm2_table() -> Sdt { + let mut tpm = Sdt::new(*b"TPM2", 52, 3, *b"CLOUDH", *b"CHTPM2 ", 1); + + tpm.write(36, 0_u16); //Platform Class + tpm.write(38, 0_u16); // Reserved Space + tpm.write(40, 0xfed4_0040_u64); // Address of Control Area + tpm.write(48, 7_u32); //Start Method + + tpm.update_checksum(); + tpm +} + fn create_srat_table(numa_nodes: &NumaNodes) -> Sdt { let mut srat = Sdt::new(*b"SRAT", 36, 3, *b"CLOUDH", *b"CHSRAT ", 1); // SRAT reserved 12 bytes @@ -609,6 +621,7 @@ pub fn create_acpi_tables( cpu_manager: &Arc>, memory_manager: &Arc>, numa_nodes: &NumaNodes, + tpm_enabled: bool, ) -> GuestAddress { trace_scoped!("create_acpi_tables"); @@ -723,6 +736,18 @@ pub fn create_acpi_tables( prev_tbl_off = dbg2_offset; } + if tpm_enabled { + // 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.push(tpm2_offset.0); + + prev_tbl_len = tpm2.len() as u64; + prev_tbl_off = tpm2_offset; + } // SRAT and SLIT // Only created if the NUMA nodes list is not empty. if !numa_nodes.is_empty() { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 794cffabc..410734c9e 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -4167,6 +4167,29 @@ fn numa_node_id_from_memory_zone_id(numa_nodes: &NumaNodes, memory_zone_id: &str None } +struct TpmDevice {} + +impl Aml for TpmDevice { + fn to_aml_bytes(&self) -> Vec { + aml::Device::new( + "TPM2".into(), + vec![ + &aml::Name::new("_HID".into(), &"MSFT0101"), + &aml::Name::new("_STA".into(), &(0xF_usize)), + &aml::Name::new( + "_CRS".into(), + &aml::ResourceTemplate::new(vec![&aml::Memory32Fixed::new( + true, + layout::TPM_START.0 as u32, + layout::TPM_SIZE as u32, + )]), + ), + ], + ) + .to_aml_bytes() + } +} + impl Aml for DeviceManager { fn append_aml_bytes(&self, bytes: &mut Vec) { #[cfg(target_arch = "aarch64")] @@ -4328,6 +4351,13 @@ impl Aml for DeviceManager { ) .append_aml_bytes(bytes); + if self.config.lock().unwrap().tpm.is_some() { + // Add tpm device + let tpm_acpi = TpmDevice {}; + let tpm_dsdt_data = tpm_acpi.to_aml_bytes(); + bytes.extend_from_slice(tpm_dsdt_data.as_slice()); + } + self.ged_notification_device .as_ref() .unwrap() diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 3813ac371..1bc3e186b 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -2048,15 +2048,15 @@ impl Vm { if self.config.lock().unwrap().is_tdx_enabled() { return None; } - let mem = self.memory_manager.lock().unwrap().guest_memory().memory(); - + let tpm_enabled = self.config.lock().unwrap().tpm.is_some(); let rsdp_addr = crate::acpi::create_acpi_tables( &mem, &self.device_manager, &self.cpu_manager, &self.memory_manager, &self.numa_nodes, + tpm_enabled, ); info!("Created ACPI tables: rsdp_addr = 0x{:x}", rsdp_addr.0);