From nobody Mon Feb 9 10:27:20 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1626332754482980.0426529661362; Thu, 15 Jul 2021 00:05:54 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-454--Uh2YWWoNwujs62sfy3agg-1; Thu, 15 Jul 2021 03:05:51 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D816E1084F5D; Thu, 15 Jul 2021 07:05:46 +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 B65C060936; Thu, 15 Jul 2021 07:05:46 +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 7C0084EA38; Thu, 15 Jul 2021 07:05:46 +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 16F75XQ6026165 for ; Thu, 15 Jul 2021 03:05:33 -0400 Received: by smtp.corp.redhat.com (Postfix) id E5E641032A7; Thu, 15 Jul 2021 07:05:32 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E117E1032BB for ; Thu, 15 Jul 2021 07:05:29 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-2.mimecast.com [207.211.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B85E996B041 for ; Thu, 15 Jul 2021 07:05:29 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-155-pcZzDLQhMQGA6Fv43X_ZEg-4; Thu, 15 Jul 2021 03:05:27 -0400 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Jul 2021 00:05:26 -0700 Received: from nhsgx.sh.intel.com ([10.239.36.138]) by orsmga003.jf.intel.com with ESMTP; 15 Jul 2021 00:05:22 -0700 X-MC-Unique: -Uh2YWWoNwujs62sfy3agg-1 X-MC-Unique: pcZzDLQhMQGA6Fv43X_ZEg-4 X-IronPort-AV: E=McAfee;i="6200,9189,10045"; a="210300781" X-IronPort-AV: E=Sophos;i="5.84,240,1620716400"; d="scan'208";a="210300781" X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.84,240,1620716400"; d="scan'208";a="413552987" From: Haibin Huang To: libvir-list@redhat.com, haibin.huang@intel.com, jian-feng.ding@intel.com, lin.a.yang@intel.com, lianhao.lu@intel.com Subject: [libvirt][PATCH v5 3/6] Support to query SGX capability Date: Thu, 15 Jul 2021 15:02:58 +0800 Message-Id: <20210715070301.8078-4-haibin.huang@intel.com> In-Reply-To: <20210715070301.8078-1-haibin.huang@intel.com> References: <20210715070301.8078-1-haibin.huang@intel.com> X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: libvir-list@redhat.com 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 2 X-Mimecast-Originator: redhat.com X-ZM-MESSAGEID: 1626332755748100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 1.Add SGX feature in domain capabilities 2.Get sgx capabilities by query-sgx-capabilities 3.Transfer the B to KB for epc_size 4.Delete sgx1 and sgx2 Signed-off-by: Haibin Huang --- docs/schemas/domaincaps.rng | 20 +++++ src/conf/domain_capabilities.c | 29 +++++++ src/conf/domain_capabilities.h | 13 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 139 +++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 6 ++ src/qemu/qemu_monitor.c | 10 +++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 87 +++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 + 10 files changed, 311 insertions(+) diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng index 325581476d..0dc97b29bc 100644 --- a/docs/schemas/domaincaps.rng +++ b/docs/schemas/domaincaps.rng @@ -219,6 +219,9 @@ + + + =20 @@ -267,6 +270,23 @@ =20 + + + + + + + yes + no + + + + + + + + + diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index d61108e125..8024200951 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -91,6 +91,16 @@ virSEVCapabilitiesFree(virSEVCapability *cap) } =20 =20 +void +virSGXCapabilitiesFree(virSGXCapability *cap) +{ + if (!cap) + return; + + VIR_FREE(cap); +} + + static void virDomainCapsDispose(void *obj) { @@ -101,6 +111,7 @@ virDomainCapsDispose(void *obj) virObjectUnref(caps->cpu.custom); virCPUDefFree(caps->cpu.hostModel); virSEVCapabilitiesFree(caps->sev); + virSGXCapabilitiesFree(caps->sgx); =20 virDomainCapsStringValuesFree(&caps->os.loader.values); } @@ -564,6 +575,23 @@ virDomainCapsFeatureSEVFormat(virBufferPtr buf, return; } =20 +static void +virDomainCapsFeatureSGXFormat(virBufferPtr buf, + virSGXCapabilityPtr const sgx) +{ + if (!sgx) { + virBufferAddLit(buf, "\n"); + } else { + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "%s\n", sgx->flc ? "yes" : "no"); + virBufferAsprintf(buf, "%llu\n",= sgx->epc_size); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } + + return; +} =20 static void virDomainCapsFormatFeatures(const virDomainCaps *caps, @@ -584,6 +612,7 @@ virDomainCapsFormatFeatures(const virDomainCaps *caps, } =20 virDomainCapsFeatureSEVFormat(&childBuf, caps->sev); + virDomainCapsFeatureSGXFormat(&childBuf, caps->sgx); =20 virXMLFormatElement(buf, "features", NULL, &childBuf); } diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index 685d5e2a44..0b2447e81f 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -150,6 +150,13 @@ struct _virDomainCapsCPU { virDomainCapsCPUModelsPtr custom; }; =20 +typedef struct _virSGXCapability virSGXCapability; +typedef virSGXCapability *virSGXCapabilityPtr; +struct _virSGXCapability { + bool flc; + unsigned long long epc_size; +}; + typedef struct _virSEVCapability virSEVCapability; typedef virSEVCapability *virSEVCapabilityPtr; struct _virSEVCapability { @@ -191,6 +198,7 @@ struct _virDomainCaps { =20 virDomainCapsFeatureGIC gic; virSEVCapabilityPtr sev; + virSGXCapabilityPtr sgx; /* add new domain features here */ =20 virTristateBool features[VIR_DOMAIN_CAPS_FEATURE_LAST]; @@ -239,4 +247,9 @@ int virDomainCapsDeviceDefValidate(const virDomainCaps = *caps, void virSEVCapabilitiesFree(virSEVCapability *capabilities); =20 +void +virSGXCapabilitiesFree(virSGXCapability *capabilities); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSGXCapability, virSGXCapabilitiesFree); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 01c2e710cd..7b464f9592 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -215,6 +215,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virSGXCapabilitiesFree; =20 =20 # conf/domain_conf.h diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ff6ba8c9e9..e2103c7975 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -597,6 +597,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "spapr-tpm-proxy", "numa.hmat", "blockdev-hostdev-scsi", + + /* 380 */ + "sgx-epc", ); =20 =20 @@ -698,11 +701,14 @@ struct _virQEMUCaps { =20 virSEVCapability *sevCapabilities; =20 + virSGXCapability *sgxCapabilities; + /* Capabilities which may differ depending on the accelerator. */ virQEMUCapsAccel kvm; virQEMUCapsAccel tcg; }; =20 + struct virQEMUCapsSearchData { virArch arch; const char *binaryFilter; @@ -1323,6 +1329,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[= ] =3D { { "tcg-accel", QEMU_CAPS_TCG }, { "pvscsi", QEMU_CAPS_SCSI_PVSCSI }, { "spapr-tpm-proxy", QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY }, + { "sgx-epc", QEMU_CAPS_SGX_EPC }, }; =20 =20 @@ -1870,6 +1877,20 @@ virQEMUCapsSEVInfoCopy(virSEVCapabilityPtr *dst, } =20 =20 +static int +virQEMUCapsSGXInfoCopy(virSGXCapabilityPtr *dst, + virSGXCapabilityPtr src) +{ + virSGXCapability *tmp =3D g_new0(virSGXCapability, 1); + + tmp->flc =3D src->flc; + tmp->epc_size =3D src->epc_size; + + *dst =3D tmp; + return 0; +} + + static void virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccelPtr dst, virQEMUCapsAccelPtr src) @@ -1947,6 +1968,11 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qem= uCaps) qemuCaps->sevCapabilities) < 0) goto error; =20 + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC) && + virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities, + qemuCaps->sgxCapabilities) < 0) + goto error; + return ret; =20 error: @@ -1987,6 +2013,7 @@ void virQEMUCapsDispose(void *obj) VIR_FREE(qemuCaps->gicCapabilities); =20 virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virSGXCapabilitiesFree(qemuCaps->sgxCapabilities); =20 virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -2581,6 +2608,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCap= s) } =20 =20 +virSGXCapabilityPtr +virQEMUCapsGetSGXCapabilities(virQEMUCapsPtr qemuCaps) +{ + return qemuCaps->sgxCapabilities; +} + + static int virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon) @@ -3405,6 +3439,31 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCapsPtr qe= muCaps, } =20 =20 +static int +virQEMUCapsProbeQMPSGXCapabilities(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon) +{ + int rc =3D -1; + virSGXCapability *caps =3D NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC)) + return 0; + + if ((rc =3D qemuMonitorGetSGXCapabilities(mon, &caps)) < 0) + return -1; + + /* SGX isn't actually supported */ + if (rc =3D=3D 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_SGX_EPC); + return 0; + } + + virSGXCapabilitiesFree(qemuCaps->sgxCapabilities); + qemuCaps->sgxCapabilities =3D caps; + return 0; +} + + /* * Filter for features which should never be passed to QEMU. Either because * QEMU never supported them or they were dropped as they never did anythi= ng @@ -4187,6 +4246,39 @@ virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xml= XPathContextPtr ctxt) return 0; } =20 +static int +virQEMUCapsParseSGXInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt) +{ + virSGXCapability *sgx =3D g_new0(virSGXCapability, 1); + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC)) + return 0; + + if (virXPathBoolean("boolean(./sgx)", ctxt) =3D=3D 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing SGX platform data in QEMU " + "capabilities cache")); + return -1; + } + + if (virXPathBoolean("boolean(./sgx/flc)", ctxt) =3D=3D 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing SGX platform flc data in QEMU " + "capabilities cache")); + return -1; + } + + if (virXPathULongLong("string(./sgx/epc_size)", ctxt, &sgx->epc_size) = < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing or malformed SGX platform epc_size infor= mation " + "in QEMU capabilities cache")); + return -1; + } + + qemuCaps->sgxCapabilities =3D g_steal_pointer(&sgx); + return 0; +} + =20 /* * Parsing a doc that looks like @@ -4425,6 +4517,9 @@ virQEMUCapsLoadCache(virArch hostArch, if (virQEMUCapsParseSEVInfo(qemuCaps, ctxt) < 0) goto cleanup; =20 + if (virQEMUCapsParseSGXInfo(qemuCaps, ctxt) < 0) + goto cleanup; + virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM); virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU); =20 @@ -4601,6 +4696,19 @@ virQEMUCapsFormatSEVInfo(virQEMUCapsPtr qemuCaps, vi= rBufferPtr buf) virBufferAddLit(buf, "\n"); } =20 +static void +virQEMUCapsFormatSGXInfo(virQEMUCapsPtr qemuCaps, virBufferPtr buf) +{ + virSGXCapabilityPtr sgx =3D virQEMUCapsGetSGXCapabilities(qemuCaps); + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "%s\n", sgx->flc ? "yes" : "no"); + virBufferAsprintf(buf, "%llu\n", sgx->epc_size); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + =20 char * virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) @@ -4671,6 +4779,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) if (qemuCaps->sevCapabilities) virQEMUCapsFormatSEVInfo(qemuCaps, &buf); =20 + if (qemuCaps->sgxCapabilities) + virQEMUCapsFormatSGXInfo(qemuCaps, &buf); + if (qemuCaps->kvmSupportsNesting) virBufferAddLit(&buf, "\n"); =20 @@ -5323,6 +5434,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPSGXCapabilities(qemuCaps, mon) < 0) + return -1; =20 virQEMUCapsInitProcessCaps(qemuCaps); =20 @@ -6245,6 +6358,31 @@ virQEMUCapsFillDomainFeatureGICCaps(virQEMUCapsPtr q= emuCaps, } =20 =20 +/** + * virQEMUCapsFillDomainFeatureiSGXCaps: + * @qemuCaps: QEMU capabilities + * @domCaps: domain capabilities + * + * Take the information about SGX capabilities that has been obtained + * using the 'query-sgx-capabilities' QMP command and stored in @qemuCaps + * and convert it to a form suitable for @domCaps. + */ +static void +virQEMUCapsFillDomainFeatureSGXCaps(virQEMUCapsPtr qemuCaps, + virDomainCapsPtr domCaps) +{ + virSGXCapability *cap =3D qemuCaps->sgxCapabilities; + + if (!cap) + return; + + domCaps->sgx =3D g_new0(virSGXCapability, 1); + + domCaps->sgx->flc =3D cap->flc; + domCaps->sgx->epc_size =3D cap->epc_size; +} + + /** * virQEMUCapsFillDomainFeatureSEVCaps: * @qemuCaps: QEMU capabilities @@ -6316,6 +6454,7 @@ virQEMUCapsFillDomainCaps(virQEMUCapsPtr qemuCaps, virQEMUCapsFillDomainDeviceRNGCaps(qemuCaps, rng); virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps); + virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps); =20 return 0; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 5d08941538..0e3af622a7 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -578,6 +578,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for = syntax-check */ QEMU_CAPS_NUMA_HMAT, /* -numa hmat */ QEMU_CAPS_BLOCKDEV_HOSTDEV_SCSI, /* -blockdev used for (i)SCSI hostdev= s */ =20 + /* 380 */ + QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; =20 @@ -759,5 +762,8 @@ virQEMUCapsCPUFeatureFromQEMU(virQEMUCapsPtr qemuCaps, virSEVCapabilityPtr virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps); =20 +virSGXCapabilityPtr +virQEMUCapsGetSGXCapabilities(virQEMUCapsPtr qemuCaps); + virArch virQEMUCapsArchFromString(const char *arch); const char *virQEMUCapsArchToString(virArch arch); diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 637361d24d..1e377ee8dc 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3870,6 +3870,16 @@ qemuMonitorGetSEVCapabilities(qemuMonitorPtr mon, } =20 =20 +int +qemuMonitorGetSGXCapabilities(qemuMonitorPtr mon, + virSGXCapability **capabilities) +{ + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetSGXCapabilities(mon, capabilities); +} + + int qemuMonitorNBDServerStart(qemuMonitorPtr mon, const virStorageNetHostDef *server, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index d20a15c202..76b3cd54c7 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -836,6 +836,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon, int qemuMonitorGetSEVCapabilities(qemuMonitorPtr mon, virSEVCapability **capabilities); =20 +int qemuMonitorGetSGXCapabilities(qemuMonitorPtr mon, + virSGXCapability **capabilities); + typedef enum { QEMU_MONITOR_MIGRATE_BACKGROUND =3D 1 << 0, QEMU_MONITOR_MIGRATE_NON_SHARED_DISK =3D 1 << 1, /* migration with non-= shared storage with full disk copy */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 9cdf6c0f7f..69a6a31aee 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -44,6 +44,7 @@ # include "libvirt_qemu_probes.h" #endif =20 +#define KB 1024 #define VIR_FROM_THIS VIR_FROM_QEMU =20 VIR_LOG_INIT("qemu.qemu_monitor_json"); @@ -7056,6 +7057,92 @@ qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon, } =20 =20 +/** + * qemuMonitorJSONGetSGXCapabilities: + * @mon: qemu monitor object + * @capabilities: pointer to pointer to a SGX capability structure to be f= illed + * + * This function queries and fills in INTEL's SGX platform-specific data. + * Note that from QEMU's POV both -object sgx-epc and query-sgx-capabiliti= es + * can be present even if SGX is not available, which basically leaves us = with + * checking for JSON "GenericError" in order to differentiate between comp= iled-in + * support and actual SGX support on the platform. + * + * Returns -1 on error, 0 if SGX is not supported, and 1 if SGX is support= ed on + * the platform. + */ +int +qemuMonitorJSONGetSGXCapabilities(qemuMonitorPtr mon, + virSGXCapability **capabilities) +{ + int ret =3D -1; + g_autoptr(virJSONValue) cmd =3D NULL; + g_autoptr(virJSONValue) reply =3D NULL; + virJSONValuePtr caps; + bool sgx =3D false; + bool flc =3D false; + unsigned long long section_size =3D 0; + g_autoptr(virSGXCapability) capability =3D NULL; + + *capabilities =3D NULL; + + if (!(cmd =3D qemuMonitorJSONMakeCommand("query-sgx-capabilities", NUL= L))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + return ret; + + /* QEMU has only compiled-in support of SGX */ + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret =3D 0; + return ret; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + return ret; + + caps =3D virJSONValueObjectGetObject(reply, "return"); + + if (virJSONValueObjectGetBoolean(caps, "sgx", &sgx) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-sgx reply was missing" + " 'sgx' field")); + return ret; + } + if (!sgx) { + VIR_WARN("sgx is not support %d\n", sgx); + ret =3D 0; + return ret; + } + + if (virJSONValueObjectGetBoolean(caps, "flc", &flc) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-sgx-capabilities reply was missing" + " 'flc' field")); + return ret; + } + + if (virJSONValueObjectGetNumberUlong(caps, "section-size", §ion_si= ze) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-sgx-capabilities reply was missing" + " 'section-size' field")); + return ret; + } + + + if (VIR_ALLOC(capability) < 0) + return ret; + + capability->flc =3D flc; + + capability->epc_size =3D section_size/(KB); + *capabilities =3D g_steal_pointer(&capability); + ret =3D 1; + + return ret; +} + + /** * qemuMonitorJSONGetSEVCapabilities: * @mon: qemu monitor object diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 098ab857be..b0c23e57ac 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -159,6 +159,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mo= n, int qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon, virSEVCapability **capabilities); =20 +int qemuMonitorJSONGetSGXCapabilities(qemuMonitorPtr mon, + virSGXCapability **capabilities); + int qemuMonitorJSONMigrate(qemuMonitorPtr mon, unsigned int flags, const char *uri); --=20 2.17.1