static int cpuTestHasFeature(const void *arg) { const struct data *data = arg; int ret = -1; virCPUDefPtr host = NULL; union cpuData *hostData = NULL; int result; if (!(host = cpuTestLoadXML(data->arch, data->host))) goto cleanup; if (cpuEncode(host->arch, host, NULL, &hostData, NULL, NULL, NULL, NULL) < 0) goto cleanup; result = cpuHasFeature(host->arch, hostData, data->name); if (data->result == -1) virResetLastError(); if (data->result != result) { if (virTestGetVerbose()) { fprintf(stderr, "\nExpected result %s, got %s\n", cpuTestBoolWithErrorStr(data->result), cpuTestBoolWithErrorStr(result)); /* Pad to line up with test name ... in virTestRun */ fprintf(stderr, "%74s", "... "); } goto cleanup; } ret = 0; cleanup: if (host) cpuDataFree(host->arch, hostData); virCPUDefFree(host); return ret; }
virCapsPtr vmwareCapsInit(void) { virCapsPtr caps = NULL; virCapsGuestPtr guest = NULL; virCPUDefPtr cpu = NULL; virCPUDataPtr data = NULL; if ((caps = virCapabilitiesNew(virArchFromHost(), 0, 0)) == NULL) goto error; if (nodeCapsInitNUMA(caps) < 0) goto error; /* i686 guests are always supported */ if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_I686, NULL, NULL, 0, NULL)) == NULL) goto error; if (virCapabilitiesAddGuestDomain(guest, "vmware", NULL, NULL, 0, NULL) == NULL) goto error; if (VIR_ALLOC(cpu) < 0) goto error; cpu->arch = caps->host.arch; cpu->type = VIR_CPU_TYPE_HOST; if (!(data = cpuNodeData(cpu->arch)) || cpuDecode(cpu, data, NULL, 0, NULL) < 0) { goto error; } /* x86_64 guests are supported if * - Host arch is x86_64 * Or * - Host CPU is x86_64 with virtualization extensions */ if (caps->host.arch == VIR_ARCH_X86_64 || (cpuHasFeature(data, "lm") && (cpuHasFeature(data, "vmx") || cpuHasFeature(data, "svm")))) { if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64, NULL, NULL, 0, NULL)) == NULL) goto error; if (virCapabilitiesAddGuestDomain(guest, "vmware", NULL, NULL, 0, NULL) == NULL) goto error; } cleanup: virCPUDefFree(cpu); cpuDataFree(data); return caps; error: virObjectUnref(caps); goto cleanup; }