static struct ppc64_model * ppc64ModelFromCPU(const virCPUDef *cpu, const struct ppc64_map *map) { struct ppc64_model *model; if (!(model = ppc64ModelFind(map, cpu->model))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unknown CPU model %s"), cpu->model); return NULL; } return ppc64ModelCopy(model); }
static struct ppc64_model * ppc64ModelFromCPU(const virCPUDef *cpu, const struct ppc64_map *map) { struct ppc64_model *model = NULL; if ((model = ppc64ModelFind(map, cpu->model)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unknown CPU model %s"), cpu->model); goto error; } if ((model = ppc64ModelCopy(model)) == NULL) goto error; return model; error: ppc64ModelFree(model); return NULL; }
static virCPUCompareResult ppc64Compute(virCPUDefPtr host, const virCPUDef *other, virCPUDataPtr *guestData, char **message) { struct ppc64_map *map = NULL; struct ppc64_model *host_model = NULL; struct ppc64_model *guest_model = NULL; virCPUDefPtr cpu = NULL; virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; virArch arch; size_t i; /* Ensure existing configurations are handled correctly */ if (!(cpu = virCPUDefCopy(other)) || virCPUppc64ConvertLegacy(cpu) < 0) goto cleanup; 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 = ppc64LoadMap())) goto cleanup; /* Host CPU information */ if (!(host_model = ppc64ModelFromCPU(host, map))) goto cleanup; if (cpu->type == VIR_CPU_TYPE_GUEST) { /* Guest CPU information */ virCPUCompareResult tmp; switch (cpu->mode) { case VIR_CPU_MODE_HOST_MODEL: /* host-model only: * we need to take compatibility modes into account */ tmp = ppc64CheckCompatibilityMode(host->model, cpu->model); if (tmp != VIR_CPU_COMPARE_IDENTICAL) { ret = tmp; goto cleanup; } /* fallthrough */ case VIR_CPU_MODE_HOST_PASSTHROUGH: /* host-model and host-passthrough: * the guest CPU is the same as the host */ guest_model = ppc64ModelCopy(host_model); break; case VIR_CPU_MODE_CUSTOM: /* custom: * look up guest CPU information */ guest_model = ppc64ModelFromCPU(cpu, map); break; } } else { /* Other host CPU information */ guest_model = ppc64ModelFromCPU(cpu, map); } if (!guest_model) goto cleanup; if (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) if (!(*guestData = ppc64MakeCPUData(arch, &guest_model->data))) goto cleanup; ret = VIR_CPU_COMPARE_IDENTICAL; cleanup: virCPUDefFree(cpu); ppc64MapFree(map); ppc64ModelFree(host_model); ppc64ModelFree(guest_model); return ret; }