Skip to content

Commit

Permalink
fix(vmm): Set FDP_EXCPTN_ONLY and ZERO_FCS_FDS
Browse files Browse the repository at this point in the history
Sets FDP_EXCPTN_ONLY bit (CPUID.7h.0:EBX[6]) and ZERO_FCS_FDS bit
(CPUID.7h.0:EBX[13]) in Intel's CPUID normalization as recommended in
kernel doc. For more details, please refer to
https://lore.kernel.org/all/[email protected]/

Signed-off-by: Takahiro Itazuri <[email protected]>
  • Loading branch information
zulinx86 committed Jun 21, 2023
1 parent 2559e37 commit 71010a6
Show file tree
Hide file tree
Showing 20 changed files with 67 additions and 28 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

- Updated deserialization of `bitmap` for custom CPU templates to allow usage
of '_' as a separator.
- Set FDP_EXCPTN_ONLY bit (CPUID.7h.0:EBX[6]) and ZERO_FCS_FDS bit
(CPUID.7h.0:EBX[13]) in Intel's CPUID normalization process.

### Fixed

Expand Down
4 changes: 3 additions & 1 deletion docs/cpu_templates/cpuid-normalization.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ See also: [boot protocol settings](boot-protocol.md)
## Intel-specific CPUID normalization

| Description | Leaf | Subleaf | Register | Bits |
|----------------------------------------------------------------|:----------------------------------:|:-------:|:------------------:|:----:|
|----------------------------------------------------------------|:----------------------------------:|:-------:|:------------------:|:-----:|
| Update deterministic cache parameters | 0x4 | all | EAX | 31:14 |
| Disable Intel Turbo Boost technology | 0x6 | - | EAX | 1 |
| Disable frequency selection | 0x6 | - | ECX | 3 |
| Set FDP_EXCPTN_ONLY bit | 0x7 | 0x0 | EBX | 6 |
| Set "Deprecates FPU CS and FPU DS values" bit | 0x7 | 0x0 | EBX | 13 |
| Disable performance monitoring | 0xa | - | EAX, EBX, ECX, EDX | all |
| Update brand string to use a default format and real frequency | 0x80000002, 0x80000003, 0x80000004 | - | EAX, EBX, ECX, EDX | all |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
},
{
"register": "ebx",
"bitmap": "0b11010001100111110100011110101011"
"bitmap": "0b11010001100111110110011111101011"
},
{
"register": "ecx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
},
{
"register": "ebx",
"bitmap": "0b11010001100111110100011110101011"
"bitmap": "0b11010001100111110110011111101011"
},
{
"register": "ecx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
},
{
"register": "ebx",
"bitmap": "0b11110001101111110000011110101011"
"bitmap": "0b11110001101111110010011111101011"
},
{
"register": "ecx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
},
{
"register": "ebx",
"bitmap": "0b11110001101111110000011110101011"
"bitmap": "0b11110001101111110010011111101011"
},
{
"register": "ecx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
},
{
"register": "ebx",
"bitmap": "0b11010001100111110100111110111011"
"bitmap": "0b11010001100111110110111111111011"
},
{
"register": "ecx",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
},
{
"register": "ebx",
"bitmap": "0b11010001100111110100111110111011"
"bitmap": "0b11010001100111110110111111111011"
},
{
"register": "ecx",
Expand Down
2 changes: 1 addition & 1 deletion resources/tests/static_cpu_templates/c3.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"modifiers": [
{
"register": "ebx",
"bitmap": "0b000000000x0x000000x000x0x00000xx"
"bitmap": "0b000000000x0x000000x000x0xx0000xx"
},
{
"register": "ecx",
Expand Down
2 changes: 1 addition & 1 deletion resources/tests/static_cpu_templates/t2.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"modifiers": [
{
"register": "ebx",
"bitmap": "0b00000000000x000000000x1xx0x0x0xx"
"bitmap": "0b00000000000x000000x00x1xxxx0x0xx"
},
{
"register": "ecx",
Expand Down
2 changes: 1 addition & 1 deletion resources/tests/static_cpu_templates/t2a.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"modifiers": [
{
"register": "ebx",
"bitmap": "0b00000000000x000000000x1xx0x0x0xx"
"bitmap": "0b00000000000x000000x00x1xxxx0x0xx"
},
{
"register": "ecx",
Expand Down
2 changes: 1 addition & 1 deletion resources/tests/static_cpu_templates/t2cl.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"modifiers": [
{
"register": "ebx",
"bitmap": "0b00000000000x000000000x1xx0x0x0xx"
"bitmap": "0b00000000000x000000x00x1xxxx0x0xx"
},
{
"register": "ecx",
Expand Down
2 changes: 1 addition & 1 deletion resources/tests/static_cpu_templates/t2s.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"modifiers": [
{
"register": "ebx",
"bitmap": "0b00000000000x000000000x1xx0x0x0xx"
"bitmap": "0b00000000000x000000x00x1xxxx0x0xx"
},
{
"register": "ecx",
Expand Down
46 changes: 46 additions & 0 deletions src/vmm/src/cpu_config/x86_64/cpuid/intel/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub enum NormalizeCpuidError {
/// Leaf 0x6 is missing from CPUID.
#[error("Leaf 0x6 is missing from CPUID.")]
MissingLeaf6,
/// Leaf 0x7 / subleaf 0 is missing from CPUID.
#[error("Leaf 0x7 / subleaf 0 is missing from CPUID.")]
MissingLeaf7,
/// Leaf 0xA is missing from CPUID.
#[error("Leaf 0xA is missing from CPUID.")]
MissingLeafA,
Expand Down Expand Up @@ -85,6 +88,7 @@ impl super::IntelCpuid {
) -> Result<(), NormalizeCpuidError> {
self.update_deterministic_cache_entry(cpu_count, cpus_per_core)?;
self.update_power_management_entry()?;
self.update_extended_feature_flags_entry()?;
self.update_performance_monitoring_entry()?;
self.update_brand_string_entry()?;

Expand Down Expand Up @@ -197,6 +201,22 @@ impl super::IntelCpuid {
Ok(())
}

/// Update structured extended feature flags enumeration leaf
fn update_extended_feature_flags_entry(&mut self) -> Result<(), NormalizeCpuidError> {
let leaf_7_0 = self
.get_mut(&CpuidKey::subleaf(0x7, 0))
.ok_or(NormalizeCpuidError::MissingLeaf7)?;

// Set FDP_EXCPTN_ONLY bit (bit 6) and ZERO_FCS_FDS bit (bit 13) as recommended in kernel
// doc. These bits are reserved in AMD.
// https://lore.kernel.org/all/[email protected]/
// https://github.com/torvalds/linux/commit/45016721de3c714902c6f475b705e10ae0bdd801
set_bit(&mut leaf_7_0.result.ebx, 6, true);
set_bit(&mut leaf_7_0.result.ebx, 13, true);

Ok(())
}

/// Update performance monitoring entry
fn update_performance_monitoring_entry(&mut self) -> Result<(), NormalizeCpuidError> {
let leaf_a = self
Expand Down Expand Up @@ -422,4 +442,30 @@ mod tests {
}),
);
}

#[test]
fn test_update_extended_feature_flags_entry() {
let mut cpuid =
crate::cpu_config::x86_64::cpuid::IntelCpuid(std::collections::BTreeMap::from([(
crate::cpu_config::x86_64::cpuid::CpuidKey {
leaf: 0x7,
subleaf: 0,
},
crate::cpu_config::x86_64::cpuid::CpuidEntry {
flags: crate::cpu_config::x86_64::cpuid::KvmCpuidFlags::SIGNIFICANT_INDEX,
..Default::default()
},
)]));

cpuid.update_extended_feature_flags_entry().unwrap();

let leaf_7_0 = cpuid
.get(&crate::cpu_config::x86_64::cpuid::CpuidKey {
leaf: 0x7,
subleaf: 0,
})
.unwrap();
assert!((leaf_7_0.result.ebx & (1 << 6)) > 0);
assert!((leaf_7_0.result.ebx & (1 << 13)) > 0);
}
}
3 changes: 1 addition & 2 deletions src/vmm/src/cpu_config/x86_64/static_cpu_templates/c3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ pub fn c3() -> CustomCpuTemplate {
// - Bit 03: BMI1
// - Bit 04: HLE
// - Bit 05: AVX2
// - Bit 06: FDP_EXCPTN_ONLY
// - Bit 08: BMI2
// - Bit 10: INVPCID
// - Bit 11: RTM
Expand All @@ -152,7 +151,7 @@ pub fn c3() -> CustomCpuTemplate {
CpuidRegisterModifier {
register: CpuidRegister::Ebx,
bitmap: RegisterValueFilter {
filter: 0b1111_1111_1010_1111_1101_1101_0111_1100,
filter: 0b1111_1111_1010_1111_1101_1101_0011_1100,
value: 0b0000_0000_0000_0000_0000_0000_0000_0000,
},
},
Expand Down
4 changes: 1 addition & 3 deletions src/vmm/src/cpu_config/x86_64/static_cpu_templates/t2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,9 @@ pub fn t2() -> CustomCpuTemplate {
// EBX:
// - Bit 02: SGX
// - Bit 04: HLE
// - Bit 06: FDP_EXCPTN_ONLY
// - Bit 09: Enhanced REP MOVSB/STOSB
// - Bit 11: RTM
// - Bit 12: RDT-M
// - Bit 13: Deprecates FPU CS and FPU DS
// - Bit 14: MPX
// - Bit 15: RDT-A
// - Bit 16: AVX512F
Expand All @@ -153,7 +151,7 @@ pub fn t2() -> CustomCpuTemplate {
CpuidRegisterModifier {
register: CpuidRegister::Ebx,
bitmap: RegisterValueFilter {
filter: 0b1111_1111_1110_1111_1111_1010_0101_0100,
filter: 0b1111_1111_1110_1111_1101_1010_0001_0100,
value: 0b0000_0000_0000_0000_0000_0010_0000_0000,
},
},
Expand Down
4 changes: 1 addition & 3 deletions src/vmm/src/cpu_config/x86_64/static_cpu_templates/t2a.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ pub fn t2a() -> CustomCpuTemplate {
// EBX:
// - Bit 02: Reserved (AMD APM) / SGX (Intel SDM)
// - Bit 04: Reserved (AMD APM) / HLE (Intel SDM)
// - Bit 06: Reserved (AMD APM) / FDP_EXCPTN_ONLY (Intel SDM)
// - Bit 09: Reserved (AMD APM) / Enhanced REP MOVSB/STOSB (Intel SDM)
// - Bit 11: Reserved (AMD APM) / RTM (Intel SDM)
// - Bit 12: PQM (AMD APM) / RDT-M (Intel SDM)
// - Bit 13: Reserved (AMD APM) / Deprecates FPU CS and FPU DS (Intel SDM)
// - Bit 14: Reserved (AMD APM) / MPX (Intel SDM)
// - Bit 15: PQE (AMD APM) / RDT-A (Intel SDM)
// - Bit 16: Reserved (AMD APM) / AVX512F (Intel SDM)
Expand All @@ -112,7 +110,7 @@ pub fn t2a() -> CustomCpuTemplate {
CpuidRegisterModifier {
register: CpuidRegister::Ebx,
bitmap: RegisterValueFilter {
filter: 0b1111_1111_1110_1111_1111_1010_0101_0100,
filter: 0b1111_1111_1110_1111_1101_1010_0001_0100,
value: 0b0000_0000_0000_0000_0000_0010_0000_0000,
},
},
Expand Down
4 changes: 1 addition & 3 deletions src/vmm/src/cpu_config/x86_64/static_cpu_templates/t2cl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,9 @@ pub fn t2cl() -> CustomCpuTemplate {
// EBX:
// - Bit 02: SGX (Intel SDM) / Reserved (AMD APM)
// - Bit 04: HLE (Intel SDM) / Reserved (AMD APM)
// - Bit 06: FDP_EXCPTN_ONLY (Intel SDM) / Reserved (AMD APM)
// - Bit 09: Enhanced REP MOVSB/STOSB (Intel SDM) / Reserved (AMD APM)
// - Bit 11: RTM (Intel SDM) / Reserved (AMD APM)
// - Bit 12: RDT-M (Intel SDM) / PQM (AMD APM)
// - Bit 13: Deprecates FPU CS and FPU DS (Intel SDM) / Reserved (AMD APM)
// - Bit 14: MPX (Intel SDM) / Reserved (AMD APM)
// - Bit 15: RDT-A (Intel SDM) / PQE (AMD APM)
// - Bit 16: AVX512F (Intel SDM) / Reserved (AMD APM)
Expand All @@ -113,7 +111,7 @@ pub fn t2cl() -> CustomCpuTemplate {
CpuidRegisterModifier {
register: CpuidRegister::Ebx,
bitmap: RegisterValueFilter {
filter: 0b1111_1111_1110_1111_1111_1010_0101_0100,
filter: 0b1111_1111_1110_1111_1101_1010_0001_0100,
value: 0b0000_0000_0000_0000_0000_0010_0000_0000,
},
},
Expand Down
4 changes: 1 addition & 3 deletions src/vmm/src/cpu_config/x86_64/static_cpu_templates/t2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ pub fn t2s() -> CustomCpuTemplate {
// EBX:
// - Bit 02: SGX
// - Bit 04: HLE
// - Bit 06: FDP_EXCPTN_ONLY
// - Bit 09: Enhanced REP MOVSB/STOSB
// - Bit 11: RTM
// - Bit 12: RDT-M
// - Bit 13: Deprecates FPU CS and FPU DS
// - Bit 14: MPX
// - Bit 15: RDT-A
// - Bit 16: AVX512F
Expand All @@ -110,7 +108,7 @@ pub fn t2s() -> CustomCpuTemplate {
CpuidRegisterModifier {
register: CpuidRegister::Ebx,
bitmap: RegisterValueFilter {
filter: 0b1111_1111_1110_1111_1111_1010_0101_0100,
filter: 0b1111_1111_1110_1111_1101_1010_0001_0100,
value: 0b0000_0000_0000_0000_0000_0010_0000_0000,
},
},
Expand Down
2 changes: 0 additions & 2 deletions tests/integration_tests/functional/test_cpu_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,6 @@ def check_masked_features(test_microvm, cpu_template):
(1 << 3) | # BMI1
(1 << 4) | # HLE
(1 << 5) | # AVX2
(1 << 6) | # FPDP
(1 << 8) | # BMI2
(1 << 10) | # INVPCID
(1 << 11) | # RTM
Expand Down Expand Up @@ -907,7 +906,6 @@ def check_masked_features(test_microvm, cpu_template):
(0x7, 0x0, "ebx",
(1 << 2) | # SGX
(1 << 4) | # HLE
(1 << 6) | # FPDP
(1 << 11) | # RTM
(1 << 12) | # RDT_M
(1 << 14) | # MPX
Expand Down

0 comments on commit 71010a6

Please sign in to comment.