mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00:00
cpu_map: Add script to sync from QEMU i386 cpu features
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>
This commit is contained in:
parent
1d946ac794
commit
fe69966cbb
278
src/cpu_map/sync_qemu_features_i386.py
Executable file
278
src/cpu_map/sync_qemu_features_i386.py
Executable file
@ -0,0 +1,278 @@
|
||||
#!/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())
|
Loading…
x
Reference in New Issue
Block a user