mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: Include feature MSRs in boot_msr_entries
Whenever a CPU profile is selected there will be feature MSRs that need to be set when the CPU is configured. We thus adapt the boot_msr_entries method to include the feature MSRs that are passed to the vCPU upon construction. Since KVM applies compatibility checks for all feature MSRs (except IA32_ARCH_CAPABILITIES) we can only proceed if all MSR boot entries are successfully set upon vCPU configuration. This new check also applies to the regular boot entries when the host profile is selected (the default), but that is arguably an improvement in terms of correctness. 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
d2d13beb28
commit
30063eff7e
@@ -11,6 +11,8 @@ use std::result;
|
||||
use hypervisor::arch::x86::gdt::{gdt_entry, segment_from_gdt};
|
||||
use hypervisor::arch::x86::regs::CR0_PE;
|
||||
use hypervisor::arch::x86::{FpuState, SpecialRegisters};
|
||||
#[cfg(all(feature = "kvm", not(feature = "sev_snp")))]
|
||||
use log::error;
|
||||
use thiserror::Error;
|
||||
use vm_memory::{Address, Bytes, GuestMemoryBackend, GuestMemoryError};
|
||||
|
||||
@@ -33,6 +35,9 @@ pub enum Error {
|
||||
/// Setting up MSRs failed.
|
||||
#[error("Setting up MSRs failed")]
|
||||
SetModelSpecificRegisters(#[source] hypervisor::HypervisorCpuError),
|
||||
/// Setting up MSRs failed because not all setup entries were set.
|
||||
#[error("Some MSRs could not be set")]
|
||||
SetModelSpecificRegistersAll,
|
||||
/// Failed to set SREGs for this CPU.
|
||||
#[error("Failed to set SREGs for this CPU")]
|
||||
SetStatusRegisters(#[source] hypervisor::HypervisorCpuError),
|
||||
@@ -81,10 +86,31 @@ pub fn setup_fpu(vcpu: &dyn hypervisor::Vcpu) -> Result<()> {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||
#[cfg_attr(
|
||||
any(not(feature = "kvm"), feature = "sev_snp"),
|
||||
allow(unused_variables)
|
||||
)]
|
||||
pub fn setup_msrs(vcpu: &dyn hypervisor::Vcpu) -> Result<()> {
|
||||
vcpu.set_msrs(vcpu.boot_msr_entries())
|
||||
let setup_entries = vcpu.boot_msr_entries();
|
||||
let num_msrs_set = vcpu
|
||||
.set_msrs(&setup_entries)
|
||||
.map_err(Error::SetModelSpecificRegisters)?;
|
||||
|
||||
// Check that all setup entries were set. We can only do this for KVM
|
||||
// (when SEV-SNP is not enabled) as MSHV always returns Ok(0) on success.
|
||||
#[cfg(all(feature = "kvm", not(feature = "sev_snp")))]
|
||||
if matches!(vcpu.hypervisor_type(), hypervisor::HypervisorType::Kvm)
|
||||
&& num_msrs_set != setup_entries.len()
|
||||
{
|
||||
for msr in &setup_entries[num_msrs_set..] {
|
||||
error!(
|
||||
"Could not set MSR with register address={:#x} and value={:#x}",
|
||||
msr.index, msr.data
|
||||
);
|
||||
}
|
||||
|
||||
return Err(Error::SetModelSpecificRegistersAll);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -614,7 +614,7 @@ pub trait Vcpu: Send + Sync {
|
||||
///
|
||||
/// Return the list of initial MSR entries for a VCPU
|
||||
///
|
||||
fn boot_msr_entries(&self) -> &'static [MsrEntry];
|
||||
fn boot_msr_entries(&self) -> Vec<MsrEntry>;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
|
||||
@@ -3549,10 +3549,12 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
///
|
||||
/// Return the list of initial MSR entries for a VCPU
|
||||
///
|
||||
fn boot_msr_entries(&self) -> &'static [MsrEntry] {
|
||||
fn boot_msr_entries(&self) -> Vec<MsrEntry> {
|
||||
use crate::arch::x86::{MTRR_ENABLE, MTRR_MEM_TYPE_WB, msr_index};
|
||||
|
||||
&[
|
||||
let mut boot_entries = self.feature_msrs.clone();
|
||||
|
||||
boot_entries.extend([
|
||||
msr!(msr_index::MSR_IA32_SYSENTER_CS),
|
||||
msr!(msr_index::MSR_IA32_SYSENTER_ESP),
|
||||
msr!(msr_index::MSR_IA32_SYSENTER_EIP),
|
||||
@@ -3567,7 +3569,9 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64
|
||||
),
|
||||
msr_data!(msr_index::MSR_MTRRdefType, MTRR_ENABLE | MTRR_MEM_TYPE_WB),
|
||||
]
|
||||
]);
|
||||
|
||||
boot_entries
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
|
||||
@@ -1564,10 +1564,10 @@ impl cpu::Vcpu for MshvVcpu {
|
||||
///
|
||||
/// Return the list of initial MSR entries for a VCPU
|
||||
///
|
||||
fn boot_msr_entries(&self) -> &'static [MsrEntry] {
|
||||
fn boot_msr_entries(&self) -> Vec<MsrEntry> {
|
||||
use crate::arch::x86::{MTRR_ENABLE, MTRR_MEM_TYPE_WB, msr_index};
|
||||
|
||||
&[
|
||||
vec![
|
||||
msr!(msr_index::MSR_IA32_SYSENTER_CS),
|
||||
msr!(msr_index::MSR_IA32_SYSENTER_ESP),
|
||||
msr!(msr_index::MSR_IA32_SYSENTER_EIP),
|
||||
|
||||
Reference in New Issue
Block a user