The function returns 'virCPUData' but doesn't do two important steps
which other code takes:
1) leaves with all-zero data is stripped from the XML output
2) the data is expected to be sorted in the array
Now the 'virHostCPUGetCPUID' helper returns both all 0 leaves and
doesn't order them as we expect.
If this is then used in conjunction with 'virCPUx86DataIsIdentical'
together with data which made a roundtrip to XML and back the result
will be always false even if the data itself is identical.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/cpu/cpu_x86.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 18e9cacfd0..7e9d1cea47 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -3354,16 +3354,17 @@ virCPUx86DataGetHost(void)
size_t i;
virCPUData *cpuid;
g_autofree struct kvm_cpuid2 *kvm_cpuid = NULL;
+ virCPUx86DataItem zero = { 0 };
if ((kvm_cpuid = virHostCPUGetCPUID()) == NULL)
return NULL;
cpuid = virCPUDataNew(virArchFromHost());
- cpuid->data.x86.len = kvm_cpuid->nent;
+ cpuid->data.x86.len = 0;
cpuid->data.x86.items = g_new0(virCPUx86DataItem, kvm_cpuid->nent);
for (i = 0; i < kvm_cpuid->nent; ++i) {
- virCPUx86DataItem *item = &cpuid->data.x86.items[i];
+ virCPUx86DataItem *item = &cpuid->data.x86.items[cpuid->data.x86.len];
item->type = VIR_CPU_X86_DATA_CPUID;
item->data.cpuid.eax_in = kvm_cpuid->entries[i].function;
item->data.cpuid.ecx_in = kvm_cpuid->entries[i].index;
@@ -3371,8 +3372,18 @@ virCPUx86DataGetHost(void)
item->data.cpuid.ebx = kvm_cpuid->entries[i].ebx;
item->data.cpuid.ecx = kvm_cpuid->entries[i].ecx;
item->data.cpuid.edx = kvm_cpuid->entries[i].edx;
+
+ /* skip all-zero leaves same as we do in the XML formatter */
+ if (virCPUx86DataItemMatch(item, &zero))
+ continue;
+
+ cpuid->data.x86.len++;
}
+ /* the rest of the code expects the function to be in order */
+ qsort(cpuid->data.x86.items, cpuid->data.x86.len,
+ sizeof(virCPUx86DataItem), virCPUx86DataSorter);
+
return cpuid;
}
#endif
--
2.35.1