Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}