mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-08-23 00:11:16 +00:00
vmm: config: Move TDX to rely on PayloadConfig
Removing the option --tdx to specify that we want to run a TD VM. Rely on --platform option by adding the "tdx" boolean parameter. This is the new way for enabling TDX with Cloud Hypervisor. Along with this change, the way to retrieve the firmware path has been updated to rely on the recently introduced PayloadConfig structure. Fixes #4556 Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
b05bd28321
commit
3793ffe888
@ -61,7 +61,8 @@ meaning it will be printing guest kernel logs to the `virtio-console` device.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
./cloud-hypervisor \
|
./cloud-hypervisor \
|
||||||
--tdx firmware=edk2-staging/Build/OvmfCh/RELEASE_GCC5/FV/OVMF.fd \
|
--platform tdx=on
|
||||||
|
--firmware edk2-staging/Build/OvmfCh/RELEASE_GCC5/FV/OVMF.fd \
|
||||||
--cpus boot=1 \
|
--cpus boot=1 \
|
||||||
--memory size=1G \
|
--memory size=1G \
|
||||||
--disk path=tdx_guest_img
|
--disk path=tdx_guest_img
|
||||||
@ -72,7 +73,8 @@ firmware:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
./cloud-hypervisor \
|
./cloud-hypervisor \
|
||||||
--tdx firmware=edk2-staging/Build/OvmfCh/DEBUG_GCC5/FV/OVMF.fd \
|
--platform tdx=on
|
||||||
|
--firmware edk2-staging/Build/OvmfCh/DEBUG_GCC5/FV/OVMF.fd \
|
||||||
--cpus boot=1 \
|
--cpus boot=1 \
|
||||||
--memory size=1G \
|
--memory size=1G \
|
||||||
--disk path=tdx_guest_img \
|
--disk path=tdx_guest_img \
|
||||||
@ -95,7 +97,8 @@ option as well.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
./cloud-hypervisor \
|
./cloud-hypervisor \
|
||||||
--tdx firmware=tdshim \
|
--platform tdx=on
|
||||||
|
--firmware tdshim \
|
||||||
--kernel bzImage \
|
--kernel bzImage \
|
||||||
--cmdline "root=/dev/vda3 console=hvc0 rw"
|
--cmdline "root=/dev/vda3 console=hvc0 rw"
|
||||||
--cpus boot=1 \
|
--cpus boot=1 \
|
||||||
|
16
src/main.rs
16
src/main.rs
@ -400,15 +400,6 @@ fn create_app<'a>(
|
|||||||
.group("vmm-config"),
|
.group("vmm-config"),
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let app = app.arg(
|
|
||||||
Arg::new("tdx")
|
|
||||||
.long("tdx")
|
|
||||||
.help("TDX Support: firmware=<tdvf path>")
|
|
||||||
.takes_value(true)
|
|
||||||
.group("vm-config"),
|
|
||||||
);
|
|
||||||
|
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,11 +568,6 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
|||||||
let payload_present =
|
let payload_present =
|
||||||
cmd_arguments.is_present("kernel") || cmd_arguments.is_present("firmware");
|
cmd_arguments.is_present("kernel") || cmd_arguments.is_present("firmware");
|
||||||
|
|
||||||
// Can't test for "vm-config" group as some have default values. The kernel (or tdx if enabled)
|
|
||||||
// is the only required option for booting the VM.
|
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let payload_present = payload_present || cmd_arguments.is_present("tdx");
|
|
||||||
|
|
||||||
if payload_present {
|
if payload_present {
|
||||||
let vm_params = config::VmParams::from_arg_matches(&cmd_arguments);
|
let vm_params = config::VmParams::from_arg_matches(&cmd_arguments);
|
||||||
let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?;
|
let vm_config = config::VmConfig::parse(vm_params).map_err(Error::ParsingConfig)?;
|
||||||
@ -744,8 +730,6 @@ mod unit_tests {
|
|||||||
sgx_epc: None,
|
sgx_epc: None,
|
||||||
numa: None,
|
numa: None,
|
||||||
watchdog: false,
|
watchdog: false,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
tdx: None,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
gdb: false,
|
gdb: false,
|
||||||
platform: None,
|
platform: None,
|
||||||
|
@ -559,8 +559,6 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/SgxEpcConfig"
|
$ref: "#/components/schemas/SgxEpcConfig"
|
||||||
tdx:
|
|
||||||
$ref: "#/components/schemas/TdxConfig"
|
|
||||||
numa:
|
numa:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -650,6 +648,9 @@ components:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
tdx:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
MemoryZoneConfig:
|
MemoryZoneConfig:
|
||||||
required:
|
required:
|
||||||
@ -1006,15 +1007,6 @@ components:
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
|
||||||
TdxConfig:
|
|
||||||
required:
|
|
||||||
- firmware
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
firmware:
|
|
||||||
type: string
|
|
||||||
description: Path to the firmware that will be used to boot the TDx guest up.
|
|
||||||
|
|
||||||
NumaDistance:
|
NumaDistance:
|
||||||
required:
|
required:
|
||||||
- destination
|
- destination
|
||||||
|
@ -153,6 +153,9 @@ pub enum ValidationError {
|
|||||||
/// CPU Hotplug is not permitted with TDX
|
/// CPU Hotplug is not permitted with TDX
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
TdxNoCpuHotplug,
|
TdxNoCpuHotplug,
|
||||||
|
/// Missing firmware for TDX
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
TdxFirmwareMissing,
|
||||||
/// Insuffient vCPUs for queues
|
/// Insuffient vCPUs for queues
|
||||||
TooManyQueues,
|
TooManyQueues,
|
||||||
/// Need shared memory for vfio-user
|
/// Need shared memory for vfio-user
|
||||||
@ -219,6 +222,10 @@ impl fmt::Display for ValidationError {
|
|||||||
TdxNoCpuHotplug => {
|
TdxNoCpuHotplug => {
|
||||||
write!(f, "CPU hotplug is not permitted with TDX")
|
write!(f, "CPU hotplug is not permitted with TDX")
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
TdxFirmwareMissing => {
|
||||||
|
write!(f, "No TDX firmware specified")
|
||||||
|
}
|
||||||
TooManyQueues => {
|
TooManyQueues => {
|
||||||
write!(f, "Number of vCPUs is insufficient for number of queues")
|
write!(f, "Number of vCPUs is insufficient for number of queues")
|
||||||
}
|
}
|
||||||
@ -363,8 +370,6 @@ pub struct VmParams<'a> {
|
|||||||
pub sgx_epc: Option<Vec<&'a str>>,
|
pub sgx_epc: Option<Vec<&'a str>>,
|
||||||
pub numa: Option<Vec<&'a str>>,
|
pub numa: Option<Vec<&'a str>>,
|
||||||
pub watchdog: bool,
|
pub watchdog: bool,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
pub tdx: Option<&'a str>,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
pub gdb: bool,
|
pub gdb: bool,
|
||||||
pub platform: Option<&'a str>,
|
pub platform: Option<&'a str>,
|
||||||
@ -397,8 +402,6 @@ impl<'a> VmParams<'a> {
|
|||||||
let numa: Option<Vec<&str>> = args.values_of("numa").map(|x| x.collect());
|
let numa: Option<Vec<&str>> = args.values_of("numa").map(|x| x.collect());
|
||||||
let watchdog = args.is_present("watchdog");
|
let watchdog = args.is_present("watchdog");
|
||||||
let platform = args.value_of("platform");
|
let platform = args.value_of("platform");
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let tdx = args.value_of("tdx");
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
let gdb = args.is_present("gdb");
|
let gdb = args.is_present("gdb");
|
||||||
VmParams {
|
VmParams {
|
||||||
@ -425,8 +428,6 @@ impl<'a> VmParams<'a> {
|
|||||||
sgx_epc,
|
sgx_epc,
|
||||||
numa,
|
numa,
|
||||||
watchdog,
|
watchdog,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
tdx,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
gdb,
|
gdb,
|
||||||
platform,
|
platform,
|
||||||
@ -642,16 +643,22 @@ pub struct PlatformConfig {
|
|||||||
pub uuid: Option<String>,
|
pub uuid: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub oem_strings: Option<Vec<String>>,
|
pub oem_strings: Option<Vec<String>>,
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
#[serde(default)]
|
||||||
|
pub tdx: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlatformConfig {
|
impl PlatformConfig {
|
||||||
pub fn parse(platform: &str) -> Result<Self> {
|
pub fn parse(platform: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("num_pci_segments");
|
parser
|
||||||
parser.add("iommu_segments");
|
.add("num_pci_segments")
|
||||||
parser.add("serial_number");
|
.add("iommu_segments")
|
||||||
parser.add("uuid");
|
.add("serial_number")
|
||||||
parser.add("oem_strings");
|
.add("uuid")
|
||||||
|
.add("oem_strings");
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
parser.add("tdx");
|
||||||
parser.parse(platform).map_err(Error::ParsePlatform)?;
|
parser.parse(platform).map_err(Error::ParsePlatform)?;
|
||||||
|
|
||||||
let num_pci_segments: u16 = parser
|
let num_pci_segments: u16 = parser
|
||||||
@ -670,12 +677,20 @@ impl PlatformConfig {
|
|||||||
.convert::<StringList>("oem_strings")
|
.convert::<StringList>("oem_strings")
|
||||||
.map_err(Error::ParsePlatform)?
|
.map_err(Error::ParsePlatform)?
|
||||||
.map(|v| v.0);
|
.map(|v| v.0);
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
let tdx = parser
|
||||||
|
.convert::<Toggle>("tdx")
|
||||||
|
.map_err(Error::ParsePlatform)?
|
||||||
|
.unwrap_or(Toggle(false))
|
||||||
|
.0;
|
||||||
Ok(PlatformConfig {
|
Ok(PlatformConfig {
|
||||||
num_pci_segments,
|
num_pci_segments,
|
||||||
iommu_segments,
|
iommu_segments,
|
||||||
serial_number,
|
serial_number,
|
||||||
uuid,
|
uuid,
|
||||||
oem_strings,
|
oem_strings,
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
tdx,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,6 +721,8 @@ impl Default for PlatformConfig {
|
|||||||
serial_number: None,
|
serial_number: None,
|
||||||
uuid: None,
|
uuid: None,
|
||||||
oem_strings: None,
|
oem_strings: None,
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
tdx: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2083,26 +2100,6 @@ impl VsockConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
|
||||||
pub struct TdxConfig {
|
|
||||||
pub firmware: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
impl TdxConfig {
|
|
||||||
pub fn parse(tdx: &str) -> Result<Self> {
|
|
||||||
let mut parser = OptionParser::new();
|
|
||||||
parser.add("firmware");
|
|
||||||
parser.parse(tdx).map_err(Error::ParseTdx)?;
|
|
||||||
let firmware = parser
|
|
||||||
.get("firmware")
|
|
||||||
.map(PathBuf::from)
|
|
||||||
.ok_or(Error::FirmwarePathMissing)?;
|
|
||||||
Ok(TdxConfig { firmware })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
||||||
pub struct SgxEpcConfig {
|
pub struct SgxEpcConfig {
|
||||||
@ -2296,8 +2293,6 @@ pub struct VmConfig {
|
|||||||
pub numa: Option<Vec<NumaConfig>>,
|
pub numa: Option<Vec<NumaConfig>>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub watchdog: bool,
|
pub watchdog: bool,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
pub tdx: Option<TdxConfig>,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
pub gdb: bool,
|
pub gdb: bool,
|
||||||
pub platform: Option<PlatformConfig>,
|
pub platform: Option<PlatformConfig>,
|
||||||
@ -2341,16 +2336,16 @@ impl VmConfig {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "tdx"))]
|
|
||||||
self.payload
|
self.payload
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(ValidationError::KernelMissing)?;
|
.ok_or(ValidationError::KernelMissing)?;
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
{
|
{
|
||||||
let tdx_enabled = self.tdx.is_some();
|
let tdx_enabled = self.platform.as_ref().map(|p| p.tdx).unwrap_or(false);
|
||||||
if !tdx_enabled && self.payload.is_none() {
|
// At this point we know payload isn't None.
|
||||||
return Err(ValidationError::KernelMissing);
|
if tdx_enabled && self.payload.as_ref().unwrap().firmware.is_none() {
|
||||||
|
return Err(ValidationError::TdxFirmwareMissing);
|
||||||
}
|
}
|
||||||
if tdx_enabled && (self.cpus.max_vcpus != self.cpus.boot_vcpus) {
|
if tdx_enabled && (self.cpus.max_vcpus != self.cpus.boot_vcpus) {
|
||||||
return Err(ValidationError::TdxNoCpuHotplug);
|
return Err(ValidationError::TdxNoCpuHotplug);
|
||||||
@ -2686,9 +2681,6 @@ impl VmConfig {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let tdx = vm_params.tdx.map(TdxConfig::parse).transpose()?;
|
|
||||||
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
let gdb = vm_params.gdb;
|
let gdb = vm_params.gdb;
|
||||||
|
|
||||||
@ -2716,8 +2708,6 @@ impl VmConfig {
|
|||||||
sgx_epc,
|
sgx_epc,
|
||||||
numa,
|
numa,
|
||||||
watchdog: vm_params.watchdog,
|
watchdog: vm_params.watchdog,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
tdx,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
gdb,
|
gdb,
|
||||||
platform,
|
platform,
|
||||||
@ -2725,6 +2715,11 @@ impl VmConfig {
|
|||||||
config.validate().map_err(Error::Validation)?;
|
config.validate().map_err(Error::Validation)?;
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
pub fn is_tdx_enabled(&self) -> bool {
|
||||||
|
self.platform.as_ref().map(|p| p.tdx).unwrap_or(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -3323,8 +3318,6 @@ mod tests {
|
|||||||
sgx_epc: None,
|
sgx_epc: None,
|
||||||
numa: None,
|
numa: None,
|
||||||
watchdog: false,
|
watchdog: false,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
tdx: None,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
gdb: false,
|
gdb: false,
|
||||||
platform: None,
|
platform: None,
|
||||||
|
@ -1419,8 +1419,6 @@ impl Vmm {
|
|||||||
let vm_config = vm.get_config();
|
let vm_config = vm.get_config();
|
||||||
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
||||||
let common_cpuid = {
|
let common_cpuid = {
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let tdx_enabled = vm_config.lock().unwrap().tdx.is_some();
|
|
||||||
let phys_bits = vm::physical_bits(vm_config.lock().unwrap().cpus.max_phys_bits);
|
let phys_bits = vm::physical_bits(vm_config.lock().unwrap().cpus.max_phys_bits);
|
||||||
arch::generate_common_cpuid(
|
arch::generate_common_cpuid(
|
||||||
hypervisor,
|
hypervisor,
|
||||||
@ -1429,7 +1427,7 @@ impl Vmm {
|
|||||||
phys_bits,
|
phys_bits,
|
||||||
vm_config.lock().unwrap().cpus.kvm_hyperv,
|
vm_config.lock().unwrap().cpus.kvm_hyperv,
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
tdx_enabled,
|
vm_config.lock().unwrap().is_tdx_enabled(),
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid': {:?}", e))
|
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid': {:?}", e))
|
||||||
@ -1612,8 +1610,6 @@ impl Vmm {
|
|||||||
let dest_cpuid = &{
|
let dest_cpuid = &{
|
||||||
let vm_config = &src_vm_config.lock().unwrap();
|
let vm_config = &src_vm_config.lock().unwrap();
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let tdx_enabled = vm_config.tdx.is_some();
|
|
||||||
let phys_bits = vm::physical_bits(vm_config.cpus.max_phys_bits);
|
let phys_bits = vm::physical_bits(vm_config.cpus.max_phys_bits);
|
||||||
arch::generate_common_cpuid(
|
arch::generate_common_cpuid(
|
||||||
self.hypervisor.clone(),
|
self.hypervisor.clone(),
|
||||||
@ -1622,7 +1618,7 @@ impl Vmm {
|
|||||||
phys_bits,
|
phys_bits,
|
||||||
vm_config.cpus.kvm_hyperv,
|
vm_config.cpus.kvm_hyperv,
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
tdx_enabled,
|
vm_config.is_tdx_enabled(),
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e))
|
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e))
|
||||||
@ -2053,8 +2049,6 @@ mod unit_tests {
|
|||||||
sgx_epc: None,
|
sgx_epc: None,
|
||||||
numa: None,
|
numa: None,
|
||||||
watchdog: false,
|
watchdog: false,
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
tdx: None,
|
|
||||||
#[cfg(feature = "gdb")]
|
#[cfg(feature = "gdb")]
|
||||||
gdb: false,
|
gdb: false,
|
||||||
platform: None,
|
platform: None,
|
||||||
|
@ -285,6 +285,10 @@ pub enum Error {
|
|||||||
#[error("Error finalizing TDX VM: {0}")]
|
#[error("Error finalizing TDX VM: {0}")]
|
||||||
FinalizeTdx(#[source] hypervisor::HypervisorVmError),
|
FinalizeTdx(#[source] hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
#[error("TDX firmware missing")]
|
||||||
|
TdxFirmwareMissing,
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
#[error("Invalid TDX payload type")]
|
#[error("Invalid TDX payload type")]
|
||||||
InvalidPayloadType,
|
InvalidPayloadType,
|
||||||
@ -515,7 +519,9 @@ impl Vm {
|
|||||||
Self::create_numa_nodes(config.lock().unwrap().numa.clone(), &memory_manager)?;
|
Self::create_numa_nodes(config.lock().unwrap().numa.clone(), &memory_manager)?;
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
let force_iommu = config.lock().unwrap().tdx.is_some();
|
let tdx_enabled = config.lock().unwrap().is_tdx_enabled();
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
let force_iommu = tdx_enabled;
|
||||||
#[cfg(not(feature = "tdx"))]
|
#[cfg(not(feature = "tdx"))]
|
||||||
let force_iommu = false;
|
let force_iommu = false;
|
||||||
|
|
||||||
@ -559,8 +565,6 @@ impl Vm {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let exit_evt_clone = exit_evt.try_clone().map_err(Error::EventFdClone)?;
|
let exit_evt_clone = exit_evt.try_clone().map_err(Error::EventFdClone)?;
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let tdx_enabled = config.lock().unwrap().tdx.is_some();
|
|
||||||
let cpus_config = { &config.lock().unwrap().cpus.clone() };
|
let cpus_config = { &config.lock().unwrap().cpus.clone() };
|
||||||
let cpu_manager = cpu::CpuManager::new(
|
let cpu_manager = cpu::CpuManager::new(
|
||||||
cpus_config,
|
cpus_config,
|
||||||
@ -723,7 +727,7 @@ impl Vm {
|
|||||||
let timestamp = Instant::now();
|
let timestamp = Instant::now();
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
let tdx_enabled = config.lock().unwrap().tdx.is_some();
|
let tdx_enabled = config.lock().unwrap().is_tdx_enabled();
|
||||||
hypervisor.check_required_extensions().unwrap();
|
hypervisor.check_required_extensions().unwrap();
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
let vm = hypervisor
|
let vm = hypervisor
|
||||||
@ -1136,7 +1140,7 @@ impl Vm {
|
|||||||
) -> Result<Option<thread::JoinHandle<Result<EntryPoint>>>> {
|
) -> Result<Option<thread::JoinHandle<Result<EntryPoint>>>> {
|
||||||
// Kernel with TDX is loaded in a different manner
|
// Kernel with TDX is loaded in a different manner
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
if config.lock().unwrap().tdx.is_some() {
|
if config.lock().unwrap().is_tdx_enabled() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1784,10 +1788,19 @@ impl Vm {
|
|||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
fn extract_tdvf_sections(&mut self) -> Result<Vec<TdvfSection>> {
|
fn extract_tdvf_sections(&mut self) -> Result<Vec<TdvfSection>> {
|
||||||
use arch::x86_64::tdx::*;
|
use arch::x86_64::tdx::*;
|
||||||
|
|
||||||
|
let firmware_path = self
|
||||||
|
.config
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.payload
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.firmware
|
||||||
|
.clone()
|
||||||
|
.ok_or(Error::TdxFirmwareMissing)?;
|
||||||
// The TDVF file contains a table of section as well as code
|
// The TDVF file contains a table of section as well as code
|
||||||
let mut firmware_file =
|
let mut firmware_file = File::open(firmware_path).map_err(Error::LoadTdvf)?;
|
||||||
File::open(&self.config.lock().unwrap().tdx.as_ref().unwrap().firmware)
|
|
||||||
.map_err(Error::LoadTdvf)?;
|
|
||||||
|
|
||||||
// For all the sections allocate some RAM backing them
|
// For all the sections allocate some RAM backing them
|
||||||
parse_tdvf_sections(&mut firmware_file).map_err(Error::ParseTdvf)
|
parse_tdvf_sections(&mut firmware_file).map_err(Error::ParseTdvf)
|
||||||
@ -1882,9 +1895,17 @@ impl Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The TDVF file contains a table of section as well as code
|
// The TDVF file contains a table of section as well as code
|
||||||
let mut firmware_file =
|
let firmware_path = self
|
||||||
File::open(&self.config.lock().unwrap().tdx.as_ref().unwrap().firmware)
|
.config
|
||||||
.map_err(Error::LoadTdvf)?;
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.payload
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.firmware
|
||||||
|
.clone()
|
||||||
|
.ok_or(Error::TdxFirmwareMissing)?;
|
||||||
|
let mut firmware_file = File::open(firmware_path).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.
|
||||||
@ -2115,7 +2136,7 @@ impl Vm {
|
|||||||
|
|
||||||
fn create_acpi_tables(&self) -> Option<GuestAddress> {
|
fn create_acpi_tables(&self) -> Option<GuestAddress> {
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
if self.config.lock().unwrap().tdx.is_some() {
|
if self.config.lock().unwrap().is_tdx_enabled() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2166,10 +2187,13 @@ impl Vm {
|
|||||||
// finish.
|
// finish.
|
||||||
let entry_point = self.entry_point()?;
|
let entry_point = self.entry_point()?;
|
||||||
|
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
let tdx_enabled = self.config.lock().unwrap().is_tdx_enabled();
|
||||||
|
|
||||||
// The initial TDX configuration must be done before the vCPUs are
|
// The initial TDX configuration must be done before the vCPUs are
|
||||||
// created
|
// created
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
if self.config.lock().unwrap().tdx.is_some() {
|
if tdx_enabled {
|
||||||
self.init_tdx()?;
|
self.init_tdx()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2181,7 +2205,7 @@ impl Vm {
|
|||||||
.map_err(Error::CpuManager)?;
|
.map_err(Error::CpuManager)?;
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
let sections = if self.config.lock().unwrap().tdx.is_some() {
|
let sections = if tdx_enabled {
|
||||||
self.extract_tdvf_sections()?
|
self.extract_tdvf_sections()?
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
@ -2189,7 +2213,7 @@ impl Vm {
|
|||||||
|
|
||||||
// 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 tdx_enabled {
|
||||||
// TDX sections are written to memory.
|
// TDX sections are written to memory.
|
||||||
self.populate_tdx_sections(§ions)?
|
self.populate_tdx_sections(§ions)?
|
||||||
} else {
|
} else {
|
||||||
@ -2715,9 +2739,12 @@ impl Snapshottable for Vm {
|
|||||||
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
|
fn snapshot(&mut self) -> std::result::Result<Snapshot, MigratableError> {
|
||||||
event!("vm", "snapshotting");
|
event!("vm", "snapshotting");
|
||||||
|
|
||||||
|
#[cfg(feature = "tdx")]
|
||||||
|
let tdx_enabled = self.config.lock().unwrap().is_tdx_enabled();
|
||||||
|
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
{
|
{
|
||||||
if self.config.lock().unwrap().tdx.is_some() {
|
if tdx_enabled {
|
||||||
return Err(MigratableError::Snapshot(anyhow!(
|
return Err(MigratableError::Snapshot(anyhow!(
|
||||||
"Snapshot not possible with TDX VM"
|
"Snapshot not possible with TDX VM"
|
||||||
)));
|
)));
|
||||||
@ -2733,8 +2760,6 @@ impl Snapshottable for Vm {
|
|||||||
|
|
||||||
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
||||||
let common_cpuid = {
|
let common_cpuid = {
|
||||||
#[cfg(feature = "tdx")]
|
|
||||||
let tdx_enabled = self.config.lock().unwrap().tdx.is_some();
|
|
||||||
let phys_bits = physical_bits(self.config.lock().unwrap().cpus.max_phys_bits);
|
let phys_bits = physical_bits(self.config.lock().unwrap().cpus.max_phys_bits);
|
||||||
arch::generate_common_cpuid(
|
arch::generate_common_cpuid(
|
||||||
self.hypervisor.clone(),
|
self.hypervisor.clone(),
|
||||||
|
Loading…
Reference in New Issue
Block a user