mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: Optional vCPU MSR configuration update in vcpu constructor
When applying a CPU profile we need a way to change the configuration of each vCPU to respect the requirements of the CPU profile. This means that we need to set the feature MSRs in accordance with the CPU profile upon configuring the vCPU and also ensuring that we do not attempt to restore any MSRs that are not compatible with the profile upon snapshot/restore. The first step is to update `Vm::create_vcpu` to take an extra parameter describing the necessary update. In the case of KVM we modify the internal MSR state buffer when constructing the vCPU whenever a VcpuMsrConfigUpdate is present. The feature MSRs contained in the configuration will be treated in follow up commits. The changes to the vmm crate that are part of this commit are just the minimum necessary to make the crate compile. We will update the vmm crate to take CPU profiles into account in a follow up commit. 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
2aff169533
commit
6ea8e8e20e
@@ -45,14 +45,14 @@ use hypervisor::StandardRegisters;
|
||||
use hypervisor::arch::aarch64::gic::Vgic;
|
||||
#[cfg(all(target_arch = "aarch64", feature = "guest_debug"))]
|
||||
use hypervisor::arch::aarch64::regs::{ID_AA64MMFR0_EL1, TCR_EL1, TTBR1_EL1};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use hypervisor::arch::x86::CpuIdEntry;
|
||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||
use hypervisor::arch::x86::MsrEntry;
|
||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||
use hypervisor::arch::x86::SpecialRegisters;
|
||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||
use hypervisor::arch::x86::msr_index;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use hypervisor::arch::x86::{CpuIdEntry, VcpuMsrConfigUpdate};
|
||||
#[cfg(feature = "tdx")]
|
||||
use hypervisor::kvm::{TdxExitDetails, TdxExitStatus};
|
||||
#[cfg(feature = "mshv")]
|
||||
@@ -504,15 +504,22 @@ impl Vcpu {
|
||||
/// * `vm` - The virtual machine this vcpu will get attached to.
|
||||
/// * `vm_ops` - Optional object for exit handling.
|
||||
/// * `cpu_vendor` - CPU vendor as reported by __cpuid(0x0)
|
||||
/// * `msr_config_update` - An optional update to MSR configuration.
|
||||
pub fn new(
|
||||
id: u32,
|
||||
apic_id: u32,
|
||||
vm: &dyn hypervisor::Vm,
|
||||
vm_ops: Option<Arc<dyn VmOps>>,
|
||||
#[cfg(target_arch = "x86_64")] cpu_vendor: CpuVendor,
|
||||
#[cfg(target_arch = "x86_64")] msr_config_update: Option<VcpuMsrConfigUpdate>,
|
||||
) -> Result<Self> {
|
||||
let vcpu = vm
|
||||
.create_vcpu(apic_id, vm_ops)
|
||||
.create_vcpu(
|
||||
apic_id,
|
||||
vm_ops,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
msr_config_update,
|
||||
)
|
||||
.map_err(|e| Error::VcpuCreate(e.into()))?;
|
||||
// Initially the cpuid per vCPU is the one supported by this VM.
|
||||
Ok(Vcpu {
|
||||
@@ -978,6 +985,8 @@ impl CpuManager {
|
||||
Some(self.vm_ops.clone()),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
self.hypervisor.get_cpu_vendor(),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
Default::default(),
|
||||
)?;
|
||||
|
||||
if let Some(snapshot) = snapshot {
|
||||
@@ -3439,7 +3448,7 @@ mod unit_tests {
|
||||
hv.check_required_extensions().unwrap();
|
||||
// Calling get_lapic will fail if there is no irqchip before hand.
|
||||
vm.create_irq_chip().unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None, Default::default()).unwrap();
|
||||
let klapic_before: LapicState = vcpu.get_lapic().unwrap();
|
||||
|
||||
// Compute the value that is expected to represent LVT0 and LVT1.
|
||||
@@ -3464,7 +3473,7 @@ mod unit_tests {
|
||||
let vm = hv
|
||||
.create_vm(HypervisorVmConfig::default())
|
||||
.expect("new VM fd creation failed");
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None, Default::default()).unwrap();
|
||||
setup_fpu(vcpu.as_ref()).unwrap();
|
||||
|
||||
let expected_fpu: FpuState = FpuState {
|
||||
@@ -3490,7 +3499,7 @@ mod unit_tests {
|
||||
let vm = hv
|
||||
.create_vm(HypervisorVmConfig::default())
|
||||
.expect("new VM fd creation failed");
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None, Default::default()).unwrap();
|
||||
setup_msrs(vcpu.as_ref()).unwrap();
|
||||
|
||||
// This test will check against the last MSR entry configured (the tenth one).
|
||||
@@ -3518,7 +3527,7 @@ mod unit_tests {
|
||||
let vm = hv
|
||||
.create_vm(HypervisorVmConfig::default())
|
||||
.expect("new VM fd creation failed");
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None, Default::default()).unwrap();
|
||||
|
||||
let mut expected_regs: StandardRegisters = vcpu.create_standard_regs();
|
||||
expected_regs.set_rflags(0x0000000000000002u64);
|
||||
@@ -3544,7 +3553,7 @@ mod unit_tests {
|
||||
let vm = hv
|
||||
.create_vm(HypervisorVmConfig::default())
|
||||
.expect("new VM fd creation failed");
|
||||
let vcpu = vm.create_vcpu(0, None).unwrap();
|
||||
let vcpu = vm.create_vcpu(0, None, Default::default()).unwrap();
|
||||
|
||||
let mut expected_regs: StandardRegisters = vcpu.create_standard_regs();
|
||||
expected_regs.set_rflags(0x0000000000000002u64);
|
||||
|
||||
@@ -3935,7 +3935,9 @@ mod unit_tests {
|
||||
mem.write_slice(&code, load_addr)
|
||||
.expect("Writing code to memory failed");
|
||||
|
||||
let mut vcpu = vm.create_vcpu(0, None).expect("new Vcpu failed");
|
||||
let mut vcpu = vm
|
||||
.create_vcpu(0, None, Default::default())
|
||||
.expect("new Vcpu failed");
|
||||
|
||||
let mut vcpu_sregs = vcpu.get_sregs().expect("get sregs failed");
|
||||
vcpu_sregs.cs.base = 0;
|
||||
@@ -4073,7 +4075,9 @@ pub fn test_vm() {
|
||||
mem.write_slice(&code, load_addr)
|
||||
.expect("Writing code to memory failed");
|
||||
|
||||
let mut vcpu = vm.create_vcpu(0, None).expect("new Vcpu failed");
|
||||
let mut vcpu = vm
|
||||
.create_vcpu(0, None, Default::default())
|
||||
.expect("new Vcpu failed");
|
||||
|
||||
let mut vcpu_sregs = vcpu.get_sregs().expect("get sregs failed");
|
||||
vcpu_sregs.cs.base = 0;
|
||||
|
||||
Reference in New Issue
Block a user