[libvirt] [PATCH 3/9] Implement cpuArchBaseline in x86 CPU driver

Jiri Denemark jdenemar at redhat.com
Fri Feb 5 15:56:52 UTC 2010


Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/cpu/cpu_x86.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 86 insertions(+), 1 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index f316db1..a9f04f0 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -137,6 +137,17 @@ x86cpuidClearBits(struct cpuX86cpuid *cpuid,
 }
 
 
+static inline void
+x86cpuidAndBits(struct cpuX86cpuid *cpuid,
+                const struct cpuX86cpuid *mask)
+{
+    cpuid->eax &= mask->eax;
+    cpuid->ebx &= mask->ebx;
+    cpuid->ecx &= mask->ecx;
+    cpuid->edx &= mask->edx;
+}
+
+
 static struct cpuX86cpuid *
 x86DataCpuid(const union cpuData *data,
              uint32_t function)
@@ -477,6 +488,27 @@ x86ModelSubtract(struct x86_model *model1,
 }
 
 
+static void
+x86ModelIntersect(struct x86_model *model1,
+                  const struct x86_model *model2)
+{
+    int i;
+    struct cpuX86cpuid *cpuid;
+
+    for (i = 0; i < model1->ncpuid; i++) {
+        struct cpuX86cpuid *intersection = model1->cpuid + i;
+
+        cpuid = x86cpuidFind(model2->cpuid,
+                             model2->ncpuid,
+                             intersection->function);
+        if (cpuid != NULL)
+            x86cpuidAndBits(intersection, cpuid);
+        else
+            x86cpuidClearBits(intersection, intersection);
+    }
+}
+
+
 static int
 x86ModelAdd(struct x86_model *model1,
             const struct x86_model *model2)
@@ -1192,6 +1224,59 @@ error:
 #endif
 
 
+static virCPUDefPtr
+x86Baseline(unsigned int ncpus,
+            virCPUDefPtr *cpus,
+            unsigned int nmodels,
+            const char **models)
+{
+    struct x86_map *map = NULL;
+    struct x86_model *base_model = NULL;
+    union cpuData *data = NULL;
+    virCPUDefPtr cpu = NULL;
+    unsigned int i;
+
+    if (!(map = x86LoadMap()))
+        goto error;
+
+    if (!(base_model = x86ModelFromCPU(cpus[0], map, 0)))
+        goto error;
+
+    if (VIR_ALLOC(cpu) < 0 ||
+        !(cpu->arch = strdup(cpus[0]->arch)))
+        goto no_memory;
+
+    for (i = 1; i < ncpus; i++) {
+        struct x86_model *model;
+        if (!(model = x86ModelFromCPU(cpus[i], map, 0)))
+            goto error;
+
+        x86ModelIntersect(base_model, model);
+        x86ModelFree(model);
+    }
+
+    if (!(data = x86DataFromModel(base_model)))
+        goto no_memory;
+
+    if (x86Decode(cpu, data, nmodels, models) < 0)
+        goto error;
+
+cleanup:
+    x86DataFree(data);
+    x86ModelFree(base_model);
+    x86MapFree(map);
+
+    return cpu;
+
+no_memory:
+    virReportOOMError(NULL);
+error:
+    virCPUDefFree(cpu);
+    cpu = NULL;
+    goto cleanup;
+}
+
+
 struct cpuArchDriver cpuDriverX86 = {
     .name = "x86",
     .arch = archs,
@@ -1206,5 +1291,5 @@ struct cpuArchDriver cpuDriverX86 = {
     .nodeData   = NULL,
 #endif
     .guestData  = x86GuestData,
-    .baseline   = NULL,
+    .baseline   = x86Baseline,
 };
-- 
1.6.6.1




More information about the libvir-list mailing list