Skip to content

Commit 45e966f

Browse files
committed
KVM: x86: Do not return host topology information from KVM_GET_SUPPORTED_CPUID
Passing the host topology to the guest is almost certainly wrong and will confuse the scheduler. In addition, several fields of these CPUID leaves vary on each processor; it is simply impossible to return the right values from KVM_GET_SUPPORTED_CPUID in such a way that they can be passed to KVM_SET_CPUID2. The values that will most likely prevent confusion are all zeroes. Userspace will have to override it anyway if it wishes to present a specific topology to the guest. Cc: [email protected] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 74905e3 commit 45e966f

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8310,6 +8310,20 @@ CPU[EAX=1]:ECX[24] (TSC_DEADLINE) is not reported by ``KVM_GET_SUPPORTED_CPUID``
83108310
It can be enabled if ``KVM_CAP_TSC_DEADLINE_TIMER`` is present and the kernel
83118311
has enabled in-kernel emulation of the local APIC.
83128312

8313+
CPU topology
8314+
~~~~~~~~~~~~
8315+
8316+
Several CPUID values include topology information for the host CPU:
8317+
0x0b and 0x1f for Intel systems, 0x8000001e for AMD systems. Different
8318+
versions of KVM return different values for this information and userspace
8319+
should not rely on it. Currently they return all zeroes.
8320+
8321+
If userspace wishes to set up a guest topology, it should be careful that
8322+
the values of these three leaves differ for each CPU. In particular,
8323+
the APIC ID is found in EDX for all subleaves of 0x0b and 0x1f, and in EAX
8324+
for 0x8000001e; the latter also encodes the core id and node id in bits
8325+
7:0 of EBX and ECX respectively.
8326+
83138327
Obsolete ioctls and capabilities
83148328
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83158329

arch/x86/kvm/cpuid.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -770,16 +770,22 @@ struct kvm_cpuid_array {
770770
int nent;
771771
};
772772

773+
static struct kvm_cpuid_entry2 *get_next_cpuid(struct kvm_cpuid_array *array)
774+
{
775+
if (array->nent >= array->maxnent)
776+
return NULL;
777+
778+
return &array->entries[array->nent++];
779+
}
780+
773781
static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
774782
u32 function, u32 index)
775783
{
776-
struct kvm_cpuid_entry2 *entry;
784+
struct kvm_cpuid_entry2 *entry = get_next_cpuid(array);
777785

778-
if (array->nent >= array->maxnent)
786+
if (!entry)
779787
return NULL;
780788

781-
entry = &array->entries[array->nent++];
782-
783789
memset(entry, 0, sizeof(*entry));
784790
entry->function = function;
785791
entry->index = index;
@@ -956,22 +962,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
956962
entry->edx = edx.full;
957963
break;
958964
}
959-
/*
960-
* Per Intel's SDM, the 0x1f is a superset of 0xb,
961-
* thus they can be handled by common code.
962-
*/
963965
case 0x1f:
964966
case 0xb:
965967
/*
966-
* Populate entries until the level type (ECX[15:8]) of the
967-
* previous entry is zero. Note, CPUID EAX.{0x1f,0xb}.0 is
968-
* the starting entry, filled by the primary do_host_cpuid().
968+
* No topology; a valid topology is indicated by the presence
969+
* of subleaf 1.
969970
*/
970-
for (i = 1; entry->ecx & 0xff00; ++i) {
971-
entry = do_host_cpuid(array, function, i);
972-
if (!entry)
973-
goto out;
974-
}
971+
entry->eax = entry->ebx = entry->ecx = 0;
975972
break;
976973
case 0xd: {
977974
u64 permitted_xcr0 = kvm_caps.supported_xcr0 & xstate_get_guest_group_perm();
@@ -1202,6 +1199,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
12021199
entry->ebx = entry->ecx = entry->edx = 0;
12031200
break;
12041201
case 0x8000001e:
1202+
/* Do not return host topology information. */
1203+
entry->eax = entry->ebx = entry->ecx = 0;
1204+
entry->edx = 0; /* reserved */
12051205
break;
12061206
case 0x8000001F:
12071207
if (!kvm_cpu_cap_has(X86_FEATURE_SEV)) {

0 commit comments

Comments
 (0)