[libvirt] [PATCH v2 4/7] conf: Report TSC frequency in host CPU capabilities

Jiri Denemark jdenemar at redhat.com
Mon Jun 3 12:27:55 UTC 2019


This patch adds a new

    <counter name='tsc' frequency='N' scaling='on|off'/>

element into the host CPU capabilities XML.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/conf/cpu_conf.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
 src/conf/cpu_conf.h |  2 ++
 2 files changed, 50 insertions(+)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index bd2beab33e..dc46e7f57a 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -112,6 +112,7 @@ virCPUDefFree(virCPUDefPtr def)
 
     virCPUDefFreeModel(def);
     VIR_FREE(def->cache);
+    VIR_FREE(def->tsc);
     VIR_FREE(def);
 }
 
@@ -233,6 +234,13 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu)
         *copy->cache = *cpu->cache;
     }
 
+    if (cpu->tsc) {
+        if (VIR_ALLOC(copy->tsc) < 0)
+            goto error;
+
+        *copy->tsc = *cpu->tsc;
+    }
+
     return copy;
 
  error:
@@ -286,6 +294,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
     char *cpuMode;
     char *fallback = NULL;
     char *vendor_id = NULL;
+    char *tscScaling = NULL;
+    virHostCPUTscInfoPtr tsc = NULL;
     int ret = -1;
 
     *cpu = NULL;
@@ -402,6 +412,32 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
                            _("invalid microcode version"));
             goto cleanup;
         }
+
+        if (virXPathBoolean("boolean(./counter[@name='tsc'])", ctxt) > 0) {
+            if (VIR_ALLOC(tsc) < 0)
+                goto cleanup;
+
+            if (virXPathULongLong("./counter[@name='tsc']/@frequency", ctxt,
+                                  &tsc->frequency) < 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("Invalid TSC frequency"));
+                goto cleanup;
+            }
+
+            tscScaling = virXPathString("string(./counter[@name='tsc']/@scaling)",
+                                        ctxt);
+            if (tscScaling) {
+                int scaling = virTristateBoolTypeFromString(tscScaling);
+                if (scaling < 0) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("Invalid TSC scaling attribute"));
+                    goto cleanup;
+                }
+                tsc->scaling = scaling;
+            }
+
+            VIR_STEAL_PTR(def->tsc, tsc);
+        }
     }
 
     if (!(def->model = virXPathString("string(./model[1])", ctxt)) &&
@@ -587,6 +623,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt,
     VIR_FREE(fallback);
     VIR_FREE(vendor_id);
     VIR_FREE(nodes);
+    VIR_FREE(tscScaling);
+    VIR_FREE(tsc);
     virCPUDefFree(def);
     return ret;
 }
@@ -744,6 +782,16 @@ virCPUDefFormatBuf(virBufferPtr buf,
         virBufferAsprintf(buf, "<microcode version='%u'/>\n",
                           def->microcodeVersion);
 
+    if (def->type == VIR_CPU_TYPE_HOST && def->tsc) {
+        virBufferAddLit(buf, "<counter name='tsc'");
+        virBufferAsprintf(buf, " frequency='%llu'", def->tsc->frequency);
+        if (def->tsc->scaling) {
+            virBufferAsprintf(buf, " scaling='%s'",
+                              virTristateBoolTypeToString(def->tsc->scaling));
+        }
+        virBufferAddLit(buf, "/>\n");
+    }
+
     if (def->sockets && def->cores && def->threads) {
         virBufferAddLit(buf, "<topology");
         virBufferAsprintf(buf, " sockets='%u'", def->sockets);
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index c98db65693..51bf744fab 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -28,6 +28,7 @@
 # include "virarch.h"
 # include "numa_conf.h"
 # include "virenum.h"
+# include "virhostcpu.h"
 
 # define VIR_CPU_VENDOR_ID_LENGTH 12
 
@@ -139,6 +140,7 @@ struct _virCPUDef {
     size_t nfeatures_max;
     virCPUFeatureDefPtr features;
     virCPUCacheDefPtr cache;
+    virHostCPUTscInfoPtr tsc;
 };
 
 
-- 
2.21.0




More information about the libvir-list mailing list