Skip to content

Commit 4d04f8c

Browse files
cpuid: Mask the Cache Topology
... in order to match the user configured number of vCPUs. Signed-off-by: Andreea Florescu <[email protected]>
1 parent ea6d700 commit 4d04f8c

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

vmm/src/vstate.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ const ECX_HYPERVISOR_SHIFT: u32 = 31; // Flag to be set when the cpu is running
133133
const ECX_LEVEL_TYPE_SHIFT: u32 = 8; // Shift for setting level type for leaf 11
134134
const EDX_HTT_SHIFT: u32 = 28; // Hyper Threading Enabled.
135135

136+
// Deterministic Cache Parameters Leaf
137+
const EAX_CACHE_LEVEL: u32 = 5;
138+
const EAX_MAX_ADDR_IDS_SHARING_CACHE: u32 = 14;
139+
const EAX_MAX_ADDR_IDS_IN_PACKAGE: u32 = 26;
140+
136141
const LEAFBH_LEVEL_TYPE_INVALID: u32 = 0;
137142
const LEAFBH_LEVEL_TYPE_THREAD: u32 = 1;
138143
const LEAFBH_LEVEL_TYPE_CORE: u32 = 2;
@@ -199,6 +204,48 @@ impl Vcpu {
199204
entry.edx |= 1 << EDX_HTT_SHIFT;
200205
}
201206
}
207+
4 => {
208+
// Deterministic Cache Parameters Leaf
209+
// Only use the last 3 bits of EAX[5:32] because the level is encoded in EAX[5:7]
210+
let cache_level = (entry.eax >> EAX_CACHE_LEVEL) & (0b111 as u32);
211+
match cache_level {
212+
// L1 & L2 Cache
213+
1 | 2 => {
214+
// Set the maximum addressable IDS sharing the data cache to zero
215+
// when you only have 1 vcpu because there are no other threads on
216+
// the machine to share the data/instruction cache
217+
// This sets EAX[25:14]
218+
entry.eax &= !(0b111111111111 << EAX_MAX_ADDR_IDS_SHARING_CACHE);
219+
if cpu_count > 1 {
220+
// Hyperthreading is enabled by default for vcpu_count > 2
221+
entry.eax |= 1 << EAX_MAX_ADDR_IDS_SHARING_CACHE;
222+
}
223+
}
224+
// L3 Cache
225+
3 => {
226+
// Set the maximum addressable IDS sharing the data cache to zero
227+
// when you only have 1 vcpu because there are no other threads on
228+
// the machine to share the data/instruction cache
229+
// This sets EAX[25:14]
230+
entry.eax &= !(0b111111111111 << EAX_MAX_ADDR_IDS_SHARING_CACHE);
231+
if cpu_count > 1 {
232+
entry.eax |=
233+
((cpu_count - 1) as u32) << EAX_MAX_ADDR_IDS_SHARING_CACHE;
234+
}
235+
}
236+
_ => (),
237+
}
238+
239+
// Maximum number of addressable IDs for processor cores in the physical package
240+
// should be the same on all cache levels
241+
// set this to 0 because there is only 1 core available for vcpu_count <= 2
242+
// This sets EAX[31:26]
243+
entry.eax &= !(0b111111 << EAX_MAX_ADDR_IDS_IN_PACKAGE);
244+
if cpu_count > 2 {
245+
// we have HT enabled by default, so we will have cpu_count/2 cores in package
246+
entry.eax |= (((cpu_count >> 1) - 1) as u32) << EAX_MAX_ADDR_IDS_IN_PACKAGE;
247+
}
248+
}
202249
6 => {
203250
// Clear X86 EPB feature. No frequency selection in the hypervisor.
204251
entry.ecx &= !(1 << ECX_EPB_SHIFT);

0 commit comments

Comments
 (0)