]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virCPUx86DataGetHost: Fix construction of the returned data
authorPeter Krempa <pkrempa@redhat.com>
Mon, 25 Apr 2022 12:47:26 +0000 (14:47 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 25 Apr 2022 14:38:01 +0000 (16:38 +0200)
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@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/cpu/cpu_x86.c

index 18e9cacfd06af78a667bf8ae21746b1485ecd91e..7e9d1cea47d1dbd18018cf4a1cd7a9974b7d44d3 100644 (file)
@@ -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