From ac2924813141609b07860a0df5c6bd56eddf0b3e Mon Sep 17 00:00:00 2001 Message-Id: From: Jiri Denemark Date: Fri, 22 Feb 2019 17:20:59 +0100 Subject: [PATCH] cpu_x86: Allow multiple signatures for a CPU model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPU signatures in the cpu_map serve as a hint for CPUID to CPU model matching algorithm. If the CPU signatures matches any CPU model in the cpu_map, this model will be the preferred one. This works out well and solved several mismatches, but in real world CPUs which should match a single CPU model may be produced with several different signatures. For example, low voltage Broadwell CPUs for laptops and Broadwell CPUs for servers differ in CPU model numbers while we should detect them all as Broadwell CPU model. This patch adds support for storing several signatures for a single CPU model to make this hint useful for more CPUs. Later commits will provide additional signatures for existing CPU models, which will correct some results in our CPU test suite. Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko (cherry picked from commit dfeb3e598438a891a05487c34e6723d1d3ed9256) https://bugzilla.redhat.com/show_bug.cgi?id=1558558 https://bugzilla.redhat.com/show_bug.cgi?id=1687515 Conflicts: src/cpu/cpu_x86.c - most refactoring was not backported - VIR_AUTOFREE is not in RHEL-7.6 Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko --- src/cpu/cpu_x86.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 543533148f..f6844aaa0d 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1204,41 +1204,57 @@ x86ModelCompare(virCPUx86ModelPtr model1, static int -x86ModelParseSignature(virCPUx86ModelPtr model, - xmlXPathContextPtr ctxt) +x86ModelParseSignatures(virCPUx86ModelPtr model, + xmlXPathContextPtr ctxt) { + xmlNodePtr *nodes = NULL; + xmlNodePtr root = ctxt->node; + size_t i; + int n; + int ret = -1; + + if ((n = virXPathNodeSet("./signature", ctxt, &nodes)) <= 0) + return n; + /* Remove inherited signatures. */ VIR_FREE(model->signatures); - if (virXPathBoolean("boolean(./signature)", ctxt)) { + model->nsignatures = n; + if (VIR_ALLOC_N(model->signatures, n) < 0) + goto cleanup; + + for (i = 0; i < n; i++) { unsigned int sigFamily = 0; unsigned int sigModel = 0; int rc; - model->nsignatures = 1; - if (VIR_ALLOC_N(model->signatures, 1) < 0) - return -1; + ctxt->node = nodes[i]; - rc = virXPathUInt("string(./signature/@family)", ctxt, &sigFamily); + rc = virXPathUInt("string(@family)", ctxt, &sigFamily); if (rc < 0 || sigFamily == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid CPU signature family in model %s"), model->name); - return -1; + goto cleanup; } - rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel); + rc = virXPathUInt("string(@model)", ctxt, &sigModel); if (rc < 0 || sigModel == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid CPU signature model in model %s"), model->name); - return -1; + goto cleanup; } - model->signatures[0] = x86MakeSignature(sigFamily, sigModel, 0); + model->signatures[i] = x86MakeSignature(sigFamily, sigModel, 0); } - return 0; + ctxt->node = root; + ret = 0; + + cleanup: + VIR_FREE(nodes); + return ret; } @@ -1290,8 +1306,8 @@ x86ModelParse(xmlXPathContextPtr ctxt, goto error; } - if (x86ModelParseSignature(model, ctxt) < 0) - goto error; + if (x86ModelParseSignatures(model, ctxt) < 0) + goto cleanup; if (virXPathBoolean("boolean(./vendor)", ctxt)) { vendor = virXPathString("string(./vendor/@name)", ctxt); -- 2.21.0