Exemple #1
0
static struct ppc64_model *
ppc64ModelCopy(const struct ppc64_model *model)
{
    struct ppc64_model *copy;

    if (VIR_ALLOC(copy) < 0 ||
        VIR_STRDUP(copy->name, model->name) < 0) {
        ppc64ModelFree(copy);
        return NULL;
    }

    copy->data.pvr = model->data.pvr;
    copy->vendor = model->vendor;

    return copy;
}
Exemple #2
0
static void
ppc64MapFree(struct ppc64_map *map)
{
    size_t i;

    if (!map)
        return;

    for (i = 0; i < map->nmodels; i++)
        ppc64ModelFree(map->models[i]);
    VIR_FREE(map->models);

    for (i = 0; i < map->nvendors; i++)
        ppc64VendorFree(map->vendors[i]);
    VIR_FREE(map->vendors);

    VIR_FREE(map);
}
Exemple #3
0
static void
ppc64MapFree(struct ppc64_map *map)
{
    if (map == NULL)
        return;

    while (map->models != NULL) {
        struct ppc64_model *model = map->models;
        map->models = model->next;
        ppc64ModelFree(model);
    }

    while (map->vendors != NULL) {
        struct ppc64_vendor *vendor = map->vendors;
        map->vendors = vendor->next;
        ppc64VendorFree(vendor);
    }

    VIR_FREE(map);
}
Exemple #4
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;
}
Exemple #5
0
static struct ppc64_model *
ppc64ModelCopy(const struct ppc64_model *model)
{
    struct ppc64_model *copy;

    if (VIR_ALLOC(copy) < 0)
        goto error;

    if (VIR_STRDUP(copy->name, model->name) < 0)
        goto error;

    if (ppc64DataCopy(&copy->data, &model->data) < 0)
        goto error;

    copy->vendor = model->vendor;

    return copy;

 error:
    ppc64ModelFree(copy);
    return NULL;
}
Exemple #6
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;
}
Exemple #7
0
static struct ppc64_model *
ppc64ModelParse(xmlXPathContextPtr ctxt,
                struct ppc64_map *map)
{
    struct ppc64_model *model;
    xmlNodePtr *nodes = NULL;
    char *vendor = NULL;
    unsigned long pvr;
    size_t i;
    int n;

    if (VIR_ALLOC(model) < 0)
        goto error;

    model->name = virXPathString("string(@name)", ctxt);
    if (!model->name) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Missing CPU model name"));
        goto error;
    }

    if (ppc64ModelFind(map, model->name)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("CPU model %s already defined"), model->name);
        goto error;
    }

    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 error;
        }

        if (!(model->vendor = ppc64VendorFind(map, vendor))) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unknown vendor %s referenced by CPU model %s"),
                           vendor, model->name);
            goto error;
        }
    }

    if ((n = virXPathNodeSet("./pvr", ctxt, &nodes)) <= 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Missing PVR information for CPU model %s"),
                       model->name);
        goto error;
    }

    if (VIR_ALLOC_N(model->data.pvr, n) < 0)
        goto error;

    model->data.len = n;

    for (i = 0; i < n; i++) {
        ctxt->node = nodes[i];

        if (virXPathULongHex("string(./@value)", ctxt, &pvr) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Missing or invalid PVR value in CPU model %s"),
                           model->name);
            goto error;
        }
        model->data.pvr[i].value = pvr;

        if (virXPathULongHex("string(./@mask)", ctxt, &pvr) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Missing or invalid PVR mask in CPU model %s"),
                           model->name);
            goto error;
        }
        model->data.pvr[i].mask = pvr;
    }

 cleanup:
    VIR_FREE(vendor);
    VIR_FREE(nodes);
    return model;

 error:
    ppc64ModelFree(model);
    model = NULL;
    goto cleanup;
}
Exemple #8
0
static virCPUCompareResult
ppc64Compute(virCPUDefPtr host,
             const virCPUDef *cpu,
             virCPUDataPtr *guestData,
             char **message)

{
    struct ppc64_map *map = NULL;
    struct ppc64_model *host_model = NULL;
    struct ppc64_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 = ppc64LoadMap()) ||
        !(host_model = ppc64ModelFromCPU(host, map)) ||
        !(guest_model = ppc64ModelFromCPU(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 = ppc64MakeCPUData(arch, &guest_model->data)))
            goto cleanup;
    }

    ret = VIR_CPU_COMPARE_IDENTICAL;

 cleanup:
    ppc64MapFree(map);
    ppc64ModelFree(host_model);
    ppc64ModelFree(guest_model);
    return ret;
}
Exemple #9
0
static int
ppc64ModelLoad(xmlXPathContextPtr ctxt,
               struct ppc64_map *map)
{
    struct ppc64_model *model;
    char *vendor = NULL;
    unsigned long pvr;

    if (VIR_ALLOC(model) < 0)
        return -1;

    model->name = virXPathString("string(@name)", ctxt);
    if (!model->name) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Missing CPU model name"));
        goto ignore;
    }

    if (ppc64ModelFind(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 = ppc64VendorFind(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:
    ppc64ModelFree(model);
    goto cleanup;
}