[libvirt PATCH 9/9] cpu-gather: Merge cpu-cpuid.py

Tim Wiederhake twiederh at redhat.com
Mon Jan 4 11:30:19 UTC 2021


Old usage:
  cpu-cpuid.py diff FILE...
New usage:
  cpu-gather.py diff FILE...

Signed-off-by: Tim Wiederhake <twiederh at redhat.com>
---
 tests/cputestdata/cpu-cpuid.py  | 152 --------------------------------
 tests/cputestdata/cpu-gather.py | 137 +++++++++++++++++++++++++++-
 2 files changed, 134 insertions(+), 155 deletions(-)
 delete mode 100755 tests/cputestdata/cpu-cpuid.py

diff --git a/tests/cputestdata/cpu-cpuid.py b/tests/cputestdata/cpu-cpuid.py
deleted file mode 100755
index 3e852d5d55..0000000000
--- a/tests/cputestdata/cpu-cpuid.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env python3
-
-import argparse
-import os
-import sys
-import json
-import xml.etree.ElementTree
-
-
-_KEYS = {
-    "cpuid": ["eax_in", "ecx_in"],
-    "msr": ["index"],
-}
-
-_REGS = {
-    "cpuid": ["eax", "ebx", "ecx", "edx"],
-    "msr": ["eax", "edx"],
-}
-
-
-def checkFeature(cpuData, feature):
-    for key in ["type"] + _KEYS.get(feature["type"], list()):
-        if feature[key] not in cpuData:
-            return False
-        cpuData = cpuData[feature[key]]
-
-    for reg in _REGS.get(feature["type"], list()):
-        if feature[reg] > 0 and feature[reg] == feature[reg] & cpuData[reg]:
-            return True
-    return False
-
-
-def addFeature(cpuData, feature):
-    for key in ["type"] + _KEYS.get(feature["type"], list()):
-        if feature[key] not in cpuData:
-            cpuData[feature[key]] = dict()
-        cpuData = cpuData[feature[key]]
-
-    for reg in _REGS.get(feature["type"], list()):
-        cpuData[reg] = cpuData.get(reg, 0) | feature[reg]
-
-
-def parseQemu(path, features):
-    cpuData = {}
-    with open(path, "r") as f:
-        data, pos = json.JSONDecoder().raw_decode(f.read())
-
-    for (prop, val) in data["return"]["model"]["props"].items():
-        if val and prop in features:
-            addFeature(cpuData, features[prop])
-
-    return cpuData
-
-
-def parseCPUData(path):
-    cpuData = dict()
-    for f in xml.etree.ElementTree.parse(path).getroot():
-        if f.tag not in ("cpuid", "msr"):
-            continue
-
-        feature = {"type": f.tag}
-        for reg in _KEYS[f.tag] + _REGS[f.tag]:
-            feature[reg] = int(f.attrib.get(reg, "0"), 0)
-        addFeature(cpuData, feature)
-    return cpuData
-
-
-def parseMap():
-    path = os.path.dirname(sys.argv[0])
-    path = os.path.join(path, "..", "..", "src", "cpu_map", "x86_features.xml")
-
-    cpuMap = dict()
-    for f in xml.etree.ElementTree.parse(path).getroot().iter("feature"):
-        if f[0].tag not in ("cpuid", "msr"):
-            continue
-
-        feature = {"type": f[0].tag}
-        for reg in _KEYS[f[0].tag] + _REGS[f[0].tag]:
-            feature[reg] = int(f[0].attrib.get(reg, "0"), 0)
-        cpuMap[f.attrib["name"]] = feature
-    return cpuMap
-
-
-def formatCPUData(cpuData, path, comment):
-    print(path)
-    with open(path, "w") as f:
-        f.write("<!-- " + comment + " -->\n")
-        f.write("<cpudata arch='x86'>\n")
-
-        cpuid = cpuData["cpuid"]
-        for eax_in in sorted(cpuid.keys()):
-            for ecx_in in sorted(cpuid[eax_in].keys()):
-                leaf = cpuid[eax_in][ecx_in]
-                line = ("  <cpuid eax_in='0x%08x' ecx_in='0x%02x' "
-                        "eax='0x%08x' ebx='0x%08x' "
-                        "ecx='0x%08x' edx='0x%08x'/>\n")
-                f.write(line % (
-                        eax_in, ecx_in,
-                        leaf["eax"], leaf["ebx"], leaf["ecx"], leaf["edx"]))
-
-        if "msr" in cpuData:
-            msr = cpuData["msr"]
-            for index in sorted(msr.keys()):
-                f.write("  <msr index='0x%x' edx='0x%08x' eax='0x%08x'/>\n" %
-                        (index, msr[index]['edx'], msr[index]['eax']))
-
-        f.write("</cpudata>\n")
-
-
-def diff(args):
-    cpuMap = parseMap()
-
-    for jsonFile in args.json_files:
-        cpuDataFile = jsonFile.replace(".json", ".xml")
-        enabledFile = jsonFile.replace(".json", "-enabled.xml")
-        disabledFile = jsonFile.replace(".json", "-disabled.xml")
-
-        cpuData = parseCPUData(cpuDataFile)
-        qemu = parseQemu(jsonFile, cpuMap)
-
-        enabled = dict()
-        disabled = dict()
-        for feature in cpuMap.values():
-            if checkFeature(qemu, feature):
-                addFeature(enabled, feature)
-            elif checkFeature(cpuData, feature):
-                addFeature(disabled, feature)
-
-        formatCPUData(enabled, enabledFile, "Features enabled by QEMU")
-        formatCPUData(disabled, disabledFile, "Features disabled by QEMU")
-
-
-def main():
-    parser = argparse.ArgumentParser(description="Diff cpuid results")
-    subparsers = parser.add_subparsers(dest="action", required=True)
-    diffparser = subparsers.add_parser(
-        "diff",
-        help="Diff json description of CPU model against known features.")
-    diffparser.add_argument(
-        "json_files",
-        nargs="+",
-        metavar="FILE",
-        type=os.path.realpath,
-        help="Path to one or more json CPU model descriptions.")
-    args = parser.parse_args()
-
-    diff(args)
-    exit(0)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/tests/cputestdata/cpu-gather.py b/tests/cputestdata/cpu-gather.py
index a4a4050e42..f679fb9066 100755
--- a/tests/cputestdata/cpu-gather.py
+++ b/tests/cputestdata/cpu-gather.py
@@ -8,6 +8,18 @@ import re
 import struct
 import subprocess
 import sys
+import xml.etree.ElementTree
+
+
+_KEYS = {
+    "cpuid": ["eax_in", "ecx_in"],
+    "msr": ["index"],
+}
+
+_REGS = {
+    "cpuid": ["eax", "ebx", "ecx", "edx"],
+    "msr": ["eax", "edx"],
+}
 
 
 def gather_name(args):
@@ -304,6 +316,118 @@ def parse(args, data):
     args.json_files = getattr(args, "json_files", list()) + [filename_json]
 
 
+def checkFeature(cpuData, feature):
+    for key in ["type"] + _KEYS.get(feature["type"], list()):
+        if feature[key] not in cpuData:
+            return False
+        cpuData = cpuData[feature[key]]
+
+    for reg in _REGS.get(feature["type"], list()):
+        if feature[reg] > 0 and feature[reg] == feature[reg] & cpuData[reg]:
+            return True
+    return False
+
+
+def addFeature(cpuData, feature):
+    for key in ["type"] + _KEYS.get(feature["type"], list()):
+        if feature[key] not in cpuData:
+            cpuData[feature[key]] = dict()
+        cpuData = cpuData[feature[key]]
+
+    for reg in _REGS.get(feature["type"], list()):
+        cpuData[reg] = cpuData.get(reg, 0) | feature[reg]
+
+
+def parseQemu(path, features):
+    cpuData = {}
+    with open(path, "r") as f:
+        data, pos = json.JSONDecoder().raw_decode(f.read())
+
+    for (prop, val) in data["return"]["model"]["props"].items():
+        if val and prop in features:
+            addFeature(cpuData, features[prop])
+
+    return cpuData
+
+
+def parseCPUData(path):
+    cpuData = dict()
+    for f in xml.etree.ElementTree.parse(path).getroot():
+        if f.tag not in ("cpuid", "msr"):
+            continue
+
+        feature = {"type": f.tag}
+        for reg in _KEYS[f.tag] + _REGS[f.tag]:
+            feature[reg] = int(f.attrib.get(reg, "0"), 0)
+        addFeature(cpuData, feature)
+    return cpuData
+
+
+def parseMap():
+    path = os.path.dirname(sys.argv[0])
+    path = os.path.join(path, "..", "..", "src", "cpu_map", "x86_features.xml")
+
+    cpuMap = dict()
+    for f in xml.etree.ElementTree.parse(path).getroot().iter("feature"):
+        if f[0].tag not in ("cpuid", "msr"):
+            continue
+
+        feature = {"type": f[0].tag}
+        for reg in _KEYS[f[0].tag] + _REGS[f[0].tag]:
+            feature[reg] = int(f[0].attrib.get(reg, "0"), 0)
+        cpuMap[f.attrib["name"]] = feature
+    return cpuMap
+
+
+def formatCPUData(cpuData, path, comment):
+    print(path)
+    with open(path, "w") as f:
+        f.write("<!-- " + comment + " -->\n")
+        f.write("<cpudata arch='x86'>\n")
+
+        cpuid = cpuData["cpuid"]
+        for eax_in in sorted(cpuid.keys()):
+            for ecx_in in sorted(cpuid[eax_in].keys()):
+                leaf = cpuid[eax_in][ecx_in]
+                line = ("  <cpuid eax_in='0x%08x' ecx_in='0x%02x' "
+                        "eax='0x%08x' ebx='0x%08x' "
+                        "ecx='0x%08x' edx='0x%08x'/>\n")
+                f.write(line % (
+                        eax_in, ecx_in,
+                        leaf["eax"], leaf["ebx"], leaf["ecx"], leaf["edx"]))
+
+        if "msr" in cpuData:
+            msr = cpuData["msr"]
+            for index in sorted(msr.keys()):
+                f.write("  <msr index='0x%x' edx='0x%08x' eax='0x%08x'/>\n" %
+                        (index, msr[index]['edx'], msr[index]['eax']))
+
+        f.write("</cpudata>\n")
+
+
+def diff(args):
+    cpuMap = parseMap()
+
+    for jsonFile in args.json_files:
+        cpuDataFile = jsonFile.replace(".json", ".xml")
+        enabledFile = jsonFile.replace(".json", "-enabled.xml")
+        disabledFile = jsonFile.replace(".json", "-disabled.xml")
+
+        cpuData = parseCPUData(cpuDataFile)
+        qemu = parseQemu(jsonFile, cpuMap)
+
+        enabled = dict()
+        disabled = dict()
+        for feature in cpuMap.values():
+            if checkFeature(qemu, feature):
+                addFeature(enabled, feature)
+            elif checkFeature(cpuData, feature):
+                addFeature(disabled, feature)
+
+        formatCPUData(enabled, enabledFile, "Features enabled by QEMU")
+        formatCPUData(disabled, disabledFile, "Features disabled by QEMU")
+
+
 def main():
     parser = argparse.ArgumentParser(description="Gather cpu test data")
     parser.add_argument(
@@ -332,6 +456,15 @@ def main():
     subparsers.add_parser(
         "full",
         help="Equivalent to `cpu-gather gather | cpu-gather parse`.")
+    diffparser = subparsers.add_parser(
+        "diff",
+        help="Diff json description of CPU model against known features.")
+    diffparser.add_argument(
+        "json_files",
+        nargs="+",
+        metavar="FILE",
+        type=os.path.realpath,
+        help="Path to one or more json CPU model descriptions.")
 
     args = parser.parse_args()
 
@@ -359,9 +492,7 @@ def main():
         parse(args, data)
 
     if "json_files" in args:
-        cmd = ["./cpu-cpuid.py", "diff"]
-        cmd.extend(args.json_files)
-        subprocess.check_call(cmd, universal_newlines=True)
+        diff(args)
 
 
 if __name__ == "__main__":
-- 
2.26.2




More information about the libvir-list mailing list