From c465e315637d0b2cf01d2957de3d816186e0fd0f Mon Sep 17 00:00:00 2001 Message-Id: From: Jiri Denemark Date: Fri, 21 Jun 2019 09:25:38 +0200 Subject: [PATCH] cpu_x86: Store virCPUx86DataItem content in union MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The structure can only be used for CPUID data now. Adding a type indicator and moving the data into a union will let us store alternative data types. Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko (cherry picked from commit 370177e2f6784319b2fc86d8fe7a271248a5982e) https://bugzilla.redhat.com/show_bug.cgi?id=1697627 Signed-off-by: Jiri Denemark Message-Id: <00cf7daca0cde66e9a90f64435182ef430983b2e.1561068591.git.jdenemar@redhat.com> Reviewed-by: Ján Tomko --- src/cpu/cpu_x86.c | 202 ++++++++++++++++++++++++--------- src/cpu/cpu_x86_data.h | 10 +- src/libxl/libxl_capabilities.c | 3 +- src/qemu/qemu_monitor_json.c | 3 +- 4 files changed, 160 insertions(+), 58 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 11c023ac31..e6da974b31 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -59,7 +59,9 @@ struct _virCPUx86Feature { }; -#define CPUID(...) { .cpuid = {__VA_ARGS__} } +#define CPUID(...) \ + { .type = VIR_CPU_X86_DATA_CPUID, \ + .data = { .cpuid = {__VA_ARGS__} } } #define KVM_FEATURE_DEF(Name, Eax_in, Eax) \ static virCPUx86DataItem Name ## _data[] = { \ @@ -193,10 +195,22 @@ static bool virCPUx86DataItemMatch(const virCPUx86DataItem *item1, const virCPUx86DataItem *item2) { - return (item1->cpuid.eax == item2->cpuid.eax && - item1->cpuid.ebx == item2->cpuid.ebx && - item1->cpuid.ecx == item2->cpuid.ecx && - item1->cpuid.edx == item2->cpuid.edx); + const virCPUx86CPUID *cpuid1; + const virCPUx86CPUID *cpuid2; + + switch (item1->type) { + case VIR_CPU_X86_DATA_CPUID: + cpuid1 = &item1->data.cpuid; + cpuid2 = &item2->data.cpuid; + return (cpuid1->eax == cpuid2->eax && + cpuid1->ebx == cpuid2->ebx && + cpuid1->ecx == cpuid2->ecx && + cpuid1->edx == cpuid2->edx); + + case VIR_CPU_X86_DATA_NONE: + default: + return false; + } } @@ -204,10 +218,22 @@ static bool virCPUx86DataItemMatchMasked(const virCPUx86DataItem *item, const virCPUx86DataItem *mask) { - return ((item->cpuid.eax & mask->cpuid.eax) == mask->cpuid.eax && - (item->cpuid.ebx & mask->cpuid.ebx) == mask->cpuid.ebx && - (item->cpuid.ecx & mask->cpuid.ecx) == mask->cpuid.ecx && - (item->cpuid.edx & mask->cpuid.edx) == mask->cpuid.edx); + const virCPUx86CPUID *cpuid; + const virCPUx86CPUID *cpuidMask; + + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: + cpuid = &item->data.cpuid; + cpuidMask = &mask->data.cpuid; + return ((cpuid->eax & cpuidMask->eax) == cpuidMask->eax && + (cpuid->ebx & cpuidMask->ebx) == cpuidMask->ebx && + (cpuid->ecx & cpuidMask->ecx) == cpuidMask->ecx && + (cpuid->edx & cpuidMask->edx) == cpuidMask->edx); + + case VIR_CPU_X86_DATA_NONE: + default: + return false; + } } @@ -215,13 +241,26 @@ static void virCPUx86DataItemSetBits(virCPUx86DataItemPtr item, const virCPUx86DataItem *mask) { + virCPUx86CPUIDPtr cpuid; + const virCPUx86CPUID *cpuidMask; + if (!mask) return; - item->cpuid.eax |= mask->cpuid.eax; - item->cpuid.ebx |= mask->cpuid.ebx; - item->cpuid.ecx |= mask->cpuid.ecx; - item->cpuid.edx |= mask->cpuid.edx; + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: + cpuid = &item->data.cpuid; + cpuidMask = &mask->data.cpuid; + cpuid->eax |= cpuidMask->eax; + cpuid->ebx |= cpuidMask->ebx; + cpuid->ecx |= cpuidMask->ecx; + cpuid->edx |= cpuidMask->edx; + break; + + case VIR_CPU_X86_DATA_NONE: + default: + break; + } } @@ -229,13 +268,26 @@ static void virCPUx86DataItemClearBits(virCPUx86DataItemPtr item, const virCPUx86DataItem *mask) { + virCPUx86CPUIDPtr cpuid; + const virCPUx86CPUID *cpuidMask; + if (!mask) return; - item->cpuid.eax &= ~mask->cpuid.eax; - item->cpuid.ebx &= ~mask->cpuid.ebx; - item->cpuid.ecx &= ~mask->cpuid.ecx; - item->cpuid.edx &= ~mask->cpuid.edx; + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: + cpuid = &item->data.cpuid; + cpuidMask = &mask->data.cpuid; + cpuid->eax &= ~cpuidMask->eax; + cpuid->ebx &= ~cpuidMask->ebx; + cpuid->ecx &= ~cpuidMask->ecx; + cpuid->edx &= ~cpuidMask->edx; + break; + + case VIR_CPU_X86_DATA_NONE: + default: + break; + } } @@ -243,13 +295,26 @@ static void virCPUx86DataItemAndBits(virCPUx86DataItemPtr item, const virCPUx86DataItem *mask) { + virCPUx86CPUIDPtr cpuid; + const virCPUx86CPUID *cpuidMask; + if (!mask) return; - item->cpuid.eax &= mask->cpuid.eax; - item->cpuid.ebx &= mask->cpuid.ebx; - item->cpuid.ecx &= mask->cpuid.ecx; - item->cpuid.edx &= mask->cpuid.edx; + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: + cpuid = &item->data.cpuid; + cpuidMask = &mask->data.cpuid; + cpuid->eax &= cpuidMask->eax; + cpuid->ebx &= cpuidMask->ebx; + cpuid->ecx &= cpuidMask->ecx; + cpuid->edx &= cpuidMask->edx; + break; + + case VIR_CPU_X86_DATA_NONE: + default: + break; + } } @@ -289,15 +354,29 @@ virCPUx86DataSorter(const void *a, const void *b) virCPUx86DataItemPtr da = (virCPUx86DataItemPtr) a; virCPUx86DataItemPtr db = (virCPUx86DataItemPtr) b; - if (da->cpuid.eax_in > db->cpuid.eax_in) + if (da->type > db->type) return 1; - else if (da->cpuid.eax_in < db->cpuid.eax_in) + else if (da->type < db->type) return -1; - if (da->cpuid.ecx_in > db->cpuid.ecx_in) - return 1; - else if (da->cpuid.ecx_in < db->cpuid.ecx_in) - return -1; + switch (da->type) { + case VIR_CPU_X86_DATA_CPUID: + if (da->data.cpuid.eax_in > db->data.cpuid.eax_in) + return 1; + else if (da->data.cpuid.eax_in < db->data.cpuid.eax_in) + return -1; + + if (da->data.cpuid.ecx_in > db->data.cpuid.ecx_in) + return 1; + else if (da->data.cpuid.ecx_in < db->data.cpuid.ecx_in) + return -1; + + break; + + case VIR_CPU_X86_DATA_NONE: + default: + break; + } return 0; } @@ -526,9 +605,9 @@ x86DataToVendor(const virCPUx86Data *data, static int virCPUx86VendorToData(const char *vendor, - virCPUx86DataItemPtr data) + virCPUx86DataItemPtr item) { - virCPUx86CPUIDPtr cpuid = &data->cpuid; + virCPUx86CPUIDPtr cpuid; if (strlen(vendor) != VENDOR_STRING_LENGTH) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -536,6 +615,8 @@ virCPUx86VendorToData(const char *vendor, return -1; } + item->type = VIR_CPU_X86_DATA_CPUID; + cpuid = &item->data.cpuid; cpuid->eax_in = 0; cpuid->ecx_in = 0; cpuid->ebx = virReadBufInt32LE(vendor); @@ -611,7 +692,7 @@ x86DataToSignatureFull(const virCPUx86Data *data, if (!(item = virCPUx86DataGet(data, &leaf1))) return; - cpuid = &item->cpuid; + cpuid = &item->data.cpuid; *family = ((cpuid->eax >> 20) & 0xff) + ((cpuid->eax >> 8) & 0xf); *model = ((cpuid->eax >> 12) & 0xf0) + ((cpuid->eax >> 4) & 0xf); *stepping = cpuid->eax & 0xf; @@ -630,7 +711,7 @@ x86DataToSignature(const virCPUx86Data *data) if (!(item = virCPUx86DataGet(data, &leaf1))) return 0; - return item->cpuid.eax & SIGNATURE_MASK; + return item->data.cpuid.eax & SIGNATURE_MASK; } @@ -885,7 +966,8 @@ x86ParseCPUID(xmlXPathContextPtr ctxt, ret_eax == -2 || ret_ebx == -2 || ret_ecx == -2 || ret_edx == -2) return -1; - cpuid = &item->cpuid; + item->type = VIR_CPU_X86_DATA_CPUID; + cpuid = &item->data.cpuid; cpuid->eax_in = eax_in; cpuid->ecx_in = ecx_in; cpuid->eax = eax; @@ -1461,13 +1543,23 @@ virCPUx86DataFormat(const virCPUData *data) virBufferAddLit(&buf, "\n"); while ((item = virCPUx86DataNext(&iter))) { - virCPUx86CPUIDPtr cpuid = &item->cpuid; - virBufferAsprintf(&buf, - " \n", - cpuid->eax_in, cpuid->ecx_in, - cpuid->eax, cpuid->ebx, cpuid->ecx, cpuid->edx); + virCPUx86CPUIDPtr cpuid; + + switch (item->type) { + case VIR_CPU_X86_DATA_CPUID: + cpuid = &item->data.cpuid; + virBufferAsprintf(&buf, + " \n", + cpuid->eax_in, cpuid->ecx_in, + cpuid->eax, cpuid->ebx, cpuid->ecx, cpuid->edx); + break; + + case VIR_CPU_X86_DATA_NONE: + default: + break; + } } virBufferAddLit(&buf, "\n"); @@ -2226,7 +2318,7 @@ cpuidSetLeaf4(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = *subLeaf0; - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; if (virCPUx86DataAdd(data, subLeaf0) < 0) return -1; @@ -2250,13 +2342,13 @@ cpuidSetLeaf7(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = CPUID(.eax_in = 0x7); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; uint32_t sub; if (virCPUx86DataAdd(data, subLeaf0) < 0) return -1; - for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { + for (sub = 1; sub <= subLeaf0->data.cpuid.eax; sub++) { cpuid->ecx_in = sub; cpuidCall(cpuid); if (virCPUx86DataAdd(data, &item) < 0) @@ -2278,7 +2370,7 @@ cpuidSetLeafB(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = *subLeaf0; - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; while (cpuid->ecx & 0xff00) { if (virCPUx86DataAdd(data, &item) < 0) @@ -2303,7 +2395,7 @@ cpuidSetLeafD(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = CPUID(.eax_in = 0xd); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; virCPUx86CPUID sub0; virCPUx86CPUID sub1; uint32_t sub; @@ -2316,7 +2408,7 @@ cpuidSetLeafD(virCPUDataPtr data, if (virCPUx86DataAdd(data, &item) < 0) return -1; - sub0 = subLeaf0->cpuid; + sub0 = subLeaf0->data.cpuid; sub1 = *cpuid; for (sub = 2; sub < 64; sub++) { if (sub < 32 && @@ -2351,8 +2443,8 @@ cpuidSetLeafResID(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0, uint32_t res) { - virCPUx86DataItem item = CPUID(.eax_in = subLeaf0->cpuid.eax_in); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86DataItem item = CPUID(.eax_in = subLeaf0->data.cpuid.eax_in); + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; uint32_t sub; if (virCPUx86DataAdd(data, subLeaf0) < 0) @@ -2380,11 +2472,11 @@ cpuidSetLeaf12(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = CPUID(.eax_in = 0x7); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; virCPUx86DataItemPtr leaf7; if (!(leaf7 = virCPUx86DataGet(&data->data.x86, &item)) || - !(leaf7->cpuid.ebx & (1 << 2))) + !(leaf7->data.cpuid.ebx & (1 << 2))) return 0; if (virCPUx86DataAdd(data, subLeaf0) < 0) @@ -2417,13 +2509,13 @@ cpuidSetLeaf14(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = CPUID(.eax_in = 0x14); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; uint32_t sub; if (virCPUx86DataAdd(data, subLeaf0) < 0) return -1; - for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { + for (sub = 1; sub <= subLeaf0->data.cpuid.eax; sub++) { cpuid->ecx_in = sub; cpuidCall(cpuid); if (virCPUx86DataAdd(data, &item) < 0) @@ -2443,16 +2535,16 @@ cpuidSetLeaf17(virCPUDataPtr data, virCPUx86DataItemPtr subLeaf0) { virCPUx86DataItem item = CPUID(.eax_in = 0x17); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; uint32_t sub; - if (subLeaf0->cpuid.eax < 3) + if (subLeaf0->data.cpuid.eax < 3) return 0; if (virCPUx86DataAdd(data, subLeaf0) < 0) return -1; - for (sub = 1; sub <= subLeaf0->cpuid.eax; sub++) { + for (sub = 1; sub <= subLeaf0->data.cpuid.eax; sub++) { cpuid->ecx_in = sub; cpuidCall(cpuid); if (virCPUx86DataAdd(data, &item) < 0) @@ -2469,7 +2561,7 @@ cpuidSet(uint32_t base, virCPUDataPtr data) uint32_t max; uint32_t leaf; virCPUx86DataItem item = CPUID(.eax_in = base); - virCPUx86CPUIDPtr cpuid = &item.cpuid; + virCPUx86CPUIDPtr cpuid = &item.data.cpuid; cpuidCall(cpuid); max = cpuid->eax; diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h index e93b355cf0..da8e91fe71 100644 --- a/src/cpu/cpu_x86_data.h +++ b/src/cpu/cpu_x86_data.h @@ -71,10 +71,18 @@ struct _virCPUx86CPUID { # define VIR_CPU_X86_DATA_INIT { 0 } +typedef enum { + VIR_CPU_X86_DATA_NONE = 0, + VIR_CPU_X86_DATA_CPUID, +} virCPUx86DataType; + typedef struct _virCPUx86DataItem virCPUx86DataItem; typedef virCPUx86DataItem *virCPUx86DataItemPtr; struct _virCPUx86DataItem { - virCPUx86CPUID cpuid; + virCPUx86DataType type; + union { + virCPUx86CPUID cpuid; + } data; }; typedef struct _virCPUx86Data virCPUx86Data; diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c index 2b351fbdde..6630aa2c0b 100644 --- a/src/libxl/libxl_capabilities.c +++ b/src/libxl/libxl_capabilities.c @@ -70,8 +70,9 @@ libxlCapsAddCPUID(virCPUDataPtr data, virCPUx86CPUID *cpuid, ssize_t ncaps) virCPUx86DataItem item = { 0 }; size_t i; + item.type = VIR_CPU_X86_DATA_CPUID; for (i = 0; i < ncaps; i++) { - item.cpuid = cpuid[i]; + item.data.cpuid = cpuid[i]; if (virCPUx86DataAdd(data, &item) < 0) { VIR_DEBUG("Failed to add CPUID(%x,%x)", diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index abfaa6e68a..e6ac82e96b 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -7049,9 +7049,10 @@ qemuMonitorJSONParseCPUx86Features(virJSONValuePtr data) if (!(cpudata = virCPUDataNew(VIR_ARCH_X86_64))) goto error; + item.type = VIR_CPU_X86_DATA_CPUID; for (i = 0; i < virJSONValueArraySize(data); i++) { if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), - &item.cpuid) < 0 || + &item.data.cpuid) < 0 || virCPUx86DataAdd(cpudata, &item) < 0) goto error; } -- 2.22.0