};
-#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[] = { \
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
+ }
}
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;
}
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,
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);
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;
if (!(item = virCPUx86DataGet(data, &leaf1)))
return 0;
- return item->cpuid.eax & SIGNATURE_MASK;
+ return item->data.cpuid.eax & SIGNATURE_MASK;
}
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;
virBufferAddLit(&buf, "<cpudata arch='x86'>\n");
while ((item = virCPUx86DataNext(&iter))) {
- virCPUx86CPUIDPtr cpuid = &item->cpuid;
- virBufferAsprintf(&buf,
- " <cpuid eax_in='0x%08x' ecx_in='0x%08x'"
- " eax='0x%08x' ebx='0x%08x'"
- " ecx='0x%08x' edx='0x%08x'/>\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,
+ " <cpuid eax_in='0x%08x' ecx_in='0x%08x'"
+ " eax='0x%08x' ebx='0x%08x'"
+ " ecx='0x%08x' edx='0x%08x'/>\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, "</cpudata>\n");
virCPUx86DataItemPtr subLeaf0)
{
virCPUx86DataItem item = *subLeaf0;
- virCPUx86CPUIDPtr cpuid = &item.cpuid;
+ virCPUx86CPUIDPtr cpuid = &item.data.cpuid;
if (virCPUx86DataAdd(data, subLeaf0) < 0)
return -1;
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)
virCPUx86DataItemPtr subLeaf0)
{
virCPUx86DataItem item = *subLeaf0;
- virCPUx86CPUIDPtr cpuid = &item.cpuid;
+ virCPUx86CPUIDPtr cpuid = &item.data.cpuid;
while (cpuid->ecx & 0xff00) {
if (virCPUx86DataAdd(data, &item) < 0)
virCPUx86DataItemPtr subLeaf0)
{
virCPUx86DataItem item = CPUID(.eax_in = 0xd);
- virCPUx86CPUIDPtr cpuid = &item.cpuid;
+ virCPUx86CPUIDPtr cpuid = &item.data.cpuid;
virCPUx86CPUID sub0;
virCPUx86CPUID sub1;
uint32_t sub;
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 &&
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)
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)
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)
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)
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;