[libvirt PATCH 5/5] cpu_map: Generate x86 feature map from libcpuinfo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Tim Wiederhake <twiederh@xxxxxxxxxx>
---
 src/cpu_map/x86_features.py | 119 ++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100755 src/cpu_map/x86_features.py

diff --git a/src/cpu_map/x86_features.py b/src/cpu_map/x86_features.py
new file mode 100755
index 0000000000..5bc7e06216
--- /dev/null
+++ b/src/cpu_map/x86_features.py
@@ -0,0 +1,119 @@
+#!/bin/env python3
+
+import os
+import pycpuinfo
+
+non_migratable = (
+    "invtsc",
+    "xsaves",
+)
+
+family_x86 = pycpuinfo.Family.find("x86")
+
+features_cpuid = dict()
+features_msr = dict()
+
+
+def cpuid_to_reg_value(data):
+    if data[2]:
+        return "eax", data[2]
+    if data[3]:
+        return "ebx", data[3]
+    if data[4]:
+        return "ecx", data[4]
+    if data[5]:
+        return "edx", data[5]
+
+
+def add_cpuid(feature):
+    name = feature.name("libvirt")
+    data = feature.extra_x86_cpuid()
+    reg_value = cpuid_to_reg_value(data)
+
+    if data[0] not in features_cpuid:
+        features_cpuid[data[0]] = dict()
+
+    if data[1] not in features_cpuid[data[0]]:
+        features_cpuid[data[0]][data[1]] = dict()
+
+    if reg_value[0] not in features_cpuid[data[0]][data[1]]:
+        features_cpuid[data[0]][data[1]][reg_value[0]] = set()
+
+    features_cpuid[data[0]][data[1]][reg_value[0]].add((
+        reg_value[1],
+        name,
+    ))
+
+
+def add_msr(feature):
+    data = feature.extra_x86_msr()
+    if data[0] not in features_msr:
+        features_msr[data[0]] = set()
+
+    features_msr[data[0]].add((
+        data[2],
+        data[1],
+        feature.name("libvirt"),
+    ))
+
+
+def print_feature_cpuid(f):
+    tmpl_ecx = (
+        "  <!-- cpuid level 0x{0:08x}, ecx 0x{1:04x} ({2}) -->\n",
+        "    <cpuid eax_in='0x{0:08x}' ecx_in='0x{1:08x}' {2}='0x{3:08x}'/>\n"
+    )
+    tmpl_any = (
+        "  <!-- cpuid level 0x{0:08x} ({2}) -->\n",
+        "    <cpuid eax_in='0x{0:08x}' {2}='0x{3:08x}'/>\n"
+    )
+
+    for eax in sorted(features_cpuid):
+        for ecx in sorted(features_cpuid[eax]):
+            if ecx == pycpuinfo.x86.CPUINFO_X86_CPUID_ECX_NONE:
+                template = tmpl_any
+            else:
+                template = tmpl_ecx
+
+            for reg in sorted(features_cpuid[eax][ecx]):
+                f.write(template[0].format(eax, ecx, reg))
+                for data in sorted(features_cpuid[eax][ecx][reg]):
+                    extra = ""
+                    if data[1] in non_migratable:
+                        extra = " migratable='no'"
+                    f.write("  <feature name='{}'{}>\n".format(data[1], extra))
+                    f.write(template[1].format(eax, ecx, reg, data[0]))
+                    f.write("  </feature>\n")
+                f.write("\n")
+
+
+def print_feature_msr(f):
+    template = "    <msr index='0x{:08x}' edx='0x{:08x}' eax='0x{:08x}'/>\n"
+    for msr in sorted(features_msr):
+        f.write("  <!-- msr 0x{:08x} -->\n".format(msr))
+        for data in sorted(features_msr[msr]):
+            f.write("  <feature name='{}'>\n".format(data[2]))
+            f.write(template.format(msr, data[0], data[1]))
+            f.write("  </feature>\n")
+        f.write("\n")
+
+
+for feature in pycpuinfo.features():
+    if feature.family() != family_x86:
+        continue
+
+    if feature.extra_x86_cpuid():
+        add_cpuid(feature)
+    elif feature.extra_x86_msr():
+        add_msr(feature)
+
+
+filename = os.path.join(os.path.dirname(__file__), "x86_features.xml")
+with open(filename, "tw") as f:
+    f.write(
+        "<!--\n  After adding new features, update existing test files with\n"
+        "\n    tests/cputestdata/cpu-data.py diff tests/cputestdata/x86_64-"
+        "cpuid-*.json\n\n-->\n")
+    f.write("<cpus>\n")
+    print_feature_cpuid(f)
+    print_feature_msr(f)
+    f.write("</cpus>\n")
-- 
2.39.2




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux