Re: [PATCH 1/3] CPU: Implement guestData for PPC CPU driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Any comments about my CPU patches?


On 2013年08月29日 16:46, Li Zhang wrote:
From: Li Zhang <zhlcindy@xxxxxxxxxxxxxxxxxx>

On Power platform, Power7+ can support Power7 guest.
It needs to define XML configuration to specify guest's CPU model.

For exmaple:
   <cpu match='exact'>
     <model>POWER7+_v2.1</model>
     <vendor>IBM</vendor>
   </cpu>

Signed-off-by: Li Zhang <zhlcindy@xxxxxxxxxxxxxxxxxx>
---
  src/cpu/cpu_powerpc.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 164 insertions(+), 2 deletions(-)

diff --git a/src/cpu/cpu_powerpc.c b/src/cpu/cpu_powerpc.c
index 647a8a1..84fa3f7 100644
--- a/src/cpu/cpu_powerpc.c
+++ b/src/cpu/cpu_powerpc.c
@@ -99,6 +99,23 @@ ppcModelFindPVR(const struct ppc_map *map,
      return NULL;
  }
+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;
+}
+
  static struct ppc_vendor *
  ppcVendorFind(const struct ppc_map *map,
                const char *name)
@@ -126,6 +143,29 @@ ppcVendorFree(struct ppc_vendor *vendor)
      VIR_FREE(vendor);
  }
+static struct ppc_model *
+ppcModelFromCPU(const virCPUDefPtr 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;
+}
+
+
  static int
  ppcVendorLoad(xmlXPathContextPtr ctxt,
                struct ppc_map *map)
@@ -288,6 +328,112 @@ error:
      return NULL;
  }
+static virCPUDataPtr
+ppcMakeCPUData(virArch arch, struct cpuPPCData *data)
+{
+    virCPUDataPtr cpuData;
+
+    if (VIR_ALLOC(cpuData) < 0)
+        return NULL;
+
+    cpuData->arch = arch;
+    cpuData->data.ppc = *data;
+    data = NULL;
+
+    return cpuData;
+}
+
+static virCPUCompareResult
+ppcCompute(virCPUDefPtr host,
+             const virCPUDefPtr cpu,
+             virCPUDataPtr *guestData,
+             char **message)
+
+{
+    struct ppc_map *map = NULL;
+    struct ppc_model *host_model = NULL;
+    struct ppc_model *guest_model = NULL;
+
+    int ret = 0;
+    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 error;
+            return VIR_CPU_COMPARE_INCOMPATIBLE;
+        }
+        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 error;
+        return VIR_CPU_COMPARE_INCOMPATIBLE;
+    }
+
+    if (!(map = ppcLoadMap()) ||
+        !(host_model = ppcModelFromCPU(host, map)) ||
+        !(guest_model = ppcModelFromCPU(cpu, map)))
+        goto error;
+
+    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 error;
+            return VIR_CPU_COMPARE_INCOMPATIBLE;
+        }
+
+        if (!(*guestData = ppcMakeCPUData(arch, &guest_model->data)))
+            goto error;
+    }
+
+    ret = VIR_CPU_COMPARE_IDENTICAL;
+
+out:
+   ppcMapFree(map);
+   ppcModelFree(host_model);
+   ppcModelFree(guest_model);
+   return ret;
+
+error:
+   ret = VIR_CPU_COMPARE_ERROR;
+   goto out;
+
+}
+
  static virCPUCompareResult
  ppcCompare(virCPUDefPtr host,
             virCPUDefPtr cpu)
@@ -369,6 +515,15 @@ ppcNodeData(void)
  }
  #endif
+static virCPUCompareResult
+ppcGuestData(virCPUDefPtr host,
+             virCPUDefPtr guest,
+             virCPUDataPtr *data,
+             char **message)
+{
+    return ppcCompute(host, guest, data, message);
+}
+
  static int
  ppcUpdate(virCPUDefPtr guest ATTRIBUTE_UNUSED,
            const virCPUDefPtr host ATTRIBUTE_UNUSED)
@@ -466,6 +621,13 @@ error:
      goto cleanup;
  }
+static int
+ppcHasFeature(const virCPUDataPtr data ATTRIBUTE_UNUSED,
+                         const char *name ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
  struct cpuArchDriver cpuDriverPowerPC = {
      .name = "ppc64",
      .arch = archs,
@@ -479,8 +641,8 @@ struct cpuArchDriver cpuDriverPowerPC = {
  #else
      .nodeData   = NULL,
  #endif
-    .guestData  = NULL,
+    .guestData  = ppcGuestData,
      .baseline   = ppcBaseline,
      .update     = ppcUpdate,
-    .hasFeature = NULL,
+    .hasFeature = ppcHasFeature,
  };

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]