Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions arch/src/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ impl CpuidFeatureEntry {
pub fn generate_common_cpuid(
hypervisor: &dyn hypervisor::Hypervisor,
config: &CpuidConfig,
#[cfg(feature = "tdx")] vm: Option<&dyn hypervisor::Vm>,
) -> super::Result<Vec<CpuIdEntry>> {
#[allow(unused_unsafe)]
// SAFETY: cpuid called with valid leaves
Expand Down Expand Up @@ -634,6 +635,16 @@ pub fn generate_common_cpuid(

CpuidPatch::patch_cpuid(&mut cpuid, &cpuid_patches);

#[cfg(feature = "tdx")]
if config.tdx {
let tdx_vm = vm.ok_or_else(|| {
Error::TdxCapabilities(HypervisorVmError::InitializeTdx(std::io::Error::other(
"Missing VM instance for TDX CPUID generation",
)))
})?;
common_cpuid_tdx_configuration(&mut cpuid, tdx_vm)?;
}

// Update some existing CPUID
for entry in cpuid.as_mut_slice().iter_mut() {
#[allow(unused_unsafe)]
Expand All @@ -648,9 +659,6 @@ pub fn generate_common_cpuid(
entry.edx &= !(1 << AMX_COMPLEX);
}
}
0xd =>
{
}
// Tile Information (purely AMX related).
0x1d if !config.amx => {
entry.eax = 0;
Expand Down Expand Up @@ -792,6 +800,41 @@ pub fn generate_common_cpuid(
Ok(cpuid)
}

#[cfg(feature = "tdx")]
fn common_cpuid_tdx_configuration(
cpuid: &mut [CpuIdEntry],
vm: &dyn hypervisor::Vm,
) -> super::Result<()> {
let caps = vm.tdx_capabilities().map_err(Error::TdxCapabilities)?;
debug!("TDX capabilities supported_attrs={:#x} supported_xfam={:#x}",
caps.supported_attrs, caps.supported_xfam);

// XCR0-managed (user) XSAVE state components. Must include the AMX
// tile state components (XTILECFG bit 17, XTILEDATA bit 18); otherwise
// AMX is stripped from CPUID.0xD.0 and never makes it into the TD XFAM.
// Bits: x87(0) SSE(1) AVX(2) BNDREG(3) BNDCSR(4) OPMASK(5) ZMM_Hi256(6)
// Hi16_ZMM(7) PKRU(9) XTILECFG(17) XTILEDATA(18).
let xcr0_mask: u64 = 0x602ff;
// IA32_XSS-managed (supervisor) XSAVE state components currently defined
// by the architecture. Listed explicitly (rather than `!xcr0_mask`) so
// reserved/undefined bits (19-63) are masked to zero instead of relying
// on `supported_xfam` to already be zero there.
// Bits: PT(8) ENQCMD/PASID(10) CET_U(11) CET_S(12) HDC(13) UINTR(14)
// LBR(15) HWP(16).
let xss_mask: u64 = 0x1fd00;
for entry in cpuid.iter_mut().filter(|entry| entry.function == 0xd) {
if entry.index == 0 {
entry.eax &= (caps.supported_xfam as u32) & (xcr0_mask as u32);
entry.edx &= ((caps.supported_xfam & xcr0_mask) >> 32) as u32;
} else if entry.index == 1 {
entry.ecx &= (caps.supported_xfam as u32) & (xss_mask as u32);
entry.edx &= ((caps.supported_xfam & xss_mask) >> 32) as u32;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Bit 8: PT (Processor Trace)
// Bit 11: CET_U (User Shadow Stack)
// Bit 12: CET_S (Supervisor Shadow Stack)
// Bit 13: HDC
// Bit 14: UINTR (User Interrupts)
// Bit 15: LBR (Last Branch Record)
const XSS_PT_BIT: u64 = 8;
const XSS_CET_U_BIT: u64 = 11;
const XSS_CET_S_BIT: u64 = 12;
const XSS_HDC_BIT: u64 = 13;
const XSS_UINTR_BIT: u64 = 14;
const XSS_LBR_BIT: u64 = 15;

let xss_mask: u64 = (1 << XSS_PT_BIT)
| (1 << XSS_CET_U_BIT)
| (1 << XSS_CET_S_BIT)
| (1 << XSS_HDC_BIT)
| (1 << XSS_UINTR_BIT)
| (1 << XSS_LBR_BIT);

better than let xss_mask: u64 = !xcr0_mask;

}

Ok(())
}

#[allow(clippy::too_many_arguments)]
pub fn configure_vcpu(
vcpu: &dyn hypervisor::Vcpu,
Expand Down
2 changes: 2 additions & 0 deletions vmm/src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,8 @@ impl CpuManager {
tdx,
amx: self.config.features.amx,
},
#[cfg(feature = "tdx")]
vm,
)
.map_err(Error::CommonCpuId)?
};
Expand Down
6 changes: 6 additions & 0 deletions vmm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,9 @@ impl Vmm {
tdx: false,
amx,
},
#[cfg(feature = "tdx")]
// Live Migration is not supported when TDX is enabled
None,
)
.map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error generating common cpuid': {e:?}"))
Expand Down Expand Up @@ -1440,6 +1443,9 @@ impl Vmm {
tdx: false,
amx: vm_config.cpus.features.amx,
},
#[cfg(feature = "tdx")]
// Live Migration is not supported when TDX is enabled
None,
)
.map_err(|e| {
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {e:?}"))
Expand Down
3 changes: 3 additions & 0 deletions vmm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3395,6 +3395,9 @@ impl Snapshottable for Vm {
tdx: false,
amx,
},
#[cfg(feature = "tdx")]
// Snapshot not possible with TDX VM
None,
)
.map_err(|e| {
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {e:?}"))
Expand Down
Loading