vmm: tdx: Reorder TDX ioctls

Separate the population of the memory and the HOB from the TDX
initialisation of the memory so that the latter can happen after the CPU
is initialised.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-05-13 14:30:59 +01:00 committed by Samuel Ortiz
parent d100c014bc
commit 5296bd10c1

View File

@ -30,6 +30,8 @@ use crate::{
}; };
use anyhow::anyhow; use anyhow::anyhow;
use arch::get_host_cpu_phys_bits; use arch::get_host_cpu_phys_bits;
#[cfg(feature = "tdx")]
use arch::x86_64::tdx::TdvfSection;
use arch::EntryPoint; use arch::EntryPoint;
use devices::AcpiNotificationFlags; use devices::AcpiNotificationFlags;
use hypervisor::vm::{HypervisorVmError, VmmOps}; use hypervisor::vm::{HypervisorVmError, VmmOps};
@ -1508,7 +1510,19 @@ impl Vm {
} }
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
fn init_tdx_memory(&mut self) -> Result<Option<u64>> { fn extract_tdvf_sections(&mut self) -> Result<Vec<TdvfSection>> {
use arch::x86_64::tdx::*;
// The TDVF file contains a table of section as well as code
let mut firmware_file =
File::open(&self.config.lock().unwrap().tdx.as_ref().unwrap().firmware)
.map_err(Error::LoadTdvf)?;
// For all the sections allocate some RAM backing them
parse_tdvf_sections(&mut firmware_file).map_err(Error::ParseTdvf)
}
#[cfg(feature = "tdx")]
fn populate_tdx_sections(&mut self, sections: &[TdvfSection]) -> Result<Option<u64>> {
use arch::x86_64::tdx::*; use arch::x86_64::tdx::*;
// Get the memory end *before* we start adding TDVF ram regions // Get the memory end *before* we start adding TDVF ram regions
let mem_end = { let mem_end = {
@ -1516,15 +1530,7 @@ impl Vm {
let mem = guest_memory.memory(); let mem = guest_memory.memory();
mem.last_addr() mem.last_addr()
}; };
for section in sections {
// The TDVF file contains a table of section as well as code
let mut firmware_file =
File::open(&self.config.lock().unwrap().tdx.as_ref().unwrap().firmware)
.map_err(Error::LoadTdvf)?;
// For all the sections allocate some RAM backing them
let sections = parse_tdvf_sections(&mut firmware_file).map_err(Error::ParseTdvf)?;
for section in &sections {
info!("Allocating TDVF Section: {:?}", section); info!("Allocating TDVF Section: {:?}", section);
self.memory_manager self.memory_manager
.lock() .lock()
@ -1533,12 +1539,17 @@ impl Vm {
.map_err(Error::AllocatingTdvfMemory)?; .map_err(Error::AllocatingTdvfMemory)?;
} }
// The TDVF file contains a table of section as well as code
let mut firmware_file =
File::open(&self.config.lock().unwrap().tdx.as_ref().unwrap().firmware)
.map_err(Error::LoadTdvf)?;
// The guest memory at this point now has all the required regions so it // The guest memory at this point now has all the required regions so it
// is safe to copy from the TDVF file into it. // is safe to copy from the TDVF file into it.
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory(); let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
let mem = guest_memory.memory(); let mem = guest_memory.memory();
let mut hob_offset = None; let mut hob_offset = None;
for section in &sections { for section in sections {
info!("Populating TDVF Section: {:?}", section); info!("Populating TDVF Section: {:?}", section);
match section.r#type { match section.r#type {
TdvfSectionType::Bfv | TdvfSectionType::Cfv => { TdvfSectionType::Bfv | TdvfSectionType::Cfv => {
@ -1611,7 +1622,15 @@ impl Vm {
hob.finish(&mem).map_err(Error::PopulateHob)?; hob.finish(&mem).map_err(Error::PopulateHob)?;
for section in &sections { Ok(hob_offset)
}
#[cfg(feature = "tdx")]
fn init_tdx_memory(&mut self, sections: &[TdvfSection]) -> Result<()> {
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
let mem = guest_memory.memory();
for section in sections {
self.vm self.vm
.tdx_init_memory_region( .tdx_init_memory_region(
mem.get_host_address(GuestAddress(section.address)).unwrap() as u64, mem.get_host_address(GuestAddress(section.address)).unwrap() as u64,
@ -1622,8 +1641,7 @@ impl Vm {
) )
.map_err(Error::InitializeTdxMemoryRegion)?; .map_err(Error::InitializeTdxMemoryRegion)?;
} }
Ok(())
Ok(hob_offset)
} }
pub fn boot(&mut self) -> Result<()> { pub fn boot(&mut self) -> Result<()> {
@ -1657,10 +1675,13 @@ impl Vm {
.create_boot_vcpus(entry_point) .create_boot_vcpus(entry_point)
.map_err(Error::CpuManager)?; .map_err(Error::CpuManager)?;
#[cfg(feature = "tdx")]
let sections = self.extract_tdvf_sections()?;
// Configuring the TDX regions requires that the vCPUs are created // Configuring the TDX regions requires that the vCPUs are created
#[cfg(feature = "tdx")] #[cfg(feature = "tdx")]
let hob_address = if self.config.lock().unwrap().tdx.is_some() { let hob_address = if self.config.lock().unwrap().tdx.is_some() {
self.init_tdx_memory()? self.populate_tdx_sections(&sections)?
} else { } else {
None None
}; };
@ -1677,6 +1698,7 @@ impl Vm {
.unwrap() .unwrap()
.initialize_tdx(hob_address) .initialize_tdx(hob_address)
.map_err(Error::CpuManager)?; .map_err(Error::CpuManager)?;
self.init_tdx_memory(&sections)?;
// With TDX memory and CPU state configured TDX setup is complete // With TDX memory and CPU state configured TDX setup is complete
self.vm.tdx_finalize().map_err(Error::FinalizeTdx)?; self.vm.tdx_finalize().map_err(Error::FinalizeTdx)?;
} }