From nobody Sat Feb 7 15:35:24 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 1531195045866117.50460235899322; Mon, 9 Jul 2018 20:57:25 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 40A294E4C6; Tue, 10 Jul 2018 03:57:24 +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 EEF085D761; Tue, 10 Jul 2018 03:57:23 +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 9DFD318037F5; Tue, 10 Jul 2018 03:57:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w6A3v5fs003355 for ; Mon, 9 Jul 2018 23:57:05 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8F1A37C59; Tue, 10 Jul 2018 03:57:05 +0000 (UTC) Received: from cv1.lan (ovpn-120-63.rdu2.redhat.com [10.10.120.63]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0F2B57C4D; Tue, 10 Jul 2018 03:57:04 +0000 (UTC) From: Chris Venteicher To: libvir-list@redhat.com Date: Mon, 9 Jul 2018 22:56:49 -0500 Message-Id: <20180710035655.24983-6-cventeic@redhat.com> In-Reply-To: <20180710035655.24983-1-cventeic@redhat.com> References: <20180710035655.24983-1-cventeic@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com Cc: walling@linux.ibm.com, Chris Venteicher , david@redhat.com Subject: [libvirt] [PATCHv2 05/11] qemu_monitor: CPUModelExpansion on both model name and properties 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 10 Jul 2018 03:57:24 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Send both model name and a set of features/properties to QEMU for expansion rather than just the model name. Required to expand name+props models of the form computed by baseline into fully expanded (all props/features listed) output. --- src/qemu/qemu_capabilities.c | 42 +++++++++++++++++----- src/qemu/qemu_monitor.c | 38 ++++++++++++++++---- src/qemu/qemu_monitor.h | 5 ++- src/qemu/qemu_monitor_json.c | 69 ++++++++++++++++++++++++------------ src/qemu/qemu_monitor_json.h | 7 ++-- tests/cputest.c | 7 +++- 6 files changed, 122 insertions(+), 46 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 3d78e2e29b..72ab012a78 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2343,23 +2343,32 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, qemuMonitorCPUModelInfoPtr modelInfo =3D NULL; qemuMonitorCPUModelInfoPtr nonMigratable =3D NULL; virHashTablePtr hash =3D NULL; - const char *model; + const char *model_name; qemuMonitorCPUModelExpansionType type; virDomainVirtType virtType; virQEMUCapsHostCPUDataPtr cpuData; int ret =3D -1; + int err =3D -1; =20 if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) return 0; =20 if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { virtType =3D VIR_DOMAIN_VIRT_QEMU; - model =3D "max"; + model_name =3D "max"; } else { virtType =3D VIR_DOMAIN_VIRT_KVM; - model =3D "host"; + model_name =3D "host"; } =20 + if ((VIR_ALLOC(modelInfo) < 0) || + (VIR_ALLOC(nonMigratable) < 0)) + goto cleanup; + + if ((qemuMonitorCPUModelInfoInit(model_name, modelInfo) < 0) || + (qemuMonitorCPUModelInfoInit(model_name, nonMigratable) < 0)) + goto cleanup; + cpuData =3D virQEMUCapsGetHostCPUData(qemuCaps, virtType); =20 /* Some x86_64 features defined in cpu_map.xml use spelling which diff= er @@ -2372,16 +2381,31 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, else type =3D QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC; =20 - if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo= ) < 0) + if ((err =3D qemuMonitorGetCPUModelExpansion(mon, type, true, modelInf= o)) < 0) goto cleanup; =20 - /* Try to check migratability of each feature. */ - if (modelInfo && - qemuMonitorGetCPUModelExpansion(mon, type, model, false, - &nonMigratable) < 0) + if (err =3D=3D 1) { + ret =3D 0; /* Qemu can't do expansion 1, exit without error */ + goto cleanup; /* We don't have info so don't update cpuData->info = */ + } + + if ((err =3D qemuMonitorGetCPUModelExpansion(mon, type, false, nonMigr= atable)) < 0) goto cleanup; =20 - if (nonMigratable) { + /* Try to check migratability of each feature */ + /* Expansion 1 sets migratable features true + * Expansion 2 sets migratable and non-migratable features true + * (non-migratable set true only in some archs like X86) + * + * If delta between Expansion 1 and 2 exists... + * - both migratable and non-migratable features set prop->value =3D t= rue + * - migratable features set prop->migatable =3D VIR_TRISTATE_BOOL_YES + * - non-migratable features set prop->migatable =3D VIR_TRISTATE_BOOL= _NO + */ + if (err =3D=3D 0) { + /* Expansion 2 succeded + * Qemu expanded both migratable and nonMigratable features */ + qemuMonitorCPUPropertyPtr prop; qemuMonitorCPUPropertyPtr nmProp; size_t i; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2d9297c3a7..91b946c8b4 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3619,20 +3619,46 @@ qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr = cpu) } =20 =20 +/* + * type static: + * Expand to static base model + delta property changes + * Returned model is invariant and migration safe + * + * model_info->name =3D base model name + * model_info->props =3D features to +/- to base model to achive model_n= ame + * + * type full: + * Expand model to enumerate all properties + * Returned model isn't guaranteed to be invariant or migration safe. + * + * model_info->name =3D base model name + * model_info->props =3D features to +/- to empty set to achive model_na= me + * + * type static_full: + * Expand to static base model + delta property changes (pass 0) + * Expand model to enumerate all properties (pass 1) + * Returned model is invariant and migration safe + * + * model_info->name =3D base model name + * model_info->props =3D features to +/- to empty set to achive model_na= me + * + * migratable_only: + * true: QEMU excludes non-migratable features + * false: QEMU includes non-migratable features for some archs like X86 + */ int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType type, - const char *model_name, - bool migratable, - qemuMonitorCPUModelInfoPtr *model_info) + bool migratable_only, + qemuMonitorCPUModelInfoPtr model_info) { VIR_DEBUG("type=3D%d model_name=3D%s migratable=3D%d", - type, model_name, migratable); + type, (model_info ? NULLSTR(model_info->name):"NULL"), + migratable_only); =20 QEMU_CHECK_MONITOR(mon); =20 - return qemuMonitorJSONGetCPUModelExpansion(mon, type, model_name, - migratable, model_info); + return qemuMonitorJSONGetCPUModelExpansion(mon, type, migratable_only,= model_info); } =20 =20 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 0b84a91fbc..6b4b527512 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1016,9 +1016,8 @@ typedef enum { =20 int qemuMonitorGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType type, - const char *model_name, - bool migratable, - qemuMonitorCPUModelInfoPtr *model_info= ); + bool migratable_only, + qemuMonitorCPUModelInfoPtr model_info); =20 void qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfoPtr model_info); void qemuMonitorCPUModelInfoFreeContents(qemuMonitorCPUModelInfoPtr model_= info); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 90d43eee97..9b681f4592 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5390,8 +5390,11 @@ qemuMonitorJSONBuildCPUModelInfoToJSON(qemuMonitorCP= UModelInfoPtr model) } } =20 - ignore_value(virJSONValueObjectCreate(&model_json, "s:name", model->na= me, - "a:props", &cpu_props, NULL)); + if (model->nprops > 0) + ignore_value(virJSONValueObjectCreate(&model_json, "s:name", model= ->name, + "a:props", &cpu_props, NULL)= ); + else + ignore_value(virJSONValueObjectCreate(&model_json, "s:name", model= ->name, NULL)); =20 cleanup: virJSONValueFree(cpu_props); @@ -5440,38 +5443,52 @@ qemuMonitorJSONBuildCPUModelInfoFromJSON(virJSONVal= uePtr cpu_model) return model; } =20 + +/* return: + * -1 - Execution Failure + * 0 - Success + * 1 - Qemu unable to do expansion leaving "model" unmodified + */ int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType type, - const char *model_name, - bool migratable, - qemuMonitorCPUModelInfoPtr *model_info) + bool migratable_only, + qemuMonitorCPUModelInfoPtr model) { int ret =3D -1; - virJSONValuePtr model =3D NULL; - virJSONValuePtr props =3D NULL; + virJSONValuePtr json_model =3D NULL; virJSONValuePtr cmd =3D NULL; virJSONValuePtr reply =3D NULL; virJSONValuePtr data; virJSONValuePtr cpu_model; + qemuMonitorCPUModelInfoPtr expanded_model =3D NULL; + qemuMonitorCPUModelInfoPtr model_info =3D NULL; const char *typeStr =3D ""; =20 - *model_info =3D NULL; + if (!(model_info =3D qemuMonitorCPUModelInfoCopy(model))) + return -1; + + qemuMonitorCPUModelInfoFreeContents(model); =20 - if (!(model =3D virJSONValueNewObject())) - goto cleanup; + if (!migratable_only) { + /* Add property to input CPUModelInfo causing QEMU to include + * non-migratable properties for some architectures like X86 */ =20 - if (virJSONValueObjectAppendString(model, "name", model_name) < 0) - goto cleanup; + qemuMonitorCPUProperty prop; + prop.type =3D QEMU_MONITOR_CPU_PROPERTY_BOOLEAN; + prop.value.boolean =3D false; + prop.migratable =3D false; + + if (VIR_STRDUP(prop.name, "migratable") < 0) + goto cleanup; =20 - if (!migratable) { - if (!(props =3D virJSONValueNewObject()) || - virJSONValueObjectAppendBoolean(props, "migratable", false) < = 0 || - virJSONValueObjectAppend(model, "props", props) < 0) + if (VIR_APPEND_ELEMENT(model_info->props, model_info->nprops, prop= ) < 0) goto cleanup; - props =3D NULL; } =20 + if (!(json_model =3D qemuMonitorJSONBuildCPUModelInfoToJSON(model_info= ))) + goto cleanup; + retry: switch (type) { case QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC: @@ -5486,7 +5503,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mo= n, =20 if (!(cmd =3D qemuMonitorJSONMakeCommand("query-cpu-model-expansion", "s:type", typeStr, - "a:model", &model, + "a:model", &json_model, NULL))) goto cleanup; =20 @@ -5498,7 +5515,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mo= n, * guest architecture or it is not supported in the host environment. */ if (qemuMonitorJSONHasError(reply, "GenericError")) { - ret =3D 0; + ret =3D 1; goto cleanup; } =20 @@ -5517,7 +5534,9 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mo= n, * on the result of the initial "static" expansion. */ if (type =3D=3D QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL) { - if (!(model =3D virJSONValueCopy(cpu_model))) + virJSONValueFree(json_model); + + if (!(json_model =3D virJSONValueCopy(cpu_model))) goto cleanup; =20 virJSONValueFree(cmd); @@ -5526,16 +5545,20 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr = mon, goto retry; } =20 - if (!(*model_info =3D qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_mod= el))) + if (!(expanded_model =3D qemuMonitorJSONBuildCPUModelInfoFromJSON(cpu_= model))) goto cleanup; =20 + *model =3D *expanded_model; /* overwrite contents */ + ret =3D 0; =20 cleanup: + VIR_FREE(expanded_model); /* Free structure but not reused contents */ + qemuMonitorCPUModelInfoFreeContents(model_info); + virJSONValueFree(cmd); virJSONValueFree(reply); - virJSONValueFree(model); - virJSONValueFree(props); + virJSONValueFree(json_model); return ret; } =20 diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 73e1cb6ace..9950483c5c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -362,10 +362,9 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mo= n, =20 int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon, qemuMonitorCPUModelExpansionType t= ype, - const char *model_name, - bool migratable, - qemuMonitorCPUModelInfoPtr *model_= info) - ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5); + bool migratable_only, + qemuMonitorCPUModelInfoPtr model_i= nfo) + ATTRIBUTE_NONNULL(4); =20 int qemuMonitorJSONGetCPUModelBaseline(qemuMonitorPtr mon, qemuMonitorCPUModelInfoPtr model_a, diff --git a/tests/cputest.c b/tests/cputest.c index baf2b3c648..27727aa29e 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -495,9 +495,14 @@ cpuTestMakeQEMUCaps(const struct data *data) if (!(testMon =3D qemuMonitorTestNewFromFile(json, driver.xmlopt, true= ))) goto error; =20 + if ((VIR_ALLOC(model) < 0) || + (qemuMonitorCPUModelInfoInit("host", model) < 0)) + goto cleanup; + + if (qemuMonitorGetCPUModelExpansion(qemuMonitorTestGetMonitor(testMon), QEMU_MONITOR_CPU_MODEL_EXPANSION_S= TATIC, - "host", true, &model) < 0) + true, model) < 0) goto error; =20 if (!(qemuCaps =3D virQEMUCapsNew())) --=20 2.17.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list