Skip to content

Commit 709f01d

Browse files
arch: Check for CPU Vendor compatibility with CPU profile
When generating the common CPUID we utilize a CPU profile if given, but the current compatibility checks don't check that the CPU vendors between the current host and the compatibility target coincide. Hence we introduce this extra check here. We are happy to have it as a stand alone check for now, but we should consider making this part of the check_cpuid_compatibility function in the future. Signed-Off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de> On-behalf-of: SAP oliver.anderson@sap.com
1 parent 3aee856 commit 709f01d

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

arch/src/x86_64/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod mptable;
1818
pub mod regs;
1919
use std::mem;
2020

21-
use anyhow::Context;
21+
use anyhow::{Context, anyhow};
2222
use hypervisor::arch::x86::{CPUID_FLAG_VALID_INDEX, CpuIdEntry};
2323
use hypervisor::{CpuVendor, HypervisorCpuError, HypervisorError};
2424
use linux_loader::loader::bootparam::{boot_params, setup_header};
@@ -631,7 +631,7 @@ pub fn generate_common_cpuid(
631631
let use_custom_profile = config.profile != CpuProfile::Host;
632632
// Obtain cpuid entries that are adjusted to the specified CPU profile and the cpuid entries of the compatibility target
633633
// TODO: Try to write this in a clearer way
634-
let (mut host_adjusted_to_profile, mut compatibility_target_cpuid) = {
634+
let (mut host_adjusted_to_profile, mut compatibility_target_cpuid, profile_cpu_vendor) = {
635635
config
636636
.profile
637637
.data()
@@ -642,22 +642,34 @@ pub fn generate_common_cpuid(
642642
&profile_data.adjustments,
643643
)),
644644
Some(profile_data.compatibility_target),
645+
Some(profile_data.cpu_vendor),
645646
)
646647
})
647-
.unwrap_or((None, None))
648+
.unwrap_or((None, None, None))
648649
};
649650

651+
// There should be relatively few cases where live migration can succeed between hosts from different
652+
// CPU vendors and making our checks account for that possibility would complicate things substantially.
653+
// We thus require that the host's cpu vendor matches the one used to generate the CPU profile.
654+
if let Some(profile_cpu_vendor) = profile_cpu_vendor
655+
&& profile_cpu_vendor != hypervisor.get_cpu_vendor()
656+
{
657+
return Err(Error::CpuProfileIncompatibility(anyhow!(
658+
"Unable to utilize CPU profile: CPU vendor mismatch detected"
659+
))
660+
.into());
661+
}
650662
// We now make the modifications according to the config parameters to each of the cpuid entries
651663
// declared above and then perform a compatibility check.
652664
for cpuid_optiion in [
653665
Some(&mut host_cpuid),
654666
host_adjusted_to_profile.as_mut(),
655667
compatibility_target_cpuid.as_mut(),
656668
] {
657-
let Some(mut cpuid) = cpuid_optiion else {
669+
let Some(cpuid) = cpuid_optiion else {
658670
break;
659671
};
660-
CpuidPatch::patch_cpuid(&mut cpuid, &cpuid_patches);
672+
CpuidPatch::patch_cpuid(cpuid, &cpuid_patches);
661673

662674
#[cfg(feature = "tdx")]
663675
let tdx_capabilities = if config.tdx {

0 commit comments

Comments
 (0)