render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
7a3408
From 81e7bf1fe3b4c70180f8d9b1d89071c13f804002 Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <81e7bf1fe3b4c70180f8d9b1d89071c13f804002@dist-git>
7a3408
From: Andrea Bolognani <abologna@redhat.com>
7a3408
Date: Tue, 11 Aug 2015 17:15:49 +0200
7a3408
Subject: [PATCH] cpu: Rename {powerpc, ppc} => ppc64 (filesystem)
7a3408
7a3408
The driver only supports VIR_ARCH_PPC64 and VIR_ARCH_PPC64LE.
7a3408
7a3408
Just shuffling files around and updating the build system
7a3408
accordingly. No functional changes.
7a3408
7a3408
(cherry picked from commit ef770f016021967359c9443c3bab0f77a55e4afe)
7a3408
7a3408
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1250977
7a3408
7a3408
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 po/POTFILES.in           |   2 +-
7a3408
 src/Makefile.am          |   5 +-
7a3408
 src/cpu/cpu.c            |   2 +-
7a3408
 src/cpu/cpu.h            |   2 +-
7a3408
 src/cpu/cpu_powerpc.c    | 711 -----------------------------------------------
7a3408
 src/cpu/cpu_powerpc.h    |  32 ---
7a3408
 src/cpu/cpu_ppc64.c      | 711 +++++++++++++++++++++++++++++++++++++++++++++++
7a3408
 src/cpu/cpu_ppc64.h      |  32 +++
7a3408
 src/cpu/cpu_ppc64_data.h |  33 +++
7a3408
 src/cpu/cpu_ppc_data.h   |  33 ---
7a3408
 10 files changed, 782 insertions(+), 781 deletions(-)
7a3408
 delete mode 100644 src/cpu/cpu_powerpc.c
7a3408
 delete mode 100644 src/cpu/cpu_powerpc.h
7a3408
 create mode 100644 src/cpu/cpu_ppc64.c
7a3408
 create mode 100644 src/cpu/cpu_ppc64.h
7a3408
 create mode 100644 src/cpu/cpu_ppc64_data.h
7a3408
 delete mode 100644 src/cpu/cpu_ppc_data.h
7a3408
7a3408
diff --git a/po/POTFILES.in b/po/POTFILES.in
7a3408
index a75f5ae..c58a7c1 100644
7a3408
--- a/po/POTFILES.in
7a3408
+++ b/po/POTFILES.in
7a3408
@@ -39,7 +39,7 @@ src/conf/virchrdev.c
7a3408
 src/cpu/cpu.c
7a3408
 src/cpu/cpu_generic.c
7a3408
 src/cpu/cpu_map.c
7a3408
-src/cpu/cpu_powerpc.c
7a3408
+src/cpu/cpu_ppc64.c
7a3408
 src/cpu/cpu_x86.c
7a3408
 src/driver.c
7a3408
 src/esx/esx_driver.c
7a3408
diff --git a/src/Makefile.am b/src/Makefile.am
7a3408
index be63e26..62b8fd6 100644
7a3408
--- a/src/Makefile.am
7a3408
+++ b/src/Makefile.am
7a3408
@@ -1008,8 +1008,9 @@ CPU_SOURCES =							\
7a3408
 		cpu/cpu_s390.h cpu/cpu_s390.c			\
7a3408
 		cpu/cpu_arm.h cpu/cpu_arm.c			\
7a3408
 		cpu/cpu_aarch64.h cpu/cpu_aarch64.c		\
7a3408
-		cpu/cpu_map.h cpu/cpu_map.c cpu/cpu_powerpc.h	\
7a3408
-		cpu/cpu_powerpc.c cpu/cpu_ppc_data.h
7a3408
+		cpu/cpu_ppc64.h cpu/cpu_ppc64.c			\
7a3408
+		cpu/cpu_ppc64_data.h				\
7a3408
+		cpu/cpu_map.h cpu/cpu_map.c
7a3408
 
7a3408
 VMX_SOURCES =							\
7a3408
 		vmx/vmx.c vmx/vmx.h
7a3408
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
7a3408
index 9e67ddd..2e34f81 100644
7a3408
--- a/src/cpu/cpu.c
7a3408
+++ b/src/cpu/cpu.c
7a3408
@@ -29,7 +29,7 @@
7a3408
 #include "cpu.h"
7a3408
 #include "cpu_map.h"
7a3408
 #include "cpu_x86.h"
7a3408
-#include "cpu_powerpc.h"
7a3408
+#include "cpu_ppc64.h"
7a3408
 #include "cpu_s390.h"
7a3408
 #include "cpu_arm.h"
7a3408
 #include "cpu_aarch64.h"
7a3408
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
7a3408
index 09e9538..c0371cd 100644
7a3408
--- a/src/cpu/cpu.h
7a3408
+++ b/src/cpu/cpu.h
7a3408
@@ -29,7 +29,7 @@
7a3408
 # include "virarch.h"
7a3408
 # include "conf/cpu_conf.h"
7a3408
 # include "cpu_x86_data.h"
7a3408
-# include "cpu_ppc_data.h"
7a3408
+# include "cpu_ppc64_data.h"
7a3408
 
7a3408
 
7a3408
 typedef struct _virCPUData virCPUData;
7a3408
diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c
7a3408
deleted file mode 100644
7a3408
index 733a0cd..0000000
7a3408
--- a/src/cpu/cpu_powerpc.c
7a3408
+++ /dev/null
7a3408
@@ -1,711 +0,0 @@
7a3408
-/*
7a3408
- * cpu_powerpc.c: CPU driver for PowerPC CPUs
7a3408
- *
7a3408
- * Copyright (C) 2013 Red Hat, Inc.
7a3408
- * Copyright (C) IBM Corporation, 2010
7a3408
- *
7a3408
- * This library is free software; you can redistribute it and/or
7a3408
- * modify it under the terms of the GNU Lesser General Public
7a3408
- * License as published by the Free Software Foundation; either
7a3408
- * version 2.1 of the License, or (at your option) any later version.
7a3408
- *
7a3408
- * This library is distributed in the hope that it will be useful,
7a3408
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a3408
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7a3408
- * Lesser General Public License for more details.
7a3408
- *
7a3408
- * You should have received a copy of the GNU Lesser General Public
7a3408
- * License along with this library.  If not, see
7a3408
- * <http://www.gnu.org/licenses/>.
7a3408
- *
7a3408
- * Authors:
7a3408
- *      Anton Blanchard <anton@au.ibm.com>
7a3408
- *      Prerna Saxena <prerna@linux.vnet.ibm.com>
7a3408
- *      Li Zhang <zhlcindy@linux.vnet.ibm.com>
7a3408
- */
7a3408
-
7a3408
-#include <config.h>
7a3408
-#include <stdint.h>
7a3408
-
7a3408
-#include "virlog.h"
7a3408
-#include "viralloc.h"
7a3408
-#include "cpu.h"
7a3408
-#include "virstring.h"
7a3408
-#include "cpu_map.h"
7a3408
-#include "virbuffer.h"
7a3408
-
7a3408
-#define VIR_FROM_THIS VIR_FROM_CPU
7a3408
-
7a3408
-VIR_LOG_INIT("cpu.cpu_powerpc");
7a3408
-
7a3408
-static const virArch archs[] = { VIR_ARCH_PPC64, VIR_ARCH_PPC64LE };
7a3408
-
7a3408
-struct ppc_vendor {
7a3408
-    char *name;
7a3408
-    struct ppc_vendor *next;
7a3408
-};
7a3408
-
7a3408
-struct ppc_model {
7a3408
-    char *name;
7a3408
-    const struct ppc_vendor *vendor;
7a3408
-    struct cpuPPCData data;
7a3408
-    struct ppc_model *next;
7a3408
-};
7a3408
-
7a3408
-struct ppc_map {
7a3408
-    struct ppc_vendor *vendors;
7a3408
-    struct ppc_model *models;
7a3408
-};
7a3408
-
7a3408
-
7a3408
-static void
7a3408
-ppcModelFree(struct ppc_model *model)
7a3408
-{
7a3408
-    if (model == NULL)
7a3408
-        return;
7a3408
-
7a3408
-    VIR_FREE(model->name);
7a3408
-    VIR_FREE(model);
7a3408
-}
7a3408
-
7a3408
-static struct ppc_model *
7a3408
-ppcModelFind(const struct ppc_map *map,
7a3408
-             const char *name)
7a3408
-{
7a3408
-    struct ppc_model *model;
7a3408
-
7a3408
-    model = map->models;
7a3408
-    while (model != NULL) {
7a3408
-        if (STREQ(model->name, name))
7a3408
-            return model;
7a3408
-
7a3408
-        model = model->next;
7a3408
-    }
7a3408
-
7a3408
-    return NULL;
7a3408
-}
7a3408
-
7a3408
-static struct ppc_model *
7a3408
-ppcModelFindPVR(const struct ppc_map *map,
7a3408
-                uint32_t pvr)
7a3408
-{
7a3408
-    struct ppc_model *model;
7a3408
-
7a3408
-    model = map->models;
7a3408
-    while (model != NULL) {
7a3408
-        if (model->data.pvr == pvr)
7a3408
-            return model;
7a3408
-
7a3408
-        model = model->next;
7a3408
-    }
7a3408
-
7a3408
-    /* PowerPC Processor Version Register is interpreted as follows :
7a3408
-     * Higher order 16 bits : Power ISA generation.
7a3408
-     * Lower order 16 bits : CPU chip version number.
7a3408
-     * If the exact CPU isn't found, return the nearest matching CPU generation
7a3408
-     */
7a3408
-    if (pvr & 0x0000FFFFul)
7a3408
-        return ppcModelFindPVR(map, (pvr & 0xFFFF0000ul));
7a3408
-
7a3408
-    return NULL;
7a3408
-}
7a3408
-
7a3408
-static struct ppc_model *
7a3408
-ppcModelCopy(const struct ppc_model *model)
7a3408
-{
7a3408
-    struct ppc_model *copy;
7a3408
-
7a3408
-    if (VIR_ALLOC(copy) < 0 ||
7a3408
-        VIR_STRDUP(copy->name, model->name) < 0) {
7a3408
-        ppcModelFree(copy);
7a3408
-        return NULL;
7a3408
-    }
7a3408
-
7a3408
-    copy->data.pvr = model->data.pvr;
7a3408
-    copy->vendor = model->vendor;
7a3408
-
7a3408
-    return copy;
7a3408
-}
7a3408
-
7a3408
-static struct ppc_vendor *
7a3408
-ppcVendorFind(const struct ppc_map *map,
7a3408
-              const char *name)
7a3408
-{
7a3408
-    struct ppc_vendor *vendor;
7a3408
-
7a3408
-    vendor = map->vendors;
7a3408
-    while (vendor) {
7a3408
-        if (STREQ(vendor->name, name))
7a3408
-            return vendor;
7a3408
-
7a3408
-        vendor = vendor->next;
7a3408
-    }
7a3408
-
7a3408
-    return NULL;
7a3408
-}
7a3408
-
7a3408
-static void
7a3408
-ppcVendorFree(struct ppc_vendor *vendor)
7a3408
-{
7a3408
-    if (!vendor)
7a3408
-        return;
7a3408
-
7a3408
-    VIR_FREE(vendor->name);
7a3408
-    VIR_FREE(vendor);
7a3408
-}
7a3408
-
7a3408
-static struct ppc_model *
7a3408
-ppcModelFromCPU(const virCPUDef *cpu,
7a3408
-                const struct ppc_map *map)
7a3408
-{
7a3408
-    struct ppc_model *model = NULL;
7a3408
-
7a3408
-    if ((model = ppcModelFind(map, cpu->model)) == NULL) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       _("Unknown CPU model %s"), cpu->model);
7a3408
-        goto error;
7a3408
-    }
7a3408
-
7a3408
-    if ((model = ppcModelCopy(model)) == NULL)
7a3408
-        goto error;
7a3408
-
7a3408
-    return model;
7a3408
-
7a3408
- error:
7a3408
-    ppcModelFree(model);
7a3408
-    return NULL;
7a3408
-}
7a3408
-
7a3408
-
7a3408
-static int
7a3408
-ppcVendorLoad(xmlXPathContextPtr ctxt,
7a3408
-              struct ppc_map *map)
7a3408
-{
7a3408
-    struct ppc_vendor *vendor = NULL;
7a3408
-
7a3408
-    if (VIR_ALLOC(vendor) < 0)
7a3408
-        return -1;
7a3408
-
7a3408
-    vendor->name = virXPathString("string(@name)", ctxt);
7a3408
-    if (!vendor->name) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       "%s", _("Missing CPU vendor name"));
7a3408
-        goto ignore;
7a3408
-    }
7a3408
-
7a3408
-    if (ppcVendorFind(map, vendor->name)) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       _("CPU vendor %s already defined"), vendor->name);
7a3408
-        goto ignore;
7a3408
-    }
7a3408
-
7a3408
-    if (!map->vendors) {
7a3408
-        map->vendors = vendor;
7a3408
-    } else {
7a3408
-        vendor->next = map->vendors;
7a3408
-        map->vendors = vendor;
7a3408
-    }
7a3408
-
7a3408
- cleanup:
7a3408
-    return 0;
7a3408
-
7a3408
- ignore:
7a3408
-    ppcVendorFree(vendor);
7a3408
-    goto cleanup;
7a3408
-}
7a3408
-
7a3408
-static int
7a3408
-ppcModelLoad(xmlXPathContextPtr ctxt,
7a3408
-             struct ppc_map *map)
7a3408
-{
7a3408
-    struct ppc_model *model;
7a3408
-    char *vendor = NULL;
7a3408
-    unsigned long pvr;
7a3408
-
7a3408
-    if (VIR_ALLOC(model) < 0)
7a3408
-        return -1;
7a3408
-
7a3408
-    model->name = virXPathString("string(@name)", ctxt);
7a3408
-    if (!model->name) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       "%s", _("Missing CPU model name"));
7a3408
-        goto ignore;
7a3408
-    }
7a3408
-
7a3408
-    if (ppcModelFind(map, model->name)) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       _("CPU model %s already defined"), model->name);
7a3408
-        goto ignore;
7a3408
-    }
7a3408
-
7a3408
-    if (virXPathBoolean("boolean(./vendor)", ctxt)) {
7a3408
-        vendor = virXPathString("string(./vendor/@name)", ctxt);
7a3408
-        if (!vendor) {
7a3408
-            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                           _("Invalid vendor element in CPU model %s"),
7a3408
-                           model->name);
7a3408
-            goto ignore;
7a3408
-        }
7a3408
-
7a3408
-        if (!(model->vendor = ppcVendorFind(map, vendor))) {
7a3408
-            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                           _("Unknown vendor %s referenced by CPU model %s"),
7a3408
-                           vendor, model->name);
7a3408
-            goto ignore;
7a3408
-        }
7a3408
-    }
7a3408
-
7a3408
-    if (!virXPathBoolean("boolean(./pvr)", ctxt) ||
7a3408
-        virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       _("Missing or invalid PVR value in CPU model %s"),
7a3408
-                       model->name);
7a3408
-        goto ignore;
7a3408
-    }
7a3408
-    model->data.pvr = pvr;
7a3408
-
7a3408
-    if (map->models == NULL) {
7a3408
-        map->models = model;
7a3408
-    } else {
7a3408
-        model->next = map->models;
7a3408
-        map->models = model;
7a3408
-    }
7a3408
-
7a3408
- cleanup:
7a3408
-    VIR_FREE(vendor);
7a3408
-    return 0;
7a3408
-
7a3408
- ignore:
7a3408
-    ppcModelFree(model);
7a3408
-    goto cleanup;
7a3408
-}
7a3408
-
7a3408
-static int
7a3408
-ppcMapLoadCallback(cpuMapElement element,
7a3408
-                   xmlXPathContextPtr ctxt,
7a3408
-                   void *data)
7a3408
-{
7a3408
-    struct ppc_map *map = data;
7a3408
-
7a3408
-    switch (element) {
7a3408
-    case CPU_MAP_ELEMENT_VENDOR:
7a3408
-        return ppcVendorLoad(ctxt, map);
7a3408
-    case CPU_MAP_ELEMENT_MODEL:
7a3408
-        return ppcModelLoad(ctxt, map);
7a3408
-    case CPU_MAP_ELEMENT_FEATURE:
7a3408
-    case CPU_MAP_ELEMENT_LAST:
7a3408
-        break;
7a3408
-    }
7a3408
-
7a3408
-    return 0;
7a3408
-}
7a3408
-
7a3408
-static void
7a3408
-ppcMapFree(struct ppc_map *map)
7a3408
-{
7a3408
-    if (map == NULL)
7a3408
-        return;
7a3408
-
7a3408
-    while (map->models != NULL) {
7a3408
-        struct ppc_model *model = map->models;
7a3408
-        map->models = model->next;
7a3408
-        ppcModelFree(model);
7a3408
-    }
7a3408
-
7a3408
-    while (map->vendors != NULL) {
7a3408
-        struct ppc_vendor *vendor = map->vendors;
7a3408
-        map->vendors = vendor->next;
7a3408
-        ppcVendorFree(vendor);
7a3408
-    }
7a3408
-
7a3408
-    VIR_FREE(map);
7a3408
-}
7a3408
-
7a3408
-static struct ppc_map *
7a3408
-ppcLoadMap(void)
7a3408
-{
7a3408
-    struct ppc_map *map;
7a3408
-
7a3408
-    if (VIR_ALLOC(map) < 0)
7a3408
-        return NULL;
7a3408
-
7a3408
-    if (cpuMapLoad("ppc64", ppcMapLoadCallback, map) < 0)
7a3408
-        goto error;
7a3408
-
7a3408
-    return map;
7a3408
-
7a3408
- error:
7a3408
-    ppcMapFree(map);
7a3408
-    return NULL;
7a3408
-}
7a3408
-
7a3408
-static virCPUDataPtr
7a3408
-ppcMakeCPUData(virArch arch, struct cpuPPCData *data)
7a3408
-{
7a3408
-    virCPUDataPtr cpuData;
7a3408
-
7a3408
-    if (VIR_ALLOC(cpuData) < 0)
7a3408
-        return NULL;
7a3408
-
7a3408
-    cpuData->arch = arch;
7a3408
-    cpuData->data.ppc = *data;
7a3408
-    data = NULL;
7a3408
-
7a3408
-    return cpuData;
7a3408
-}
7a3408
-
7a3408
-static virCPUCompareResult
7a3408
-ppcCompute(virCPUDefPtr host,
7a3408
-           const virCPUDef *cpu,
7a3408
-           virCPUDataPtr *guestData,
7a3408
-           char **message)
7a3408
-
7a3408
-{
7a3408
-    struct ppc_map *map = NULL;
7a3408
-    struct ppc_model *host_model = NULL;
7a3408
-    struct ppc_model *guest_model = NULL;
7a3408
-
7a3408
-    virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
7a3408
-    virArch arch;
7a3408
-    size_t i;
7a3408
-
7a3408
-    if (cpu->arch != VIR_ARCH_NONE) {
7a3408
-        bool found = false;
7a3408
-
7a3408
-        for (i = 0; i < ARRAY_CARDINALITY(archs); i++) {
7a3408
-            if (archs[i] == cpu->arch) {
7a3408
-                found = true;
7a3408
-                break;
7a3408
-            }
7a3408
-        }
7a3408
-
7a3408
-        if (!found) {
7a3408
-            VIR_DEBUG("CPU arch %s does not match host arch",
7a3408
-                      virArchToString(cpu->arch));
7a3408
-            if (message &&
7a3408
-                virAsprintf(message,
7a3408
-                            _("CPU arch %s does not match host arch"),
7a3408
-                            virArchToString(cpu->arch)) < 0)
7a3408
-                goto cleanup;
7a3408
-
7a3408
-            ret = VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
-            goto cleanup;
7a3408
-        }
7a3408
-        arch = cpu->arch;
7a3408
-    } else {
7a3408
-        arch = host->arch;
7a3408
-    }
7a3408
-
7a3408
-    if (cpu->vendor &&
7a3408
-        (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) {
7a3408
-        VIR_DEBUG("host CPU vendor does not match required CPU vendor %s",
7a3408
-                  cpu->vendor);
7a3408
-        if (message &&
7a3408
-            virAsprintf(message,
7a3408
-                        _("host CPU vendor does not match required "
7a3408
-                        "CPU vendor %s"),
7a3408
-                        cpu->vendor) < 0)
7a3408
-            goto cleanup;
7a3408
-
7a3408
-        ret = VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
-        goto cleanup;
7a3408
-    }
7a3408
-
7a3408
-    if (!(map = ppcLoadMap()) ||
7a3408
-        !(host_model = ppcModelFromCPU(host, map)) ||
7a3408
-        !(guest_model = ppcModelFromCPU(cpu, map)))
7a3408
-        goto cleanup;
7a3408
-
7a3408
-    if (guestData != NULL) {
7a3408
-        if (cpu->type == VIR_CPU_TYPE_GUEST &&
7a3408
-            cpu->match == VIR_CPU_MATCH_STRICT &&
7a3408
-            STRNEQ(guest_model->name, host_model->name)) {
7a3408
-            VIR_DEBUG("host CPU model does not match required CPU model %s",
7a3408
-                      guest_model->name);
7a3408
-            if (message &&
7a3408
-                virAsprintf(message,
7a3408
-                            _("host CPU model does not match required "
7a3408
-                            "CPU model %s"),
7a3408
-                            guest_model->name) < 0)
7a3408
-                goto cleanup;
7a3408
-
7a3408
-            ret = VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
-            goto cleanup;
7a3408
-        }
7a3408
-
7a3408
-        if (!(*guestData = ppcMakeCPUData(arch, &guest_model->data)))
7a3408
-            goto cleanup;
7a3408
-    }
7a3408
-
7a3408
-    ret = VIR_CPU_COMPARE_IDENTICAL;
7a3408
-
7a3408
- cleanup:
7a3408
-    ppcMapFree(map);
7a3408
-    ppcModelFree(host_model);
7a3408
-    ppcModelFree(guest_model);
7a3408
-    return ret;
7a3408
-}
7a3408
-
7a3408
-static virCPUCompareResult
7a3408
-ppcCompare(virCPUDefPtr host,
7a3408
-           virCPUDefPtr cpu,
7a3408
-           bool failIncompatible)
7a3408
-{
7a3408
-    if ((cpu->arch == VIR_ARCH_NONE || host->arch == cpu->arch) &&
7a3408
-        STREQ(host->model, cpu->model))
7a3408
-        return VIR_CPU_COMPARE_IDENTICAL;
7a3408
-
7a3408
-    if (failIncompatible) {
7a3408
-        virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
7a3408
-        return VIR_CPU_COMPARE_ERROR;
7a3408
-    } else {
7a3408
-        return VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
-    }
7a3408
-}
7a3408
-
7a3408
-static int
7a3408
-ppcDecode(virCPUDefPtr cpu,
7a3408
-          const virCPUData *data,
7a3408
-          const char **models,
7a3408
-          unsigned int nmodels,
7a3408
-          const char *preferred ATTRIBUTE_UNUSED,
7a3408
-          unsigned int flags)
7a3408
-{
7a3408
-    int ret = -1;
7a3408
-    struct ppc_map *map;
7a3408
-    const struct ppc_model *model;
7a3408
-
7a3408
-    virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, -1);
7a3408
-
7a3408
-    if (data == NULL || (map = ppcLoadMap()) == NULL)
7a3408
-        return -1;
7a3408
-
7a3408
-    if (!(model = ppcModelFindPVR(map, data->data.ppc.pvr))) {
7a3408
-        virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
-                       _("Cannot find CPU model with PVR 0x%08x"),
7a3408
-                       data->data.ppc.pvr);
7a3408
-        goto cleanup;
7a3408
-    }
7a3408
-
7a3408
-    if (!cpuModelIsAllowed(model->name, models, nmodels)) {
7a3408
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
7a3408
-                       _("CPU model %s is not supported by hypervisor"),
7a3408
-                       model->name);
7a3408
-        goto cleanup;
7a3408
-    }
7a3408
-
7a3408
-    if (VIR_STRDUP(cpu->model, model->name) < 0 ||
7a3408
-        (model->vendor && VIR_STRDUP(cpu->vendor, model->vendor->name) < 0)) {
7a3408
-        goto cleanup;
7a3408
-    }
7a3408
-
7a3408
-    ret = 0;
7a3408
-
7a3408
- cleanup:
7a3408
-    ppcMapFree(map);
7a3408
-
7a3408
-    return ret;
7a3408
-}
7a3408
-
7a3408
-
7a3408
-static void
7a3408
-ppcDataFree(virCPUDataPtr data)
7a3408
-{
7a3408
-    if (data == NULL)
7a3408
-        return;
7a3408
-
7a3408
-    VIR_FREE(data);
7a3408
-}
7a3408
-
7a3408
-static virCPUDataPtr
7a3408
-ppcNodeData(virArch arch)
7a3408
-{
7a3408
-    virCPUDataPtr cpuData;
7a3408
-
7a3408
-    if (VIR_ALLOC(cpuData) < 0)
7a3408
-        return NULL;
7a3408
-
7a3408
-    cpuData->arch = arch;
7a3408
-
7a3408
-#if defined(__powerpc__) || defined(__powerpc64__)
7a3408
-    asm("mfpvr %0"
7a3408
-        : "=r" (cpuData->data.ppc.pvr));
7a3408
-#endif
7a3408
-
7a3408
-    return cpuData;
7a3408
-}
7a3408
-
7a3408
-static virCPUCompareResult
7a3408
-ppcGuestData(virCPUDefPtr host,
7a3408
-             virCPUDefPtr guest,
7a3408
-             virCPUDataPtr *data,
7a3408
-             char **message)
7a3408
-{
7a3408
-    return ppcCompute(host, guest, data, message);
7a3408
-}
7a3408
-
7a3408
-static int
7a3408
-ppcUpdate(virCPUDefPtr guest,
7a3408
-          const virCPUDef *host)
7a3408
-{
7a3408
-    switch ((virCPUMode) guest->mode) {
7a3408
-    case VIR_CPU_MODE_HOST_MODEL:
7a3408
-    case VIR_CPU_MODE_HOST_PASSTHROUGH:
7a3408
-        guest->match = VIR_CPU_MATCH_EXACT;
7a3408
-        virCPUDefFreeModel(guest);
7a3408
-        return virCPUDefCopyModel(guest, host, true);
7a3408
-
7a3408
-    case VIR_CPU_MODE_CUSTOM:
7a3408
-        return 0;
7a3408
-
7a3408
-    case VIR_CPU_MODE_LAST:
7a3408
-        break;
7a3408
-    }
7a3408
-
7a3408
-    virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                   _("Unexpected CPU mode: %d"), guest->mode);
7a3408
-    return -1;
7a3408
-}
7a3408
-
7a3408
-static virCPUDefPtr
7a3408
-ppcBaseline(virCPUDefPtr *cpus,
7a3408
-            unsigned int ncpus,
7a3408
-            const char **models ATTRIBUTE_UNUSED,
7a3408
-            unsigned int nmodels ATTRIBUTE_UNUSED,
7a3408
-            unsigned int flags)
7a3408
-{
7a3408
-    struct ppc_map *map = NULL;
7a3408
-    const struct ppc_model *model;
7a3408
-    const struct ppc_vendor *vendor = NULL;
7a3408
-    virCPUDefPtr cpu = NULL;
7a3408
-    size_t i;
7a3408
-
7a3408
-    virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
7a3408
-                  VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
7a3408
-
7a3408
-    if (!(map = ppcLoadMap()))
7a3408
-        goto error;
7a3408
-
7a3408
-    if (!(model = ppcModelFind(map, cpus[0]->model))) {
7a3408
-        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
-                       _("Unknown CPU model %s"), cpus[0]->model);
7a3408
-        goto error;
7a3408
-    }
7a3408
-
7a3408
-    for (i = 0; i < ncpus; i++) {
7a3408
-        const struct ppc_vendor *vnd;
7a3408
-
7a3408
-        if (STRNEQ(cpus[i]->model, model->name)) {
7a3408
-            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
7a3408
-                           _("CPUs are incompatible"));
7a3408
-            goto error;
7a3408
-        }
7a3408
-
7a3408
-        if (!cpus[i]->vendor)
7a3408
-            continue;
7a3408
-
7a3408
-        if (!(vnd = ppcVendorFind(map, cpus[i]->vendor))) {
7a3408
-            virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
-                           _("Unknown CPU vendor %s"), cpus[i]->vendor);
7a3408
-            goto error;
7a3408
-        }
7a3408
-
7a3408
-        if (model->vendor) {
7a3408
-            if (model->vendor != vnd) {
7a3408
-                virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
-                               _("CPU vendor %s of model %s differs from "
7a3408
-                                 "vendor %s"),
7a3408
-                               model->vendor->name, model->name,
7a3408
-                               vnd->name);
7a3408
-                goto error;
7a3408
-            }
7a3408
-        } else if (vendor) {
7a3408
-            if (vendor != vnd) {
7a3408
-                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
7a3408
-                               _("CPU vendors do not match"));
7a3408
-                goto error;
7a3408
-            }
7a3408
-        } else {
7a3408
-            vendor = vnd;
7a3408
-        }
7a3408
-    }
7a3408
-
7a3408
-    if (VIR_ALLOC(cpu) < 0 ||
7a3408
-        VIR_STRDUP(cpu->model, model->name) < 0)
7a3408
-        goto error;
7a3408
-
7a3408
-    if (vendor && VIR_STRDUP(cpu->vendor, vendor->name) < 0)
7a3408
-        goto error;
7a3408
-
7a3408
-    cpu->type = VIR_CPU_TYPE_GUEST;
7a3408
-    cpu->match = VIR_CPU_MATCH_EXACT;
7a3408
-
7a3408
- cleanup:
7a3408
-    ppcMapFree(map);
7a3408
-
7a3408
-    return cpu;
7a3408
-
7a3408
- error:
7a3408
-    virCPUDefFree(cpu);
7a3408
-    cpu = NULL;
7a3408
-    goto cleanup;
7a3408
-}
7a3408
-
7a3408
-static int
7a3408
-ppcGetModels(char ***models)
7a3408
-{
7a3408
-    struct ppc_map *map;
7a3408
-    struct ppc_model *model;
7a3408
-    char *name;
7a3408
-    size_t nmodels = 0;
7a3408
-
7a3408
-    if (!(map = ppcLoadMap()))
7a3408
-        goto error;
7a3408
-
7a3408
-    if (models && VIR_ALLOC_N(*models, 0) < 0)
7a3408
-        goto error;
7a3408
-
7a3408
-    model = map->models;
7a3408
-    while (model != NULL) {
7a3408
-        if (models) {
7a3408
-            if (VIR_STRDUP(name, model->name) < 0)
7a3408
-                goto error;
7a3408
-
7a3408
-            if (VIR_APPEND_ELEMENT(*models, nmodels, name) < 0)
7a3408
-                goto error;
7a3408
-        } else {
7a3408
-            nmodels++;
7a3408
-        }
7a3408
-
7a3408
-        model = model->next;
7a3408
-    }
7a3408
-
7a3408
- cleanup:
7a3408
-    ppcMapFree(map);
7a3408
-
7a3408
-    return nmodels;
7a3408
-
7a3408
- error:
7a3408
-    if (models) {
7a3408
-        virStringFreeList(*models);
7a3408
-        *models = NULL;
7a3408
-    }
7a3408
-    nmodels = -1;
7a3408
-    goto cleanup;
7a3408
-}
7a3408
-
7a3408
-struct cpuArchDriver cpuDriverPowerPC = {
7a3408
-    .name = "ppc64",
7a3408
-    .arch = archs,
7a3408
-    .narch = ARRAY_CARDINALITY(archs),
7a3408
-    .compare    = ppcCompare,
7a3408
-    .decode     = ppcDecode,
7a3408
-    .encode     = NULL,
7a3408
-    .free       = ppcDataFree,
7a3408
-    .nodeData   = ppcNodeData,
7a3408
-    .guestData  = ppcGuestData,
7a3408
-    .baseline   = ppcBaseline,
7a3408
-    .update     = ppcUpdate,
7a3408
-    .hasFeature = NULL,
7a3408
-    .getModels  = ppcGetModels,
7a3408
-};
7a3408
diff --git a/src/cpu/cpu_powerpc.h b/src/cpu/cpu_powerpc.h
7a3408
deleted file mode 100644
7a3408
index 312886e..0000000
7a3408
--- a/src/cpu/cpu_powerpc.h
7a3408
+++ /dev/null
7a3408
@@ -1,32 +0,0 @@
7a3408
-/*
7a3408
- * cpu_powerpc.h: CPU driver for PowerPC CPUs
7a3408
- *
7a3408
- * Copyright (C) Copyright (C) IBM Corporation, 2010
7a3408
- *
7a3408
- * This library is free software; you can redistribute it and/or
7a3408
- * modify it under the terms of the GNU Lesser General Public
7a3408
- * License as published by the Free Software Foundation; either
7a3408
- * version 2.1 of the License, or (at your option) any later version.
7a3408
- *
7a3408
- * This library is distributed in the hope that it will be useful,
7a3408
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a3408
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7a3408
- * Lesser General Public License for more details.
7a3408
- *
7a3408
- * You should have received a copy of the GNU Lesser General Public
7a3408
- * License along with this library.  If not, see
7a3408
- * <http://www.gnu.org/licenses/>.
7a3408
- *
7a3408
- * Authors:
7a3408
- *      Anton Blanchard <anton@au.ibm.com>
7a3408
- *      Prerna Saxena <prerna@linux.vnet.ibm.com>
7a3408
- */
7a3408
-
7a3408
-#ifndef __VIR_CPU_POWERPC_H__
7a3408
-# define __VIR_CPU_POWERPC_H__
7a3408
-
7a3408
-# include "cpu.h"
7a3408
-
7a3408
-extern struct cpuArchDriver cpuDriverPowerPC;
7a3408
-
7a3408
-#endif /* __VIR_CPU_POWERPC_H__ */
7a3408
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
7a3408
new file mode 100644
7a3408
index 0000000..7866bdd
7a3408
--- /dev/null
7a3408
+++ b/src/cpu/cpu_ppc64.c
7a3408
@@ -0,0 +1,711 @@
7a3408
+/*
7a3408
+ * cpu_ppc64.c: CPU driver for PowerPC CPUs
7a3408
+ *
7a3408
+ * Copyright (C) 2013 Red Hat, Inc.
7a3408
+ * Copyright (C) IBM Corporation, 2010
7a3408
+ *
7a3408
+ * This library is free software; you can redistribute it and/or
7a3408
+ * modify it under the terms of the GNU Lesser General Public
7a3408
+ * License as published by the Free Software Foundation; either
7a3408
+ * version 2.1 of the License, or (at your option) any later version.
7a3408
+ *
7a3408
+ * This library is distributed in the hope that it will be useful,
7a3408
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a3408
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7a3408
+ * Lesser General Public License for more details.
7a3408
+ *
7a3408
+ * You should have received a copy of the GNU Lesser General Public
7a3408
+ * License along with this library.  If not, see
7a3408
+ * <http://www.gnu.org/licenses/>.
7a3408
+ *
7a3408
+ * Authors:
7a3408
+ *      Anton Blanchard <anton@au.ibm.com>
7a3408
+ *      Prerna Saxena <prerna@linux.vnet.ibm.com>
7a3408
+ *      Li Zhang <zhlcindy@linux.vnet.ibm.com>
7a3408
+ */
7a3408
+
7a3408
+#include <config.h>
7a3408
+#include <stdint.h>
7a3408
+
7a3408
+#include "virlog.h"
7a3408
+#include "viralloc.h"
7a3408
+#include "cpu.h"
7a3408
+#include "virstring.h"
7a3408
+#include "cpu_map.h"
7a3408
+#include "virbuffer.h"
7a3408
+
7a3408
+#define VIR_FROM_THIS VIR_FROM_CPU
7a3408
+
7a3408
+VIR_LOG_INIT("cpu.cpu_powerpc");
7a3408
+
7a3408
+static const virArch archs[] = { VIR_ARCH_PPC64, VIR_ARCH_PPC64LE };
7a3408
+
7a3408
+struct ppc_vendor {
7a3408
+    char *name;
7a3408
+    struct ppc_vendor *next;
7a3408
+};
7a3408
+
7a3408
+struct ppc_model {
7a3408
+    char *name;
7a3408
+    const struct ppc_vendor *vendor;
7a3408
+    struct cpuPPCData data;
7a3408
+    struct ppc_model *next;
7a3408
+};
7a3408
+
7a3408
+struct ppc_map {
7a3408
+    struct ppc_vendor *vendors;
7a3408
+    struct ppc_model *models;
7a3408
+};
7a3408
+
7a3408
+
7a3408
+static void
7a3408
+ppcModelFree(struct ppc_model *model)
7a3408
+{
7a3408
+    if (model == NULL)
7a3408
+        return;
7a3408
+
7a3408
+    VIR_FREE(model->name);
7a3408
+    VIR_FREE(model);
7a3408
+}
7a3408
+
7a3408
+static struct ppc_model *
7a3408
+ppcModelFind(const struct ppc_map *map,
7a3408
+             const char *name)
7a3408
+{
7a3408
+    struct ppc_model *model;
7a3408
+
7a3408
+    model = map->models;
7a3408
+    while (model != NULL) {
7a3408
+        if (STREQ(model->name, name))
7a3408
+            return model;
7a3408
+
7a3408
+        model = model->next;
7a3408
+    }
7a3408
+
7a3408
+    return NULL;
7a3408
+}
7a3408
+
7a3408
+static struct ppc_model *
7a3408
+ppcModelFindPVR(const struct ppc_map *map,
7a3408
+                uint32_t pvr)
7a3408
+{
7a3408
+    struct ppc_model *model;
7a3408
+
7a3408
+    model = map->models;
7a3408
+    while (model != NULL) {
7a3408
+        if (model->data.pvr == pvr)
7a3408
+            return model;
7a3408
+
7a3408
+        model = model->next;
7a3408
+    }
7a3408
+
7a3408
+    /* PowerPC Processor Version Register is interpreted as follows :
7a3408
+     * Higher order 16 bits : Power ISA generation.
7a3408
+     * Lower order 16 bits : CPU chip version number.
7a3408
+     * If the exact CPU isn't found, return the nearest matching CPU generation
7a3408
+     */
7a3408
+    if (pvr & 0x0000FFFFul)
7a3408
+        return ppcModelFindPVR(map, (pvr & 0xFFFF0000ul));
7a3408
+
7a3408
+    return NULL;
7a3408
+}
7a3408
+
7a3408
+static struct ppc_model *
7a3408
+ppcModelCopy(const struct ppc_model *model)
7a3408
+{
7a3408
+    struct ppc_model *copy;
7a3408
+
7a3408
+    if (VIR_ALLOC(copy) < 0 ||
7a3408
+        VIR_STRDUP(copy->name, model->name) < 0) {
7a3408
+        ppcModelFree(copy);
7a3408
+        return NULL;
7a3408
+    }
7a3408
+
7a3408
+    copy->data.pvr = model->data.pvr;
7a3408
+    copy->vendor = model->vendor;
7a3408
+
7a3408
+    return copy;
7a3408
+}
7a3408
+
7a3408
+static struct ppc_vendor *
7a3408
+ppcVendorFind(const struct ppc_map *map,
7a3408
+              const char *name)
7a3408
+{
7a3408
+    struct ppc_vendor *vendor;
7a3408
+
7a3408
+    vendor = map->vendors;
7a3408
+    while (vendor) {
7a3408
+        if (STREQ(vendor->name, name))
7a3408
+            return vendor;
7a3408
+
7a3408
+        vendor = vendor->next;
7a3408
+    }
7a3408
+
7a3408
+    return NULL;
7a3408
+}
7a3408
+
7a3408
+static void
7a3408
+ppcVendorFree(struct ppc_vendor *vendor)
7a3408
+{
7a3408
+    if (!vendor)
7a3408
+        return;
7a3408
+
7a3408
+    VIR_FREE(vendor->name);
7a3408
+    VIR_FREE(vendor);
7a3408
+}
7a3408
+
7a3408
+static struct ppc_model *
7a3408
+ppcModelFromCPU(const virCPUDef *cpu,
7a3408
+                const struct ppc_map *map)
7a3408
+{
7a3408
+    struct ppc_model *model = NULL;
7a3408
+
7a3408
+    if ((model = ppcModelFind(map, cpu->model)) == NULL) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       _("Unknown CPU model %s"), cpu->model);
7a3408
+        goto error;
7a3408
+    }
7a3408
+
7a3408
+    if ((model = ppcModelCopy(model)) == NULL)
7a3408
+        goto error;
7a3408
+
7a3408
+    return model;
7a3408
+
7a3408
+ error:
7a3408
+    ppcModelFree(model);
7a3408
+    return NULL;
7a3408
+}
7a3408
+
7a3408
+
7a3408
+static int
7a3408
+ppcVendorLoad(xmlXPathContextPtr ctxt,
7a3408
+              struct ppc_map *map)
7a3408
+{
7a3408
+    struct ppc_vendor *vendor = NULL;
7a3408
+
7a3408
+    if (VIR_ALLOC(vendor) < 0)
7a3408
+        return -1;
7a3408
+
7a3408
+    vendor->name = virXPathString("string(@name)", ctxt);
7a3408
+    if (!vendor->name) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       "%s", _("Missing CPU vendor name"));
7a3408
+        goto ignore;
7a3408
+    }
7a3408
+
7a3408
+    if (ppcVendorFind(map, vendor->name)) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       _("CPU vendor %s already defined"), vendor->name);
7a3408
+        goto ignore;
7a3408
+    }
7a3408
+
7a3408
+    if (!map->vendors) {
7a3408
+        map->vendors = vendor;
7a3408
+    } else {
7a3408
+        vendor->next = map->vendors;
7a3408
+        map->vendors = vendor;
7a3408
+    }
7a3408
+
7a3408
+ cleanup:
7a3408
+    return 0;
7a3408
+
7a3408
+ ignore:
7a3408
+    ppcVendorFree(vendor);
7a3408
+    goto cleanup;
7a3408
+}
7a3408
+
7a3408
+static int
7a3408
+ppcModelLoad(xmlXPathContextPtr ctxt,
7a3408
+             struct ppc_map *map)
7a3408
+{
7a3408
+    struct ppc_model *model;
7a3408
+    char *vendor = NULL;
7a3408
+    unsigned long pvr;
7a3408
+
7a3408
+    if (VIR_ALLOC(model) < 0)
7a3408
+        return -1;
7a3408
+
7a3408
+    model->name = virXPathString("string(@name)", ctxt);
7a3408
+    if (!model->name) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       "%s", _("Missing CPU model name"));
7a3408
+        goto ignore;
7a3408
+    }
7a3408
+
7a3408
+    if (ppcModelFind(map, model->name)) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       _("CPU model %s already defined"), model->name);
7a3408
+        goto ignore;
7a3408
+    }
7a3408
+
7a3408
+    if (virXPathBoolean("boolean(./vendor)", ctxt)) {
7a3408
+        vendor = virXPathString("string(./vendor/@name)", ctxt);
7a3408
+        if (!vendor) {
7a3408
+            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                           _("Invalid vendor element in CPU model %s"),
7a3408
+                           model->name);
7a3408
+            goto ignore;
7a3408
+        }
7a3408
+
7a3408
+        if (!(model->vendor = ppcVendorFind(map, vendor))) {
7a3408
+            virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                           _("Unknown vendor %s referenced by CPU model %s"),
7a3408
+                           vendor, model->name);
7a3408
+            goto ignore;
7a3408
+        }
7a3408
+    }
7a3408
+
7a3408
+    if (!virXPathBoolean("boolean(./pvr)", ctxt) ||
7a3408
+        virXPathULongHex("string(./pvr/@value)", ctxt, &pvr) < 0) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       _("Missing or invalid PVR value in CPU model %s"),
7a3408
+                       model->name);
7a3408
+        goto ignore;
7a3408
+    }
7a3408
+    model->data.pvr = pvr;
7a3408
+
7a3408
+    if (map->models == NULL) {
7a3408
+        map->models = model;
7a3408
+    } else {
7a3408
+        model->next = map->models;
7a3408
+        map->models = model;
7a3408
+    }
7a3408
+
7a3408
+ cleanup:
7a3408
+    VIR_FREE(vendor);
7a3408
+    return 0;
7a3408
+
7a3408
+ ignore:
7a3408
+    ppcModelFree(model);
7a3408
+    goto cleanup;
7a3408
+}
7a3408
+
7a3408
+static int
7a3408
+ppcMapLoadCallback(cpuMapElement element,
7a3408
+                   xmlXPathContextPtr ctxt,
7a3408
+                   void *data)
7a3408
+{
7a3408
+    struct ppc_map *map = data;
7a3408
+
7a3408
+    switch (element) {
7a3408
+    case CPU_MAP_ELEMENT_VENDOR:
7a3408
+        return ppcVendorLoad(ctxt, map);
7a3408
+    case CPU_MAP_ELEMENT_MODEL:
7a3408
+        return ppcModelLoad(ctxt, map);
7a3408
+    case CPU_MAP_ELEMENT_FEATURE:
7a3408
+    case CPU_MAP_ELEMENT_LAST:
7a3408
+        break;
7a3408
+    }
7a3408
+
7a3408
+    return 0;
7a3408
+}
7a3408
+
7a3408
+static void
7a3408
+ppcMapFree(struct ppc_map *map)
7a3408
+{
7a3408
+    if (map == NULL)
7a3408
+        return;
7a3408
+
7a3408
+    while (map->models != NULL) {
7a3408
+        struct ppc_model *model = map->models;
7a3408
+        map->models = model->next;
7a3408
+        ppcModelFree(model);
7a3408
+    }
7a3408
+
7a3408
+    while (map->vendors != NULL) {
7a3408
+        struct ppc_vendor *vendor = map->vendors;
7a3408
+        map->vendors = vendor->next;
7a3408
+        ppcVendorFree(vendor);
7a3408
+    }
7a3408
+
7a3408
+    VIR_FREE(map);
7a3408
+}
7a3408
+
7a3408
+static struct ppc_map *
7a3408
+ppcLoadMap(void)
7a3408
+{
7a3408
+    struct ppc_map *map;
7a3408
+
7a3408
+    if (VIR_ALLOC(map) < 0)
7a3408
+        return NULL;
7a3408
+
7a3408
+    if (cpuMapLoad("ppc64", ppcMapLoadCallback, map) < 0)
7a3408
+        goto error;
7a3408
+
7a3408
+    return map;
7a3408
+
7a3408
+ error:
7a3408
+    ppcMapFree(map);
7a3408
+    return NULL;
7a3408
+}
7a3408
+
7a3408
+static virCPUDataPtr
7a3408
+ppcMakeCPUData(virArch arch, struct cpuPPCData *data)
7a3408
+{
7a3408
+    virCPUDataPtr cpuData;
7a3408
+
7a3408
+    if (VIR_ALLOC(cpuData) < 0)
7a3408
+        return NULL;
7a3408
+
7a3408
+    cpuData->arch = arch;
7a3408
+    cpuData->data.ppc = *data;
7a3408
+    data = NULL;
7a3408
+
7a3408
+    return cpuData;
7a3408
+}
7a3408
+
7a3408
+static virCPUCompareResult
7a3408
+ppcCompute(virCPUDefPtr host,
7a3408
+           const virCPUDef *cpu,
7a3408
+           virCPUDataPtr *guestData,
7a3408
+           char **message)
7a3408
+
7a3408
+{
7a3408
+    struct ppc_map *map = NULL;
7a3408
+    struct ppc_model *host_model = NULL;
7a3408
+    struct ppc_model *guest_model = NULL;
7a3408
+
7a3408
+    virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
7a3408
+    virArch arch;
7a3408
+    size_t i;
7a3408
+
7a3408
+    if (cpu->arch != VIR_ARCH_NONE) {
7a3408
+        bool found = false;
7a3408
+
7a3408
+        for (i = 0; i < ARRAY_CARDINALITY(archs); i++) {
7a3408
+            if (archs[i] == cpu->arch) {
7a3408
+                found = true;
7a3408
+                break;
7a3408
+            }
7a3408
+        }
7a3408
+
7a3408
+        if (!found) {
7a3408
+            VIR_DEBUG("CPU arch %s does not match host arch",
7a3408
+                      virArchToString(cpu->arch));
7a3408
+            if (message &&
7a3408
+                virAsprintf(message,
7a3408
+                            _("CPU arch %s does not match host arch"),
7a3408
+                            virArchToString(cpu->arch)) < 0)
7a3408
+                goto cleanup;
7a3408
+
7a3408
+            ret = VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
+            goto cleanup;
7a3408
+        }
7a3408
+        arch = cpu->arch;
7a3408
+    } else {
7a3408
+        arch = host->arch;
7a3408
+    }
7a3408
+
7a3408
+    if (cpu->vendor &&
7a3408
+        (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) {
7a3408
+        VIR_DEBUG("host CPU vendor does not match required CPU vendor %s",
7a3408
+                  cpu->vendor);
7a3408
+        if (message &&
7a3408
+            virAsprintf(message,
7a3408
+                        _("host CPU vendor does not match required "
7a3408
+                        "CPU vendor %s"),
7a3408
+                        cpu->vendor) < 0)
7a3408
+            goto cleanup;
7a3408
+
7a3408
+        ret = VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
+        goto cleanup;
7a3408
+    }
7a3408
+
7a3408
+    if (!(map = ppcLoadMap()) ||
7a3408
+        !(host_model = ppcModelFromCPU(host, map)) ||
7a3408
+        !(guest_model = ppcModelFromCPU(cpu, map)))
7a3408
+        goto cleanup;
7a3408
+
7a3408
+    if (guestData != NULL) {
7a3408
+        if (cpu->type == VIR_CPU_TYPE_GUEST &&
7a3408
+            cpu->match == VIR_CPU_MATCH_STRICT &&
7a3408
+            STRNEQ(guest_model->name, host_model->name)) {
7a3408
+            VIR_DEBUG("host CPU model does not match required CPU model %s",
7a3408
+                      guest_model->name);
7a3408
+            if (message &&
7a3408
+                virAsprintf(message,
7a3408
+                            _("host CPU model does not match required "
7a3408
+                            "CPU model %s"),
7a3408
+                            guest_model->name) < 0)
7a3408
+                goto cleanup;
7a3408
+
7a3408
+            ret = VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
+            goto cleanup;
7a3408
+        }
7a3408
+
7a3408
+        if (!(*guestData = ppcMakeCPUData(arch, &guest_model->data)))
7a3408
+            goto cleanup;
7a3408
+    }
7a3408
+
7a3408
+    ret = VIR_CPU_COMPARE_IDENTICAL;
7a3408
+
7a3408
+ cleanup:
7a3408
+    ppcMapFree(map);
7a3408
+    ppcModelFree(host_model);
7a3408
+    ppcModelFree(guest_model);
7a3408
+    return ret;
7a3408
+}
7a3408
+
7a3408
+static virCPUCompareResult
7a3408
+ppcCompare(virCPUDefPtr host,
7a3408
+           virCPUDefPtr cpu,
7a3408
+           bool failIncompatible)
7a3408
+{
7a3408
+    if ((cpu->arch == VIR_ARCH_NONE || host->arch == cpu->arch) &&
7a3408
+        STREQ(host->model, cpu->model))
7a3408
+        return VIR_CPU_COMPARE_IDENTICAL;
7a3408
+
7a3408
+    if (failIncompatible) {
7a3408
+        virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
7a3408
+        return VIR_CPU_COMPARE_ERROR;
7a3408
+    } else {
7a3408
+        return VIR_CPU_COMPARE_INCOMPATIBLE;
7a3408
+    }
7a3408
+}
7a3408
+
7a3408
+static int
7a3408
+ppcDecode(virCPUDefPtr cpu,
7a3408
+          const virCPUData *data,
7a3408
+          const char **models,
7a3408
+          unsigned int nmodels,
7a3408
+          const char *preferred ATTRIBUTE_UNUSED,
7a3408
+          unsigned int flags)
7a3408
+{
7a3408
+    int ret = -1;
7a3408
+    struct ppc_map *map;
7a3408
+    const struct ppc_model *model;
7a3408
+
7a3408
+    virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, -1);
7a3408
+
7a3408
+    if (data == NULL || (map = ppcLoadMap()) == NULL)
7a3408
+        return -1;
7a3408
+
7a3408
+    if (!(model = ppcModelFindPVR(map, data->data.ppc.pvr))) {
7a3408
+        virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
+                       _("Cannot find CPU model with PVR 0x%08x"),
7a3408
+                       data->data.ppc.pvr);
7a3408
+        goto cleanup;
7a3408
+    }
7a3408
+
7a3408
+    if (!cpuModelIsAllowed(model->name, models, nmodels)) {
7a3408
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
7a3408
+                       _("CPU model %s is not supported by hypervisor"),
7a3408
+                       model->name);
7a3408
+        goto cleanup;
7a3408
+    }
7a3408
+
7a3408
+    if (VIR_STRDUP(cpu->model, model->name) < 0 ||
7a3408
+        (model->vendor && VIR_STRDUP(cpu->vendor, model->vendor->name) < 0)) {
7a3408
+        goto cleanup;
7a3408
+    }
7a3408
+
7a3408
+    ret = 0;
7a3408
+
7a3408
+ cleanup:
7a3408
+    ppcMapFree(map);
7a3408
+
7a3408
+    return ret;
7a3408
+}
7a3408
+
7a3408
+
7a3408
+static void
7a3408
+ppcDataFree(virCPUDataPtr data)
7a3408
+{
7a3408
+    if (data == NULL)
7a3408
+        return;
7a3408
+
7a3408
+    VIR_FREE(data);
7a3408
+}
7a3408
+
7a3408
+static virCPUDataPtr
7a3408
+ppcNodeData(virArch arch)
7a3408
+{
7a3408
+    virCPUDataPtr cpuData;
7a3408
+
7a3408
+    if (VIR_ALLOC(cpuData) < 0)
7a3408
+        return NULL;
7a3408
+
7a3408
+    cpuData->arch = arch;
7a3408
+
7a3408
+#if defined(__powerpc__) || defined(__powerpc64__)
7a3408
+    asm("mfpvr %0"
7a3408
+        : "=r" (cpuData->data.ppc.pvr));
7a3408
+#endif
7a3408
+
7a3408
+    return cpuData;
7a3408
+}
7a3408
+
7a3408
+static virCPUCompareResult
7a3408
+ppcGuestData(virCPUDefPtr host,
7a3408
+             virCPUDefPtr guest,
7a3408
+             virCPUDataPtr *data,
7a3408
+             char **message)
7a3408
+{
7a3408
+    return ppcCompute(host, guest, data, message);
7a3408
+}
7a3408
+
7a3408
+static int
7a3408
+ppcUpdate(virCPUDefPtr guest,
7a3408
+          const virCPUDef *host)
7a3408
+{
7a3408
+    switch ((virCPUMode) guest->mode) {
7a3408
+    case VIR_CPU_MODE_HOST_MODEL:
7a3408
+    case VIR_CPU_MODE_HOST_PASSTHROUGH:
7a3408
+        guest->match = VIR_CPU_MATCH_EXACT;
7a3408
+        virCPUDefFreeModel(guest);
7a3408
+        return virCPUDefCopyModel(guest, host, true);
7a3408
+
7a3408
+    case VIR_CPU_MODE_CUSTOM:
7a3408
+        return 0;
7a3408
+
7a3408
+    case VIR_CPU_MODE_LAST:
7a3408
+        break;
7a3408
+    }
7a3408
+
7a3408
+    virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                   _("Unexpected CPU mode: %d"), guest->mode);
7a3408
+    return -1;
7a3408
+}
7a3408
+
7a3408
+static virCPUDefPtr
7a3408
+ppcBaseline(virCPUDefPtr *cpus,
7a3408
+            unsigned int ncpus,
7a3408
+            const char **models ATTRIBUTE_UNUSED,
7a3408
+            unsigned int nmodels ATTRIBUTE_UNUSED,
7a3408
+            unsigned int flags)
7a3408
+{
7a3408
+    struct ppc_map *map = NULL;
7a3408
+    const struct ppc_model *model;
7a3408
+    const struct ppc_vendor *vendor = NULL;
7a3408
+    virCPUDefPtr cpu = NULL;
7a3408
+    size_t i;
7a3408
+
7a3408
+    virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES |
7a3408
+                  VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL);
7a3408
+
7a3408
+    if (!(map = ppcLoadMap()))
7a3408
+        goto error;
7a3408
+
7a3408
+    if (!(model = ppcModelFind(map, cpus[0]->model))) {
7a3408
+        virReportError(VIR_ERR_INTERNAL_ERROR,
7a3408
+                       _("Unknown CPU model %s"), cpus[0]->model);
7a3408
+        goto error;
7a3408
+    }
7a3408
+
7a3408
+    for (i = 0; i < ncpus; i++) {
7a3408
+        const struct ppc_vendor *vnd;
7a3408
+
7a3408
+        if (STRNEQ(cpus[i]->model, model->name)) {
7a3408
+            virReportError(VIR_ERR_OPERATION_FAILED, "%s",
7a3408
+                           _("CPUs are incompatible"));
7a3408
+            goto error;
7a3408
+        }
7a3408
+
7a3408
+        if (!cpus[i]->vendor)
7a3408
+            continue;
7a3408
+
7a3408
+        if (!(vnd = ppcVendorFind(map, cpus[i]->vendor))) {
7a3408
+            virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
+                           _("Unknown CPU vendor %s"), cpus[i]->vendor);
7a3408
+            goto error;
7a3408
+        }
7a3408
+
7a3408
+        if (model->vendor) {
7a3408
+            if (model->vendor != vnd) {
7a3408
+                virReportError(VIR_ERR_OPERATION_FAILED,
7a3408
+                               _("CPU vendor %s of model %s differs from "
7a3408
+                                 "vendor %s"),
7a3408
+                               model->vendor->name, model->name,
7a3408
+                               vnd->name);
7a3408
+                goto error;
7a3408
+            }
7a3408
+        } else if (vendor) {
7a3408
+            if (vendor != vnd) {
7a3408
+                virReportError(VIR_ERR_OPERATION_FAILED, "%s",
7a3408
+                               _("CPU vendors do not match"));
7a3408
+                goto error;
7a3408
+            }
7a3408
+        } else {
7a3408
+            vendor = vnd;
7a3408
+        }
7a3408
+    }
7a3408
+
7a3408
+    if (VIR_ALLOC(cpu) < 0 ||
7a3408
+        VIR_STRDUP(cpu->model, model->name) < 0)
7a3408
+        goto error;
7a3408
+
7a3408
+    if (vendor && VIR_STRDUP(cpu->vendor, vendor->name) < 0)
7a3408
+        goto error;
7a3408
+
7a3408
+    cpu->type = VIR_CPU_TYPE_GUEST;
7a3408
+    cpu->match = VIR_CPU_MATCH_EXACT;
7a3408
+
7a3408
+ cleanup:
7a3408
+    ppcMapFree(map);
7a3408
+
7a3408
+    return cpu;
7a3408
+
7a3408
+ error:
7a3408
+    virCPUDefFree(cpu);
7a3408
+    cpu = NULL;
7a3408
+    goto cleanup;
7a3408
+}
7a3408
+
7a3408
+static int
7a3408
+ppcGetModels(char ***models)
7a3408
+{
7a3408
+    struct ppc_map *map;
7a3408
+    struct ppc_model *model;
7a3408
+    char *name;
7a3408
+    size_t nmodels = 0;
7a3408
+
7a3408
+    if (!(map = ppcLoadMap()))
7a3408
+        goto error;
7a3408
+
7a3408
+    if (models && VIR_ALLOC_N(*models, 0) < 0)
7a3408
+        goto error;
7a3408
+
7a3408
+    model = map->models;
7a3408
+    while (model != NULL) {
7a3408
+        if (models) {
7a3408
+            if (VIR_STRDUP(name, model->name) < 0)
7a3408
+                goto error;
7a3408
+
7a3408
+            if (VIR_APPEND_ELEMENT(*models, nmodels, name) < 0)
7a3408
+                goto error;
7a3408
+        } else {
7a3408
+            nmodels++;
7a3408
+        }
7a3408
+
7a3408
+        model = model->next;
7a3408
+    }
7a3408
+
7a3408
+ cleanup:
7a3408
+    ppcMapFree(map);
7a3408
+
7a3408
+    return nmodels;
7a3408
+
7a3408
+ error:
7a3408
+    if (models) {
7a3408
+        virStringFreeList(*models);
7a3408
+        *models = NULL;
7a3408
+    }
7a3408
+    nmodels = -1;
7a3408
+    goto cleanup;
7a3408
+}
7a3408
+
7a3408
+struct cpuArchDriver cpuDriverPowerPC = {
7a3408
+    .name = "ppc64",
7a3408
+    .arch = archs,
7a3408
+    .narch = ARRAY_CARDINALITY(archs),
7a3408
+    .compare    = ppcCompare,
7a3408
+    .decode     = ppcDecode,
7a3408
+    .encode     = NULL,
7a3408
+    .free       = ppcDataFree,
7a3408
+    .nodeData   = ppcNodeData,
7a3408
+    .guestData  = ppcGuestData,
7a3408
+    .baseline   = ppcBaseline,
7a3408
+    .update     = ppcUpdate,
7a3408
+    .hasFeature = NULL,
7a3408
+    .getModels  = ppcGetModels,
7a3408
+};
7a3408
diff --git a/src/cpu/cpu_ppc64.h b/src/cpu/cpu_ppc64.h
7a3408
new file mode 100644
7a3408
index 0000000..e9ef2be
7a3408
--- /dev/null
7a3408
+++ b/src/cpu/cpu_ppc64.h
7a3408
@@ -0,0 +1,32 @@
7a3408
+/*
7a3408
+ * cpu_ppc64.h: CPU driver for PowerPC CPUs
7a3408
+ *
7a3408
+ * Copyright (C) Copyright (C) IBM Corporation, 2010
7a3408
+ *
7a3408
+ * This library is free software; you can redistribute it and/or
7a3408
+ * modify it under the terms of the GNU Lesser General Public
7a3408
+ * License as published by the Free Software Foundation; either
7a3408
+ * version 2.1 of the License, or (at your option) any later version.
7a3408
+ *
7a3408
+ * This library is distributed in the hope that it will be useful,
7a3408
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a3408
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7a3408
+ * Lesser General Public License for more details.
7a3408
+ *
7a3408
+ * You should have received a copy of the GNU Lesser General Public
7a3408
+ * License along with this library.  If not, see
7a3408
+ * <http://www.gnu.org/licenses/>.
7a3408
+ *
7a3408
+ * Authors:
7a3408
+ *      Anton Blanchard <anton@au.ibm.com>
7a3408
+ *      Prerna Saxena <prerna@linux.vnet.ibm.com>
7a3408
+ */
7a3408
+
7a3408
+#ifndef __VIR_CPU_POWERPC_H__
7a3408
+# define __VIR_CPU_POWERPC_H__
7a3408
+
7a3408
+# include "cpu.h"
7a3408
+
7a3408
+extern struct cpuArchDriver cpuDriverPowerPC;
7a3408
+
7a3408
+#endif /* __VIR_CPU_POWERPC_H__ */
7a3408
diff --git a/src/cpu/cpu_ppc64_data.h b/src/cpu/cpu_ppc64_data.h
7a3408
new file mode 100644
7a3408
index 0000000..a70b099
7a3408
--- /dev/null
7a3408
+++ b/src/cpu/cpu_ppc64_data.h
7a3408
@@ -0,0 +1,33 @@
7a3408
+/*
7a3408
+ * cpu_ppc64_data.h: PowerPC specific CPU data
7a3408
+ *
7a3408
+ * Copyright (C) 2012 IBM Corporation.
7a3408
+ *
7a3408
+ * This library is free software; you can redistribute it and/or
7a3408
+ * modify it under the terms of the GNU Lesser General Public
7a3408
+ * License as published by the Free Software Foundation; either
7a3408
+ * version 2.1 of the License, or (at your option) any later version.
7a3408
+ *
7a3408
+ * This library is distributed in the hope that it will be useful,
7a3408
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a3408
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7a3408
+ * Lesser General Public License for more details.
7a3408
+ *
7a3408
+ * You should have received a copy of the GNU Lesser General Public
7a3408
+ * License along with this library;  If not, see
7a3408
+ * <http://www.gnu.org/licenses/>.
7a3408
+ *
7a3408
+ * Authors:
7a3408
+ *      Li Zhang <zhlcindy@linux.vnet.ibm.com>
7a3408
+ */
7a3408
+
7a3408
+#ifndef __VIR_CPU_PPC_DATA_H__
7a3408
+# define __VIR_CPU_PPC_DATA_H__
7a3408
+
7a3408
+# include <stdint.h>
7a3408
+
7a3408
+struct cpuPPCData {
7a3408
+    uint32_t pvr;
7a3408
+};
7a3408
+
7a3408
+#endif /* __VIR_CPU_PPC_DATA_H__ */
7a3408
diff --git a/src/cpu/cpu_ppc_data.h b/src/cpu/cpu_ppc_data.h
7a3408
deleted file mode 100644
7a3408
index 685332a..0000000
7a3408
--- a/src/cpu/cpu_ppc_data.h
7a3408
+++ /dev/null
7a3408
@@ -1,33 +0,0 @@
7a3408
-/*
7a3408
- * cpu_ppc_data.h: PowerPC specific CPU data
7a3408
- *
7a3408
- * Copyright (C) 2012 IBM Corporation.
7a3408
- *
7a3408
- * This library is free software; you can redistribute it and/or
7a3408
- * modify it under the terms of the GNU Lesser General Public
7a3408
- * License as published by the Free Software Foundation; either
7a3408
- * version 2.1 of the License, or (at your option) any later version.
7a3408
- *
7a3408
- * This library is distributed in the hope that it will be useful,
7a3408
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
7a3408
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
7a3408
- * Lesser General Public License for more details.
7a3408
- *
7a3408
- * You should have received a copy of the GNU Lesser General Public
7a3408
- * License along with this library;  If not, see
7a3408
- * <http://www.gnu.org/licenses/>.
7a3408
- *
7a3408
- * Authors:
7a3408
- *      Li Zhang <zhlcindy@linux.vnet.ibm.com>
7a3408
- */
7a3408
-
7a3408
-#ifndef __VIR_CPU_PPC_DATA_H__
7a3408
-# define __VIR_CPU_PPC_DATA_H__
7a3408
-
7a3408
-# include <stdint.h>
7a3408
-
7a3408
-struct cpuPPCData {
7a3408
-    uint32_t pvr;
7a3408
-};
7a3408
-
7a3408
-#endif /* __VIR_CPU_PPC_DATA_H__ */
7a3408
-- 
7a3408
2.5.0
7a3408