From nobody Sun Feb 8 20:53:13 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 155127418683295.17504772786617; Wed, 27 Feb 2019 05:29:46 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 71668313C245; Wed, 27 Feb 2019 13:29:44 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 492011001DD3; Wed, 27 Feb 2019 13:29:44 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id F3A0C181A137; Wed, 27 Feb 2019 13:29:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x1RDTUpp004061 for ; Wed, 27 Feb 2019 08:29:30 -0500 Received: by smtp.corp.redhat.com (Postfix) id 2FD6019C7C; Wed, 27 Feb 2019 13:29:30 +0000 (UTC) Received: from virval.usersys.redhat.com (unknown [10.43.2.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CF9EC2B46F for ; Wed, 27 Feb 2019 13:29:27 +0000 (UTC) Received: by virval.usersys.redhat.com (Postfix, from userid 500) id 0F0E8106FB7; Wed, 27 Feb 2019 14:29:19 +0100 (CET) From: Jiri Denemark To: libvir-list@redhat.com Date: Wed, 27 Feb 2019 14:29:01 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 11/26] cpu_x86: Allow multiple signatures for a CPU model X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Wed, 27 Feb 2019 13:29:45 +0000 (UTC) Content-Type: text/plain; charset="utf-8" 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=C3=A1n Tomko --- src/cpu/cpu_x86.c | 104 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 18 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index c2f22f399f..89303400af 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -147,7 +147,8 @@ typedef virCPUx86Model *virCPUx86ModelPtr; struct _virCPUx86Model { char *name; virCPUx86VendorPtr vendor; - uint32_t signature; + size_t nsignatures; + uint32_t *signatures; virCPUx86Data data; }; =20 @@ -974,11 +975,29 @@ x86ModelFree(virCPUx86ModelPtr model) return; =20 VIR_FREE(model->name); + VIR_FREE(model->signatures); virCPUx86DataClear(&model->data); VIR_FREE(model); } =20 =20 +static int +x86ModelCopySignatures(virCPUx86ModelPtr dst, + virCPUx86ModelPtr src) +{ + size_t i; + + if (VIR_ALLOC_N(dst->signatures, src->nsignatures) < 0) + return -1; + + dst->nsignatures =3D src->nsignatures; + for (i =3D 0; i < src->nsignatures; i++) + dst->signatures[i] =3D src->signatures[i]; + + return 0; +} + + static virCPUx86ModelPtr x86ModelCopy(virCPUx86ModelPtr model) { @@ -986,13 +1005,13 @@ x86ModelCopy(virCPUx86ModelPtr model) =20 if (VIR_ALLOC(copy) < 0 || VIR_STRDUP(copy->name, model->name) < 0 || + x86ModelCopySignatures(copy, model) < 0 || x86DataCopy(©->data, &model->data) < 0) { x86ModelFree(copy); return NULL; } =20 copy->vendor =3D model->vendor; - copy->signature =3D model->signature; =20 return copy; } @@ -1178,8 +1197,8 @@ x86ModelParseAncestor(virCPUx86ModelPtr model, } =20 model->vendor =3D ancestor->vendor; - model->signature =3D ancestor->signature; - if (x86DataCopy(&model->data, &ancestor->data) < 0) + if (x86ModelCopySignatures(model, ancestor) < 0 || + x86DataCopy(&model->data, &ancestor->data) < 0) return -1; =20 return 0; @@ -1187,16 +1206,32 @@ x86ModelParseAncestor(virCPUx86ModelPtr model, =20 =20 static int -x86ModelParseSignature(virCPUx86ModelPtr model, - xmlXPathContextPtr ctxt) +x86ModelParseSignatures(virCPUx86ModelPtr model, + xmlXPathContextPtr ctxt) { - int rc; + VIR_AUTOFREE(xmlNodePtr *) nodes =3D NULL; + xmlNodePtr root =3D ctxt->node; + size_t i; + int n; =20 - if (virXPathBoolean("boolean(./signature)", ctxt)) { + if ((n =3D virXPathNodeSet("./signature", ctxt, &nodes)) <=3D 0) + return n; + + /* Remove inherited signatures. */ + VIR_FREE(model->signatures); + + model->nsignatures =3D n; + if (VIR_ALLOC_N(model->signatures, n) < 0) + return -1; + + for (i =3D 0; i < n; i++) { unsigned int sigFamily =3D 0; unsigned int sigModel =3D 0; + int rc; =20 - rc =3D virXPathUInt("string(./signature/@family)", ctxt, &sigFamil= y); + ctxt->node =3D nodes[i]; + + rc =3D virXPathUInt("string(@family)", ctxt, &sigFamily); if (rc < 0 || sigFamily =3D=3D 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid CPU signature family in model %s"), @@ -1204,7 +1239,7 @@ x86ModelParseSignature(virCPUx86ModelPtr model, return -1; } =20 - rc =3D virXPathUInt("string(./signature/@model)", ctxt, &sigModel); + rc =3D virXPathUInt("string(@model)", ctxt, &sigModel); if (rc < 0 || sigModel =3D=3D 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid CPU signature model in model %s"), @@ -1212,9 +1247,10 @@ x86ModelParseSignature(virCPUx86ModelPtr model, return -1; } =20 - model->signature =3D x86MakeSignature(sigFamily, sigModel, 0); + model->signatures[i] =3D x86MakeSignature(sigFamily, sigModel, 0); } =20 + ctxt->node =3D root; return 0; } =20 @@ -1311,7 +1347,7 @@ x86ModelParse(xmlXPathContextPtr ctxt, if (x86ModelParseAncestor(model, ctxt, map) < 0) goto cleanup; =20 - if (x86ModelParseSignature(model, ctxt) < 0) + if (x86ModelParseSignatures(model, ctxt) < 0) goto cleanup; =20 if (x86ModelParseVendor(model, ctxt, map) < 0) @@ -1615,7 +1651,8 @@ x86Compute(virCPUDefPtr host, &host_model->vendor->cpuid) < 0) goto error; =20 - if (x86DataAddSignature(&guest_model->data, host_model->signature)= < 0) + if (host_model->signatures && + x86DataAddSignature(&guest_model->data, *host_model->signature= s) < 0) goto error; =20 if (cpu->type =3D=3D VIR_CPU_TYPE_GUEST @@ -1721,6 +1758,21 @@ virCPUx86Compare(virCPUDefPtr host, } =20 =20 +static bool +x86ModelHasSignature(virCPUx86ModelPtr model, + uint32_t signature) +{ + size_t i; + + for (i =3D 0; i < model->nsignatures; i++) { + if (model->signatures[i] =3D=3D signature) + return true; + } + + return false; +} + + /* * Checks whether a candidate model is a better fit for the CPU data than = the * current model. @@ -1762,8 +1814,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current, * consider candidates with matching family/model. */ if (signature && - current->signature =3D=3D signature && - candidate->signature !=3D signature) { + x86ModelHasSignature(current, signature) && + !x86ModelHasSignature(candidate, signature)) { VIR_DEBUG("%s differs in signature from matching %s", cpuCandidate->model, cpuCurrent->model); return 0; @@ -1779,8 +1831,8 @@ x86DecodeUseCandidate(virCPUx86ModelPtr current, * result in longer list of features. */ if (signature && - candidate->signature =3D=3D signature && - current->signature !=3D signature) { + x86ModelHasSignature(candidate, signature) && + !x86ModelHasSignature(current, signature)) { VIR_DEBUG("%s provides matching signature", cpuCandidate->model); return 1; } @@ -1844,6 +1896,8 @@ x86Decode(virCPUDefPtr cpu, virCPUx86Data features =3D VIR_CPU_X86_DATA_INIT; virCPUx86VendorPtr vendor; virDomainCapsCPUModelPtr hvModel =3D NULL; + virBuffer sigBuf =3D VIR_BUFFER_INITIALIZER; + char *sigs =3D NULL; uint32_t signature; ssize_t i; int rc; @@ -1936,6 +1990,18 @@ x86Decode(virCPUDefPtr cpu, if (vendor && VIR_STRDUP(cpu->vendor, vendor->name) < 0) goto cleanup; =20 + for (i =3D 0; i < model->nsignatures; i++) + virBufferAsprintf(&sigBuf, "%06x,", model->signatures[i]); + + virBufferTrim(&sigBuf, ",", -1); + if (virBufferCheckError(&sigBuf) < 0) + goto cleanup; + + sigs =3D virBufferContentAndReset(&sigBuf); + + VIR_DEBUG("Using CPU model %s (signatures %s) for CPU with signature %= 06lx", + model->name, sigs, (long)signature); + VIR_STEAL_PTR(cpu->model, cpuModel->model); VIR_STEAL_PTR(cpu->features, cpuModel->features); cpu->nfeatures =3D cpuModel->nfeatures; @@ -1950,6 +2016,7 @@ x86Decode(virCPUDefPtr cpu, virCPUx86DataClear(&data); virCPUx86DataClear(©); virCPUx86DataClear(&features); + VIR_FREE(sigs); return ret; } =20 @@ -2848,7 +2915,8 @@ virCPUx86Translate(virCPUDefPtr cpu, virCPUx86DataAddCPUIDInt(&model->data, &model->vendor->cpuid) < 0) goto cleanup; =20 - if (x86DataAddSignature(&model->data, model->signature) < 0) + if (model->signatures && + x86DataAddSignature(&model->data, model->signatures[0]) < 0) goto cleanup; =20 if (!(translated =3D virCPUDefCopyWithoutModel(cpu))) --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list