sync_qemu_models_i386: Copy signatures from base model

The signatures in the CPU map are used for matching physical CPUs and
thus we need to cover all possible real world variants we know about.
When adding a new version of an existing CPU model, we should copy the
signature(s) of the existing model rather than replacing it with the
signature that QEMU uses.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Jiri Denemark 2024-10-22 12:38:04 +02:00
parent 7133d72eff
commit a410f0256a

View File

@ -429,7 +429,30 @@ def transform(item):
raise RuntimeError("unexpected item type")
def expand_model(model):
def get_signature(outdir, model):
file = os.path.join(outdir, f"x86_{model}.xml")
if not os.path.isfile(file):
return None
xml = lxml.etree.parse(file)
signature = []
for sig in xml.xpath("//signature"):
attr = sig.attrib
family = attr["family"]
model = attr["model"]
if "stepping" in attr:
stepping = attr["stepping"]
else:
stepping = None
signature.append((family, model, stepping))
return signature
def expand_model(outdir, model):
"""Expand a qemu cpu model description that has its feature split up into
different fields and may have differing versions into several libvirt-
friendly cpu models."""
@ -438,11 +461,14 @@ def expand_model(model):
"name": model.pop(".name"),
"vendor": translate_vendor(model.pop(".vendor")),
"features": set(),
"extra": dict()}
"extra": dict(),
"signature": list(),
}
if ".family" in model and ".model" in model:
result["family"] = model.pop(".family")
result["model"] = model.pop(".model")
result["signature"].append((model.pop(".family"),
model.pop(".model"),
None))
for k in [k for k in model if k.startswith(".features")]:
v = model.pop(k)
@ -470,6 +496,10 @@ def expand_model(model):
if not alias and ver == 1:
alias = name
sig = get_signature(outdir, name)
if sig:
result["signature"] = sig
props = version.pop(".props", dict())
for k, v in props:
if k not in ("model-id", "stepping", "model"):
@ -524,7 +554,11 @@ def output_model(f, extra, model):
if "alias" in model:
f.write(f" <model name='{model['alias']}'/>\n")
else:
f.write(f" <signature family='{model['family']}' model='{model['model']}'/>\n")
for sig_family, sig_model, sig_stepping in model['signature']:
f.write(f" <signature family='{sig_family}' model='{sig_model}'")
if sig_stepping:
f.write(f" stepping='{sig_stepping}'")
f.write("/>\n")
f.write(f" <vendor name='{model['vendor']}'/>\n")
for feature in sorted(model["features"]):
@ -600,7 +634,7 @@ def main():
models = list()
for model in models_json:
models.extend(expand_model(model))
models.extend(expand_model(args.outdir, model))
files = dict()