Use a typedef instead of the plain struct and heap allocation. This will make it easier to extend the ppc64 specific CPU data later on. --- src/cpu/cpu.h | 2 +- src/cpu/cpu_ppc64.c | 81 ++++++++++++++++++++++++++++++++++++++---------- src/cpu/cpu_ppc64_data.h | 3 +- 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 49d4226..7375876 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -38,7 +38,7 @@ struct _virCPUData { virArch arch; union { virCPUx86Data *x86; - struct cpuPPC64Data ppc64; + virCPUppc64Data *ppc64; /* generic driver needs no data */ } data; }; diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 4428a55..d186d4c 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -48,7 +48,7 @@ struct ppc64_vendor { struct ppc64_model { char *name; const struct ppc64_vendor *vendor; - struct cpuPPC64Data data; + virCPUppc64Data *data; struct ppc64_model *next; }; @@ -58,6 +58,31 @@ struct ppc64_map { }; static void +ppc64DataFree(virCPUppc64Data *data) +{ + if (!data) + return; + + VIR_FREE(data); +} + +static virCPUppc64Data * +ppc64DataCopy(virCPUppc64Data *data) +{ + virCPUppc64Data *copy; + + if (!data) + return NULL; + + if (VIR_ALLOC(copy) < 0) + return NULL; + + copy->pvr = data->pvr; + + return copy; +} + +static void ppc64VendorFree(struct ppc64_vendor *vendor) { if (!vendor) @@ -90,6 +115,7 @@ ppc64ModelFree(struct ppc64_model *model) if (!model) return; + ppc64DataFree(model->data); VIR_FREE(model->name); VIR_FREE(model); } @@ -102,16 +128,22 @@ ppc64ModelCopy(const struct ppc64_model *model) if (!model) return NULL; - if (VIR_ALLOC(copy) < 0 || - VIR_STRDUP(copy->name, model->name) < 0) { - ppc64ModelFree(copy); - return NULL; - } + if (VIR_ALLOC(copy) < 0) + goto error; + + if (VIR_STRDUP(copy->name, model->name) < 0) + goto error; + + if (!(copy->data = ppc64DataCopy(model->data))) + goto error; - copy->data.pvr = model->data.pvr; copy->vendor = model->vendor; return copy; + + error: + ppc64ModelFree(copy); + return NULL; } static struct ppc64_model * @@ -139,7 +171,7 @@ ppc64ModelFindPVR(const struct ppc64_map *map, model = map->models; while (model) { - if (model->data.pvr == pvr) + if (model->data->pvr == pvr) return model; model = model->next; @@ -248,6 +280,11 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, if (VIR_ALLOC(model) < 0) return -1; + if (VIR_ALLOC(model->data) < 0) { + ppc64ModelFree(model); + return -1; + } + model->name = virXPathString("string(@name)", ctxt); if (!model->name) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -285,7 +322,7 @@ ppc64ModelLoad(xmlXPathContextPtr ctxt, model->name); goto ignore; } - model->data.pvr = pvr; + model->data->pvr = pvr; if (!map->models) { map->models = model; @@ -329,7 +366,7 @@ ppc64LoadMap(void) struct ppc64_map *map; if (VIR_ALLOC(map) < 0) - return NULL; + goto error; if (cpuMapLoad("ppc64", ppc64MapLoadCallback, map) < 0) goto error; @@ -343,7 +380,7 @@ ppc64LoadMap(void) static virCPUDataPtr ppc64MakeCPUData(virArch arch, - struct cpuPPC64Data *data) + virCPUppc64Data *data) { virCPUDataPtr cpuData; @@ -351,7 +388,9 @@ ppc64MakeCPUData(virArch arch, return NULL; cpuData->arch = arch; - cpuData->data.ppc64 = *data; + + if (!(cpuData->data.ppc64 = ppc64DataCopy(data))) + VIR_FREE(cpuData); return cpuData; } @@ -432,7 +471,7 @@ ppc64Compute(virCPUDefPtr host, } if (guestData) - if (!(*guestData = ppc64MakeCPUData(arch, &guest_model->data))) + if (!(*guestData = ppc64MakeCPUData(arch, guest_model->data))) goto cleanup; ret = VIR_CPU_COMPARE_IDENTICAL; @@ -484,10 +523,10 @@ ppc64DriverDecode(virCPUDefPtr cpu, if (!data || !(map = ppc64LoadMap())) return -1; - if (!(model = ppc64ModelFindPVR(map, data->data.ppc64.pvr))) { + if (!(model = ppc64ModelFindPVR(map, data->data.ppc64->pvr))) { virReportError(VIR_ERR_OPERATION_FAILED, _("Cannot find CPU model with PVR 0x%08x"), - data->data.ppc64.pvr); + data->data.ppc64->pvr); goto cleanup; } @@ -517,6 +556,7 @@ ppc64DriverFree(virCPUDataPtr data) if (!data) return; + ppc64DataFree(data->data.ppc64); VIR_FREE(data); } @@ -526,16 +566,23 @@ ppc64DriverNodeData(virArch arch) virCPUDataPtr cpuData; if (VIR_ALLOC(cpuData) < 0) - return NULL; + goto error; + + if (VIR_ALLOC(cpuData->data.ppc64) < 0) + goto error; cpuData->arch = arch; #if defined(__powerpc__) || defined(__powerpc64__) asm("mfpvr %0" - : "=r" (cpuData->data.ppc64.pvr)); + : "=r" (cpuData->data.ppc64->pvr)); #endif return cpuData; + + error: + VIR_FREE(cpuData); + return NULL; } static virCPUCompareResult diff --git a/src/cpu/cpu_ppc64_data.h b/src/cpu/cpu_ppc64_data.h index 45152de..c18fc63 100644 --- a/src/cpu/cpu_ppc64_data.h +++ b/src/cpu/cpu_ppc64_data.h @@ -26,7 +26,8 @@ # include <stdint.h> -struct cpuPPC64Data { +typedef struct _virCPUppc64Data virCPUppc64Data; +struct _virCPUppc64Data { uint32_t pvr; }; -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list