From nobody Sat Feb 7 18:46:31 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 1538083639782660.3009632634826; Thu, 27 Sep 2018 14:27:19 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D895330E6849; Thu, 27 Sep 2018 21:27:17 +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 948FD17BA9; Thu, 27 Sep 2018 21:27:17 +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 4694E181A12F; Thu, 27 Sep 2018 21:27:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w8RLQwEe005762 for ; Thu, 27 Sep 2018 17:26:58 -0400 Received: by smtp.corp.redhat.com (Postfix) id D33425D772; Thu, 27 Sep 2018 21:26:58 +0000 (UTC) Received: from cv1.lan (ovpn-125-53.rdu2.redhat.com [10.10.125.53]) by smtp.corp.redhat.com (Postfix) with ESMTP id E7E4D5D6A9; Thu, 27 Sep 2018 21:26:57 +0000 (UTC) From: Chris Venteicher To: libvir-list@redhat.com Date: Thu, 27 Sep 2018 16:26:42 -0500 Message-Id: <20180927212645.20758-4-cventeic@redhat.com> In-Reply-To: <20180927212645.20758-1-cventeic@redhat.com> References: <20180927212645.20758-1-cventeic@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: walling@linux.ibm.com, Chris Venteicher , david@redhat.com Subject: [libvirt] [PATCH v3 3/6] qemu_monitor: qemuMonitorGetCPUModelExpansion inputs and outputs CPUModelInfo 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.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Thu, 27 Sep 2018 21:27:18 +0000 (UTC) X-ZohoMail: RDMRC_0 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" A Full CPUModelInfo structure with props is sent to QEMU for expansion. virQEMUCapsProbeQMPHostCPU migratability logic partitioned into new function for clarity. Signed-off-by: Chris Venteicher --- src/qemu/qemu_capabilities.c | 125 ++++++++++++++++++++++++----------- src/qemu/qemu_monitor.c | 47 +++++++++++-- src/qemu/qemu_monitor.h | 5 +- src/qemu/qemu_monitor_json.c | 20 ++++-- src/qemu/qemu_monitor_json.h | 6 +- tests/cputest.c | 11 ++- 6 files changed, 156 insertions(+), 58 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e60a4b369e..d38530ca80 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2352,15 +2352,82 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qe= muCaps, return 0; } =20 +/* virQEMUCapsMigratablePropsDiff + * @migratable: migratable props=3Dtrue, non-migratable & unsupported prop= s=3Dfalse + * @nonMigratable: migratable & non-migratable props =3D true, unsupported= props =3D false + * @augmented: prop->migratable =3D VIR_TRISTATE_BOOL_{YES/NO} base on diff + * + * Use differences in Expanded CPUModelInfo inputs + * to augment with prop->migratable in CPUModelInfo output + */ +static int +virQEMUCapsMigratablePropsDiff(qemuMonitorCPUModelInfoPtr migratable, + qemuMonitorCPUModelInfoPtr nonMigratable, + qemuMonitorCPUModelInfoPtr *augmented) +{ + int ret =3D -1; + qemuMonitorCPUModelInfoPtr tmp; + qemuMonitorCPUPropertyPtr prop; + qemuMonitorCPUPropertyPtr mProp; + qemuMonitorCPUPropertyPtr nmProp; + virHashTablePtr hash =3D NULL; + size_t i; + + *augmented =3D NULL; + + if (!(tmp =3D qemuMonitorCPUModelInfoCopy(migratable))) + goto cleanup; + + if (!nonMigratable) + goto done; + + if (!(hash =3D virHashCreate(0, NULL))) + goto cleanup; + + for (i =3D 0; i < tmp->nprops; i++) { + prop =3D tmp->props + i; + + if (virHashAddEntry(hash, prop->name, prop) < 0) + goto cleanup; + } + + for (i =3D 0; i < nonMigratable->nprops; i++) { + nmProp =3D nonMigratable->props + i; + + if (!(mProp =3D virHashLookup(hash, nmProp->name)) || + mProp->type !=3D QEMU_MONITOR_CPU_PROPERTY_BOOLEAN || + mProp->type !=3D nmProp->type) + continue; /* In non-migratable list but not in migratable lis= t */ + + if (mProp->value.boolean) { + mProp->migratable =3D VIR_TRISTATE_BOOL_YES; + } else if (nmProp->value.boolean) { + mProp->value.boolean =3D true; + mProp->migratable =3D VIR_TRISTATE_BOOL_NO; + } + } + + tmp->migratability =3D true; + + done: + VIR_STEAL_PTR(*augmented, tmp); + ret =3D 0; + + cleanup: + qemuMonitorCPUModelInfoFree(tmp); + virHashFree(hash); + return ret; +} =20 static int virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon, bool tcg) { - qemuMonitorCPUModelInfoPtr modelInfo =3D NULL; + qemuMonitorCPUModelInfoPtr input; + qemuMonitorCPUModelInfoPtr migratable =3D NULL; qemuMonitorCPUModelInfoPtr nonMigratable =3D NULL; - virHashTablePtr hash =3D NULL; + qemuMonitorCPUModelInfoPtr augmented =3D NULL; const char *model; qemuMonitorCPUModelExpansionType type; virDomainVirtType virtType; @@ -2380,6 +2447,8 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, =20 cpuData =3D virQEMUCapsGetHostCPUData(qemuCaps, virtType); =20 + cpuData->info =3D NULL; + /* Some x86_64 features defined in cpu_map.xml use spelling which diff= er * from the one preferred by QEMU. Static expansion would give us only= the * preferred spelling, thus we need to do a full expansion on the resu= lt of @@ -2390,54 +2459,30 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, else type =3D QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC; =20 - if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo= ) < 0) + if (!(input =3D qemuMonitorCPUModelInfoNew(model)) || + qemuMonitorGetCPUModelExpansion(mon, type, true, input, &migratabl= e) < 0) goto cleanup; =20 - /* Try to check migratability of each feature. */ - if (modelInfo && - qemuMonitorGetCPUModelExpansion(mon, type, model, false, - &nonMigratable) < 0) + if (!migratable) { + ret =3D 0; /* Qemu can't expand the model name, exit without = error */ goto cleanup; + } =20 - if (nonMigratable) { - qemuMonitorCPUPropertyPtr prop; - qemuMonitorCPUPropertyPtr nmProp; - size_t i; - - if (!(hash =3D virHashCreate(0, NULL))) - goto cleanup; - - for (i =3D 0; i < modelInfo->nprops; i++) { - prop =3D modelInfo->props + i; - if (virHashAddEntry(hash, prop->name, prop) < 0) - goto cleanup; - } - - for (i =3D 0; i < nonMigratable->nprops; i++) { - nmProp =3D nonMigratable->props + i; - if (!(prop =3D virHashLookup(hash, nmProp->name)) || - prop->type !=3D QEMU_MONITOR_CPU_PROPERTY_BOOLEAN || - prop->type !=3D nmProp->type) - continue; - - if (prop->value.boolean) { - prop->migratable =3D VIR_TRISTATE_BOOL_YES; - } else if (nmProp->value.boolean) { - prop->value.boolean =3D true; - prop->migratable =3D VIR_TRISTATE_BOOL_NO; - } - } + /* Try to check migratability of each feature. */ + if (qemuMonitorGetCPUModelExpansion(mon, type, false, input, &nonMigra= table) < 0) + goto cleanup; =20 - modelInfo->migratability =3D true; - } + if (virQEMUCapsMigratablePropsDiff(migratable, nonMigratable, &augment= ed) < 0) + goto cleanup; =20 - VIR_STEAL_PTR(cpuData->info, modelInfo); + VIR_STEAL_PTR(cpuData->info, augmented); ret =3D 0; =20 cleanup: - virHashFree(hash); + qemuMonitorCPUModelInfoFree(input); + qemuMonitorCPUModelInfoFree(migratable); qemuMonitorCPUModelInfoFree(nonMigratable); - qemuMonitorCPUModelInfoFree(modelInfo); + qemuMonitorCPUModelInfoFree(augmented); =20 return ret; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 801c072eff..c64b3ad38a 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3653,20 +3653,57 @@ qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr = cpu) } =20 =20 +/** + * qemuMonitorGetCPUModelExpansion: + * @mon: + * @type: qemuMonitorCPUModelExpansionType + * @migratable: Prompt QEMU to include non-migratable features for X86 mod= els if false. + * @input: Non-expanded input model + * @expansion: Expanded output model (or NULL if QEMU rejects model / requ= est) + * + * CPU property lists are computed from CPUModelInfo structures by 1) conv= erting + * model->name into a property list using a static lookup table and 2) add= ing or + * removing properties in the resulting list from model->props. + * + * This function uses QEMU to identify a base model name that most closely + * matches the migratable CPU properties in the input CPU Model. + * + * This function also uses QEMU to enumerate model->props in various ways = based + * on the qemuMonitorCPUModelExpansionType. + * + * full_input_props =3D LookupProps(input->name) then +/- input->props + * + * migratable_input_props =3D full_input_props - non_migratable_input_props + * + * base_model =3D FindClosestBaseModel(migratable_input_props) + * + * expansion->name =3D base_model->name + * + * @type =3D=3D QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC + * expansion->props =3D props to +/- to base_model to approximate migrat= able_input_props + * + * @type =3D=3D QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL + * expansion->props =3D full_input_props + * + * @type =3D=3D QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL + * expansion->props =3D migratable_input_props + * + * Returns 0 in case of success, -1 in case of failure + */ int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType type, - const char *model_name, bool migratable, - qemuMonitorCPUModelInfoPtr *model_info) + qemuMonitorCPUModelInfoPtr input, + qemuMonitorCPUModelInfoPtr *expansion + ) { VIR_DEBUG("type=3D%d model_name=3D%s migratable=3D%d", - type, model_name, migratable); + type, input->name, migratable); =20 QEMU_CHECK_MONITOR(mon); =20 - return qemuMonitorJSONGetCPUModelExpansion(mon, type, model_name, - migratable, model_info); + return qemuMonitorJSONGetCPUModelExpansion(mon, type, migratable, inpu= t, expansion); } =20 =20 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 0a09590ed1..d3efd37099 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1036,9 +1036,10 @@ typedef enum { =20 int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType type, - const char *model_name, bool migratable, - qemuMonitorCPUModelInfoPtr *model_info= ); + qemuMonitorCPUModelInfoPtr input, + qemuMonitorCPUModelInfoPtr *expansion) + ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); =20 void qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info); =20 diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index f20e9e9379..4e6e220a8c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5600,12 +5600,17 @@ qemuMonitorJSONBuildCPUModelInfoFromJSON(virJSONVal= uePtr cpu_model) return ret; } =20 + +/* return: + * -1 - Execution Failure + * 0 - Success + */ int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType type, - const char *model_name, bool migratable, - qemuMonitorCPUModelInfoPtr *model_info) + qemuMonitorCPUModelInfoPtr input, + qemuMonitorCPUModelInfoPtr *expansion) { int ret =3D -1; virJSONValuePtr json_model_in =3D NULL; @@ -5613,12 +5618,13 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr = mon, virJSONValuePtr reply =3D NULL; virJSONValuePtr data; virJSONValuePtr cpu_model; + qemuMonitorCPUModelInfoPtr expanded_model =3D NULL; qemuMonitorCPUModelInfoPtr model_in =3D NULL; const char *typeStr =3D ""; =20 - *model_info =3D NULL; + *expansion =3D NULL; =20 - if (!(model_in =3D qemuMonitorCPUModelInfoNew(model_name))) + if (!(model_in =3D qemuMonitorCPUModelInfoCopy(input))) goto cleanup; =20 if (!migratable && @@ -5684,13 +5690,17 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr = mon, goto retry; } =20 - if (!(*model_info =3D qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_mod= el))) + if (!(expanded_model =3D qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_= model))) goto cleanup; =20 + VIR_STEAL_PTR(*expansion, expanded_model); ret =3D 0; =20 cleanup: + VIR_FREE(expanded_model); /* Free structure but not reused contents */ qemuMonitorCPUModelInfoFree(model_in); + qemuMonitorCPUModelInfoFree(expanded_model); + virJSONValueFree(cmd); virJSONValueFree(reply); virJSONValueFree(json_model_in); diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index da267b15b0..2d5679094e 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -367,10 +367,10 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr m= on, =20 int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType t= ype, - const char *model_name, bool migratable, - qemuMonitorCPUModelInfoPtr *model_= info) - ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5); + qemuMonitorCPUModelInfoPtr input, + qemuMonitorCPUModelInfoPtr *expans= ion) + ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); =20 int qemuMonitorJSONGetCommands(qemuMonitorPtr mon, char ***commands) diff --git a/tests/cputest.c b/tests/cputest.c index 339119c63f..c438a8d09e 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -483,6 +483,7 @@ cpuTestMakeQEMUCaps(const struct data *data) virQEMUCapsPtr qemuCaps =3D NULL; qemuMonitorTestPtr testMon =3D NULL; qemuMonitorCPUModelInfoPtr model =3D NULL; + qemuMonitorCPUModelInfoPtr expansion =3D NULL; char *json =3D NULL; =20 if (virAsprintf(&json, "%s/cputestdata/%s-cpuid-%s.json", @@ -492,9 +493,12 @@ cpuTestMakeQEMUCaps(const struct data *data) if (!(testMon =3D qemuMonitorTestNewFromFile(json, driver.xmlopt, true= ))) goto error; =20 + if (!(model =3D qemuMonitorCPUModelInfoNew("host"))) + goto cleanup; + if (qemuMonitorGetCPUModelExpansion(qemuMonitorTestGetMonitor(testMon), QEMU_MONITOR_CPU_MODEL_EXPANSION_S= TATIC, - "host", true, &model) < 0) + true, model, &expansion) < 0) goto error; =20 if (!(qemuCaps =3D virQEMUCapsNew())) @@ -506,8 +510,8 @@ cpuTestMakeQEMUCaps(const struct data *data) virQEMUCapsSet(qemuCaps, QEMU_CAPS_QUERY_CPU_DEFINITIONS); =20 virQEMUCapsSetArch(qemuCaps, data->arch); - virQEMUCapsSetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM, model); - model =3D NULL; + virQEMUCapsSetCPUModelInfo(qemuCaps, VIR_DOMAIN_VIRT_KVM, expansion); + expansion =3D NULL; =20 if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, qemuMonitorTestGetMonitor(testMo= n), @@ -516,6 +520,7 @@ cpuTestMakeQEMUCaps(const struct data *data) =20 cleanup: qemuMonitorCPUModelInfoFree(model); + qemuMonitorCPUModelInfoFree(expansion); qemuMonitorTestFree(testMon); VIR_FREE(json); =20 --=20 2.17.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list