Pablo Greco 40546a
From 891f6c594088c787c92279af08ba0ab037492bdd Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <891f6c594088c787c92279af08ba0ab037492bdd@dist-git>
Pablo Greco 40546a
From: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Date: Fri, 21 Jun 2019 09:25:22 +0200
Pablo Greco 40546a
Subject: [PATCH] cpu_x86: Introduce virCPUx86DataItem container struct
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
The following patches introduce CPU features read from MSR in addition
Pablo Greco 40546a
to those queried via CPUID instruction. Let's introduce a container
Pablo Greco 40546a
struct which will be able to describe either feature type.
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
(cherry picked from commit 3673269e3aa22566f87e06a2b10dbc3b20110f84)
Pablo Greco 40546a
Pablo Greco 40546a
https://bugzilla.redhat.com/show_bug.cgi?id=1697627
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Message-Id: <161419b9968304180f18b33e6dc29ba70d9174d0.1561068591.git.jdenemar@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/cpu/cpu_x86.c              | 312 ++++++++++++++++++---------------
Pablo Greco 40546a
 src/cpu/cpu_x86.h              |   2 +-
Pablo Greco 40546a
 src/cpu/cpu_x86_data.h         |   9 +-
Pablo Greco 40546a
 src/libxl/libxl_capabilities.c |   8 +-
Pablo Greco 40546a
 src/qemu/qemu_monitor_json.c   |   6 +-
Pablo Greco 40546a
 5 files changed, 183 insertions(+), 154 deletions(-)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
Pablo Greco 40546a
index 98e8d608d6..2e953eaa12 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_x86.c
Pablo Greco 40546a
+++ b/src/cpu/cpu_x86.c
Pablo Greco 40546a
@@ -49,7 +49,7 @@ typedef struct _virCPUx86Vendor virCPUx86Vendor;
Pablo Greco 40546a
 typedef virCPUx86Vendor *virCPUx86VendorPtr;
Pablo Greco 40546a
 struct _virCPUx86Vendor {
Pablo Greco 40546a
     char *name;
Pablo Greco 40546a
-    virCPUx86CPUID cpuid;
Pablo Greco 40546a
+    virCPUx86DataItem cpuid;
Pablo Greco 40546a
 };
Pablo Greco 40546a
 
Pablo Greco 40546a
 typedef struct _virCPUx86Feature virCPUx86Feature;
Pablo Greco 40546a
@@ -61,17 +61,19 @@ struct _virCPUx86Feature {
Pablo Greco 40546a
 };
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
+#define CPUID(...) { .cpuid = {__VA_ARGS__} }
Pablo Greco 40546a
+
Pablo Greco 40546a
 #define KVM_FEATURE_DEF(Name, Eax_in, Eax) \
Pablo Greco 40546a
-    static virCPUx86CPUID Name ## _cpuid[] = { \
Pablo Greco 40546a
-        { .eax_in = Eax_in, .eax = Eax }, \
Pablo Greco 40546a
+    static virCPUx86DataItem Name ## _data[] = { \
Pablo Greco 40546a
+        CPUID(.eax_in = Eax_in, .eax = Eax), \
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
 #define KVM_FEATURE(Name) \
Pablo Greco 40546a
     { \
Pablo Greco 40546a
         .name = (char *) Name, \
Pablo Greco 40546a
         .data = { \
Pablo Greco 40546a
-            .len = ARRAY_CARDINALITY(Name ## _cpuid), \
Pablo Greco 40546a
-            .data = Name ## _cpuid \
Pablo Greco 40546a
+            .len = ARRAY_CARDINALITY(Name ## _data), \
Pablo Greco 40546a
+            .items = Name ## _data, \
Pablo Greco 40546a
         } \
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -286,17 +288,17 @@ x86FeatureFindInternal(const char *name)
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 virCPUx86CPUIDSorter(const void *a, const void *b)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID *da = (virCPUx86CPUID *) a;
Pablo Greco 40546a
-    virCPUx86CPUID *db = (virCPUx86CPUID *) b;
Pablo Greco 40546a
+    virCPUx86DataItemPtr da = (virCPUx86DataItemPtr) a;
Pablo Greco 40546a
+    virCPUx86DataItemPtr db = (virCPUx86DataItemPtr) b;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (da->eax_in > db->eax_in)
Pablo Greco 40546a
+    if (da->cpuid.eax_in > db->cpuid.eax_in)
Pablo Greco 40546a
         return 1;
Pablo Greco 40546a
-    else if (da->eax_in < db->eax_in)
Pablo Greco 40546a
+    else if (da->cpuid.eax_in < db->cpuid.eax_in)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (da->ecx_in > db->ecx_in)
Pablo Greco 40546a
+    if (da->cpuid.ecx_in > db->cpuid.ecx_in)
Pablo Greco 40546a
         return 1;
Pablo Greco 40546a
-    else if (da->ecx_in < db->ecx_in)
Pablo Greco 40546a
+    else if (da->cpuid.ecx_in < db->cpuid.ecx_in)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -304,7 +306,7 @@ virCPUx86CPUIDSorter(const void *a, const void *b)
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 /* skips all zero CPUID leaves */
Pablo Greco 40546a
-static virCPUx86CPUID *
Pablo Greco 40546a
+static virCPUx86DataItemPtr
Pablo Greco 40546a
 x86DataCpuidNext(virCPUx86DataIteratorPtr iterator)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     const virCPUx86Data *data = iterator->data;
Pablo Greco 40546a
@@ -313,24 +315,26 @@ x86DataCpuidNext(virCPUx86DataIteratorPtr iterator)
Pablo Greco 40546a
         return NULL;
Pablo Greco 40546a
 
Pablo Greco 40546a
     while (++iterator->pos < data->len) {
Pablo Greco 40546a
-        if (!x86cpuidMatch(data->data + iterator->pos, &cpuidNull))
Pablo Greco 40546a
-            return data->data + iterator->pos;
Pablo Greco 40546a
+        virCPUx86DataItemPtr item = data->items + iterator->pos;
Pablo Greco 40546a
+
Pablo Greco 40546a
+        if (!x86cpuidMatch(&item->cpuid, &cpuidNull))
Pablo Greco 40546a
+            return item;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     return NULL;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static virCPUx86CPUID *
Pablo Greco 40546a
+static virCPUx86DataItemPtr
Pablo Greco 40546a
 x86DataCpuid(const virCPUx86Data *data,
Pablo Greco 40546a
-             const virCPUx86CPUID *cpuid)
Pablo Greco 40546a
+             const virCPUx86DataItem *cpuid)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < data->len; i++) {
Pablo Greco 40546a
-        if (data->data[i].eax_in == cpuid->eax_in &&
Pablo Greco 40546a
-            data->data[i].ecx_in == cpuid->ecx_in)
Pablo Greco 40546a
-            return data->data + i;
Pablo Greco 40546a
+        if (data->items[i].cpuid.eax_in == cpuid->cpuid.eax_in &&
Pablo Greco 40546a
+            data->items[i].cpuid.ecx_in == cpuid->cpuid.ecx_in)
Pablo Greco 40546a
+            return data->items + i;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     return NULL;
Pablo Greco 40546a
@@ -342,7 +346,7 @@ virCPUx86DataClear(virCPUx86Data *data)
Pablo Greco 40546a
     if (!data)
Pablo Greco 40546a
         return;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    VIR_FREE(data->data);
Pablo Greco 40546a
+    VIR_FREE(data->items);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -362,12 +366,12 @@ x86DataCopy(virCPUx86Data *dst, const virCPUx86Data *src)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (VIR_ALLOC_N(dst->data, src->len) < 0)
Pablo Greco 40546a
+    if (VIR_ALLOC_N(dst->items, src->len) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     dst->len = src->len;
Pablo Greco 40546a
     for (i = 0; i < src->len; i++)
Pablo Greco 40546a
-        dst->data[i] = src->data[i];
Pablo Greco 40546a
+        dst->items[i] = src->items[i];
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -375,19 +379,19 @@ x86DataCopy(virCPUx86Data *dst, const virCPUx86Data *src)
Pablo Greco 40546a
 
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 virCPUx86DataAddCPUIDInt(virCPUx86Data *data,
Pablo Greco 40546a
-                         const virCPUx86CPUID *cpuid)
Pablo Greco 40546a
+                         const virCPUx86DataItem *cpuid)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID *existing;
Pablo Greco 40546a
+    virCPUx86DataItemPtr existing;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if ((existing = x86DataCpuid(data, cpuid))) {
Pablo Greco 40546a
-        x86cpuidSetBits(existing, cpuid);
Pablo Greco 40546a
+        x86cpuidSetBits(&existing->cpuid, &cpuid->cpuid);
Pablo Greco 40546a
     } else {
Pablo Greco 40546a
-        if (VIR_APPEND_ELEMENT_COPY(data->data, data->len,
Pablo Greco 40546a
-                                    *((virCPUx86CPUID *)cpuid)) < 0)
Pablo Greco 40546a
+        if (VIR_APPEND_ELEMENT_COPY(data->items, data->len,
Pablo Greco 40546a
+                                    *((virCPUx86DataItemPtr)cpuid)) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-        qsort(data->data, data->len,
Pablo Greco 40546a
-              sizeof(virCPUx86CPUID), virCPUx86CPUIDSorter);
Pablo Greco 40546a
+        qsort(data->items, data->len,
Pablo Greco 40546a
+              sizeof(virCPUx86DataItem), virCPUx86CPUIDSorter);
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -399,14 +403,14 @@ x86DataAdd(virCPUx86Data *data1,
Pablo Greco 40546a
            const virCPUx86Data *data2)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data2);
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid1;
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid2;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid1;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid2;
Pablo Greco 40546a
 
Pablo Greco 40546a
     while ((cpuid2 = x86DataCpuidNext(&iter))) {
Pablo Greco 40546a
         cpuid1 = x86DataCpuid(data1, cpuid2);
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (cpuid1) {
Pablo Greco 40546a
-            x86cpuidSetBits(cpuid1, cpuid2);
Pablo Greco 40546a
+            x86cpuidSetBits(&cpuid1->cpuid, &cpuid2->cpuid);
Pablo Greco 40546a
         } else {
Pablo Greco 40546a
             if (virCPUx86DataAddCPUIDInt(data1, cpuid2) < 0)
Pablo Greco 40546a
                 return -1;
Pablo Greco 40546a
@@ -422,12 +426,12 @@ x86DataSubtract(virCPUx86Data *data1,
Pablo Greco 40546a
                 const virCPUx86Data *data2)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1);
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid1;
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid2;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid1;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid2;
Pablo Greco 40546a
 
Pablo Greco 40546a
     while ((cpuid1 = x86DataCpuidNext(&iter))) {
Pablo Greco 40546a
-        cpuid2 = x86DataCpuid(data2, cpuid1);
Pablo Greco 40546a
-        x86cpuidClearBits(cpuid1, cpuid2);
Pablo Greco 40546a
+        if ((cpuid2 = x86DataCpuid(data2, cpuid1)))
Pablo Greco 40546a
+            x86cpuidClearBits(&cpuid1->cpuid, &cpuid2->cpuid);
Pablo Greco 40546a
     }
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -437,15 +441,15 @@ x86DataIntersect(virCPUx86Data *data1,
Pablo Greco 40546a
                  const virCPUx86Data *data2)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     virCPUx86DataIterator iter = virCPUx86DataIteratorInit(data1);
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid1;
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid2;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid1;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid2;
Pablo Greco 40546a
 
Pablo Greco 40546a
     while ((cpuid1 = x86DataCpuidNext(&iter))) {
Pablo Greco 40546a
         cpuid2 = x86DataCpuid(data2, cpuid1);
Pablo Greco 40546a
         if (cpuid2)
Pablo Greco 40546a
-            x86cpuidAndBits(cpuid1, cpuid2);
Pablo Greco 40546a
+            x86cpuidAndBits(&cpuid1->cpuid, &cpuid2->cpuid);
Pablo Greco 40546a
         else
Pablo Greco 40546a
-            x86cpuidClearBits(cpuid1, cpuid1);
Pablo Greco 40546a
+            x86cpuidClearBits(&cpuid1->cpuid, &cpuid1->cpuid);
Pablo Greco 40546a
     }
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -465,12 +469,12 @@ x86DataIsSubset(const virCPUx86Data *data,
Pablo Greco 40546a
 {
Pablo Greco 40546a
 
Pablo Greco 40546a
     virCPUx86DataIterator iter = virCPUx86DataIteratorInit((virCPUx86Data *)subset);
Pablo Greco 40546a
-    const virCPUx86CPUID *cpuid;
Pablo Greco 40546a
-    const virCPUx86CPUID *cpuidSubset;
Pablo Greco 40546a
+    const virCPUx86DataItem *cpuid;
Pablo Greco 40546a
+    const virCPUx86DataItem *cpuidSubset;
Pablo Greco 40546a
 
Pablo Greco 40546a
     while ((cpuidSubset = x86DataCpuidNext(&iter))) {
Pablo Greco 40546a
         if (!(cpuid = x86DataCpuid(data, cpuidSubset)) ||
Pablo Greco 40546a
-            !x86cpuidMatchMasked(cpuid, cpuidSubset))
Pablo Greco 40546a
+            !x86cpuidMatchMasked(&cpuid->cpuid, &cpuidSubset->cpuid))
Pablo Greco 40546a
             return false;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -505,14 +509,14 @@ static virCPUx86VendorPtr
Pablo Greco 40546a
 x86DataToVendor(const virCPUx86Data *data,
Pablo Greco 40546a
                 virCPUx86MapPtr map)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < map->nvendors; i++) {
Pablo Greco 40546a
         virCPUx86VendorPtr vendor = map->vendors[i];
Pablo Greco 40546a
         if ((cpuid = x86DataCpuid(data, &vendor->cpuid)) &&
Pablo Greco 40546a
-            x86cpuidMatchMasked(cpuid, &vendor->cpuid)) {
Pablo Greco 40546a
-            x86cpuidClearBits(cpuid, &vendor->cpuid);
Pablo Greco 40546a
+            x86cpuidMatchMasked(&cpuid->cpuid, &vendor->cpuid.cpuid)) {
Pablo Greco 40546a
+            x86cpuidClearBits(&cpuid->cpuid, &vendor->cpuid.cpuid);
Pablo Greco 40546a
             return vendor;
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
@@ -523,8 +527,10 @@ x86DataToVendor(const virCPUx86Data *data,
Pablo Greco 40546a
 
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 virCPUx86VendorToCPUID(const char *vendor,
Pablo Greco 40546a
-                       virCPUx86CPUID *cpuid)
Pablo Greco 40546a
+                       virCPUx86DataItemPtr data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &data->cpuid;
Pablo Greco 40546a
+
Pablo Greco 40546a
     if (strlen(vendor) != VENDOR_STRING_LENGTH) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("Invalid CPU vendor string '%s'"), vendor);
Pablo Greco 40546a
@@ -597,14 +603,16 @@ x86DataToSignatureFull(const virCPUx86Data *data,
Pablo Greco 40546a
                        unsigned int *model,
Pablo Greco 40546a
                        unsigned int *stepping)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID leaf1 = { .eax_in = 0x1 };
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid;
Pablo Greco 40546a
+    virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1);
Pablo Greco 40546a
+    virCPUx86DataItemPtr item;
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid;
Pablo Greco 40546a
 
Pablo Greco 40546a
     *family = *model = *stepping = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (!(cpuid = x86DataCpuid(data, &leaf1)))
Pablo Greco 40546a
+    if (!(item = x86DataCpuid(data, &leaf1)))
Pablo Greco 40546a
         return;
Pablo Greco 40546a
 
Pablo Greco 40546a
+    cpuid = &item->cpuid;
Pablo Greco 40546a
     *family = ((cpuid->eax >> 20) & 0xff) + ((cpuid->eax >> 8) & 0xf);
Pablo Greco 40546a
     *model = ((cpuid->eax >> 12) & 0xf0) + ((cpuid->eax >> 4) & 0xf);
Pablo Greco 40546a
     *stepping = cpuid->eax & 0xf;
Pablo Greco 40546a
@@ -617,13 +625,13 @@ x86DataToSignatureFull(const virCPUx86Data *data,
Pablo Greco 40546a
 static uint32_t
Pablo Greco 40546a
 x86DataToSignature(const virCPUx86Data *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID leaf1 = { .eax_in = 0x1 };
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid;
Pablo Greco 40546a
+    virCPUx86DataItem leaf1 = CPUID(.eax_in = 0x1);
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(cpuid = x86DataCpuid(data, &leaf1)))
Pablo Greco 40546a
         return 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    return cpuid->eax & SIGNATURE_MASK;
Pablo Greco 40546a
+    return cpuid->cpuid.eax & SIGNATURE_MASK;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -631,7 +639,7 @@ static int
Pablo Greco 40546a
 x86DataAddSignature(virCPUx86Data *data,
Pablo Greco 40546a
                     uint32_t signature)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = 0x1, .eax = signature };
Pablo Greco 40546a
+    virCPUx86DataItem cpuid = CPUID(.eax_in = 0x1, .eax = signature);
Pablo Greco 40546a
 
Pablo Greco 40546a
     return virCPUx86DataAddCPUIDInt(data, &cpuid);
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -856,13 +864,14 @@ x86FeatureNames(virCPUx86MapPtr map,
Pablo Greco 40546a
 
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 x86ParseCPUID(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-              virCPUx86CPUID *cpuid)
Pablo Greco 40546a
+              virCPUx86DataItemPtr item)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid;
Pablo Greco 40546a
     unsigned long eax_in, ecx_in;
Pablo Greco 40546a
     unsigned long eax, ebx, ecx, edx;
Pablo Greco 40546a
     int ret_eax_in, ret_ecx_in, ret_eax, ret_ebx, ret_ecx, ret_edx;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    memset(cpuid, 0, sizeof(*cpuid));
Pablo Greco 40546a
+    memset(item, 0, sizeof(*item));
Pablo Greco 40546a
 
Pablo Greco 40546a
     eax_in = ecx_in = 0;
Pablo Greco 40546a
     eax = ebx = ecx = edx = 0;
Pablo Greco 40546a
@@ -877,6 +886,7 @@ x86ParseCPUID(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         ret_eax == -2 || ret_ebx == -2 || ret_ecx == -2 || ret_edx == -2)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
+    cpuid = &item->cpuid;
Pablo Greco 40546a
     cpuid->eax_in = eax_in;
Pablo Greco 40546a
     cpuid->ecx_in = ecx_in;
Pablo Greco 40546a
     cpuid->eax = eax;
Pablo Greco 40546a
@@ -895,7 +905,7 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
     virCPUx86MapPtr map = data;
Pablo Greco 40546a
     xmlNodePtr *nodes = NULL;
Pablo Greco 40546a
     virCPUx86FeaturePtr feature;
Pablo Greco 40546a
-    virCPUx86CPUID cpuid;
Pablo Greco 40546a
+    virCPUx86DataItem cpuid;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
     int n;
Pablo Greco 40546a
     char *str = NULL;
Pablo Greco 40546a
@@ -1138,16 +1148,16 @@ x86ModelCompare(virCPUx86ModelPtr model1,
Pablo Greco 40546a
     virCPUx86CompareResult result = EQUAL;
Pablo Greco 40546a
     virCPUx86DataIterator iter1 = virCPUx86DataIteratorInit(&model1->data);
Pablo Greco 40546a
     virCPUx86DataIterator iter2 = virCPUx86DataIteratorInit(&model2->data);
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid1;
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid2;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid1;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid2;
Pablo Greco 40546a
 
Pablo Greco 40546a
     while ((cpuid1 = x86DataCpuidNext(&iter1))) {
Pablo Greco 40546a
         virCPUx86CompareResult match = SUPERSET;
Pablo Greco 40546a
 
Pablo Greco 40546a
         if ((cpuid2 = x86DataCpuid(&model2->data, cpuid1))) {
Pablo Greco 40546a
-            if (x86cpuidMatch(cpuid1, cpuid2))
Pablo Greco 40546a
+            if (x86cpuidMatch(&cpuid1->cpuid, &cpuid2->cpuid))
Pablo Greco 40546a
                 continue;
Pablo Greco 40546a
-            else if (!x86cpuidMatchMasked(cpuid1, cpuid2))
Pablo Greco 40546a
+            else if (!x86cpuidMatchMasked(&cpuid1->cpuid, &cpuid2->cpuid))
Pablo Greco 40546a
                 match = SUBSET;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1161,9 +1171,9 @@ x86ModelCompare(virCPUx86ModelPtr model1,
Pablo Greco 40546a
         virCPUx86CompareResult match = SUBSET;
Pablo Greco 40546a
 
Pablo Greco 40546a
         if ((cpuid1 = x86DataCpuid(&model1->data, cpuid2))) {
Pablo Greco 40546a
-            if (x86cpuidMatch(cpuid2, cpuid1))
Pablo Greco 40546a
+            if (x86cpuidMatch(&cpuid2->cpuid, &cpuid1->cpuid))
Pablo Greco 40546a
                 continue;
Pablo Greco 40546a
-            else if (!x86cpuidMatchMasked(cpuid2, cpuid1))
Pablo Greco 40546a
+            else if (!x86cpuidMatchMasked(&cpuid2->cpuid, &cpuid1->cpuid))
Pablo Greco 40546a
                 match = SUPERSET;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1447,11 +1457,12 @@ static char *
Pablo Greco 40546a
 virCPUx86DataFormat(const virCPUData *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     virCPUx86DataIterator iter = virCPUx86DataIteratorInit(&data->data.x86);
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid;
Pablo Greco 40546a
+    virCPUx86DataItemPtr item;
Pablo Greco 40546a
     virBuffer buf = VIR_BUFFER_INITIALIZER;
Pablo Greco 40546a
 
Pablo Greco 40546a
     virBufferAddLit(&buf, "<cpudata arch='x86'>\n");
Pablo Greco 40546a
-    while ((cpuid = x86DataCpuidNext(&iter))) {
Pablo Greco 40546a
+    while ((item = x86DataCpuidNext(&iter))) {
Pablo Greco 40546a
+        virCPUx86CPUIDPtr cpuid = &item->cpuid;
Pablo Greco 40546a
         virBufferAsprintf(&buf,
Pablo Greco 40546a
                           "  
Pablo Greco 40546a
                           " eax='0x%08x' ebx='0x%08x'"
Pablo Greco 40546a
@@ -1473,7 +1484,7 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     xmlNodePtr *nodes = NULL;
Pablo Greco 40546a
     virCPUDataPtr cpuData = NULL;
Pablo Greco 40546a
-    virCPUx86CPUID cpuid;
Pablo Greco 40546a
+    virCPUx86DataItem cpuid;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
     int n;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2059,7 +2070,7 @@ x86EncodePolicy(virCPUx86Data *data,
Pablo Greco 40546a
 
Pablo Greco 40546a
     *data = model->data;
Pablo Greco 40546a
     model->data.len = 0;
Pablo Greco 40546a
-    model->data.data = NULL;
Pablo Greco 40546a
+    model->data.items = NULL;
Pablo Greco 40546a
     x86ModelFree(model);
Pablo Greco 40546a
 
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2213,17 +2224,18 @@ cpuidCall(virCPUx86CPUID *cpuid)
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeaf4(virCPUDataPtr data,
Pablo Greco 40546a
-              virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+              virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = *subLeaf0;
Pablo Greco 40546a
+    virCPUx86DataItem item = *subLeaf0;
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    while (cpuid.eax & 0x1f) {
Pablo Greco 40546a
-        cpuid.ecx_in++;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    while (cpuid->eax & 0x1f) {
Pablo Greco 40546a
+        cpuid->ecx_in++;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2236,18 +2248,19 @@ cpuidSetLeaf4(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeaf7(virCPUDataPtr data,
Pablo Greco 40546a
-              virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+              virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = 0x7 };
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = 0x7);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
     uint32_t sub;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    for (sub = 1; sub <= subLeaf0->eax; sub++) {
Pablo Greco 40546a
-        cpuid.ecx_in = sub;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) {
Pablo Greco 40546a
+        cpuid->ecx_in = sub;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2263,15 +2276,16 @@ cpuidSetLeaf7(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeafB(virCPUDataPtr data,
Pablo Greco 40546a
-              virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+              virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = *subLeaf0;
Pablo Greco 40546a
+    virCPUx86DataItem item = *subLeaf0;
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    while (cpuid.ecx & 0xff00) {
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    while (cpuid->ecx & 0xff00) {
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
-        cpuid.ecx_in++;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
+        cpuid->ecx_in++;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -2287,9 +2301,10 @@ cpuidSetLeafB(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeafD(virCPUDataPtr data,
Pablo Greco 40546a
-              virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+              virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = 0xd };
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = 0xd);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
     virCPUx86CPUID sub0;
Pablo Greco 40546a
     virCPUx86CPUID sub1;
Pablo Greco 40546a
     uint32_t sub;
Pablo Greco 40546a
@@ -2297,13 +2312,13 @@ cpuidSetLeafD(virCPUDataPtr data,
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    cpuid.ecx_in = 1;
Pablo Greco 40546a
-    cpuidCall(&cpuid);
Pablo Greco 40546a
-    if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    cpuid->ecx_in = 1;
Pablo Greco 40546a
+    cpuidCall(cpuid);
Pablo Greco 40546a
+    if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    sub0 = *subLeaf0;
Pablo Greco 40546a
-    sub1 = cpuid;
Pablo Greco 40546a
+    sub0 = subLeaf0->cpuid;
Pablo Greco 40546a
+    sub1 = *cpuid;
Pablo Greco 40546a
     for (sub = 2; sub < 64; sub++) {
Pablo Greco 40546a
         if (sub < 32 &&
Pablo Greco 40546a
             !(sub0.eax & (1 << sub)) &&
Pablo Greco 40546a
@@ -2314,9 +2329,9 @@ cpuidSetLeafD(virCPUDataPtr data,
Pablo Greco 40546a
             !(sub1.edx & (1 << (sub - 32))))
Pablo Greco 40546a
             continue;
Pablo Greco 40546a
 
Pablo Greco 40546a
-        cpuid.ecx_in = sub;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+        cpuid->ecx_in = sub;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2334,10 +2349,11 @@ cpuidSetLeafD(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeafResID(virCPUDataPtr data,
Pablo Greco 40546a
-                  virCPUx86CPUID *subLeaf0,
Pablo Greco 40546a
+                  virCPUx86DataItemPtr subLeaf0,
Pablo Greco 40546a
                   uint32_t res)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = subLeaf0->eax_in };
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = subLeaf0->cpuid.eax_in);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
     uint32_t sub;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
@@ -2346,9 +2362,9 @@ cpuidSetLeafResID(virCPUDataPtr data,
Pablo Greco 40546a
     for (sub = 1; sub < 32; sub++) {
Pablo Greco 40546a
         if (!(res & (1 << sub)))
Pablo Greco 40546a
             continue;
Pablo Greco 40546a
-        cpuid.ecx_in = sub;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+        cpuid->ecx_in = sub;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2362,31 +2378,32 @@ cpuidSetLeafResID(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeaf12(virCPUDataPtr data,
Pablo Greco 40546a
-               virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+               virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = 0x7 };
Pablo Greco 40546a
-    virCPUx86CPUID *cpuid7;
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = 0x7);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
+    virCPUx86DataItemPtr cpuid7;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (!(cpuid7 = x86DataCpuid(&data->data.x86, &cpuid)) ||
Pablo Greco 40546a
-        !(cpuid7->ebx & (1 << 2)))
Pablo Greco 40546a
+    if (!(cpuid7 = x86DataCpuid(&data->data.x86, &item)) ||
Pablo Greco 40546a
+        !(cpuid7->cpuid.ebx & (1 << 2)))
Pablo Greco 40546a
         return 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    cpuid.eax_in = 0x12;
Pablo Greco 40546a
-    cpuid.ecx_in = 1;
Pablo Greco 40546a
-    cpuidCall(&cpuid);
Pablo Greco 40546a
-    if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    cpuid->eax_in = 0x12;
Pablo Greco 40546a
+    cpuid->ecx_in = 1;
Pablo Greco 40546a
+    cpuidCall(cpuid);
Pablo Greco 40546a
+    if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    cpuid.ecx_in = 2;
Pablo Greco 40546a
-    cpuidCall(&cpuid);
Pablo Greco 40546a
-    while (cpuid.eax & 0xf) {
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    cpuid->ecx_in = 2;
Pablo Greco 40546a
+    cpuidCall(cpuid);
Pablo Greco 40546a
+    while (cpuid->eax & 0xf) {
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
-        cpuid.ecx_in++;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
+        cpuid->ecx_in++;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -2398,18 +2415,19 @@ cpuidSetLeaf12(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeaf14(virCPUDataPtr data,
Pablo Greco 40546a
-               virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+               virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = 0x14 };
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = 0x14);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
     uint32_t sub;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    for (sub = 1; sub <= subLeaf0->eax; sub++) {
Pablo Greco 40546a
-        cpuid.ecx_in = sub;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) {
Pablo Greco 40546a
+        cpuid->ecx_in = sub;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2423,21 +2441,22 @@ cpuidSetLeaf14(virCPUDataPtr data,
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuidSetLeaf17(virCPUDataPtr data,
Pablo Greco 40546a
-               virCPUx86CPUID *subLeaf0)
Pablo Greco 40546a
+               virCPUx86DataItemPtr subLeaf0)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = 0x17 };
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = 0x17);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
     uint32_t sub;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (subLeaf0->eax < 3)
Pablo Greco 40546a
+    if (subLeaf0->cpuid.eax < 3)
Pablo Greco 40546a
         return 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86DataAddCPUID(data, subLeaf0) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    for (sub = 1; sub <= subLeaf0->eax; sub++) {
Pablo Greco 40546a
-        cpuid.ecx_in = sub;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, &cpuid) < 0)
Pablo Greco 40546a
+    for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) {
Pablo Greco 40546a
+        cpuid->ecx_in = sub;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
     }
Pablo Greco 40546a
     return 0;
Pablo Greco 40546a
@@ -2450,39 +2469,40 @@ cpuidSet(uint32_t base, virCPUDataPtr data)
Pablo Greco 40546a
     int rc;
Pablo Greco 40546a
     uint32_t max;
Pablo Greco 40546a
     uint32_t leaf;
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { .eax_in = base };
Pablo Greco 40546a
+    virCPUx86DataItem item = CPUID(.eax_in = base);
Pablo Greco 40546a
+    virCPUx86CPUIDPtr cpuid = &item.cpuid;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    cpuidCall(&cpuid);
Pablo Greco 40546a
-    max = cpuid.eax;
Pablo Greco 40546a
+    cpuidCall(cpuid);
Pablo Greco 40546a
+    max = cpuid->eax;
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (leaf = base; leaf <= max; leaf++) {
Pablo Greco 40546a
-        cpuid.eax_in = leaf;
Pablo Greco 40546a
-        cpuid.ecx_in = 0;
Pablo Greco 40546a
-        cpuidCall(&cpuid);
Pablo Greco 40546a
+        cpuid->eax_in = leaf;
Pablo Greco 40546a
+        cpuid->ecx_in = 0;
Pablo Greco 40546a
+        cpuidCall(cpuid);
Pablo Greco 40546a
 
Pablo Greco 40546a
         /* Handle CPUID leaves that depend on previously queried bits or
Pablo Greco 40546a
          * which provide additional sub leaves for ecx_in > 0
Pablo Greco 40546a
          */
Pablo Greco 40546a
         if (leaf == 0x4)
Pablo Greco 40546a
-            rc = cpuidSetLeaf4(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeaf4(data, &item);
Pablo Greco 40546a
         else if (leaf == 0x7)
Pablo Greco 40546a
-            rc = cpuidSetLeaf7(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeaf7(data, &item);
Pablo Greco 40546a
         else if (leaf == 0xb)
Pablo Greco 40546a
-            rc = cpuidSetLeafB(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeafB(data, &item);
Pablo Greco 40546a
         else if (leaf == 0xd)
Pablo Greco 40546a
-            rc = cpuidSetLeafD(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeafD(data, &item);
Pablo Greco 40546a
         else if (leaf == 0xf)
Pablo Greco 40546a
-            rc = cpuidSetLeafResID(data, &cpuid, cpuid.edx);
Pablo Greco 40546a
+            rc = cpuidSetLeafResID(data, &item, cpuid->edx);
Pablo Greco 40546a
         else if (leaf == 0x10)
Pablo Greco 40546a
-            rc = cpuidSetLeafResID(data, &cpuid, cpuid.ebx);
Pablo Greco 40546a
+            rc = cpuidSetLeafResID(data, &item, cpuid->ebx);
Pablo Greco 40546a
         else if (leaf == 0x12)
Pablo Greco 40546a
-            rc = cpuidSetLeaf12(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeaf12(data, &item);
Pablo Greco 40546a
         else if (leaf == 0x14)
Pablo Greco 40546a
-            rc = cpuidSetLeaf14(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeaf14(data, &item);
Pablo Greco 40546a
         else if (leaf == 0x17)
Pablo Greco 40546a
-            rc = cpuidSetLeaf17(data, &cpuid);
Pablo Greco 40546a
+            rc = cpuidSetLeaf17(data, &item);
Pablo Greco 40546a
         else
Pablo Greco 40546a
-            rc = virCPUx86DataAddCPUID(data, &cpuid);
Pablo Greco 40546a
+            rc = virCPUx86DataAddCPUID(data, &item);
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (rc < 0)
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
@@ -3058,7 +3078,7 @@ virCPUx86ValidateFeatures(virCPUDefPtr cpu)
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
Pablo Greco 40546a
-                      const virCPUx86CPUID *cpuid)
Pablo Greco 40546a
+                      const virCPUx86DataItem *cpuid)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     return virCPUx86DataAddCPUIDInt(&cpuData->data.x86, cpuid);
Pablo Greco 40546a
 }
Pablo Greco 40546a
@@ -3092,7 +3112,7 @@ int
Pablo Greco 40546a
 virCPUx86DataSetVendor(virCPUDataPtr cpuData,
Pablo Greco 40546a
                        const char *vendor)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    virCPUx86CPUID cpuid = { 0 };
Pablo Greco 40546a
+    virCPUx86DataItem cpuid = CPUID(0);
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86VendorToCPUID(vendor, &cpuid) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h
Pablo Greco 40546a
index 9d3c2b2cdd..94655746c6 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_x86.h
Pablo Greco 40546a
+++ b/src/cpu/cpu_x86.h
Pablo Greco 40546a
@@ -30,7 +30,7 @@
Pablo Greco 40546a
 extern struct cpuArchDriver cpuDriverX86;
Pablo Greco 40546a
 
Pablo Greco 40546a
 int virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
Pablo Greco 40546a
-                          const virCPUx86CPUID *cpuid);
Pablo Greco 40546a
+                          const virCPUx86DataItem *cpuid);
Pablo Greco 40546a
 
Pablo Greco 40546a
 int virCPUx86DataSetSignature(virCPUDataPtr cpuData,
Pablo Greco 40546a
                               unsigned int family,
Pablo Greco 40546a
diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h
Pablo Greco 40546a
index 090a21156f..e93b355cf0 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_x86_data.h
Pablo Greco 40546a
+++ b/src/cpu/cpu_x86_data.h
Pablo Greco 40546a
@@ -27,6 +27,7 @@
Pablo Greco 40546a
 # include <stdint.h>
Pablo Greco 40546a
 
Pablo Greco 40546a
 typedef struct _virCPUx86CPUID virCPUx86CPUID;
Pablo Greco 40546a
+typedef virCPUx86CPUID *virCPUx86CPUIDPtr;
Pablo Greco 40546a
 struct _virCPUx86CPUID {
Pablo Greco 40546a
     uint32_t eax_in;
Pablo Greco 40546a
     uint32_t ecx_in;
Pablo Greco 40546a
@@ -70,10 +71,16 @@ struct _virCPUx86CPUID {
Pablo Greco 40546a
 
Pablo Greco 40546a
 # define VIR_CPU_X86_DATA_INIT { 0 }
Pablo Greco 40546a
 
Pablo Greco 40546a
+typedef struct _virCPUx86DataItem virCPUx86DataItem;
Pablo Greco 40546a
+typedef virCPUx86DataItem *virCPUx86DataItemPtr;
Pablo Greco 40546a
+struct _virCPUx86DataItem {
Pablo Greco 40546a
+    virCPUx86CPUID cpuid;
Pablo Greco 40546a
+};
Pablo Greco 40546a
+
Pablo Greco 40546a
 typedef struct _virCPUx86Data virCPUx86Data;
Pablo Greco 40546a
 struct _virCPUx86Data {
Pablo Greco 40546a
     size_t len;
Pablo Greco 40546a
-    virCPUx86CPUID *data;
Pablo Greco 40546a
+    virCPUx86DataItem *items;
Pablo Greco 40546a
 };
Pablo Greco 40546a
 
Pablo Greco 40546a
 #endif /* __VIR_CPU_X86_DATA_H__ */
Pablo Greco 40546a
diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
Pablo Greco 40546a
index 18596c7c72..231d72669f 100644
Pablo Greco 40546a
--- a/src/libxl/libxl_capabilities.c
Pablo Greco 40546a
+++ b/src/libxl/libxl_capabilities.c
Pablo Greco 40546a
@@ -67,13 +67,15 @@ struct guest_arch {
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 libxlCapsAddCPUID(virCPUDataPtr data, virCPUx86CPUID *cpuid, ssize_t ncaps)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    virCPUx86DataItem item = { 0 };
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < ncaps; i++) {
Pablo Greco 40546a
-        virCPUx86CPUID *c = &cpuid[i];
Pablo Greco 40546a
+        item.cpuid = cpuid[i];
Pablo Greco 40546a
 
Pablo Greco 40546a
-        if (virCPUx86DataAddCPUID(data, c) < 0) {
Pablo Greco 40546a
-            VIR_DEBUG("Failed to add CPUID(%x,%x)", c->eax_in, c->ecx_in);
Pablo Greco 40546a
+        if (virCPUx86DataAddCPUID(data, &item) < 0) {
Pablo Greco 40546a
+            VIR_DEBUG("Failed to add CPUID(%x,%x)",
Pablo Greco 40546a
+                      cpuid[i].eax_in, cpuid[i].ecx_in);
Pablo Greco 40546a
             return -1;
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
Pablo Greco 40546a
index d6c11666c5..0b4dfd70c0 100644
Pablo Greco 40546a
--- a/src/qemu/qemu_monitor_json.c
Pablo Greco 40546a
+++ b/src/qemu/qemu_monitor_json.c
Pablo Greco 40546a
@@ -7043,7 +7043,7 @@ static virCPUDataPtr
Pablo Greco 40546a
 qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     virCPUDataPtr cpudata = NULL;
Pablo Greco 40546a
-    virCPUx86CPUID cpuid;
Pablo Greco 40546a
+    virCPUx86DataItem item = { 0 };
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(cpudata = virCPUDataNew(VIR_ARCH_X86_64)))
Pablo Greco 40546a
@@ -7051,8 +7051,8 @@ qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data)
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < virJSONValueArraySize(data); i++) {
Pablo Greco 40546a
         if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i),
Pablo Greco 40546a
-                                                  &cpuid) < 0 ||
Pablo Greco 40546a
-            virCPUx86DataAddCPUID(cpudata, &cpuid) < 0)
Pablo Greco 40546a
+                                                  &item.cpuid) < 0 ||
Pablo Greco 40546a
+            virCPUx86DataAddCPUID(cpudata, &item) < 0)
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a