Blob Blame History Raw
From 45c1fda7075b723a1bf292b9bbcb0b27cab9e72c Mon Sep 17 00:00:00 2001
Message-Id: <45c1fda7075b723a1bf292b9bbcb0b27cab9e72c.1383922566.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 8 Nov 2013 12:33:32 +0100
Subject: [PATCH] cpu: x86: Add internal CPUID features support and KVM feature
 bits

https://bugzilla.redhat.com/show_bug.cgi?id=1008989

Some of the emulator features are presented in the <features> element in
the domain XML although they are virtual CPUID feature bits when
presented to the guest. To avoid confusing the users with these
features, as they are not configurable via the <cpu> element, this patch
adds an internal array where those can be stored privately instead of
exposing them in the XML.

Additionaly KVM feature bits are added as example usage of this code.

(cherry picked from commit 2e8f90802ddc5405121ba1b92f47b885867a325a)

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/cpu/cpu_x86.c      | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/cpu/cpu_x86_data.h | 12 ++++++++++
 2 files changed, 76 insertions(+)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 3bdb3c3..7bd8acb 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -56,6 +56,25 @@ struct x86_feature {
     struct x86_feature *next;
 };
 
+struct x86_kvm_feature {
+    const char *name;
+    const virCPUx86CPUID cpuid;
+};
+
+static const struct x86_kvm_feature x86_kvm_features[] =
+{
+    {VIR_CPU_x86_KVM_CLOCKSOURCE,  { .function = 0x40000001, .eax = 0x00000001 }},
+    {VIR_CPU_x86_KVM_NOP_IO_DELAY, { .function = 0x40000001, .eax = 0x00000002 }},
+    {VIR_CPU_x86_KVM_MMU_OP,       { .function = 0x40000001, .eax = 0x00000004 }},
+    {VIR_CPU_x86_KVM_CLOCKSOURCE2, { .function = 0x40000001, .eax = 0x00000008 }},
+    {VIR_CPU_x86_KVM_ASYNC_PF,     { .function = 0x40000001, .eax = 0x00000010 }},
+    {VIR_CPU_x86_KVM_STEAL_TIME,   { .function = 0x40000001, .eax = 0x00000020 }},
+    {VIR_CPU_x86_KVM_PV_EOI,       { .function = 0x40000001, .eax = 0x00000040 }},
+    {VIR_CPU_x86_KVM_PV_UNHALT,    { .function = 0x40000001, .eax = 0x00000080 }},
+    {VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT,
+                                   { .function = 0x40000001, .eax = 0x01000000 }},
+};
+
 struct x86_model {
     char *name;
     const struct x86_vendor *vendor;
@@ -1068,6 +1087,48 @@ x86MapLoadCallback(enum cpuMapElement element,
 }
 
 
+static int
+x86MapLoadInternalFeatures(struct x86_map *map)
+{
+    size_t i;
+    struct x86_feature *feature = NULL;
+
+    for (i = 0; i < ARRAY_CARDINALITY(x86_kvm_features); i++) {
+        const char *name = x86_kvm_features[i].name;
+
+        if (x86FeatureFind(map, name)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("CPU feature %s already defined"), name);
+            return -1;
+        }
+
+        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;
+
+        if (map->features == NULL) {
+            map->features = feature;
+        } else {
+            feature->next = map->features;
+            map->features = feature;
+        }
+
+        feature = NULL;
+    }
+
+    return 0;
+
+error:
+    x86FeatureFree(feature);
+    return -1;
+}
+
+
 static struct x86_map *
 virCPUx86LoadMap(void)
 {
@@ -1079,6 +1140,9 @@ virCPUx86LoadMap(void)
     if (cpuMapLoad("x86", x86MapLoadCallback, map) < 0)
         goto error;
 
+    if (x86MapLoadInternalFeatures(map) < 0)
+        goto error;
+
     return map;
 
 error:
diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h
index 69066f1..88dccf6 100644
--- a/src/cpu/cpu_x86_data.h
+++ b/src/cpu/cpu_x86_data.h
@@ -36,8 +36,20 @@ struct _virCPUx86CPUID {
 };
 
 # define CPUX86_BASIC    0x0
+# define CPUX86_KVM      0x40000000
 # define CPUX86_EXTENDED 0x80000000
 
+# define VIR_CPU_x86_KVM_CLOCKSOURCE  "__kvm_clocksource"
+# define VIR_CPU_x86_KVM_NOP_IO_DELAY "__kvm_no_io_delay"
+# define VIR_CPU_x86_KVM_MMU_OP       "__kvm_mmu_op"
+# define VIR_CPU_x86_KVM_CLOCKSOURCE2 "__kvm_clocksource2"
+# define VIR_CPU_x86_KVM_ASYNC_PF     "__kvm_async_pf"
+# define VIR_CPU_x86_KVM_STEAL_TIME   "__kvm_steal_time"
+# define VIR_CPU_x86_KVM_PV_EOI       "__kvm_pv_eoi"
+# define VIR_CPU_x86_KVM_PV_UNHALT    "__kvm_pv_unhalt"
+# define VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT "__kvm_clocksource_stable"
+
+
 typedef struct _virCPUx86Data virCPUx86Data;
 struct _virCPUx86Data {
     size_t len;
-- 
1.8.4.2