mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
arch: Generate required_msr_updates function
We introduce a function somewhat analogous to `generate_common_cpuid`, except that it is only relevant for CPU profiles. This function is more "high level" than the CpuProfile::required_msr_updates method and is intended to be called from the vmm crate. Signed-off-by: Oliver Anderson <oliver.anderson@cyberus-technology.de> On-behalf-of: SAP oliver.anderson@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
faa94bddec
commit
6d9dd42abb
@@ -25,7 +25,7 @@ mod smbios;
|
||||
use std::arch::x86_64;
|
||||
|
||||
use helpers::{deserialize_u32_hex, serialize_u32_hex};
|
||||
use hypervisor::arch::x86::{CPUID_FLAG_VALID_INDEX, CpuIdEntry};
|
||||
use hypervisor::arch::x86::{CPUID_FLAG_VALID_INDEX, CpuIdEntry, VcpuMsrConfigUpdate};
|
||||
use hypervisor::{CpuVendor, HypervisorCpuError, HypervisorError};
|
||||
use linux_loader::loader::bootparam::{boot_params, setup_header};
|
||||
use linux_loader::loader::elf::start_info::{
|
||||
@@ -185,6 +185,15 @@ pub enum Error {
|
||||
)]
|
||||
CpuProfileMsrIncompatibility,
|
||||
|
||||
/// Error when trying to apply a CPU profile because the MSR index list could not be obtained
|
||||
#[error("The selected CPU profile could not be utilized: failed to obtain MSR index list")]
|
||||
CpuProfileMsrIndexList(#[source] HypervisorError),
|
||||
|
||||
/// Error when trying to apply a CPU profile because the feature MSRs could not be obtained
|
||||
/// from the hypervisor.
|
||||
#[error("The selected CPU profile could not be utilized: failed to obtain feature MSRs")]
|
||||
CpuProfileFeatureMsrs(#[source] HypervisorError),
|
||||
|
||||
// Error writing EBDA address
|
||||
#[error("Error writing EBDA address")]
|
||||
EbdaSetup(#[source] vm_memory::GuestMemoryError),
|
||||
@@ -715,6 +724,61 @@ pub fn generate_common_cpuid(
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the MSR related updates that are required in order to be compatible with the given CPU profile (if any).
|
||||
///
|
||||
/// An error is returned if any MSR required by the given CPU profile is not reported by the hypervisor. If
|
||||
/// the `kvm_hyperv` parameter is `false` then Hyper-V related MSRs are exempt from this check.
|
||||
///
|
||||
/// If nested is `false` then feature MSRs describing virtualization capabilities will not be considered part of
|
||||
/// the CPU profile.
|
||||
///
|
||||
/// ## Feature MSRs compatibility
|
||||
///
|
||||
/// The hypervisor is expected to reject setting feature MSRs that are incompatible with the host. This is why this
|
||||
/// function does **NOT perform such compatibility checks** itself.
|
||||
///
|
||||
/// The one and only exception to this rule is the IA32_ARCH_CAPABILITIES MSR. This function will check that the
|
||||
/// host is compatible with the CPU profile's value for that MSR when present as KVM permits setting it regardless
|
||||
/// of what the host actually supports.
|
||||
pub fn generate_required_msr_updates(
|
||||
hypervisor: &dyn hypervisor::Hypervisor,
|
||||
cpu_profile: CpuProfile,
|
||||
kvm_hyperv: bool,
|
||||
nested: bool,
|
||||
) -> super::Result<Option<VcpuMsrConfigUpdate>> {
|
||||
if matches!(cpu_profile, CpuProfile::Host) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let host_supported_msrs = hypervisor
|
||||
.get_msr_index_list()
|
||||
.map_err(Error::CpuProfileMsrIndexList)?;
|
||||
|
||||
let host_feature_msrs = hypervisor
|
||||
.get_feature_msrs()
|
||||
.map_err(Error::CpuProfileFeatureMsrs)?;
|
||||
|
||||
let required_updates = cpu_profile.required_msr_updates(
|
||||
&host_feature_msrs,
|
||||
&host_supported_msrs,
|
||||
kvm_hyperv,
|
||||
nested,
|
||||
)?;
|
||||
|
||||
if let Some(required_updates) = &required_updates {
|
||||
// If IA32_ARCH_CAPABILITIES is present then we need to check for compatibility.
|
||||
// This MSR is only available on Intel CPUs as of now, but we do not check for vendor equality here.
|
||||
//
|
||||
// TODO: Consider adding a CPU vendor equality requirement to `check_cpuid_compatibility` even though
|
||||
// it is extremely unlikely that CPUs from different vendors will pass the existing checks.
|
||||
arch_capabilities_checks::valid_required_arch_capabilities_update(
|
||||
required_updates,
|
||||
&host_feature_msrs,
|
||||
)?;
|
||||
}
|
||||
Ok(required_updates)
|
||||
}
|
||||
|
||||
/// Apply updates to common CPUID (not vCPU specific) that are necessary regardless of
|
||||
/// the chosen CPU profile.
|
||||
fn required_common_cpuid_updates(
|
||||
|
||||
Reference in New Issue
Block a user