Skip to content

Commit f13dd57

Browse files
Serban Iorgaacatangiu
authored andcommitted
AMD: set the total number of threads
We don't support more then 64 threads right now. It's safe to put them all on the same processor. Signed-off-by: Serban Iorga <[email protected]>
1 parent 8fe4aeb commit f13dd57

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

cpuid/src/cpu_leaf.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,21 @@ pub mod leaf_0x80000001 {
232232
pub const PDPE1GB_SHIFT: u32 = 26; // 1-GByte pages are available if 1.
233233
}
234234
}
235+
236+
pub mod leaf_0x80000008 {
237+
pub const LEAF_NUM: u32 = 0x8000_0008;
238+
239+
pub mod ecx {
240+
use bit_helper::BitRange;
241+
242+
// The number of bits in the initial ApicId value that indicate thread ID within a package
243+
// Possible values:
244+
// 0-3 -> Reserved
245+
// 4 -> 1 Die, up to 16 threads
246+
// 5 -> 2 Die, up to 32 threads
247+
// 6 -> 3,4 Die, up to 64 threads
248+
pub const THREAD_ID_SIZE_BITRANGE: BitRange = bit_range!(15, 12);
249+
// The number of threads in the package - 1
250+
pub const NUM_THREADS_BITRANGE: BitRange = bit_range!(7, 0);
251+
}
252+
}

cpuid/src/transformer/amd.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use transformer::common::use_host_cpuid_function;
1212

1313
// Largest extended function. It has to be larger then 0x8000001d (Extended Cache Topology).
1414
const LARGEST_EXTENDED_FN: u32 = 0x8000_001f;
15+
// This value allows at most 64 logical threads within a package.
16+
// See also the documentation for leaf_0x80000008::ecx::THREAD_ID_SIZE_BITRANGE
17+
const THREAD_ID_MAX_SIZE: u32 = 6;
1518

1619
pub fn update_structured_extended_entry(
1720
entry: &mut kvm_cpuid_entry2,
@@ -56,6 +59,22 @@ pub fn update_extended_feature_info_entry(
5659
Ok(())
5760
}
5861

62+
pub fn update_amd_features_entry(
63+
entry: &mut kvm_cpuid_entry2,
64+
vm_spec: &VmSpec,
65+
) -> Result<(), Error> {
66+
use cpu_leaf::leaf_0x80000008::*;
67+
68+
// We don't support more then 64 threads right now.
69+
// It's safe to put them all on the same processor.
70+
entry
71+
.ecx
72+
.write_bits_in_range(&ecx::THREAD_ID_SIZE_BITRANGE, THREAD_ID_MAX_SIZE)
73+
.write_bits_in_range(&ecx::NUM_THREADS_BITRANGE, u32::from(vm_spec.cpu_count - 1));
74+
75+
Ok(())
76+
}
77+
5978
pub fn update_extended_cache_topology_entry(
6079
entry: &mut kvm_cpuid_entry2,
6180
vm_spec: &VmSpec,
@@ -78,6 +97,7 @@ impl CpuidTransformer for AmdCpuidTransformer {
7897
leaf_0x7::LEAF_NUM => Some(amd::update_structured_extended_entry),
7998
leaf_0x80000000::LEAF_NUM => Some(amd::update_largest_extended_fn_entry),
8099
leaf_0x80000001::LEAF_NUM => Some(amd::update_extended_feature_info_entry),
100+
leaf_0x80000008::LEAF_NUM => Some(amd::update_amd_features_entry),
81101
leaf_0x8000001d::LEAF_NUM => Some(amd::update_extended_cache_topology_entry),
82102
0x8000_0002..=0x8000_0004 => Some(common::update_brand_string_entry),
83103
_ => None,
@@ -169,6 +189,33 @@ mod test {
169189
assert_eq!(entry.ecx.read_bit(ecx::TOPOEXT_INDEX), true);
170190
}
171191

192+
fn check_update_amd_features_entry(cpu_count: u8, ht_enabled: bool) {
193+
use cpu_leaf::leaf_0x80000008::*;
194+
195+
let vm_spec = VmSpec::new(VENDOR_ID_AMD, 0, cpu_count, ht_enabled);
196+
let mut entry = &mut kvm_cpuid_entry2 {
197+
function: LEAF_NUM,
198+
index: 0,
199+
flags: 0,
200+
eax: 0,
201+
ebx: 0,
202+
ecx: 0,
203+
edx: 0,
204+
padding: [0, 0, 0],
205+
};
206+
207+
assert!(update_amd_features_entry(&mut entry, &vm_spec).is_ok());
208+
209+
assert_eq!(
210+
entry.ecx.read_bits_in_range(&ecx::NUM_THREADS_BITRANGE),
211+
u32::from(cpu_count - 1)
212+
);
213+
assert_eq!(
214+
entry.ecx.read_bits_in_range(&ecx::THREAD_ID_SIZE_BITRANGE),
215+
THREAD_ID_MAX_SIZE
216+
);
217+
}
218+
172219
#[test]
173220
fn test_update_extended_cache_topology_entry() {
174221
let vm_spec = VmSpec::new(VENDOR_ID_AMD, 0, 1, false);
@@ -187,4 +234,24 @@ mod test {
187234

188235
assert_eq!(entry.flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX, 1);
189236
}
237+
238+
#[test]
239+
fn test_1vcpu_ht_off() {
240+
check_update_amd_features_entry(1, false);
241+
}
242+
243+
#[test]
244+
fn test_1vcpu_ht_on() {
245+
check_update_amd_features_entry(1, true);
246+
}
247+
248+
#[test]
249+
fn test_2vcpu_ht_off() {
250+
check_update_amd_features_entry(2, false);
251+
}
252+
253+
#[test]
254+
fn test_2vcpu_ht_on() {
255+
check_update_amd_features_entry(2, true);
256+
}
190257
}

0 commit comments

Comments
 (0)