Skip to content

Commit

Permalink
fix(vmm): disable IA32_ARCH_CAPABILITIES MSR on AMD
Browse files Browse the repository at this point in the history
Disable IA32_ARCH_CAPABILITIES MSR on AMD by disabling
CPUID.07H(ECX=0):EDX[bit 29].

This normalization was added in PR firecracker-microvm#1030, but was removed in PR firecracker-microvm#3076.

Signed-off-by: Takahiro Itazuri <[email protected]>
  • Loading branch information
zulinx86 authored and sladyn98 committed Jun 19, 2023
1 parent 1ec8c45 commit dae1fd7
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions src/vmm/src/guest_config/cpuid/amd/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub enum NormalizeCpuidError {
/// Failed to passthrough cache topology.
#[error("Failed to passthrough cache topology: {0}")]
PassthroughCacheTopology(#[from] PassthroughCacheTopologyError),
/// Missing leaf 0x7 / subleaf 0.
#[error("Missing leaf 0x7 / subleaf 0.")]
MissingLeaf0x7Subleaf0,
/// Missing leaf 0x80000000.
#[error("Missing leaf 0x80000000.")]
MissingLeaf0x80000000,
Expand Down Expand Up @@ -119,6 +122,7 @@ impl super::AmdCpuid {
cpus_per_core: u8,
) -> Result<(), NormalizeCpuidError> {
self.passthrough_cache_topology()?;
self.update_structured_extended_entry()?;
self.update_largest_extended_fn_entry()?;
self.update_extended_feature_fn_entry()?;
self.update_amd_feature_entry(cpu_count)?;
Expand Down Expand Up @@ -227,6 +231,20 @@ impl super::AmdCpuid {
Ok(())
}

// Update structured extended feature entry.
fn update_structured_extended_entry(&mut self) -> Result<(), NormalizeCpuidError> {
let leaf_7_subleaf_0 = self
.get_mut(&CpuidKey::subleaf(0x7, 0x0))
.ok_or(NormalizeCpuidError::MissingLeaf0x7Subleaf0)?;

// According to AMD64 Architecture Programmer’s Manual, IA32_ARCH_CAPABILITIES MSR is not
// available on AMD. The availability of IA32_ARCH_CAPABILITIES MSR is controlled via
// CPUID.07H(ECX=0):EDX[bit 29]. KVM sets this bit no matter what but this feature is not
// supported by hardware.
set_bit(&mut leaf_7_subleaf_0.result.edx, 29, false);
Ok(())
}

/// Update AMD feature entry.
#[allow(clippy::unwrap_used, clippy::unwrap_in_result)]
fn update_amd_feature_entry(&mut self, cpu_count: u8) -> Result<(), FeatureEntryError> {
Expand Down Expand Up @@ -408,3 +426,57 @@ impl super::AmdCpuid {
Ok(())
}
}

#[cfg(test)]
mod tests {

use std::collections::BTreeMap;

use super::*;
use crate::guest_config::cpuid::AmdCpuid;

#[test]
fn test_update_structured_extended_entry_invalid() {
// `update_structured_extended_entry()` should exit with MissingLeaf0x7Subleaf0 error for
// CPUID lacking leaf 0x7 / subleaf 0.
let mut cpuid = AmdCpuid(BTreeMap::new());
assert_eq!(
cpuid.update_structured_extended_entry().unwrap_err(),
NormalizeCpuidError::MissingLeaf0x7Subleaf0
);
}

#[test]
fn test_update_structured_extended_entry_valid() {
// `update_structured_extended_entry()` should succeed for CPUID having leaf 0x7 / subleaf
// 0, and bit 29 of EDX (IA32_ARCH_CAPABILITIES MSR enumeration) should be disabled.
let mut cpuid = AmdCpuid(BTreeMap::from([(
CpuidKey {
leaf: 0x7,
subleaf: 0x0,
},
CpuidEntry {
flags: KvmCpuidFlags::SIGNIFICANT_INDEX,
result: CpuidRegisters {
eax: 0,
ebx: 0,
ecx: 0,
edx: u32::MAX,
},
},
)]));
assert!(cpuid.update_structured_extended_entry().is_ok());
assert_eq!(
cpuid
.get(&CpuidKey {
leaf: 0x7,
subleaf: 0x0
})
.unwrap()
.result
.edx
& (1 << 29),
0
);
}
}

0 comments on commit dae1fd7

Please sign in to comment.