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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-12-08 16:09:56 +01:00 committed by Bo Chen
parent 2c367bdde8
commit 0489b6314e
2 changed files with 31 additions and 14 deletions

View File

@ -73,7 +73,7 @@ impl Default for TdvfSectionType {
}
}
fn tdvf_descriptor_offset(file: &mut File) -> Result<SeekFrom, TdvfError> {
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<SeekFrom, TdvfError> {
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<SeekFrom, TdvfError> {
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<Vec<TdvfSection>, TdvfError> {
let descriptor_offset = tdvf_descriptor_offset(file)?;
pub fn parse_tdvf_sections(file: &mut File) -> Result<(Vec<TdvfSection>, 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<Vec<TdvfSection>, 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)
}

View File

@ -1649,7 +1649,7 @@ impl Vm {
}
#[cfg(feature = "tdx")]
fn extract_tdvf_sections(&mut self) -> Result<Vec<TdvfSection>> {
fn extract_tdvf_sections(&mut self) -> Result<(Vec<TdvfSection>, 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<Option<u64>> {
fn populate_tdx_sections(
&mut self,
sections: &[TdvfSection],
guid_found: bool,
) -> Result<Option<u64>> {
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(&sections)?
self.populate_tdx_sections(&sections, guid_found)?
} else {
None
};