Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}