From 0489b6314efaba513786f5efb530c67c6854f6cf Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 8 Dec 2022 16:09:56 +0100 Subject: [PATCH] tdx: Support new way of declaring memory resources Without breaking the former way of declaring them. This is simply based on the presence of the GUID TDX Metadata offset. If not present, we consider the firmware is quite old and therefore we fallback onto the previous way to expose memory resources. Signed-off-by: Sebastien Boeuf --- arch/src/x86_64/tdx/mod.rs | 29 +++++++++++++++++++++-------- vmm/src/vm.rs | 16 ++++++++++------ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/arch/src/x86_64/tdx/mod.rs b/arch/src/x86_64/tdx/mod.rs index b0edb36f7..79604236c 100644 --- a/arch/src/x86_64/tdx/mod.rs +++ b/arch/src/x86_64/tdx/mod.rs @@ -73,7 +73,7 @@ impl Default for TdvfSectionType { } } -fn tdvf_descriptor_offset(file: &mut File) -> Result { +fn tdvf_descriptor_offset(file: &mut File) -> Result<(SeekFrom, bool), TdvfError> { // Let's first try to identify the presence of the table footer GUID file.seek(SeekFrom::End(-0x30)) .map_err(TdvfError::ReadGuidTable)?; @@ -125,8 +125,11 @@ fn tdvf_descriptor_offset(file: &mut File) -> Result { let expected_uuid = Uuid::from_str(TDVF_METADATA_OFFSET_GUID).map_err(TdvfError::UuidCreation)?; if entry_uuid == expected_uuid && entry_size == 22 { - return Ok(SeekFrom::End( - -(u32::from_le_bytes(table[offset..offset + 4].try_into().unwrap()) as i64), + return Ok(( + SeekFrom::End( + -(u32::from_le_bytes(table[offset..offset + 4].try_into().unwrap()) as i64), + ), + true, )); } } @@ -146,11 +149,14 @@ fn tdvf_descriptor_offset(file: &mut File) -> Result { file.read_exact(&mut descriptor_offset) .map_err(TdvfError::ReadDescriptorOffset)?; - Ok(SeekFrom::Start(u32::from_le_bytes(descriptor_offset) as u64)) + Ok(( + SeekFrom::Start(u32::from_le_bytes(descriptor_offset) as u64), + false, + )) } -pub fn parse_tdvf_sections(file: &mut File) -> Result, TdvfError> { - let descriptor_offset = tdvf_descriptor_offset(file)?; +pub fn parse_tdvf_sections(file: &mut File) -> Result<(Vec, bool), TdvfError> { + let (descriptor_offset, guid_found) = tdvf_descriptor_offset(file)?; file.seek(descriptor_offset) .map_err(TdvfError::ReadDescriptor)?; @@ -192,7 +198,7 @@ pub fn parse_tdvf_sections(file: &mut File) -> Result, TdvfErro }) .map_err(TdvfError::ReadDescriptor)?; - Ok(sections) + Ok((sections, guid_found)) } #[repr(u16)] @@ -393,12 +399,19 @@ impl TdHob { physical_start: u64, resource_length: u64, ram: bool, + guid_found: bool, ) -> Result<(), TdvfError> { self.add_resource( mem, physical_start, resource_length, if ram { + if guid_found { + 0x7 /* EFI_RESOURCE_MEMORY_UNACCEPTED */ + } else { + 0 /* EFI_RESOURCE_SYSTEM_MEMORY */ + } + } else if guid_found { 0 /* EFI_RESOURCE_SYSTEM_MEMORY */ } else { 0x5 /*EFI_RESOURCE_MEMORY_RESERVED */ @@ -526,7 +539,7 @@ mod tests { #[ignore] fn test_parse_tdvf_sections() { let mut f = std::fs::File::open("tdvf.fd").unwrap(); - let sections = parse_tdvf_sections(&mut f).unwrap(); + let (sections, _) = parse_tdvf_sections(&mut f).unwrap(); for section in sections { eprintln!("{:x?}", section) } diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 481ba26b4..d3e00133c 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -1649,7 +1649,7 @@ impl Vm { } #[cfg(feature = "tdx")] - fn extract_tdvf_sections(&mut self) -> Result> { + fn extract_tdvf_sections(&mut self) -> Result<(Vec, bool)> { use arch::x86_64::tdx::*; let firmware_path = self @@ -1730,7 +1730,11 @@ impl Vm { } #[cfg(feature = "tdx")] - fn populate_tdx_sections(&mut self, sections: &[TdvfSection]) -> Result> { + fn populate_tdx_sections( + &mut self, + sections: &[TdvfSection], + guid_found: bool, + ) -> Result> { use arch::x86_64::tdx::*; // Get the memory end *before* we start adding TDVF ram regions let boot_guest_memory = self @@ -1868,7 +1872,7 @@ impl Vm { sorted_sections.reverse(); for (start, size, ram) in Vm::hob_memory_resources(sorted_sections, &boot_guest_memory) { - hob.add_memory_resource(&mem, start, size, ram) + hob.add_memory_resource(&mem, start, size, ram, guid_found) .map_err(Error::PopulateHob)?; } @@ -2072,17 +2076,17 @@ impl Vm { } #[cfg(feature = "tdx")] - let sections = if tdx_enabled { + let (sections, guid_found) = if tdx_enabled { self.extract_tdvf_sections()? } else { - Vec::new() + (Vec::new(), false) }; // Configuring the TDX regions requires that the vCPUs are created. #[cfg(feature = "tdx")] let hob_address = if tdx_enabled { // TDX sections are written to memory. - self.populate_tdx_sections(§ions)? + self.populate_tdx_sections(§ions, guid_found)? } else { None };