mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-09 13:11:36 +00:00
This script is intended to help in synchronizing i386 QEMU cpu feature definitions with libvirt. QEMU's attribute list for the "max-x86_64-cpu" contains non-cpu-feature items and needs to be filtered before being useful. Signed-off-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
279 lines
6.9 KiB
Python
Executable File
279 lines
6.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
import xml.etree.ElementTree
|
|
|
|
|
|
def ignore_feature(feature):
|
|
ignored_features = [
|
|
# VIA/Cyrix/Centaur-defined CPU features
|
|
# CPUID level 0xC0000001, word 5
|
|
"ace2",
|
|
"ace2-en",
|
|
"phe",
|
|
"phe-en",
|
|
"pmm",
|
|
"pmm-en",
|
|
"xcrypt",
|
|
"xcrypt-en",
|
|
"xstore",
|
|
"xstore-en",
|
|
|
|
# non-features
|
|
"check",
|
|
"cpuid-0xb",
|
|
"enforce",
|
|
"fill-mtrr-mask",
|
|
"full-cpuid-auto-level",
|
|
"full-width-write",
|
|
"host-cache-info",
|
|
"host-phys-bits",
|
|
"hotpluggable",
|
|
"hotplugged",
|
|
"hv-apicv",
|
|
"hv-avic",
|
|
"hv-crash",
|
|
"hv-emsr-bitmap",
|
|
"hv-enforce-cpuid",
|
|
"hv-evmcs",
|
|
"hv-frequencies",
|
|
"hv-ipi",
|
|
"hv-passthrough",
|
|
"hv-reenlightenment",
|
|
"hv-relaxed",
|
|
"hv-reset",
|
|
"hv-runtime",
|
|
"hv-stimer",
|
|
"hv-stimer-direct",
|
|
"hv-syndbg",
|
|
"hv-synic",
|
|
"hv-time",
|
|
"hv-tlbflush",
|
|
"hv-tlbflush-direct",
|
|
"hv-tlbflush-ext",
|
|
"hv-vapic",
|
|
"hv-vpindex",
|
|
"hv-xmm-input",
|
|
"kvm",
|
|
"kvm-asyncpf",
|
|
"kvm-asyncpf-int",
|
|
"kvm-hint-dedicated",
|
|
"kvm-mmu",
|
|
"kvm-msi-ext-dest-id",
|
|
"kvm-no-smi-migration",
|
|
"kvm-nopiodelay",
|
|
"kvm-poll-control",
|
|
"kvm-pv-enforce-cpuid",
|
|
"kvm-pv-eoi",
|
|
"kvm-pv-ipi",
|
|
"kvm-pv-sched-yield",
|
|
"kvm-pv-tlb-flush",
|
|
"kvm-pv-unhalt",
|
|
"kvm-steal-time",
|
|
"kvm_asyncpf",
|
|
"kvm_asyncpf_int",
|
|
"kvm_mmu",
|
|
"kvm_nopiodelay",
|
|
"kvm_poll_control",
|
|
"kvm_pv_eoi",
|
|
"kvm_pv_unhalt",
|
|
"kvm_steal_time",
|
|
"kvmclock",
|
|
"kvmclock-stable-bit",
|
|
"l3-cache",
|
|
"legacy-cache",
|
|
"lmce",
|
|
"migratable",
|
|
"pmu",
|
|
"realized",
|
|
"start-powered-off",
|
|
"tcg-cpuid",
|
|
"vmware-cpuid-freq",
|
|
"vmx-activity-hlt",
|
|
"vmx-activity-shutdown",
|
|
"vmx-activity-wait-sipi",
|
|
"vmx-apicv-register",
|
|
"vmx-apicv-vid",
|
|
"vmx-apicv-x2apic",
|
|
"vmx-apicv-xapic",
|
|
"vmx-cr3-load-noexit",
|
|
"vmx-cr3-store-noexit",
|
|
"vmx-cr8-load-exit",
|
|
"vmx-cr8-store-exit",
|
|
"vmx-desc-exit",
|
|
"vmx-encls-exit",
|
|
"vmx-entry-ia32e-mode",
|
|
"vmx-entry-load-bndcfgs",
|
|
"vmx-entry-load-efer",
|
|
"vmx-entry-load-pat",
|
|
"vmx-entry-load-perf-global-ctrl",
|
|
"vmx-entry-load-pkrs",
|
|
"vmx-entry-load-rtit-ctl",
|
|
"vmx-entry-noload-debugctl",
|
|
"vmx-ept",
|
|
"vmx-ept-1gb",
|
|
"vmx-ept-2mb",
|
|
"vmx-ept-advanced-exitinfo",
|
|
"vmx-ept-execonly",
|
|
"vmx-eptad",
|
|
"vmx-eptp-switching",
|
|
"vmx-exit-ack-intr",
|
|
"vmx-exit-clear-bndcfgs",
|
|
"vmx-exit-clear-rtit-ctl",
|
|
"vmx-exit-load-efer",
|
|
"vmx-exit-load-pat",
|
|
"vmx-exit-load-perf-global-ctrl",
|
|
"vmx-exit-load-pkrs",
|
|
"vmx-exit-nosave-debugctl",
|
|
"vmx-exit-save-efer",
|
|
"vmx-exit-save-pat",
|
|
"vmx-exit-save-preemption-timer",
|
|
"vmx-flexpriority",
|
|
"vmx-hlt-exit",
|
|
"vmx-ins-outs",
|
|
"vmx-intr-exit",
|
|
"vmx-invept",
|
|
"vmx-invept-all-context",
|
|
"vmx-invept-single-context",
|
|
"vmx-invept-single-context-noglobals",
|
|
"vmx-invlpg-exit",
|
|
"vmx-invpcid-exit",
|
|
"vmx-invvpid",
|
|
"vmx-invvpid-all-context",
|
|
"vmx-invvpid-single-addr",
|
|
"vmx-io-bitmap",
|
|
"vmx-io-exit",
|
|
"vmx-monitor-exit",
|
|
"vmx-movdr-exit",
|
|
"vmx-msr-bitmap",
|
|
"vmx-mtf",
|
|
"vmx-mwait-exit",
|
|
"vmx-nmi-exit",
|
|
"vmx-page-walk-4",
|
|
"vmx-page-walk-5",
|
|
"vmx-pause-exit",
|
|
"vmx-ple",
|
|
"vmx-pml",
|
|
"vmx-posted-intr",
|
|
"vmx-preemption-timer",
|
|
"vmx-rdpmc-exit",
|
|
"vmx-rdrand-exit",
|
|
"vmx-rdseed-exit",
|
|
"vmx-rdtsc-exit",
|
|
"vmx-rdtscp-exit",
|
|
"vmx-secondary-ctls",
|
|
"vmx-shadow-vmcs",
|
|
"vmx-store-lma",
|
|
"vmx-true-ctls",
|
|
"vmx-tsc-offset",
|
|
"vmx-tsc-scaling",
|
|
"vmx-unrestricted-guest",
|
|
"vmx-vintr-pending",
|
|
"vmx-vmfunc",
|
|
"vmx-vmwrite-vmexit-fields",
|
|
"vmx-vnmi",
|
|
"vmx-vnmi-pending",
|
|
"vmx-vpid",
|
|
"vmx-wbinvd-exit",
|
|
"vmx-xsaves",
|
|
"vmx-zero-len-inject",
|
|
]
|
|
|
|
if feature["type"] != "bool":
|
|
return True
|
|
|
|
name = feature["name"]
|
|
|
|
if name.startswith("x-"):
|
|
return True
|
|
|
|
if name in ignored_features:
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def get_qemu_feature_list(path_to_qemu):
|
|
cmd = [
|
|
path_to_qemu,
|
|
"-machine", "accel=kvm",
|
|
"-cpu", "host",
|
|
"-nodefaults",
|
|
"-nographic",
|
|
"-qmp",
|
|
"stdio"
|
|
]
|
|
|
|
request = """
|
|
{
|
|
"execute": "qmp_capabilities"
|
|
}
|
|
{
|
|
"execute": "qom-list-properties",
|
|
"arguments": {
|
|
"typename": "max-x86_64-cpu"
|
|
},
|
|
"id": "qom-list-properties"
|
|
}
|
|
{
|
|
"execute": "quit"
|
|
}
|
|
"""
|
|
|
|
decoder = json.JSONDecoder()
|
|
output = subprocess.check_output(cmd, input=request, text=True)
|
|
while output:
|
|
obj, idx = decoder.raw_decode(output)
|
|
output = output[idx:].strip()
|
|
if obj.get("id") != "qom-list-properties":
|
|
continue
|
|
for feature in obj["return"]:
|
|
if ignore_feature(feature):
|
|
continue
|
|
yield feature["name"]
|
|
|
|
|
|
def get_libvirt_feature_list(path_to_featuresfile):
|
|
dom = xml.etree.ElementTree.parse(path_to_featuresfile)
|
|
for feature in dom.getroot().iter("feature"):
|
|
yield feature.get("name")
|
|
for alias in feature:
|
|
if alias.tag == "alias" and alias.get("source") == "qemu":
|
|
yield alias.get("name")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Synchronize x86 cpu features from QEMU i386 target.")
|
|
parser.add_argument(
|
|
"--qemu",
|
|
help="Path to qemu executable",
|
|
default="qemu-system-x86_64",
|
|
type=str)
|
|
parser.add_argument(
|
|
"--features",
|
|
help="Path to 'src/cpu_map/x86_features.xml' file in "
|
|
"the libvirt repository",
|
|
default="x86_features.xml",
|
|
type=str)
|
|
|
|
args = parser.parse_args()
|
|
|
|
qfeatures = get_qemu_feature_list(args.qemu)
|
|
lfeatures = list(get_libvirt_feature_list(args.features))
|
|
missing = [f for f in sorted(qfeatures) if f not in lfeatures]
|
|
|
|
if missing:
|
|
print("The following features were reported by qemu but are "
|
|
"unknown to libvirt:")
|
|
for feature in missing:
|
|
print(" *", feature)
|
|
|
|
return len(missing) != 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit(main())
|