Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: AMD support larger extended function entries #4995

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions docs/cpu_templates/cpuid-normalization.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ See also: [boot protocol settings](boot-protocol.md)

## AMD-specifc CPUID normalization

| Description | Leaf | Subleaf | Register | Bits |
| ---------------------------------------------------- | :--------------------------------: | :-----: | :----------------: | :---: |
| Set IA32_ARCH_CAPABILITIES MSR as not present | 0x7 | - | EDX | 29 |
| Update largest extended function entry to 0x8000001f | 0x80000000 | - | EAX | 31:0 |
| Set topology extension bit | 0x80000001 | - | ECX | 22 |
| Update brand string with a default AMD value | 0x80000002, 0x80000003, 0x80000004 | - | EAX, EBX, ECX, EDX | all |
| Update number of physical threads | 0x80000008 | - | ECX | 7:0 |
| Update APIC ID size | 0x80000008 | - | ECX | 15:12 |
| Update cache topology information | 0x8000001d | all | all | all |
| Update extended APIC ID | 0x8000001e | - | EAX, EBX, ECX | all |
| Description | Leaf | Subleaf | Register | Bits |
| --------------------------------------------------------------------------------------- | :--------------------------------: | :-----: | :----------------: | :---: |
| Set IA32_ARCH_CAPABILITIES MSR as not present | 0x7 | - | EDX | 29 |
| Update largest extended function entry to largest between host cpu entry and 0x80000021 | 0x80000000 | - | EAX | 31:0 |
| Set topology extension bit | 0x80000001 | - | ECX | 22 |
| Update brand string with a default AMD value | 0x80000002, 0x80000003, 0x80000004 | - | EAX, EBX, ECX, EDX | all |
| Update number of physical threads | 0x80000008 | - | ECX | 7:0 |
| Update APIC ID size | 0x80000008 | - | ECX | 15:12 |
| Update cache topology information | 0x8000001d | all | all | all |
| Update extended APIC ID | 0x8000001e | - | EAX, EBX, ECX | all |
12 changes: 9 additions & 3 deletions src/vmm/src/cpu_config/x86_64/cpuid/amd/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,17 +184,23 @@ impl super::AmdCpuid {
/// Update largest extended fn entry.
#[allow(clippy::unwrap_used, clippy::unwrap_in_result)]
fn update_largest_extended_fn_entry(&mut self) -> Result<(), NormalizeCpuidError> {
// KVM sets the largest extended function to 0x80000000. Change it to 0x8000001f
// Since we also use the leaf 0x8000001d (Extended Cache Topology).
// KVM sets the largest extended function to 0x80000000. Change it to the largest
// between host CPU and 0x8000_0021. AMD notes that hypervisors should synthesize the value
// of both IBPB_BRTYPE and SBPB stored in leaf 0x8000_0021.
//
// https://www.amd.com/content/dam/amd/en/documents/corporate/cr/speculative-return-stack-overflow-whitepaper.pdf
let leaf_80000000 = self
.get_mut(&CpuidKey::leaf(0x80000000))
.ok_or(NormalizeCpuidError::MissingLeaf0x80000000)?;

// Take the largest between host cpu entry and 0x8000_0021
let extended_fn_entry = 0x8000_0021.max(get_range(cpuid(0x80000000).eax, 0..32));

// Largest extended function. The largest CPUID extended function input value supported by
// the processor implementation.
//
// l_func_ext: 0..32,
set_range(&mut leaf_80000000.result.eax, 0..32, 0x8000_001f).unwrap();
set_range(&mut leaf_80000000.result.eax, 0..32, extended_fn_entry).unwrap();
Ok(())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@
"modifiers": [
{
"register": "eax",
"bitmap": "0b10000000000000000000000000011111"
"bitmap": "0b10000000000000000000000000100011"
},
{
"register": "ebx",
Expand Down Expand Up @@ -1496,4 +1496,4 @@
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@
"modifiers": [
{
"register": "eax",
"bitmap": "0b10000000000000000000000000011111"
"bitmap": "0b10000000000000000000000000100011"
},
{
"register": "ebx",
Expand Down Expand Up @@ -1546,4 +1546,4 @@
}
]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,14 @@ def build_cpu_config_dict(cpu_config_path):
# https://github.com/torvalds/linux/commit/8765d75329a386dd7742f94a1ea5fdcdea8d93d0
(0x8000001B, 0x0),
(0x8000001C, 0x0),
(0x8000001F, 0x0),
# CPUID.80860000h is a Transmeta-specific leaf.
(0x80860000, 0x0),
# CPUID.C0000000h is a Centaur-specific leaf.
(0xC0000000, 0x0),
]

# An upper range of CPUID leaves which are not supported by our kernels
UNAVAILABLE_CPUID_UPPER_RANGE = range(0x8000001F, 0x80000029)

# Dictionary of CPUID bitmasks that should not be tested due to its mutability.
CPUID_EXCEPTION_LIST = {
Expand Down Expand Up @@ -281,6 +282,8 @@ def test_cpu_config_dump_vs_actual(
for key, actual in actual_cpu_config["cpuid"].items():
if (key[0], key[1]) in UNAVAILABLE_CPUID_ON_DUMP_LIST:
continue
if key[0] in UNAVAILABLE_CPUID_UPPER_RANGE:
continue
if key not in dump_cpu_config["cpuid"]:
keys_not_in_dump[key] = actual_cpu_config["cpuid"][key]
continue
Expand Down
Loading