[libvirt] [PATCH 11/41] cpu_x86: Refactor internal KVM features

Jiri Denemark jdenemar at redhat.com
Wed Jun 8 08:22:25 UTC 2016


The internal features are only used in explicit checks with
cpuHasFeature. Loading them into the CPU map is dangerous since the
features may accidentally be reported to users when decoding CPUID data.

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

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 616b07a..82921db 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -59,33 +59,75 @@ struct _virCPUx86Feature {
     bool migratable;
 };
 
-typedef struct _virCPUx86KVMFeature virCPUx86KVMFeature;
-typedef virCPUx86KVMFeature *virCPUx86KVMFeaturePtr;
-struct _virCPUx86KVMFeature {
-    const char *name;
-    const virCPUx86CPUID cpuid;
-};
-
-static const virCPUx86KVMFeature x86_kvm_features[] =
+
+#define KVM_FEATURE_DEF(Name, Eax_in, Eax)                          \
+    static virCPUx86CPUID Name ## _cpuid[] = {                      \
+        { .eax_in = Eax_in, .eax = Eax },                           \
+    }
+
+#define KVM_FEATURE(Name)                                           \
+    {                                                               \
+        .name = (char *) Name,                                      \
+        .data = {                                                   \
+            .len = ARRAY_CARDINALITY(Name ## _cpuid),               \
+            .data = Name ## _cpuid                                  \
+        }                                                           \
+    }
+
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE,
+                0x40000001, 0x00000001);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_NOP_IO_DELAY,
+                0x40000001, 0x00000002);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_MMU_OP,
+                0x40000001, 0x00000004);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE2,
+                0x40000001, 0x00000008);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_ASYNC_PF,
+                0x40000001, 0x00000010);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_STEAL_TIME,
+                0x40000001, 0x00000020);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_PV_EOI,
+                0x40000001, 0x00000040);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_PV_UNHALT,
+                0x40000001, 0x00000080);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT,
+                0x40000001, 0x01000000);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RUNTIME,
+                0x40000003, 0x00000001);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_SYNIC,
+                0x40000003, 0x00000004);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_STIMER,
+                0x40000003, 0x00000008);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RELAXED,
+                0x40000003, 0x00000020);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_SPINLOCK,
+                0x40000003, 0x00000022);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_VAPIC,
+                0x40000003, 0x00000030);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_VPINDEX,
+                0x40000003, 0x00000040);
+KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RESET,
+                0x40000003, 0x00000080);
+
+static virCPUx86Feature x86_kvm_features[] =
 {
-    {VIR_CPU_x86_KVM_CLOCKSOURCE,  { .eax_in = 0x40000001, .eax = 0x00000001 }},
-    {VIR_CPU_x86_KVM_NOP_IO_DELAY, { .eax_in = 0x40000001, .eax = 0x00000002 }},
-    {VIR_CPU_x86_KVM_MMU_OP,       { .eax_in = 0x40000001, .eax = 0x00000004 }},
-    {VIR_CPU_x86_KVM_CLOCKSOURCE2, { .eax_in = 0x40000001, .eax = 0x00000008 }},
-    {VIR_CPU_x86_KVM_ASYNC_PF,     { .eax_in = 0x40000001, .eax = 0x00000010 }},
-    {VIR_CPU_x86_KVM_STEAL_TIME,   { .eax_in = 0x40000001, .eax = 0x00000020 }},
-    {VIR_CPU_x86_KVM_PV_EOI,       { .eax_in = 0x40000001, .eax = 0x00000040 }},
-    {VIR_CPU_x86_KVM_PV_UNHALT,    { .eax_in = 0x40000001, .eax = 0x00000080 }},
-    {VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT,
-                                   { .eax_in = 0x40000001, .eax = 0x01000000 }},
-    {VIR_CPU_x86_KVM_HV_RUNTIME,   { .eax_in = 0x40000003, .eax = 0x00000001 }},
-    {VIR_CPU_x86_KVM_HV_SYNIC,     { .eax_in = 0x40000003, .eax = 0x00000004 }},
-    {VIR_CPU_x86_KVM_HV_STIMER,    { .eax_in = 0x40000003, .eax = 0x00000008 }},
-    {VIR_CPU_x86_KVM_HV_RELAXED,   { .eax_in = 0x40000003, .eax = 0x00000020 }},
-    {VIR_CPU_x86_KVM_HV_SPINLOCK,  { .eax_in = 0x40000003, .eax = 0x00000022 }},
-    {VIR_CPU_x86_KVM_HV_VAPIC,     { .eax_in = 0x40000003, .eax = 0x00000030 }},
-    {VIR_CPU_x86_KVM_HV_VPINDEX,   { .eax_in = 0x40000003, .eax = 0x00000040 }},
-    {VIR_CPU_x86_KVM_HV_RESET,     { .eax_in = 0x40000003, .eax = 0x00000080 }},
+    KVM_FEATURE(VIR_CPU_x86_KVM_CLOCKSOURCE),
+    KVM_FEATURE(VIR_CPU_x86_KVM_NOP_IO_DELAY),
+    KVM_FEATURE(VIR_CPU_x86_KVM_MMU_OP),
+    KVM_FEATURE(VIR_CPU_x86_KVM_CLOCKSOURCE2),
+    KVM_FEATURE(VIR_CPU_x86_KVM_ASYNC_PF),
+    KVM_FEATURE(VIR_CPU_x86_KVM_STEAL_TIME),
+    KVM_FEATURE(VIR_CPU_x86_KVM_PV_EOI),
+    KVM_FEATURE(VIR_CPU_x86_KVM_PV_UNHALT),
+    KVM_FEATURE(VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_RUNTIME),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_SYNIC),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_STIMER),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_RELAXED),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_SPINLOCK),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_VAPIC),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_VPINDEX),
+    KVM_FEATURE(VIR_CPU_x86_KVM_HV_RESET),
 };
 
 typedef struct _virCPUx86Model virCPUx86Model;
@@ -627,6 +669,21 @@ x86FeatureFind(virCPUx86MapPtr map,
 }
 
 
+static virCPUx86FeaturePtr
+x86FeatureFindInternal(const char *name)
+{
+    size_t i;
+    size_t count = ARRAY_CARDINALITY(x86_kvm_features);
+
+    for (i = 0; i < count; i++) {
+        if (STREQ(x86_kvm_features[i].name, name))
+            return x86_kvm_features + i;
+    }
+
+    return NULL;
+}
+
+
 static char *
 x86FeatureNames(virCPUx86MapPtr map,
                 const char *separator,
@@ -1159,47 +1216,6 @@ x86MapLoadCallback(cpuMapElement element,
 }
 
 
-static int
-x86MapLoadInternalFeatures(virCPUx86MapPtr map)
-{
-    size_t i;
-    virCPUx86FeaturePtr feature = NULL;
-    size_t nfeatures = map->nfeatures;
-    size_t count = ARRAY_CARDINALITY(x86_kvm_features);
-
-    if (VIR_EXPAND_N(map->features, nfeatures, count) < 0)
-        goto error;
-
-    for (i = 0; i < count; i++) {
-        const char *name = x86_kvm_features[i].name;
-
-        if (x86FeatureFind(map, name)) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("CPU feature %s already defined"), name);
-            goto error;
-        }
-
-        if (!(feature = x86FeatureNew()))
-            goto error;
-
-        if (VIR_STRDUP(feature->name, name) < 0)
-            goto error;
-
-        if (virCPUx86DataAddCPUID(&feature->data, &x86_kvm_features[i].cpuid))
-            goto error;
-
-        map->features[map->nfeatures++] = feature;
-        feature = NULL;
-    }
-
-    return 0;
-
- error:
-    x86FeatureFree(feature);
-    return -1;
-}
-
-
 static virCPUx86MapPtr
 virCPUx86LoadMap(void)
 {
@@ -1211,9 +1227,6 @@ virCPUx86LoadMap(void)
     if (cpuMapLoad("x86", x86MapLoadCallback, map) < 0)
         goto error;
 
-    if (x86MapLoadInternalFeatures(map) < 0)
-        goto error;
-
     return map;
 
  error:
@@ -2177,7 +2190,8 @@ x86HasFeature(const virCPUData *data,
     if (!(map = virCPUx86GetMap()))
         return -1;
 
-    if (!(feature = x86FeatureFind(map, name)))
+    if (!(feature = x86FeatureFind(map, name)) &&
+        !(feature = x86FeatureFindInternal(name)))
         goto cleanup;
 
     ret = x86DataIsSubset(&data->data.x86, &feature->data) ? 1 : 0;
-- 
2.8.3




More information about the libvir-list mailing list