static struct ppc_model * ppcModelCopy(const struct ppc_model *model) { struct ppc_model *copy; if (VIR_ALLOC(copy) < 0 || VIR_STRDUP(copy->name, model->name) < 0) { ppcModelFree(copy); return NULL; } copy->data.pvr = model->data.pvr; copy->vendor = model->vendor; return copy; }
static void ppcMapFree(struct ppc_map *map) { if (map == NULL) return; while (map->models != NULL) { struct ppc_model *model = map->models; map->models = model->next; ppcModelFree(model); } while (map->vendors != NULL) { struct ppc_vendor *vendor = map->vendors; map->vendors = vendor->next; ppcVendorFree(vendor); } VIR_FREE(map); }
static struct ppc_model * ppcModelFromCPU(const virCPUDef *cpu, const struct ppc_map *map) { struct ppc_model *model = NULL; if ((model = ppcModelFind(map, cpu->model)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unknown CPU model %s"), cpu->model); goto error; } if ((model = ppcModelCopy(model)) == NULL) goto error; return model; error: ppcModelFree(model); return NULL; }
static int ppcModelLoad(xmlXPathContextPtr ctxt, struct ppc_map *map) { struct ppc_model *model; char *vendor = NULL; unsigned long pvr; if (VIR_ALLOC(model) < 0) { virReportOOMError(); return -1; } model->name = virXPathString("string(@name)", ctxt); if (!model->name) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing CPU model name")); goto ignore; } if (ppcModelFind(map, model->name)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("CPU model %s already defined"), model->name); goto ignore; } if (virXPathBoolean("boolean(./vendor)", ctxt)) { vendor = virXPathString("string(./vendor/@name)", ctxt); if (!vendor) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid vendor element in CPU model %s"), model->name); goto ignore; } if (!(model->vendor = ppcVendorFind(map, vendor))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unknown vendor %s referenced by CPU model %s"), vendor, model->name); goto ignore; } } if (!virXPathBoolean("boolean(./pvr)", ctxt) || virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Missing or invalid PVR value in CPU model %s"), model->name); goto ignore; } model->data.pvr = pvr; if (map->models == NULL) { map->models = model; } else { model->next = map->models; map->models = model; } cleanup: VIR_FREE(vendor); return 0; ignore: ppcModelFree(model); goto cleanup; }
static virCPUCompareResult ppcCompute(virCPUDefPtr host, const virCPUDef *cpu, virCPUDataPtr *guestData, char **message) { struct ppc_map *map = NULL; struct ppc_model *host_model = NULL; struct ppc_model *guest_model = NULL; virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; virArch arch; size_t i; if (cpu->arch != VIR_ARCH_NONE) { bool found = false; for (i = 0; i < ARRAY_CARDINALITY(archs); i++) { if (archs[i] == cpu->arch) { found = true; break; } } if (!found) { VIR_DEBUG("CPU arch %s does not match host arch", virArchToString(cpu->arch)); if (message && virAsprintf(message, _("CPU arch %s does not match host arch"), virArchToString(cpu->arch)) < 0) goto cleanup; ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } arch = cpu->arch; } else { arch = host->arch; } if (cpu->vendor && (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) { VIR_DEBUG("host CPU vendor does not match required CPU vendor %s", cpu->vendor); if (message && virAsprintf(message, _("host CPU vendor does not match required " "CPU vendor %s"), cpu->vendor) < 0) goto cleanup; ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } if (!(map = ppcLoadMap()) || !(host_model = ppcModelFromCPU(host, map)) || !(guest_model = ppcModelFromCPU(cpu, map))) goto cleanup; if (guestData != NULL) { if (cpu->type == VIR_CPU_TYPE_GUEST && cpu->match == VIR_CPU_MATCH_STRICT && STRNEQ(guest_model->name, host_model->name)) { VIR_DEBUG("host CPU model does not match required CPU model %s", guest_model->name); if (message && virAsprintf(message, _("host CPU model does not match required " "CPU model %s"), guest_model->name) < 0) goto cleanup; ret = VIR_CPU_COMPARE_INCOMPATIBLE; goto cleanup; } if (!(*guestData = ppcMakeCPUData(arch, &guest_model->data))) goto cleanup; } ret = VIR_CPU_COMPARE_IDENTICAL; cleanup: ppcMapFree(map); ppcModelFree(host_model); ppcModelFree(guest_model); return ret; }