mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +00:00
arch, vmm: Add new struct CpuidConfig
This struct contains all configuration fields that controls the way how we generate CPUID for the guest on x86_64. This allows cleaner extension when adding new configuration fields. Signed-off-by: Bo Chen <chen.bo@intel.com>
This commit is contained in:
parent
30975ea102
commit
7dd260f82f
@ -92,7 +92,7 @@ pub mod x86_64;
|
||||
pub use x86_64::{
|
||||
arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid,
|
||||
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
|
||||
layout::CMDLINE_START, regs, CpuidFeatureEntry, EntryPoint, _NSIG,
|
||||
layout::CMDLINE_START, regs, CpuidConfig, CpuidFeatureEntry, EntryPoint, _NSIG,
|
||||
};
|
||||
|
||||
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
|
||||
|
@ -145,6 +145,14 @@ struct BootParamsWrapper(boot_params);
|
||||
// SAFETY: BootParamsWrap is a wrapper over `boot_params` (a series of ints).
|
||||
unsafe impl ByteValued for BootParamsWrapper {}
|
||||
|
||||
pub struct CpuidConfig {
|
||||
pub sgx_epc_sections: Option<Vec<SgxEpcSection>>,
|
||||
pub phys_bits: u8,
|
||||
pub kvm_hyperv: bool,
|
||||
#[cfg(feature = "tdx")]
|
||||
pub tdx: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Error writing MP table to memory.
|
||||
@ -552,10 +560,7 @@ impl CpuidFeatureEntry {
|
||||
|
||||
pub fn generate_common_cpuid(
|
||||
hypervisor: &Arc<dyn hypervisor::Hypervisor>,
|
||||
sgx_epc_sections: Option<Vec<SgxEpcSection>>,
|
||||
phys_bits: u8,
|
||||
kvm_hyperv: bool,
|
||||
#[cfg(feature = "tdx")] tdx_enabled: bool,
|
||||
config: &CpuidConfig,
|
||||
) -> super::Result<Vec<CpuIdEntry>> {
|
||||
// SAFETY: cpuid called with valid leaves
|
||||
if unsafe { x86_64::__cpuid(1) }.ecx & 1 << HYPERVISOR_ECX_BIT == 1 << HYPERVISOR_ECX_BIT {
|
||||
@ -573,7 +578,10 @@ pub fn generate_common_cpuid(
|
||||
);
|
||||
}
|
||||
|
||||
info!("Generating guest CPUID for with physical address size: {phys_bits}");
|
||||
info!(
|
||||
"Generating guest CPUID for with physical address size: {}",
|
||||
config.phys_bits
|
||||
);
|
||||
let cpuid_patches = vec![
|
||||
// Patch tsc deadline timer bit
|
||||
CpuidPatch {
|
||||
@ -614,12 +622,12 @@ pub fn generate_common_cpuid(
|
||||
|
||||
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
|
||||
|
||||
if let Some(sgx_epc_sections) = sgx_epc_sections {
|
||||
if let Some(sgx_epc_sections) = &config.sgx_epc_sections {
|
||||
update_cpuid_sgx(&mut cpuid, sgx_epc_sections)?;
|
||||
}
|
||||
|
||||
#[cfg(feature = "tdx")]
|
||||
let tdx_capabilities = if tdx_enabled {
|
||||
let tdx_capabilities = if config.tdx {
|
||||
let caps = hypervisor
|
||||
.tdx_capabilities()
|
||||
.map_err(Error::TdxCapabilities)?;
|
||||
@ -667,12 +675,12 @@ pub fn generate_common_cpuid(
|
||||
}
|
||||
// Set CPU physical bits
|
||||
0x8000_0008 => {
|
||||
entry.eax = (entry.eax & 0xffff_ff00) | (phys_bits as u32 & 0xff);
|
||||
entry.eax = (entry.eax & 0xffff_ff00) | (config.phys_bits as u32 & 0xff);
|
||||
}
|
||||
0x4000_0001 => {
|
||||
// These features are not supported by TDX
|
||||
#[cfg(feature = "tdx")]
|
||||
if tdx_enabled {
|
||||
if config.tdx {
|
||||
entry.eax &= !(1 << KVM_FEATURE_CLOCKSOURCE_BIT
|
||||
| 1 << KVM_FEATURE_CLOCKSOURCE2_BIT
|
||||
| 1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT
|
||||
@ -700,7 +708,7 @@ pub fn generate_common_cpuid(
|
||||
});
|
||||
}
|
||||
|
||||
if kvm_hyperv {
|
||||
if config.kvm_hyperv {
|
||||
// Remove conflicting entries
|
||||
cpuid.retain(|c| c.function != 0x4000_0000);
|
||||
cpuid.retain(|c| c.function != 0x4000_0001);
|
||||
@ -1293,7 +1301,7 @@ fn update_cpuid_topology(
|
||||
// sections exposed to the guest.
|
||||
fn update_cpuid_sgx(
|
||||
cpuid: &mut Vec<CpuIdEntry>,
|
||||
epc_sections: Vec<SgxEpcSection>,
|
||||
epc_sections: &Vec<SgxEpcSection>,
|
||||
) -> Result<(), Error> {
|
||||
// Something's wrong if there's no EPC section.
|
||||
if epc_sections.is_empty() {
|
||||
|
@ -726,7 +726,7 @@ impl CpuManager {
|
||||
&mut self,
|
||||
memory_manager: &Arc<Mutex<MemoryManager>>,
|
||||
hypervisor: &Arc<dyn hypervisor::Hypervisor>,
|
||||
#[cfg(feature = "tdx")] tdx_enabled: bool,
|
||||
#[cfg(feature = "tdx")] tdx: bool,
|
||||
) -> Result<()> {
|
||||
let sgx_epc_sections = memory_manager
|
||||
.lock()
|
||||
@ -739,11 +739,13 @@ impl CpuManager {
|
||||
let phys_bits = physical_bits(hypervisor, self.config.max_phys_bits);
|
||||
arch::generate_common_cpuid(
|
||||
hypervisor,
|
||||
sgx_epc_sections,
|
||||
phys_bits,
|
||||
self.config.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx_enabled,
|
||||
&arch::CpuidConfig {
|
||||
sgx_epc_sections,
|
||||
phys_bits,
|
||||
kvm_hyperv: self.config.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx,
|
||||
},
|
||||
)
|
||||
.map_err(Error::CommonCpuId)?
|
||||
};
|
||||
|
@ -1664,16 +1664,18 @@ impl Vmm {
|
||||
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
|
||||
let common_cpuid = {
|
||||
#[cfg(feature = "tdx")]
|
||||
let tdx_enabled = vm_config.lock().unwrap().is_tdx_enabled();
|
||||
let tdx = vm_config.lock().unwrap().is_tdx_enabled();
|
||||
let phys_bits =
|
||||
vm::physical_bits(&hypervisor, vm_config.lock().unwrap().cpus.max_phys_bits);
|
||||
arch::generate_common_cpuid(
|
||||
&hypervisor,
|
||||
None,
|
||||
phys_bits,
|
||||
vm_config.lock().unwrap().cpus.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx_enabled,
|
||||
&arch::CpuidConfig {
|
||||
sgx_epc_sections: None,
|
||||
phys_bits,
|
||||
kvm_hyperv: vm_config.lock().unwrap().cpus.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx,
|
||||
},
|
||||
)
|
||||
.map_err(|e| {
|
||||
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid': {:?}", e))
|
||||
@ -1858,11 +1860,13 @@ impl Vmm {
|
||||
let phys_bits = vm::physical_bits(&self.hypervisor, vm_config.cpus.max_phys_bits);
|
||||
arch::generate_common_cpuid(
|
||||
&self.hypervisor.clone(),
|
||||
None,
|
||||
phys_bits,
|
||||
vm_config.cpus.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
vm_config.is_tdx_enabled(),
|
||||
&arch::CpuidConfig {
|
||||
sgx_epc_sections: None,
|
||||
phys_bits,
|
||||
kvm_hyperv: vm_config.cpus.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx: vm_config.is_tdx_enabled(),
|
||||
},
|
||||
)
|
||||
.map_err(|e| {
|
||||
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e))
|
||||
|
@ -2415,11 +2415,13 @@ impl Snapshottable for Vm {
|
||||
);
|
||||
arch::generate_common_cpuid(
|
||||
&self.hypervisor,
|
||||
None,
|
||||
phys_bits,
|
||||
self.config.lock().unwrap().cpus.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx_enabled,
|
||||
&arch::CpuidConfig {
|
||||
sgx_epc_sections: None,
|
||||
phys_bits,
|
||||
kvm_hyperv: self.config.lock().unwrap().cpus.kvm_hyperv,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx: tdx_enabled,
|
||||
},
|
||||
)
|
||||
.map_err(|e| {
|
||||
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e))
|
||||
|
Loading…
Reference in New Issue
Block a user