Skip to content

Commit df9ddc9

Browse files
committed
Edit CPUID Normalization to account for possibility of hotplugging
Changes some of the CPUID leaves to account for the possibility of hotplugged vCPUs. Previously, the maximum APIC address space and L3 cache were only shared between boot_cpus. Whereas, now we want this to be extended for the maximum number of CPUs that can be added, MAX_SUPPORTED_VCPUS. Signed-off-by: James Curtis <[email protected]>
1 parent eeefec4 commit df9ddc9

14 files changed

+91
-100
lines changed

Diff for: src/vmm/src/cpu_config/x86_64/cpuid/amd/normalize.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::cpu_config::x86_64::cpuid::{
99
cpuid, cpuid_count, CpuidEntry, CpuidKey, CpuidRegisters, CpuidTrait, KvmCpuidFlags,
1010
MissingBrandStringLeaves, BRAND_STRING_LENGTH, VENDOR_ID_AMD,
1111
};
12+
use crate::vmm_config::machine_config::MAX_SUPPORTED_VCPUS;
1213

1314
/// Error type for [`super::AmdCpuid::normalize`].
1415
#[allow(clippy::module_name_repetitions)]
@@ -107,7 +108,7 @@ impl super::AmdCpuid {
107108
self.update_largest_extended_fn_entry()?;
108109
self.update_extended_feature_fn_entry()?;
109110
self.update_amd_feature_entry(cpu_count)?;
110-
self.update_extended_cache_topology_entry(cpu_count, cpus_per_core)?;
111+
self.update_extended_cache_topology_entry(cpus_per_core)?;
111112
self.update_extended_apic_id_entry(cpu_index, cpus_per_core)?;
112113
self.update_brand_string_entry()?;
113114

@@ -268,7 +269,6 @@ impl super::AmdCpuid {
268269
#[allow(clippy::unwrap_in_result, clippy::unwrap_used)]
269270
fn update_extended_cache_topology_entry(
270271
&mut self,
271-
cpu_count: u8,
272272
cpus_per_core: u8,
273273
) -> Result<(), ExtendedCacheTopologyError> {
274274
for i in 0.. {
@@ -312,7 +312,7 @@ impl super::AmdCpuid {
312312
// L3 Cache
313313
// The L3 cache is shared among all the logical threads
314314
3 => {
315-
let sub = cpu_count
315+
let sub = MAX_SUPPORTED_VCPUS
316316
.checked_sub(1)
317317
.ok_or(ExtendedCacheTopologyError::NumSharingCacheOverflow)?;
318318
set_range(&mut subleaf.result.eax, 14..26, u32::from(sub))

Diff for: src/vmm/src/cpu_config/x86_64/cpuid/intel/normalize.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::cpu_config::x86_64::cpuid::{
88
host_brand_string, CpuidKey, CpuidRegisters, CpuidTrait, MissingBrandStringLeaves,
99
BRAND_STRING_LENGTH,
1010
};
11+
use crate::vmm_config::machine_config::MAX_SUPPORTED_VCPUS;
1112

1213
/// Error type for [`super::IntelCpuid::normalize`].
1314
#[derive(Debug, thiserror::Error, displaydoc::Display, Eq, PartialEq)]
@@ -62,14 +63,10 @@ impl super::IntelCpuid {
6263
#[inline]
6364
pub fn normalize(
6465
&mut self,
65-
// The index of the current logical CPU in the range [0..cpu_count].
66-
_cpu_index: u8,
67-
// The total number of logical CPUs.
68-
cpu_count: u8,
6966
// The number of logical CPUs per core.
7067
cpus_per_core: u8,
7168
) -> Result<(), NormalizeCpuidError> {
72-
self.update_deterministic_cache_entry(cpu_count, cpus_per_core)?;
69+
self.update_deterministic_cache_entry(cpus_per_core)?;
7370
self.update_power_management_entry()?;
7471
self.update_extended_feature_flags_entry()?;
7572
self.update_performance_monitoring_entry()?;
@@ -82,7 +79,6 @@ impl super::IntelCpuid {
8279
#[allow(clippy::unwrap_in_result)]
8380
fn update_deterministic_cache_entry(
8481
&mut self,
85-
cpu_count: u8,
8682
cpus_per_core: u8,
8783
) -> Result<(), DeterministicCacheError> {
8884
for i in 0.. {
@@ -125,7 +121,7 @@ impl super::IntelCpuid {
125121
// The L3 cache is shared among all the logical threads
126122
3 => {
127123
let sub = u32::from(
128-
cpu_count
124+
MAX_SUPPORTED_VCPUS
129125
.checked_sub(1)
130126
.ok_or(DeterministicCacheError::MaxCpusPerCoreUnderflow)?,
131127
);
@@ -137,7 +133,7 @@ impl super::IntelCpuid {
137133

138134
// We know `cpus_per_core !=0` therefore this is always safe.
139135
#[allow(clippy::unwrap_used)]
140-
let cores = cpu_count.checked_div(cpus_per_core).unwrap();
136+
let cores = MAX_SUPPORTED_VCPUS.checked_div(cpus_per_core).unwrap();
141137

142138
// Maximum number of addressable IDs for processor cores in the physical package.
143139
// - Add one to the return value to get the result.

Diff for: src/vmm/src/cpu_config/x86_64/cpuid/normalize.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use crate::cpu_config::x86_64::cpuid::{
55
cpuid, CpuidEntry, CpuidKey, CpuidRegisters, CpuidTrait, KvmCpuidFlags,
66
};
7+
use crate::vmm_config::machine_config::MAX_SUPPORTED_VCPUS;
78

89
/// Error type for [`super::Cpuid::normalize`].
910
#[allow(clippy::module_name_repetitions)]
@@ -182,15 +183,15 @@ impl super::Cpuid {
182183
.checked_shl(u32::from(cpu_bits))
183184
.ok_or(NormalizeCpuidError::CpuBits(cpu_bits))?;
184185
self.update_vendor_id()?;
185-
self.update_feature_info_entry(cpu_index, cpu_count)?;
186-
self.update_extended_topology_entry(cpu_index, cpu_count, cpu_bits, cpus_per_core)?;
186+
self.update_feature_info_entry(cpu_index)?;
187+
self.update_extended_topology_entry(cpu_index, cpu_bits, cpus_per_core)?;
187188
self.update_extended_cache_features()?;
188189

189190
// Apply manufacturer specific modifications.
190191
match self {
191192
// Apply Intel specific modifications.
192193
Self::Intel(intel_cpuid) => {
193-
intel_cpuid.normalize(cpu_index, cpu_count, cpus_per_core)?;
194+
intel_cpuid.normalize(cpus_per_core)?;
194195
}
195196
// Apply AMD specific modifications.
196197
Self::Amd(amd_cpuid) => amd_cpuid.normalize(cpu_index, cpu_count, cpus_per_core)?,
@@ -216,11 +217,7 @@ impl super::Cpuid {
216217
}
217218

218219
// Update feature information entry
219-
fn update_feature_info_entry(
220-
&mut self,
221-
cpu_index: u8,
222-
cpu_count: u8,
223-
) -> Result<(), FeatureInformationError> {
220+
fn update_feature_info_entry(&mut self, cpu_index: u8) -> Result<(), FeatureInformationError> {
224221
// Flush a cache line size.
225222
const EBX_CLFLUSH_CACHELINE: u32 = 8;
226223

@@ -268,7 +265,7 @@ impl super::Cpuid {
268265
.map_err(FeatureInformationError::Clflush)?;
269266

270267
let max_cpus_per_package = u32::from(
271-
get_max_cpus_per_package(cpu_count)
268+
get_max_cpus_per_package(MAX_SUPPORTED_VCPUS)
272269
.map_err(FeatureInformationError::GetMaxCpusPerPackage)?,
273270
);
274271

@@ -294,7 +291,7 @@ impl super::Cpuid {
294291
// A value of 1 for HTT indicates the value in CPUID.1.EBX[23:16]
295292
// (the Maximum number of addressable IDs for logical processors in this package)
296293
// is valid for the package
297-
set_bit(&mut leaf_1.result.edx, 28, cpu_count > 1);
294+
set_bit(&mut leaf_1.result.edx, 28, true);
298295

299296
Ok(())
300297
}
@@ -303,7 +300,6 @@ impl super::Cpuid {
303300
fn update_extended_topology_entry(
304301
&mut self,
305302
cpu_index: u8,
306-
cpu_count: u8,
307303
cpu_bits: u8,
308304
cpus_per_core: u8,
309305
) -> Result<(), ExtendedTopologyError> {
@@ -408,8 +404,12 @@ impl super::Cpuid {
408404
set_range(&mut subleaf.result.eax, 0..5, LEAFBH_INDEX1_APICID)
409405
.map_err(ExtendedTopologyError::ApicId)?;
410406

411-
set_range(&mut subleaf.result.ebx, 0..16, u32::from(cpu_count))
412-
.map_err(ExtendedTopologyError::LogicalProcessors)?;
407+
set_range(
408+
&mut subleaf.result.ebx,
409+
0..16,
410+
u32::from(MAX_SUPPORTED_VCPUS),
411+
)
412+
.map_err(ExtendedTopologyError::LogicalProcessors)?;
413413

414414
// We expect here as this is an extremely rare case that is unlikely to ever
415415
// occur. It would require manual editing of the CPUID structure to push
@@ -577,12 +577,7 @@ mod tests {
577577
},
578578
},
579579
)])));
580-
let result = intel_cpuid.update_extended_topology_entry(
581-
cpu_index,
582-
cpu_count,
583-
cpu_bits,
584-
cpus_per_core,
585-
);
580+
let result = intel_cpuid.update_extended_topology_entry(cpu_index, cpu_bits, cpus_per_core);
586581
result.unwrap();
587582
assert!(intel_cpuid.inner().contains_key(&CpuidKey {
588583
leaf: 0xb,
@@ -605,8 +600,7 @@ mod tests {
605600
},
606601
},
607602
)])));
608-
let result =
609-
amd_cpuid.update_extended_topology_entry(cpu_index, cpu_count, cpu_bits, cpus_per_core);
603+
let result = amd_cpuid.update_extended_topology_entry(cpu_index, cpu_bits, cpus_per_core);
610604
result.unwrap();
611605
assert!(amd_cpuid.inner().contains_key(&CpuidKey {
612606
leaf: 0xb,

Diff for: tests/data/cpu_template_helper/fingerprint_AMD_MILAN_5.10host.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@
4141
},
4242
{
4343
"register": "ebx",
44-
"bitmap": "0b00000000000000010000100000000000"
44+
"bitmap": "0b00000000001000000000100000000000"
4545
},
4646
{
4747
"register": "ecx",
4848
"bitmap": "0b11110111111110100011001000000011"
4949
},
5050
{
5151
"register": "edx",
52-
"bitmap": "0b00000111100010111111101111111111"
52+
"bitmap": "0b00010111100010111111101111111111"
5353
}
5454
]
5555
},
@@ -294,7 +294,7 @@
294294
},
295295
{
296296
"register": "ebx",
297-
"bitmap": "0b00000000000000000000000000000001"
297+
"bitmap": "0b00000000000000000000000000100000"
298298
},
299299
{
300300
"register": "ecx",
@@ -1279,7 +1279,7 @@
12791279
"modifiers": [
12801280
{
12811281
"register": "eax",
1282-
"bitmap": "0b00000000000000000000000101100011"
1282+
"bitmap": "0b00000000000001111100000101100011"
12831283
},
12841284
{
12851285
"register": "ebx",
@@ -1496,4 +1496,4 @@
14961496
}
14971497
]
14981498
}
1499-
}
1499+
}

Diff for: tests/data/cpu_template_helper/fingerprint_AMD_MILAN_6.1host.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@
4141
},
4242
{
4343
"register": "ebx",
44-
"bitmap": "0b00000000000000010000100000000000"
44+
"bitmap": "0b00000000001000000000100000000000"
4545
},
4646
{
4747
"register": "ecx",
4848
"bitmap": "0b11110111111110100011001000000011"
4949
},
5050
{
5151
"register": "edx",
52-
"bitmap": "0b00000111100010111111101111111111"
52+
"bitmap": "0b00010111100010111111101111111111"
5353
}
5454
]
5555
},
@@ -294,7 +294,7 @@
294294
},
295295
{
296296
"register": "ebx",
297-
"bitmap": "0b00000000000000000000000000000001"
297+
"bitmap": "0b00000000000000000000000000100000"
298298
},
299299
{
300300
"register": "ecx",
@@ -1279,7 +1279,7 @@
12791279
"modifiers": [
12801280
{
12811281
"register": "eax",
1282-
"bitmap": "0b00000000000000000000000101100011"
1282+
"bitmap": "0b00000000000001111100000101100011"
12831283
},
12841284
{
12851285
"register": "ebx",
@@ -1546,4 +1546,4 @@
15461546
}
15471547
]
15481548
}
1549-
}
1549+
}

Diff for: tests/data/cpu_template_helper/fingerprint_INTEL_CASCADELAKE_5.10host.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@
4141
},
4242
{
4343
"register": "ebx",
44-
"bitmap": "0b00000000000000010000100000000000"
44+
"bitmap": "0b00000000001000000000100000000000"
4545
},
4646
{
4747
"register": "ecx",
4848
"bitmap": "0b11110111111110100011001000100011"
4949
},
5050
{
5151
"register": "edx",
52-
"bitmap": "0b00001111100010111111101111111111"
52+
"bitmap": "0b00011111100010111111101111111111"
5353
}
5454
]
5555
},
@@ -106,7 +106,7 @@
106106
"modifiers": [
107107
{
108108
"register": "eax",
109-
"bitmap": "0b00000000000000000000000100100001"
109+
"bitmap": "0b01111100000000000000000100100001"
110110
},
111111
{
112112
"register": "ebx",
@@ -129,7 +129,7 @@
129129
"modifiers": [
130130
{
131131
"register": "eax",
132-
"bitmap": "0b00000000000000000000000100100010"
132+
"bitmap": "0b01111100000000000000000100100010"
133133
},
134134
{
135135
"register": "ebx",
@@ -152,7 +152,7 @@
152152
"modifiers": [
153153
{
154154
"register": "eax",
155-
"bitmap": "0b00000000000000000000000101000011"
155+
"bitmap": "0b01111100000000000000000101000011"
156156
},
157157
{
158158
"register": "ebx",
@@ -175,7 +175,7 @@
175175
"modifiers": [
176176
{
177177
"register": "eax",
178-
"bitmap": "0b00000000000000000000000101100011"
178+
"bitmap": "0b01111100000001111100000101100011"
179179
},
180180
{
181181
"register": "ebx",
@@ -386,7 +386,7 @@
386386
},
387387
{
388388
"register": "ebx",
389-
"bitmap": "0b00000000000000000000000000000001"
389+
"bitmap": "0b00000000000000000000000000100000"
390390
},
391391
{
392392
"register": "ecx",
@@ -1224,4 +1224,4 @@
12241224
}
12251225
]
12261226
}
1227-
}
1227+
}

0 commit comments

Comments
 (0)