0a7476
From 5b07ca7c378a5e62fec0ed4808e8905fe447e85e Mon Sep 17 00:00:00 2001
0a7476
Message-Id: <5b07ca7c378a5e62fec0ed4808e8905fe447e85e@dist-git>
0a7476
From: Jiri Denemark <jdenemar@redhat.com>
0a7476
Date: Tue, 4 Jun 2019 13:04:30 +0200
0a7476
Subject: [PATCH] conf: Report TSC frequency in host CPU capabilities
0a7476
MIME-Version: 1.0
0a7476
Content-Type: text/plain; charset=UTF-8
0a7476
Content-Transfer-Encoding: 8bit
0a7476
0a7476
This patch adds a new
0a7476
0a7476
    <counter name='tsc' frequency='N' scaling='on|off'/>
0a7476
0a7476
element into the host CPU capabilities XML.
0a7476
0a7476
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
0a7476
(cherry picked from commit c277b9ad5c740bb4c4b915754ae74621f93f9d37)
0a7476
0a7476
https://bugzilla.redhat.com/show_bug.cgi?id=1641702
0a7476
0a7476
Conflicts:
0a7476
	src/conf/cpu_conf.h
0a7476
            - virenum.h doesn't exist downstream
0a7476
0a7476
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
0a7476
Message-Id: <c0a6203e4a667c31668e0df508b08b515177276f.1559646067.git.jdenemar@redhat.com>
0a7476
Reviewed-by: Ján Tomko <jtomko@redhat.com>
0a7476
---
0a7476
 src/conf/cpu_conf.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
0a7476
 src/conf/cpu_conf.h |  2 ++
0a7476
 2 files changed, 50 insertions(+)
0a7476
0a7476
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
0a7476
index 43a3ab5dcd..d0ad265fbe 100644
0a7476
--- a/src/conf/cpu_conf.c
0a7476
+++ b/src/conf/cpu_conf.c
0a7476
@@ -102,6 +102,7 @@ virCPUDefFree(virCPUDefPtr def)
0a7476
 
0a7476
     virCPUDefFreeModel(def);
0a7476
     VIR_FREE(def->cache);
0a7476
+    VIR_FREE(def->tsc);
0a7476
     VIR_FREE(def);
0a7476
 }
0a7476
 
0a7476
@@ -223,6 +224,13 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
0a7476
         *copy->cache = *cpu->cache;
0a7476
     }
0a7476
 
0a7476
+    if (cpu->tsc) {
0a7476
+        if (VIR_ALLOC(copy->tsc) < 0)
0a7476
+            goto error;
0a7476
+
0a7476
+        *copy->tsc = *cpu->tsc;
0a7476
+    }
0a7476
+
0a7476
     return copy;
0a7476
 
0a7476
  error:
0a7476
@@ -276,6 +284,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
0a7476
     char *cpuMode;
0a7476
     char *fallback = NULL;
0a7476
     char *vendor_id = NULL;
0a7476
+    char *tscScaling = NULL;
0a7476
+    virHostCPUTscInfoPtr tsc = NULL;
0a7476
     int ret = -1;
0a7476
 
0a7476
     *cpu = NULL;
0a7476
@@ -392,6 +402,32 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
0a7476
                            _("invalid microcode version"));
0a7476
             goto cleanup;
0a7476
         }
0a7476
+
0a7476
+        if (virXPathBoolean("boolean(./counter[@name='tsc'])", ctxt) > 0) {
0a7476
+            if (VIR_ALLOC(tsc) < 0)
0a7476
+                goto cleanup;
0a7476
+
0a7476
+            if (virXPathULongLong("./counter[@name='tsc']/@frequency", ctxt,
0a7476
+                                  &tsc->frequency) < 0) {
0a7476
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
0a7476
+                               _("Invalid TSC frequency"));
0a7476
+                goto cleanup;
0a7476
+            }
0a7476
+
0a7476
+            tscScaling = virXPathString("string(./counter[@name='tsc']/@scaling)",
0a7476
+                                        ctxt);
0a7476
+            if (tscScaling) {
0a7476
+                int scaling = virTristateBoolTypeFromString(tscScaling);
0a7476
+                if (scaling < 0) {
0a7476
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
0a7476
+                                   _("Invalid TSC scaling attribute"));
0a7476
+                    goto cleanup;
0a7476
+                }
0a7476
+                tsc->scaling = scaling;
0a7476
+            }
0a7476
+
0a7476
+            VIR_STEAL_PTR(def->tsc, tsc);
0a7476
+        }
0a7476
     }
0a7476
 
0a7476
     if (!(def->model = virXPathString("string(./model[1])", ctxt)) &&
0a7476
@@ -577,6 +613,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
0a7476
     VIR_FREE(fallback);
0a7476
     VIR_FREE(vendor_id);
0a7476
     VIR_FREE(nodes);
0a7476
+    VIR_FREE(tscScaling);
0a7476
+    VIR_FREE(tsc);
0a7476
     virCPUDefFree(def);
0a7476
     return ret;
0a7476
 }
0a7476
@@ -734,6 +772,16 @@ virCPUDefFormatBuf(virBufferPtr buf,
0a7476
         virBufferAsprintf(buf, "<microcode version='%u'/>\n",
0a7476
                           def->microcodeVersion);
0a7476
 
0a7476
+    if (def->type == VIR_CPU_TYPE_HOST && def->tsc) {
0a7476
+        virBufferAddLit(buf, "
0a7476
+        virBufferAsprintf(buf, " frequency='%llu'", def->tsc->frequency);
0a7476
+        if (def->tsc->scaling) {
0a7476
+            virBufferAsprintf(buf, " scaling='%s'",
0a7476
+                              virTristateBoolTypeToString(def->tsc->scaling));
0a7476
+        }
0a7476
+        virBufferAddLit(buf, "/>\n");
0a7476
+    }
0a7476
+
0a7476
     if (def->sockets && def->cores && def->threads) {
0a7476
         virBufferAddLit(buf, "
0a7476
         virBufferAsprintf(buf, " sockets='%u'", def->sockets);
0a7476
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
0a7476
index 9f2e7ee264..5bda4d6961 100644
0a7476
--- a/src/conf/cpu_conf.h
0a7476
+++ b/src/conf/cpu_conf.h
0a7476
@@ -30,6 +30,7 @@
0a7476
 # include "virbitmap.h"
0a7476
 # include "virarch.h"
0a7476
 # include "numa_conf.h"
0a7476
+# include "virhostcpu.h"
0a7476
 
0a7476
 # define VIR_CPU_VENDOR_ID_LENGTH 12
0a7476
 
0a7476
@@ -141,6 +142,7 @@ struct _virCPUDef {
0a7476
     size_t nfeatures_max;
0a7476
     virCPUFeatureDefPtr features;
0a7476
     virCPUCacheDefPtr cache;
0a7476
+    virHostCPUTscInfoPtr tsc;
0a7476
 };
0a7476
 
0a7476
 
0a7476
-- 
0a7476
2.21.0
0a7476