From nobody Wed May 14 07:57:19 2025 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=fail(p=none dis=none) header.from=linux.ibm.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1523920617370985.7562095008327; Mon, 16 Apr 2018 16:16:57 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id ADE815D68B; Mon, 16 Apr 2018 23:16:53 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 85C3867EE7; Mon, 16 Apr 2018 23:16:53 +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 2AD494CA9C; Mon, 16 Apr 2018 23:16:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w3GNGQJF008625 for ; Mon, 16 Apr 2018 19:16:26 -0400 Received: by smtp.corp.redhat.com (Postfix) id E82D088301; Mon, 16 Apr 2018 23:16:26 +0000 (UTC) Received: from mx1.redhat.com (ext-mx14.extmail.prod.ext.phx2.redhat.com [10.5.110.43]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E11C960182 for ; Mon, 16 Apr 2018 23:16:21 +0000 (UTC) Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 56D813142296 for ; Mon, 16 Apr 2018 23:16:20 +0000 (UTC) Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w3GNG3oa138850 for ; Mon, 16 Apr 2018 19:16:20 -0400 Received: from e17.ny.us.ibm.com (e17.ny.us.ibm.com [129.33.205.207]) by mx0a-001b2d01.pphosted.com with ESMTP id 2hd3vb343c-1 (version=TLSv1.2 cipher=AES256-SHA256 bits=256 verify=NOT) for ; Mon, 16 Apr 2018 19:16:19 -0400 Received: from localhost by e17.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 16 Apr 2018 19:16:15 -0400 Received: from b01cxnp22035.gho.pok.ibm.com (9.57.198.25) by e17.ny.us.ibm.com (146.89.104.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 16 Apr 2018 19:16:13 -0400 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp22035.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w3GNGDZc55378130; Mon, 16 Apr 2018 23:16:13 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BFF8EB204E; Mon, 16 Apr 2018 20:18:17 -0400 (EDT) Received: from collin-ThinkPad-W541.pok.ibm.com (unknown [9.56.58.57]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP id A9680B204D; Mon, 16 Apr 2018 20:18:17 -0400 (EDT) From: Collin Walling To: libvir-list@redhat.com Date: Mon, 16 Apr 2018 19:16:08 -0400 In-Reply-To: <1523920569-9386-1-git-send-email-walling@linux.ibm.com> References: <1523920569-9386-1-git-send-email-walling@linux.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18041623-0040-0000-0000-0000041BE31E X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008866; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000257; SDB=6.01018943; UDB=6.00519786; IPR=6.00798184; MB=3.00020604; MTD=3.00000008; XFM=3.00000015; UTC=2018-04-16 23:16:15 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18041623-0041-0000-0000-00000821E6EE Message-Id: <1523920569-9386-4-git-send-email-walling@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-04-16_12:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1804160192 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Mon, 16 Apr 2018 23:16:20 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Mon, 16 Apr 2018 23:16:20 +0000 (UTC) for IP:'148.163.156.1' DOMAIN:'mx0a-001b2d01.pphosted.com' HELO:'mx0a-001b2d01.pphosted.com' FROM:'walling@linux.ibm.com' RCPT:'' X-RedHat-Spam-Score: -0.701 (RCVD_IN_DNSWL_LOW, SPF_PASS) 148.163.156.1 mx0a-001b2d01.pphosted.com 148.163.156.1 mx0a-001b2d01.pphosted.com X-Scanned-By: MIMEDefang 2.84 on 10.5.110.43 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: cventeic@redhat.com Subject: [libvirt] [PATCH v1 3/4] qemu: implement query-cpu-model-comparison via qemu 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 16 Apr 2018 23:16:54 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Interfaces with QEMU to compare two CPU models. The command takes two CPU models, A and B, that are given a model name and an optional list of CPU features. Through the query-cpu-model-comparison command sent to QEMU via QMP, a third CPU model, C, is returned that contains the comparison result (identical, superset, subset, incompatible) as its model name as well as a list of properties (aka CPU features) responsible for this result. Signed-off-by: Collin Walling --- src/qemu/qemu_capabilities.c | 53 ++++++++++++++++++ src/qemu/qemu_capabilities.h | 6 ++ src/qemu/qemu_monitor.c | 14 +++++ src/qemu/qemu_monitor.h | 6 ++ src/qemu/qemu_monitor_json.c | 128 +++++++++++++++++++++++++++++++++++++++= ++++ src/qemu/qemu_monitor_json.h | 6 ++ 6 files changed, 213 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d2eb813..d385ad8 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -468,6 +468,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "virtio-tablet-ccw", "qcow2-luks", "pcie-pci-bridge", + "query-cpu-model-comparison", ); =20 =20 @@ -1030,6 +1031,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = =3D { { "query-hotpluggable-cpus", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS }, { "query-qmp-schema", QEMU_CAPS_QUERY_QMP_SCHEMA }, { "query-cpu-model-expansion", QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION }, + { "query-cpu-model-comparison", QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON }, { "query-cpu-definitions", QEMU_CAPS_QUERY_CPU_DEFINITIONS }, { "query-named-block-nodes", QEMU_CAPS_QUERY_NAMED_BLOCK_NODES }, }; @@ -4930,3 +4932,54 @@ virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCa= ps, { qemuCaps->microcodeVersion =3D microcodeVersion; } + + +static virQEMUCapsInitQMPCommandPtr +virQEMUCapsSetupBinary(char *binary) +{ + virQEMUCapsInitQMPCommandPtr cmd; + char *qmperr =3D NULL; + + if (!(cmd =3D virQEMUCapsInitQMPCommandNew(binary, "/tmp", -1, -1, &qm= perr))) + goto cleanup; + + if (virQEMUCapsInitQMPCommandRun(cmd, false) !=3D 0) + goto cleanup; + + if (qemuMonitorSetCapabilities(cmd->mon) < 0) { + VIR_DEBUG("Failed to set monitor capabilities %s", + virGetLastErrorMessage()); + goto cleanup; + } + + return cmd; + + cleanup: + virQEMUCapsInitQMPCommandFree(cmd); + return NULL; +} + + +qemuMonitorCPUModelInfoPtr +virQEMUCapsProbeQMPCPUModelComparison(char *binary, + virCPUDefPtr cpuA, + virCPUDefPtr cpuB) +{ + virQEMUCapsInitQMPCommandPtr cmd; + qemuMonitorCPUModelInfoPtr cpuC =3D NULL; + qemuMonitorCPUModelInfoPtr ret =3D NULL; + + if (!(cmd =3D virQEMUCapsSetupBinary(binary))) + goto cleanup; + + if (qemuMonitorGetCPUModelComparison(cmd->mon, cpuA, cpuB, &cpuC) < 0) + goto cleanup; + + ret =3D cpuC; + cpuC =3D NULL; + + cleanup: + virQEMUCapsInitQMPCommandFree(cmd); + qemuMonitorCPUModelInfoFree(cpuC); + return ret; +} diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index a959931..f27a359 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -452,6 +452,7 @@ typedef enum { QEMU_CAPS_DEVICE_VIRTIO_TABLET_CCW, /* -device virtio-tablet-ccw */ QEMU_CAPS_QCOW2_LUKS, /* qcow2 format support LUKS encryption */ QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE, /* -device pcie-pci-bridge */ + QEMU_CAPS_QUERY_CPU_MODEL_COMPARISON, /* qmp query-cpu-model-compariso= n */ =20 QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; @@ -578,4 +579,9 @@ bool virQEMUCapsGuestIsNative(virArch host, bool virQEMUCapsCPUFilterFeatures(const char *name, void *opaque); =20 +qemuMonitorCPUModelInfoPtr +virQEMUCapsProbeQMPCPUModelComparison(char *binary, + virCPUDefPtr cpuA, + virCPUDefPtr cpuB); + #endif /* __QEMU_CAPABILITIES_H__*/ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 22f0522..1981b62 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3792,6 +3792,20 @@ qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoP= tr model_info) } =20 =20 +int +qemuMonitorGetCPUModelComparison(qemuMonitorPtr mon, + virCPUDefPtr cpuA, + virCPUDefPtr cpuB, + qemuMonitorCPUModelInfoPtr *cpuC) +{ + VIR_DEBUG("cpuA=3D%p cpuB=3D%p", cpuA, cpuB); + + QEMU_CHECK_MONITOR_JSON(mon); + + return qemuMonitorJSONGetCPUModelComparison(mon, cpuA, cpuB, cpuC); +} + + qemuMonitorCPUModelInfoPtr qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig) { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 9556a51..cc30184 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1072,6 +1072,12 @@ int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr m= on, =20 void qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info); =20 +int +qemuMonitorGetCPUModelComparison(qemuMonitorPtr mon, + virCPUDefPtr modelA, + virCPUDefPtr modelB, + qemuMonitorCPUModelInfoPtr *cpuC); + qemuMonitorCPUModelInfoPtr qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig); =20 diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 57c2c4d..c1759ec 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5466,6 +5466,134 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr = mon, } =20 =20 +static virJSONValuePtr +qemuMonitorJSONConvertCPUDefToJSON(virCPUDefPtr cpu) +{ + virJSONValuePtr value; + virJSONValuePtr feats =3D NULL; + size_t i; + + if (!(value =3D virJSONValueNewObject()) || + !(feats =3D virJSONValueNewObject())) + goto cleanup; + + if (virJSONValueObjectAppendString(value, "name", cpu->model) < 0) + goto cleanup; + + for (i =3D 0; i < cpu->nfeatures; i++) { + char *name =3D cpu->features[i].name; + bool enabled =3D false; + + if (cpu->type =3D=3D VIR_CPU_TYPE_HOST || + cpu->features[i].policy =3D=3D VIR_CPU_FEATURE_REQUIRE) + enabled =3D true; + + if (virJSONValueObjectAppendBoolean(feats, name, enabled) < 0) + goto cleanup; + } + + if (virJSONValueObjectAppend(value, "props", feats) < 0) + goto cleanup; + + return value; + + cleanup: + virJSONValueFree(value); + virJSONValueFree(feats); + return NULL; +} + + +static int +qemuMonitorJSONParseCPUModelPropName(size_t pos ATTRIBUTE_UNUSED, + virJSONValuePtr item, + void *opaque) +{ + return qemuMonitorJSONParseCPUModelProperty(virJSONValueGetString(item= ), + item, opaque); +} + + +int +qemuMonitorJSONGetCPUModelComparison(qemuMonitorPtr mon, + virCPUDefPtr modelA, + virCPUDefPtr modelB, + qemuMonitorCPUModelInfoPtr *cpuC) +{ + int ret =3D -1; + virJSONValuePtr modela; + virJSONValuePtr modelb =3D NULL; + virJSONValuePtr cmd =3D NULL; + virJSONValuePtr reply =3D NULL; + virJSONValuePtr data; + const char *result; + virJSONValuePtr props; + qemuMonitorCPUModelInfoPtr modelc =3D NULL; + + if (!(modela =3D qemuMonitorJSONConvertCPUDefToJSON(modelA)) || + !(modelb =3D qemuMonitorJSONConvertCPUDefToJSON(modelB))) + goto cleanup; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("query-cpu-model-comparison", + "a:modela", &modela, + "a:modelb", &modelb, + NULL))) + goto cleanup; + + /* Clean up of cmd will free the below virJSONValuePtrs */ + modela =3D NULL; + modelb =3D NULL; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + data =3D virJSONValueObjectGetObject(reply, "return"); + + if (!(result =3D virJSONValueObjectGetString(data, "result"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-cpu-model-expansion reply data was missing= " + "'result'")); + goto cleanup; + } + + if (!(props =3D virJSONValueObjectGetArray(data, "responsible-properti= es"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-cpu-model-expansion reply data was missing= " + "'responsible-properties'")); + goto cleanup; + } + + if (VIR_ALLOC(modelc) < 0) + goto cleanup; + + if (VIR_STRDUP(modelc->name, result) < 0) + goto cleanup; + + if (VIR_ALLOC_N(modelc->props, virJSONValueArraySize(props)) < 0) + goto cleanup; + + if (virJSONValueArrayForeachSteal(props, + qemuMonitorJSONParseCPUModelPropName, + modelc) < 0) + goto cleanup; + + ret =3D 0; + *cpuC =3D modelc; + modelc =3D NULL; + + cleanup: + qemuMonitorCPUModelInfoFree(modelc); + virJSONValueFree(cmd); + virJSONValueFree(reply); + virJSONValueFree(modela); + virJSONValueFree(modelb); + return ret; +} + + int qemuMonitorJSONGetCommands(qemuMonitorPtr mon, char ***commands) { diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 045df49..ad9ae73 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -361,6 +361,12 @@ int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr= mon, qemuMonitorCPUModelInfoPtr *model_= info) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5); =20 +int qemuMonitorJSONGetCPUModelComparison(qemuMonitorPtr mon, + virCPUDefPtr modelA, + virCPUDefPtr modelB, + qemuMonitorCPUModelInfoPtr *cpuC) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); + int qemuMonitorJSONGetCommands(qemuMonitorPtr mon, char ***commands) ATTRIBUTE_NONNULL(2); --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list