From nobody Mon Feb 9 11:28:42 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 1639539752478189.61614599596487; Tue, 14 Dec 2021 19:42:32 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-654-WbAHwWOAPymeWYN0MgqqFg-1; Tue, 14 Dec 2021 22:42:28 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 232971DDED; Wed, 15 Dec 2021 03:42:24 +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 06CB17553C; Wed, 15 Dec 2021 03:42:24 +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 D08AD4A7CB; Wed, 15 Dec 2021 03:42:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 1BF3gCV1024524 for ; Tue, 14 Dec 2021 22:42:12 -0500 Received: by smtp.corp.redhat.com (Postfix) id 6CFE0C017DA; Wed, 15 Dec 2021 03:42:12 +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 6888BC23DB1 for ; Wed, 15 Dec 2021 03:42:12 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (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 4A86D801212 for ; Wed, 15 Dec 2021 03:42:12 +0000 (UTC) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-217-BujfBRqLO7urmdWx_N_x9A-1; Tue, 14 Dec 2021 22:42:10 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Dec 2021 19:42:08 -0800 Received: from nhsgx.sh.intel.com ([10.239.36.138]) by fmsmga002.fm.intel.com with ESMTP; 14 Dec 2021 19:42:06 -0800 X-MC-Unique: WbAHwWOAPymeWYN0MgqqFg-1 X-MC-Unique: BujfBRqLO7urmdWx_N_x9A-1 X-IronPort-AV: E=McAfee;i="6200,9189,10198"; a="236675525" X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="236675525" X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,207,1635231600"; d="scan'208";a="610210054" 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, yang.zhong@intel.com Subject: [libvirt][PATCH v9 1/5] Get SGX Capabilities from QEMU Date: Wed, 15 Dec 2021 11:40:11 +0800 Message-Id: <20211215034015.1138-2-haibin.huang@intel.com> In-Reply-To: <20211215034015.1138-1-haibin.huang@intel.com> References: <20211215034015.1138-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.85 on 10.11.54.8 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.14 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: 1639539754603100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The Qemu QMP provide the command "query-sgx-capabilities" libvirt call the command to get sgx capabilities {"execute":"query-sgx-capabilities"} {"return": {"sgx": true, "sgx1": true, "sgx2": false, "section-size": 0, \ "flc": false}} Signed-off-by: Haibin Huang --- src/conf/domain_capabilities.c | 10 ++ src/conf/domain_capabilities.h | 13 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 143 +++++++++++++++++- src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_monitor.c | 10 ++ src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 83 ++++++++++ src/qemu/qemu_monitor_json.h | 3 + .../caps_6.2.0.x86_64.replies | 22 ++- .../caps_6.2.0.x86_64.xml | 5 + 11 files changed, 292 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 22f0963326..d39be55f6a 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -78,6 +78,16 @@ virSEVCapabilitiesFree(virSEVCapability *cap) } =20 =20 +void +virSGXCapabilitiesFree(virSGXCapability *cap) +{ + if (!cap) + return; + + VIR_FREE(cap); +} + + static void virDomainCapsDispose(void *obj) { diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index d44acdcd01..b647ff8107 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -172,6 +172,13 @@ struct _virDomainCapsCPU { virDomainCapsCPUModels *custom; }; =20 +typedef struct _virSGXCapability virSGXCapability; +typedef virSGXCapability *virSGXCapabilityPtr; +struct _virSGXCapability { + bool flc; + unsigned int epc_size; +}; + typedef struct _virSEVCapability virSEVCapability; struct _virSEVCapability { char *pdh; @@ -215,6 +222,7 @@ struct _virDomainCaps { =20 virDomainCapsFeatureGIC gic; virSEVCapability *sev; + virSGXCapability *sgx; /* add new domain features here */ =20 virTristateBool features[VIR_DOMAIN_CAPS_FEATURE_LAST]; @@ -262,4 +270,9 @@ char * virDomainCapsFormat(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 c5d788285e..d90d4ee6e1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -219,6 +219,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 a607f5ea5f..8ce184ce35 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -651,6 +651,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "chardev.json", /* QEMU_CAPS_CHARDEV_JSON */ "device.json", /* QEMU_CAPS_DEVICE_JSON */ "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */ + "sgx-epc", /* QEMU_CAPS_SGX_EPC */ ); =20 =20 @@ -731,11 +732,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; @@ -1367,6 +1371,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[= ] =3D { { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL }, { "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST }, { "virtio-mem-pci", QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI }, + { "sgx-epc", QEMU_CAPS_SGX_EPC }, }; =20 =20 @@ -1918,6 +1923,22 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst, } =20 =20 +static int +virQEMUCapsSGXInfoCopy(virSGXCapabilityPtr *dst, + virSGXCapabilityPtr src) +{ + g_autoptr(virSGXCapability) tmp =3D NULL; + + tmp =3D g_new0(virSGXCapability, 1); + + tmp->flc =3D src->flc; + tmp->epc_size =3D src->epc_size; + + *dst =3D g_steal_pointer(&tmp); + return 0; +} + + static void virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccel *dst, virQEMUCapsAccel *src) @@ -1997,6 +2018,11 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCap= s) qemuCaps->sevCapabilities) < 0) return NULL; =20 + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC) && + virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities, + qemuCaps->sgxCapabilities) < 0) + return NULL; + return g_steal_pointer(&ret); } =20 @@ -2033,6 +2059,7 @@ void virQEMUCapsDispose(void *obj) g_free(qemuCaps->gicCapabilities); =20 virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virSGXCapabilitiesFree(qemuCaps->sgxCapabilities); =20 virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -2553,6 +2580,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps) } =20 =20 +virSGXCapabilityPtr +virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps) +{ + return qemuCaps->sgxCapabilities; +} + + static int virQEMUCapsProbeQMPCommands(virQEMUCaps *qemuCaps, qemuMonitor *mon) @@ -3327,6 +3361,31 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemu= Caps, } =20 =20 +static int +virQEMUCapsProbeQMPSGXCapabilities(virQEMUCaps *qemuCaps, + qemuMonitor *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 @@ -4110,6 +4169,41 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, xmlXP= athContextPtr ctxt) return 0; } =20 +static int +virQEMUCapsParseSGXInfo(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt) +{ + g_autoptr(virSGXCapability) sgx =3D NULL; + + 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; + } + + sgx =3D g_new0(virSGXCapability, 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 (virXPathUInt("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 @@ -4226,7 +4320,7 @@ virQEMUCapsLoadCache(virArch hostArch, flag =3D virQEMUCapsTypeFromString(str); if (flag < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unknown qemu capabilities flag %s"), str); + _("Haibin Unknown qemu capabilities flag %s"), = str); goto cleanup; } VIR_FREE(str); @@ -4351,6 +4445,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 @@ -4531,6 +4628,19 @@ virQEMUCapsFormatSEVInfo(virQEMUCaps *qemuCaps, virB= uffer *buf) virBufferAddLit(buf, "\n"); } =20 +static void +virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps, virBuffer *buf) +{ + virSGXCapabilityPtr sgx =3D virQEMUCapsGetSGXCapabilities(qemuCaps); + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "%s\n", sgx->flc ? "yes" : "no"); + virBufferAsprintf(buf, "%u\n", sgx->epc_size); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + =20 char * virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) @@ -4605,6 +4715,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) if (qemuCaps->sevCapabilities) virQEMUCapsFormatSEVInfo(qemuCaps, &buf); =20 + if (qemuCaps->sgxCapabilities) + virQEMUCapsFormatSGXInfo(qemuCaps, &buf); + if (qemuCaps->kvmSupportsNesting) virBufferAddLit(&buf, "\n"); =20 @@ -5276,6 +5389,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPSGXCapabilities(qemuCaps, mon) < 0) + return -1; =20 virQEMUCapsInitProcessCaps(qemuCaps); =20 @@ -6248,6 +6363,31 @@ virQEMUCapsFillDomainFeatureGICCaps(virQEMUCaps *qem= uCaps, } =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(virQEMUCaps *qemuCaps, + virDomainCaps *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 @@ -6339,6 +6479,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps, virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureS390PVCaps(qemuCaps, domCaps); + virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps); =20 return 0; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index bb53d9ae46..e8c052b27d 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -631,6 +631,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for = syntax-check */ QEMU_CAPS_CHARDEV_JSON, /* -chardev accepts JSON */ QEMU_CAPS_DEVICE_JSON, /* -device accepts JSON */ QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */ + QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */ =20 QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; @@ -824,5 +825,8 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps); bool virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_GNUC_NO_INLI= NE; =20 +virSGXCapabilityPtr +virQEMUCapsGetSGXCapabilities(virQEMUCaps *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 e8accaf2b0..dca3e94ed2 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3787,6 +3787,16 @@ qemuMonitorGetSEVCapabilities(qemuMonitor *mon, } =20 =20 +int +qemuMonitorGetSGXCapabilities(qemuMonitor *mon, + virSGXCapability **capabilities) +{ + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetSGXCapabilities(mon, capabilities); +} + + int qemuMonitorNBDServerStart(qemuMonitor *mon, const virStorageNetHostDef *server, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 52ff34d316..e08fc1bfe3 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -915,6 +915,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon, int qemuMonitorGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities); =20 +int qemuMonitorGetSGXCapabilities(qemuMonitor *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 579d986e02..b2c5042a22 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6723,6 +6723,89 @@ qemuMonitorJSONGetGICCapabilities(qemuMonitor *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(qemuMonitor *mon, + virSGXCapability **capabilities) +{ + int ret =3D -1; + virJSONValue *cmd; + virJSONValue *reply =3D NULL; + virJSONValue *caps; + bool sgx =3D false; + bool flc =3D false; + unsigned int 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) + goto cleanup; + + /* QEMU has only compiled-in support of SGX */ + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret =3D 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + caps =3D virJSONValueObjectGetObject(reply, "return"); + + if (virJSONValueObjectGetBoolean(caps, "sgx", &sgx) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-sgx reply was missing" + " 'sgx' field")); + goto cleanup; + } + + if (virJSONValueObjectGetBoolean(caps, "flc", &flc) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-sgx-capabilities reply was missing" + " 'flc' field")); + goto cleanup; + } + + if (virJSONValueObjectGetNumberUint(caps, "section-size", §ion_siz= e) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-sgx-capabilities reply was missing" + " 'section-size' field")); + goto cleanup; + } + + capability =3D g_new0(virSGXCapability, 1); + + capability->flc =3D flc; + + capability->epc_size =3D section_size/1024; + *capabilities =3D g_steal_pointer(&capability); + ret =3D 1; + + cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + + /** * qemuMonitorJSONGetSEVCapabilities: * @mon: qemu monitor object diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index c841de0a03..bfb405ed04 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -157,6 +157,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon, int qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon, virSEVCapability **capabilities); =20 +int qemuMonitorJSONGetSGXCapabilities(qemuMonitor *mon, + virSGXCapability **capabilities); + int qemuMonitorJSONMigrate(qemuMonitor *mon, unsigned int flags, const char *uri); diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies b/tests/q= emucapabilitiesdata/caps_6.2.0.x86_64.replies index aa7a779a68..1092eb7c31 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies @@ -29479,6 +29479,20 @@ } } =20 +{ + "execute": "query-sgx-capabilities", + "id": "libvirt-49" +} + +{ + "id": "libvirt-49", + "return": { + "sgx": true, + "section-size": 1024, + "flc": false + } +} + { "execute": "query-cpu-model-expansion", "arguments": { @@ -29487,7 +29501,7 @@ "name": "host" } }, - "id": "libvirt-49" + "id": "libvirt-50" } =20 { @@ -29820,7 +29834,7 @@ } } }, - "id": "libvirt-49" + "id": "libvirt-50" } =20 { @@ -29834,7 +29848,7 @@ } } }, - "id": "libvirt-50" + "id": "libvirt-51" } =20 { @@ -30167,7 +30181,7 @@ } } }, - "id": "libvirt-50" + "id": "libvirt-51" } =20 { diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml b/tests/qemuc= apabilitiesdata/caps_6.2.0.x86_64.xml index 5a46da0a6a..410964d84d 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml @@ -241,6 +241,7 @@ + 6001050 0 43100244 @@ -3711,4 +3712,8 @@ + + no + 1 + --=20 2.17.1