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@xxxxxxxxxx> --- 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