From nobody Thu Mar 28 12:01:06 2024 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=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1556746944; cv=none; d=zoho.com; s=zohoarc; b=N6ApC/4JS9fFmeL3IcwhY82dLwPsTLzM02Xsn91jWoXV38zVFX/FLgbyqfd6N9sIkR++/XzxgO1zPb1mzsHQEMvBQNdoNjIs1u+yFSVbtwBKl0/ErQJmQg1D+x9sk3GSZdM+yZjGYP8W9ews21GoAmRO0IiiHR9Jb+3k82NHnak= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1556746944; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To:ARC-Authentication-Results; bh=C0Imq/UJMgjrg8K/j7ZjatlHYT890OSyQn35MXQcslU=; b=NhKssinyunsGQvtXKDDyLmkhDAG7hRCOHg9hUUUyosF5QjSDsagWv4Amm/PfPfvKcqyvOJBW5PoRct/kS2UDw6BW6lQyzYq8BepjCXdcc3evbl6a7oZJuMpjzxEMVaq2/7EW5/x5QTsrFR2rZ2cjfsQNrWn4d1Ar/kdm/pOLXNs= ARC-Authentication-Results: i=1; mx.zoho.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 header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1556746944330478.23636711931067; Wed, 1 May 2019 14:42:24 -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 43C2AC04959E; Wed, 1 May 2019 21:42:20 +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 B8C617F81A; Wed, 1 May 2019 21:42: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 97BB918089CB; Wed, 1 May 2019 21:42:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x41LgBPi015981 for ; Wed, 1 May 2019 17:42:11 -0400 Received: by smtp.corp.redhat.com (Postfix) id 0608E78574; Wed, 1 May 2019 21:42:11 +0000 (UTC) Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C04BC7754F; Wed, 1 May 2019 21:42:08 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (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 BC28E86658; Wed, 1 May 2019 21:42:01 +0000 (UTC) Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 May 2019 14:42:00 -0700 Received: from llcarval-mobl1.amr.corp.intel.com ([10.3.52.60]) by orsmga006.jf.intel.com with ESMTP; 01 May 2019 14:41:59 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,419,1549958400"; d="scan'208";a="140486144" From: Larkins Carvalho To: libvir-list@redhat.com Date: Wed, 1 May 2019 14:41:57 -0700 Message-Id: <20190501214157.10448-1-larkins.l.carvalho@intel.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 216 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 01 May 2019 21:42:02 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 01 May 2019 21:42:02 +0000 (UTC) for IP:'134.134.136.20' DOMAIN:'mga02.intel.com' HELO:'mga02.intel.com' FROM:'larkins.l.carvalho@intel.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 134.134.136.20 mga02.intel.com 134.134.136.20 mga02.intel.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Cc: karimullah.mohammed@intel.com Subject: [libvirt] [PATCH] x86: Multi-key Total Memory Encryption (Intel) 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: , Content-Type: text/plain; charset="utf-8" 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.31]); Wed, 01 May 2019 21:42:21 +0000 (UTC) From: llcarval Total Memory Encryption (TME) =E2=80=93 provides the capability to encrypt = the entirety of the physical memory of a system. MKTME builds on TME and adds support for multiple encryption keys. High Level flow: 1. Management tool calls virNodeGetMKTMEInfo. This returns an XML document that includes the following ... 2. Management tool requests to start a guest calling virCreateXML(). The xm= l would include m0 user samplekey aes-xts-128 3. Libvirt makes system call with the provided information to generate a ke= y handle using linux keyring services. Qemu uses the key handle to launch the workload. 4. Libvirt generate the QEMU cli arg to enable the MKTME feature, a typical args looks like this: -machine memory-encryption=3Dm0 \ -object mktme-guest,id=3Dm0,handle=3D${serial} Intel MKTME spec: https://software.intel.com/sites/default/files/managed/a5= /16/Multi-Key-Total-Memory-Encryption-Spec.pdf WIP: Qemu and KVM patch to support Intel MKTME are in the process of develo= pment and community approval. The purpose of this initial review is to get on par with libvirt developmen= t and the proposed Intel MKTME feature in libvirt. Considering we have not added tests, this is a preliminary patch and based = on the community feedback, we expect more updates to follow. TODO: Add tests for launch security of type mktme. Update domaincommon.rng to add attribute of type mktme. --- docs/formatdomain.html.in | 62 +- docs/formatdomaincaps.html.in | 18 + docs/schemas/domaincaps.rng | 14 + include/libvirt/libvirt-host.h | 18 + src/conf/domain_capabilities.c | 29 + src/conf/domain_capabilities.h | 12 + src/conf/domain_conf.c | 114 +- src/conf/domain_conf.h | 13 + src/conf/virconftypes.h | 3 + src/driver-hypervisor.h | 7 + src/libvirt-host.c | 48 + src/libvirt_private.syms | 5 + src/libvirt_public.syms | 5 + src/qemu/qemu_capabilities.c | 130 +- src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_capspriv.h | 4 + src/qemu/qemu_command.c | 40 + src/qemu/qemu_driver.c | 63 + src/qemu/qemu_monitor.c | 9 + src/qemu/qemu_monitor.h | 5 + src/qemu/qemu_monitor_json.c | 52 + src/qemu/qemu_monitor_json.h | 3 + src/remote/remote_daemon_dispatch.c | 43 + src/remote/remote_driver.c | 40 +- src/remote/remote_protocol.x | 21 +- src/remote_protocol-structs | 12 + src/util/Makefile.inc.am | 2 + src/util/virmktme.c | 112 ++ src/util/virmktme.h | 33 + .../bhyve_basic.x86_64.xml | 1 + .../bhyve_fbuf.x86_64.xml | 1 + .../bhyve_uefi.x86_64.xml | 1 + tests/domaincapsschemadata/empty.xml | 1 + tests/domaincapsschemadata/libxl-xenfv.xml | 1 + tests/domaincapsschemadata/libxl-xenpv.xml | 1 + .../qemu_1.7.0.x86_64.xml | 1 + .../qemu_2.12.0-virt.aarch64.xml | 1 + .../qemu_2.12.0.ppc64.xml | 1 + .../qemu_2.12.0.s390x.xml | 1 + .../qemu_2.12.0.x86_64.xml | 1 + .../qemu_2.6.0-virt.aarch64.xml | 1 + .../qemu_2.6.0.aarch64.xml | 1 + .../domaincapsschemadata/qemu_2.6.0.ppc64.xml | 1 + .../qemu_2.6.0.x86_64.xml | 1 + .../domaincapsschemadata/qemu_2.7.0.s390x.xml | 1 + .../qemu_2.8.0-tcg.x86_64.xml | 1 + .../domaincapsschemadata/qemu_2.8.0.s390x.xml | 1 + .../qemu_2.8.0.x86_64.xml | 1 + .../qemu_2.9.0-q35.x86_64.xml | 1 + .../qemu_2.9.0-tcg.x86_64.xml | 1 + .../qemu_2.9.0.x86_64.xml | 1 + .../domaincapsschemadata/qemu_3.0.0.s390x.xml | 1 + .../qemu_3.1.0.x86_64.xml | 1 + .../qemu_4.0.0.x86_64.xml | 1 + .../qemu_5.0.0.x86_64.xml | 164 ++ tests/domaincapstest.c | 4 + .../caps_5.0.0.x86_64.xml | 1389 +++++++++++++++++ 57 files changed, 2490 insertions(+), 13 deletions(-) create mode 100644 src/util/virmktme.c create mode 100644 src/util/virmktme.h create mode 100644 tests/domaincapsschemadata/qemu_5.0.0.x86_64.xml create mode 100644 tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e1da878fcc..e96186aba9 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8924,13 +8924,16 @@ qemu-kvm -net nic,model=3D? /dev/null =20

Note: DEA/TDEA is synonymous with DES/TDES.

=20 -

Launch Security

+

Launch Security

=20

- The contents of the <launchSecurity type=3D'sev'> element + The contents of the launchSecurity element is used to provide the guest owners input used for creating an encr= ypted - VM using the AMD SEV feature (Secure Encrypted Virtualization). - + VM using the AMD SEV feature (Secure Encrypted Virtualization) + and Intel MKTME (Multi-Key Total Memory Encryption). +

+

SEV

+

SEV is an extension to the AMD-V architecture which supports running encrypted virtual machine (VMs) under the control of KVM. Encrypted VMs have their pages (code and data) secured such that only the gue= st @@ -8942,7 +8945,7 @@ qemu-kvm -net nic,model=3D? /dev/null For more information see various input parameters and its format se= e the SEV API spec Since 4.4.0 -

+

 <domain>
   ...
@@ -9039,6 +9042,55 @@ qemu-kvm -net nic,model=3D? /dev/null
       
     
=20
+	

MKTME

+

+ Total Memory Encryption (TME) =E2=80=93 provides the capability to e= ncrypt the + entirety of the physical memory of a system. MKTME builds on TME and + adds support for multiple encryption keys. + + By default MKTME uses the TME encryption key unless explicitly specified + by software. In addition to supporting a CPU generated ephemeral + key (not accessible by software or by using external interfaces to a= n SOC), + MKTME also supports software provided keys. Software provided keys are + particularly useful when used with nonvolatile memory or when combined + with attestation mechanisms and/or used with key provisioning services. + + For more information see + MKTME spec + Since 5.3.0 +

+
+<domain>
+  ...
+  <launchSecurity type=3D'mktme'>
+    <id>mktme-0</id>
+    <key_type>samplekey</key_type>
+    <type>user</type>
+    <encryption_algorithm>aes-xts-128</encryption_algorithm>
+  </launchSecurity>
+  ...
+</domain>
+
+
+
id
+
The required id element provides ability to map the= key handle. + If the id exists system returns the same mapped key handle which can be= used to=20 + encrpyt a different guest.=20 +
+
key_type
+
MKTME supports user and cpu generated keys. The required k= ey_type + element provides the type of key used for the encryption. +
+
key
+
The optional key element provides the key used for = the encryption. + Required only when the key type is of user. +
+
encryption_algorithm
+
The required encyption_algorithm element provides t= he type of=20 + encryption algorithm. Currently, MKTME supports aes-xts-128 only. +
+
+

Example configs

=20

diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in index b31b1729f4..ece891fa67 100644 --- a/docs/formatdomaincaps.html.in +++ b/docs/formatdomaincaps.html.in @@ -530,5 +530,23 @@ address space. The number of bits we lose is hypervisor dependent. =20 +

MKTME capabilities

+ +

Intel Multi-Key Total Memory Encryption (MKTME) capabilities are ex= posed under + the mktme element. + Total Memory Encryption (TME) =E2=80=93 provides the capability to enc= rypt the + entirety of the physical memory of a system. MKTME builds on TME and + adds support for multiple encryption keys.

+ +

+ For more details on MKTME feature see: + MKTME spec +

+ +
+
keys_supported
+
When mktme is enabled, keys_supported information is avaiable +
+ diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng index e629d6431f..a399e4348f 100644 --- a/docs/schemas/domaincaps.rng +++ b/docs/schemas/domaincaps.rng @@ -200,6 +200,9 @@ + + + =20 @@ -236,6 +239,17 @@ =20 + + + + + + + + + + + diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 7debb5f829..10d2e4d2f3 100644 --- a/include/libvirt/libvirt-host.h +++ b/include/libvirt/libvirt-host.h @@ -473,6 +473,24 @@ int virNodeGetSEVInfo (virConnectPtr conn, int *nparams, unsigned int flags); =20 +/** +* +* MKTME Parameters +*/ + +/** +* VIR_NODE_MKTME_KEYS_SUPPORTED: +* +* Macro represents the number of keys supported, when MKTME is enabled in = the guest. +*/ +# define VIR_NODE_MKTME_KEYS_SUPPORTED "keys_supported" + +int virNodeGetMKTMEInfo(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags); + + /** * virConnectFlags * diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 2e7e1c206b..1115fc26fc 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -78,6 +78,15 @@ virSEVCapabilitiesFree(virSEVCapability *cap) VIR_FREE(cap); } =20 +void +virMKTMECapabilitiesFree(virMKTMECapability *cap) +{ + if (!cap) + return; + + VIR_FREE(cap); +} + =20 static void virDomainCapsDispose(void *obj) @@ -89,6 +98,7 @@ virDomainCapsDispose(void *obj) virObjectUnref(caps->cpu.custom); virCPUDefFree(caps->cpu.hostModel); virSEVCapabilitiesFree(caps->sev); + virMKTMECapabilitiesFree(caps->mktme); =20 virDomainCapsStringValuesFree(&caps->os.loader.values); } @@ -593,6 +603,24 @@ virDomainCapsFeatureSEVFormat(virBufferPtr buf, return; } =20 +static void +virDomainCapsFeatureMKTMEFormat(virBufferPtr buf, + virMKTMECapabilityPtr const mktme) +{ + if (!mktme) { + virBufferAddLit(buf, "\n"); + } + else { + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "%d\n", mktme->k= eys_supported); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } + + return; +} + =20 char * virDomainCapsFormat(virDomainCapsPtr const caps) @@ -636,6 +664,7 @@ virDomainCapsFormat(virDomainCapsPtr const caps) FORMAT_SINGLE("vmcoreinfo", caps->vmcoreinfo); FORMAT_SINGLE("genid", caps->genid); virDomainCapsFeatureSEVFormat(&buf, caps->sev); + virDomainCapsFeatureMKTMEFormat(&buf, caps->mktme); =20 virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "\n"); diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index cd09d50cee..56a73546c0 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -150,6 +150,12 @@ struct _virSEVCapability { unsigned int reduced_phys_bits; }; =20 +typedef struct _virMKTMECapability virMKTMECapability; +typedef virMKTMECapability *virMKTMECapabilityPtr; +struct _virMKTMECapability { + unsigned int keys_supported; +}; + struct _virDomainCaps { virObjectLockable parent; =20 @@ -174,6 +180,7 @@ struct _virDomainCaps { virTristateBool vmcoreinfo; virTristateBool genid; virSEVCapabilityPtr sev; + virMKTMECapabilityPtr mktme; /* add new domain features here */ }; =20 @@ -222,4 +229,9 @@ virSEVCapabilitiesFree(virSEVCapability *capabilities); =20 VIR_DEFINE_AUTOPTR_FUNC(virSEVCapability, virSEVCapabilitiesFree); =20 +void +virMKTMECapabilitiesFree(virMKTMECapability *capabilities); + +VIR_DEFINE_AUTOPTR_FUNC(virMKTMECapability, virMKTMECapabilitiesFree); + #endif /* LIBVIRT_DOMAIN_CAPABILITIES_H */ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b4fb6cf981..e563840479 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1233,6 +1233,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, VIR_DOMAIN_LAUNCH_SECURITY_LAST, "", "sev", + "mktme", ); =20 static virClassPtr virDomainObjClass; @@ -3281,6 +3282,22 @@ virDomainSEVDefFree(virDomainSEVDefPtr def) VIR_FREE(def); } =20 +static void +virDomainMKTMEDefFree(virDomainMKTMEDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->id); + VIR_FREE(def->key_type); + VIR_FREE(def->key); + VIR_FREE(def->encryption_algorithm); + + + VIR_FREE(def); +} + + =20 void virDomainDefFree(virDomainDefPtr def) { @@ -3466,6 +3483,7 @@ void virDomainDefFree(virDomainDefPtr def) (def->ns.free)(def->namespaceData); =20 virDomainSEVDefFree(def->sev); + virDomainMKTMEDefFree(def->mktme); =20 xmlFreeNode(def->metadata); =20 @@ -15939,6 +15957,21 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, return ret; } =20 +static int +virDomainGetLaunchSecurityType(xmlNodePtr node) +{ + VIR_AUTOFREE(char *) type =3D NULL; + + if (!(type =3D virXMLPropString(node, "type"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing launch security type")); + return -1; + } + + return virDomainLaunchSecurityTypeFromString(type); + +} + =20 static virDomainSEVDefPtr virDomainSEVDefParseXML(xmlNodePtr sevNode, @@ -15965,6 +15998,7 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode, case VIR_DOMAIN_LAUNCH_SECURITY_SEV: break; case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_MKTME: case VIR_DOMAIN_LAUNCH_SECURITY_LAST: default: virReportError(VIR_ERR_XML_ERROR, @@ -16005,6 +16039,28 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode, goto cleanup; } =20 +static virDomainMKTMEDefPtr +virDomainMKTMEDefParseXML(xmlNodePtr mktmeNode, + xmlXPathContextPtr ctxt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + virDomainMKTMEDefPtr def; + + if (VIR_ALLOC(def) < 0) + return NULL; + + ctxt->node =3D mktmeNode; + + def->sectype =3D VIR_DOMAIN_LAUNCH_SECURITY_MKTME; + + def->id =3D virXPathString("string(./id)", ctxt); + def->key_type =3D virXPathString("string(./key_type)", ctxt); + def->key =3D virXPathString("string(./key)", ctxt); + def->encryption_algorithm =3D virXPathString("string(./encryption_algorit= hm)", ctxt); + + return def; +} + static virDomainMemoryDefPtr virDomainMemoryDefParseXML(virDomainXMLOptionPtr xmlopt, xmlNodePtr memdevNode, @@ -21127,11 +21183,33 @@ virDomainDefParseXML(xmlDocPtr xml, ctxt->node =3D node; VIR_FREE(nodes); =20 - /* Check for SEV feature */ + /* Check for launch security (MKTME/SEV) feature */ if ((node =3D virXPathNode("./launchSecurity", ctxt)) !=3D NULL) { - def->sev =3D virDomainSEVDefParseXML(node, ctxt); - if (!def->sev) - goto error; + int sectype =3D virDomainGetLaunchSecurityType(node); + + if (sectype < 0) + goto error; + + switch ((virDomainLaunchSecurity) sectype) { + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + def->sev =3D virDomainSEVDefParseXML(node, ctxt); + if (!def->sev) + goto error; + break; + case VIR_DOMAIN_LAUNCH_SECURITY_MKTME: + def->mktme =3D virDomainMKTMEDefParseXML(node, ctxt); + if (!def->mktme) + goto error; + break; + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: + default: + virReportError(VIR_ERR_XML_ERROR, + _("unsupported launch security type '%s'"), + virXMLPropString(node, "type")); + goto error; + } + } =20 /* analysis of memory devices */ @@ -27263,6 +27341,33 @@ virDomainSEVDefFormat(virBufferPtr buf, virDomainS= EVDefPtr sev) virBufferAddLit(buf, "\n"); } =20 +static void +virDomainMKTMEDefFormat(virBufferPtr buf, virDomainMKTMEDefPtr mktme) +{ + if (!mktme) + return; + + virBufferAsprintf(buf, "\n", + virDomainLaunchSecurityTypeToString(mktme->sectype)); + virBufferAdjustIndent(buf, 2); + + if (mktme->id) + virBufferEscapeString(buf, "%s\n", mktme->id); + + if (mktme->key_type) + virBufferEscapeString(buf, "%s\n", mktme->key_type); + + if (mktme->key) + virBufferEscapeString(buf, "%s\n", mktme->key); + + if (mktme->encryption_algorithm) + virBufferEscapeString(buf, "%s\n", mktme->encryption_algorithm); + + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + =20 static void virDomainPerfDefFormat(virBufferPtr buf, virDomainPerfDefPtr perf) @@ -28636,6 +28741,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virDomainKeyWrapDefFormat(buf, def->keywrap); =20 virDomainSEVDefFormat(buf, def->sev); + virDomainMKTMEDefFormat(buf, def->mktme); =20 virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 01c22d8cc3..5d08759de9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2279,6 +2279,7 @@ struct _virDomainKeyWrapDef { typedef enum { VIR_DOMAIN_LAUNCH_SECURITY_NONE, VIR_DOMAIN_LAUNCH_SECURITY_SEV, + VIR_DOMAIN_LAUNCH_SECURITY_MKTME, =20 VIR_DOMAIN_LAUNCH_SECURITY_LAST, } virDomainLaunchSecurity; @@ -2332,6 +2333,15 @@ struct _virDomainVirtioOptions { virTristateSwitch ats; }; =20 +struct _virDomainMKTMEDef { + int sectype; /* enum virDomainLaunchSecurity */ + char *id; + char *key_type; + char *key; + char *encryption_algorithm; + int key_handle; +}; + /* * Guest VM main configuration * @@ -2491,6 +2501,9 @@ struct _virDomainDef { /* SEV-specific domain */ virDomainSEVDefPtr sev; =20 + /* MKTME- domain info*/ + virDomainMKTMEDefPtr mktme; + /* Application-specific custom metadata */ xmlNodePtr metadata; =20 diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index 6a8267c422..a71ee462a0 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -346,4 +346,7 @@ typedef virDomainXMLPrivateDataCallbacks *virDomainXMLP= rivateDataCallbacksPtr; typedef struct _virDomainXenbusControllerOpts virDomainXenbusControllerOpt= s; typedef virDomainXenbusControllerOpts *virDomainXenbusControllerOptsPtr; =20 +typedef struct _virDomainMKTMEDef virDomainMKTMEDef; +typedef virDomainMKTMEDef *virDomainMKTMEDefPtr; + #endif /* LIBVIRT_VIRCONFTYPES_H */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 5315e33dde..1d26381cb4 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1322,6 +1322,12 @@ typedef int int *nparams, unsigned int flags); =20 +typedef int +(*virDrvNodeGetMKTMEInfo)(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags); + typedef int (*virDrvDomainGetLaunchSecurityInfo)(virDomainPtr domain, virTypedParameterPtr *params, @@ -1579,6 +1585,7 @@ struct _virHypervisorDriver { virDrvConnectCompareHypervisorCPU connectCompareHypervisorCPU; virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; virDrvNodeGetSEVInfo nodeGetSEVInfo; + virDrvNodeGetMKTMEInfo nodeGetMKTMEInfo; virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo; }; =20 diff --git a/src/libvirt-host.c b/src/libvirt-host.c index e20d6ee250..6696fb9998 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -1688,3 +1688,51 @@ virNodeGetSEVInfo(virConnectPtr conn, virDispatchError(conn); return -1; } + +/* + * virNodeGetMKTMEInfo: + * @conn: pointer to the hypervisor connection + * @params: where to store mktme information + * @nparams: pointer to number of MKTME parameters returned in @params + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * If hypervisor supports Intel's MKTME feature, then @params will contain= various + * platform specific information like number of keys supported. Caller is + * responsible for freeing @params. + * + * Returns 0 in case of success, and -1 in case of failure. + */ +int +virNodeGetMKTMEInfo(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + VIR_DEBUG("conn=3D%p, params=3D%p, nparams=3D%p, flags=3D0x%x", + conn, params, nparams, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, -1); + virCheckNonNullArgGoto(nparams, error); + virCheckNonNegativeArgGoto(*nparams, error); + virCheckReadOnlyGoto(conn->flags, error); + + if (VIR_DRV_SUPPORTS_FEATURE(conn->driver, conn, + VIR_DRV_FEATURE_TYPED_PARAM_STRING)) + flags |=3D VIR_TYPED_PARAM_STRING_OKAY; + + if (conn->driver->nodeGetMKTMEInfo) { + int ret; + ret =3D conn->driver->nodeGetMKTMEInfo(conn, params, nparams, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + +error: + virDispatchError(conn); + return -1; +} diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a03cf0b645..afa6925715 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -189,6 +189,7 @@ virDomainCapsEnumClear; virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; +virMKTMECapabilitiesFree; virSEVCapabilitiesFree; =20 =20 @@ -2352,6 +2353,9 @@ virMediatedDeviceSetUsedBy; virMediatedDeviceTypeFree; virMediatedDeviceTypeReadAttrs; =20 +# util/virmktme.h +virGetMktmeKeyHandle; +virMktmeIsEnabled; =20 # util/virmodule.h virModuleLoad; @@ -3315,6 +3319,7 @@ virXPathULongHex; virXPathULongLong; =20 =20 + # Let emacs know we want case-insensitive sorting # Local Variables: # sort-fold-case: t diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index dbce3336d5..d106f36db2 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -819,4 +819,9 @@ LIBVIRT_5.2.0 { virConnectGetStoragePoolCapabilities; } LIBVIRT_4.10.0; =20 +LIBVIRT_5.3.0 { + global: + virNodeGetMKTMEInfo; +} LIBVIRT_5.2.0; + # .... define new API here using predicted next version number .... diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a0b2ca73fb..c127d61a1d 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -525,6 +525,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-pci-non-transitional", "overcommit", "query-current-machine", + "mktme-guest" ); =20 =20 @@ -595,6 +596,8 @@ struct _virQEMUCaps { =20 virSEVCapability *sevCapabilities; =20 + virMKTMECapability *mktmeCapabilities; + virQEMUCapsHostCPUData kvmCPU; virQEMUCapsHostCPUData tcgCPU; }; @@ -1090,6 +1093,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[= ] =3D { { "vhost-vsock-device", QEMU_CAPS_DEVICE_VHOST_VSOCK }, { "mch", QEMU_CAPS_DEVICE_MCH }, { "sev-guest", QEMU_CAPS_SEV_GUEST }, + { "mktme-guest", QEMU_CAPS_MKTME_GUEST }, { "vfio-ap", QEMU_CAPS_DEVICE_VFIO_AP }, { "zpci", QEMU_CAPS_DEVICE_ZPCI }, { "memory-backend-memfd", QEMU_CAPS_OBJECT_MEMORY_MEMFD }, @@ -1541,6 +1545,22 @@ virQEMUCapsSEVInfoCopy(virSEVCapabilityPtr *dst, return 0; } =20 +static int +virQEMUCapsMKTMEInfoCopy(virMKTMECapabilityPtr *dst, + virMKTMECapabilityPtr src) +{ + VIR_AUTOPTR(virMKTMECapability) tmp =3D NULL; + + if (VIR_ALLOC(tmp) < 0 ) + return -1; + + tmp->keys_supported =3D src->keys_supported; + + VIR_STEAL_PTR(*dst, tmp); + return 0; +} + + =20 virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) { @@ -1612,6 +1632,12 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qem= uCaps) qemuCaps->sevCapabilities) < 0) goto error; =20 + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MKTME_GUEST) && + virQEMUCapsMKTMEInfoCopy(&ret->mktmeCapabilities, + qemuCaps->mktmeCapabilities) < 0) + goto error; + + return ret; =20 error: @@ -1643,6 +1669,7 @@ void virQEMUCapsDispose(void *obj) VIR_FREE(qemuCaps->gicCapabilities); =20 virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virMKTMECapabilitiesFree(qemuCaps->mktmeCapabilities); =20 virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU); virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU); @@ -2099,6 +2126,12 @@ virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCap= s) return qemuCaps->sevCapabilities; } =20 +virMKTMECapabilityPtr +virQEMUCapsGetMKTMECapabilities(virQEMUCapsPtr qemuCaps) +{ + return qemuCaps->mktmeCapabilities; +} + =20 static int virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps, @@ -2768,6 +2801,30 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCapsPtr qe= muCaps, return 0; } =20 +/* Returns -1 on error, 0 if MKTME is not supported, 1 if MKTME is support= ed */ +static int +virQEMUCapsProbeQMPMKTMECapabilities(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon) +{ + int rc =3D -1; + virMKTMECapability *caps =3D NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MKTME_GUEST)) + return 0; + if ((rc =3D qemuMonitorGetMKTMECapabilities(mon, &caps)) < 0) + return -1; + + /* MKTME isn't actually supported */ + if (rc =3D=3D 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_MKTME_GUEST); + return 0; + } + + virMKTMECapabilitiesFree(qemuCaps->mktmeCapabilities); + qemuCaps->mktmeCapabilities =3D caps; + return 0; +} + =20 bool virQEMUCapsCPUFilterFeatures(const char *name, @@ -3397,6 +3454,35 @@ virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xml= XPathContextPtr ctxt) return 0; } =20 +static int +virQEMUCapsParseMKTMEInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt) +{ + VIR_AUTOPTR(virMKTMECapability) mktme =3D NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MKTME_GUEST)) + return 0; + + if (virXPathBoolean("boolean(./mktme)", ctxt) =3D=3D 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing MKTME platform data in QEMU " + "capabilities cache")); + return -1; + } + + if (VIR_ALLOC(mktme) < 0) + return -1; + + if (virXPathUInt("string(./mktme/keys_supported)", ctxt, &mktme->keys_sup= ported) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing or malformed MKTME keys_supported information " + "in QEMU capabilities cache")); + return -1; + } + + VIR_STEAL_PTR(qemuCaps->mktmeCapabilities, mktme); + return 0; +} + =20 /* * Parsing a doc that looks like @@ -3650,6 +3736,10 @@ virQEMUCapsLoadCache(virArch hostArch, if (virQEMUCapsParseSEVInfo(qemuCaps, ctxt) < 0) goto cleanup; =20 + if (virQEMUCapsParseMKTMEInfo(qemuCaps, ctxt) < 0) + goto cleanup; + + virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM); virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU); =20 @@ -3786,6 +3876,17 @@ virQEMUCapsFormatSEVInfo(virQEMUCapsPtr qemuCaps, vi= rBufferPtr buf) virBufferAddLit(buf, "\n"); } =20 +static void +virQEMUCapsFormatMKTMEInfo(virQEMUCapsPtr qemuCaps, virBufferPtr buf) +{ + virMKTMECapabilityPtr mktme =3D virQEMUCapsGetMKTMECapabilities(qemuCaps); + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "%u\n", mktme->ke= ys_supported); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} =20 char * virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) @@ -3806,7 +3907,7 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) =20 for (i =3D 0; i < QEMU_CAPS_LAST; i++) { if (virQEMUCapsGet(qemuCaps, i)) { - virBufferAsprintf(&buf, "\n", + virBufferAsprintf(&buf, "\n", virQEMUCapsTypeToString(i)); } } @@ -3871,6 +3972,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) if (qemuCaps->sevCapabilities) virQEMUCapsFormatSEVInfo(qemuCaps, &buf); =20 + if (qemuCaps->mktmeCapabilities) + virQEMUCapsFormatMKTMEInfo(qemuCaps, &buf); + if (qemuCaps->kvmSupportsNesting) virBufferAddLit(&buf, "\n"); =20 @@ -4373,6 +4477,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPMKTMECapabilities(qemuCaps, mon) < 0) + return -1; =20 virQEMUCapsInitProcessCaps(qemuCaps); =20 @@ -5325,6 +5431,25 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCapsPtr q= emuCaps, return 0; } =20 +static int +virQEMUCapsFillDomainFeatureMKTMECaps(virQEMUCapsPtr qemuCaps, + virDomainCapsPtr domCaps) +{ + virMKTMECapability *cap =3D qemuCaps->mktmeCapabilities; + VIR_AUTOPTR(virMKTMECapability) mktme =3D NULL; + + if (!cap) + return 0; + + if (VIR_ALLOC(mktme) < 0) + return -1; + + mktme->keys_supported =3D cap->keys_supported; + VIR_STEAL_PTR(domCaps->mktme, mktme); + + return 0; +} + =20 int virQEMUCapsFillDomainCaps(virCapsPtr caps, @@ -5370,7 +5495,8 @@ virQEMUCapsFillDomainCaps(virCapsPtr caps, virQEMUCapsFillDomainDeviceVideoCaps(qemuCaps, video) < 0 || virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0 || virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps) < 0 || - virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps) < 0) + virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps) < 0 ||=20 + virQEMUCapsFillDomainFeatureMKTMECaps(qemuCaps, domCaps) < 0) return -1; =20 return 0; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 67c8e80462..5614479617 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -507,6 +507,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for = syntax-check */ QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL, /* virtio *-pci-{non-}transitional = devices */ QEMU_CAPS_OVERCOMMIT, /* -overcommit */ QEMU_CAPS_QUERY_CURRENT_MACHINE, /* query-current-machine command */ + QEMU_CAPS_MKTME_GUEST, /* -object mktme-guest,... */ =20 QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; @@ -644,6 +645,9 @@ bool virQEMUCapsCPUFilterFeatures(const char *name, virSEVCapabilityPtr virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps); =20 +virMKTMECapabilityPtr +virQEMUCapsGetMKTMECapabilities(virQEMUCapsPtr qemuCaps); + virArch virQEMUCapsArchFromString(const char *arch); const char *virQEMUCapsArchToString(virArch arch); =20 diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h index 2d059bee8c..2c44c7a38c 100644 --- a/src/qemu/qemu_capspriv.h +++ b/src/qemu/qemu_capspriv.h @@ -95,6 +95,10 @@ void virQEMUCapsSetSEVCapabilities(virQEMUCapsPtr qemuCaps, virSEVCapability *capabilities); =20 +void +virQEMUCapsSetMKTMECapabilities(virQEMUCapsPtr qemuCaps, + virMKTMECapability *capabilities); + int virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 50b4205267..ad193a5b4c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -59,6 +59,7 @@ #include "virgic.h" #include "virmdev.h" #include "virdomainsnapshotobjlist.h" +#include "virmktme.h" #if defined(__linux__) # include #endif @@ -7765,6 +7766,10 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, if (def->sev) virBufferAddLit(&buf, ",memory-encryption=3Dsev0"); =20 + if (def->mktme) + virBufferAddLit(&buf, ",memory-encryption=3Dm0"); + + virCommandAddArgBuffer(cmd, &buf); =20 ret =3D 0; @@ -10266,6 +10271,37 @@ qemuBuildSEVCommandLine(virDomainObjPtr vm, virCom= mandPtr cmd, return ret; } =20 +static int +qemuBuildMKTMECommandLine(virCommandPtr cmd, + virDomainMKTMEDefPtr mktme) +{ + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + int ret =3D -1; + + if (!mktme) + return 0; + + if ((mktme->key_handle =3D virGetMktmeKeyHandle(mktme->id, mktme->key_typ= e, + mktme->key, mktme->encryption_algorithm)) < 0) + { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to get MKTME key handle id %s"), mktme->id); + return -1; + + } + VIR_DEBUG("id=3D%s key_type=3D%s key_handle=3D0x%x", + mktme->id, mktme->key_type, mktme->key_handle); + + virBufferAsprintf(&buf, "mktme-guest,id=3Dm0,handle=3D%d", mktme->key_han= dle); + + virCommandAddArg(cmd, "-object"); + virCommandAddArgBuffer(cmd, &buf); + ret =3D 0; + virBufferFreeAndReset(&buf); + return ret; +} + + static int qemuBuildVMCoreInfoCommandLine(virCommandPtr cmd, const virDomainDef *def, @@ -10886,6 +10922,10 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildSEVCommandLine(vm, cmd, def->sev) < 0) goto error; =20 + if (qemuBuildMKTMECommandLine(cmd, def->mktme) < 0) + goto error; + + if (snapshot) virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL); =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b2ac737d1f..ef62c15a26 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -22266,6 +22266,68 @@ qemuNodeGetSEVInfo(virConnectPtr conn, } =20 =20 +static int +qemuGetMKTMEInfoToParams(virQEMUCapsPtr qemuCaps, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int maxpar =3D 0; + int n =3D 0; + virMKTMECapabilityPtr mktme =3D virQEMUCapsGetMKTMECapabilities(qemuCaps); + virTypedParameterPtr mktmeParams =3D NULL; + + virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1); + + if (virTypedParamsAddUInt(&mktmeParams, &n, &maxpar, + VIR_NODE_MKTME_KEYS_SUPPORTED, mktme->keys_supported) < 0) + goto cleanup; + + VIR_STEAL_PTR(*params, mktmeParams); + *nparams =3D n; + return 0; + +cleanup: + virTypedParamsFree(mktmeParams, n); + return -1; +} + + +static int +qemuNodeGetMKTMEInfo(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + virQEMUDriverPtr driver =3D conn->privateData; + virQEMUCapsPtr qemucaps =3D NULL; + int ret =3D -1; + + if (virNodeGetMktmeInfoEnsureACL(conn) < 0) + return ret; + + qemucaps =3D virQEMUCapsCacheLookupByArch(driver->qemuCapsCache, + virArchFromHost()); + if (!qemucaps) + goto cleanup; + + if (!virQEMUCapsGet(qemucaps, QEMU_CAPS_MKTME_GUEST)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("QEMU does not support MKTME guest")); + goto cleanup; + } + + if (qemuGetMKTMEInfoToParams(qemucaps, params, nparams, flags) < 0) + goto cleanup; + + ret =3D 0; + +cleanup: + virObjectUnref(qemucaps); + return ret; +} + + static int qemuDomainGetSEVMeasurement(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -22560,6 +22622,7 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .connectBaselineHypervisorCPU =3D qemuConnectBaselineHypervisorCPU, /*= 4.4.0 */ .nodeGetSEVInfo =3D qemuNodeGetSEVInfo, /* 4.5.0 */ .domainGetLaunchSecurityInfo =3D qemuDomainGetLaunchSecurityInfo, /* 4= .5.0 */ + .nodeGetMKTMEInfo =3D qemuNodeGetMKTMEInfo /* 5.3.0 */ }; =20 =20 diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index e1fcbac13f..ea06e09f95 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3921,6 +3921,15 @@ qemuMonitorGetSEVCapabilities(qemuMonitorPtr mon, return qemuMonitorJSONGetSEVCapabilities(mon, capabilities); } =20 +int +qemuMonitorGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities) +{ + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetMKTMECapabilities(mon, capabilities); +} + =20 int qemuMonitorNBDServerStart(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 9242d37407..2b39e54625 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -761,6 +761,11 @@ int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon, int qemuMonitorGetSEVCapabilities(qemuMonitorPtr mon, virSEVCapability **capabilities); =20 + +int qemuMonitorGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **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 908967f46c..708d483942 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6654,6 +6654,58 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon, return ret; } =20 +int +qemuMonitorJSONGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities) +{ + int ret =3D -1; + virJSONValuePtr cmd; + virJSONValuePtr reply =3D NULL; + virJSONValuePtr caps; + unsigned int keys_supported; + VIR_AUTOPTR(virMKTMECapability) capability =3D NULL; + + *capabilities =3D NULL; + + /* Query may change*/ + if (!(cmd =3D qemuMonitorJSONMakeCommand("query-mktme-capabilities", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret =3D 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + caps =3D virJSONValueObjectGetObject(reply, "return"); + + if (virJSONValueObjectGetNumberUint(caps, "keys_supported", &keys_support= ed) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-mktme-capabilities reply was missing" + " 'keys_supported' field")); + goto cleanup; + } + + if (VIR_ALLOC(capability) < 0) + goto cleanup; + + capability->keys_supported =3D keys_supported; + VIR_STEAL_PTR(*capabilities, capability); + ret =3D 1; +cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + + static virJSONValuePtr qemuMonitorJSONBuildInetSocketAddress(const char *host, const char *port) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 746b7072ca..e9316564ba 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -158,6 +158,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mo= n, int qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon, virSEVCapability **capabilities); =20 +int qemuMonitorJSONGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities); + int qemuMonitorJSONMigrate(qemuMonitorPtr mon, unsigned int flags, const char *uri); diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon= _dispatch.c index df28259042..f42686bfa9 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -5229,6 +5229,49 @@ remoteDispatchNodeGetSevInfo(virNetServerPtr server = ATTRIBUTE_UNUSED, return rv; } =20 +static int +remoteDispatchNodeGetMktmeInfo(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_node_get_mktme_info_args *args, + remote_node_get_mktme_info_ret *ret) +{ + virTypedParameterPtr params =3D NULL; + int nparams =3D 0; + int rv =3D -1; + struct daemonClientPrivate *priv =3D + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if (virNodeGetMKTMEInfo(priv->conn, ¶ms, &nparams, args->flags) < 0) + goto cleanup; + + if (nparams > REMOTE_NODE_MKTME_INFO_MAX) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large")); + goto cleanup; + } + + + if (virTypedParamsSerialize(params, nparams, + (virTypedParameterRemotePtr *)&ret->params.params_val, + &ret->params.params_len, + args->flags) < 0) + goto cleanup; + + rv =3D 0; + +cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + virTypedParamsFree(params, nparams); + return rv; +} + =20 static int remoteDispatchNodeGetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNU= SED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 5c4dd41227..507ce0f917 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6824,6 +6824,43 @@ remoteNodeGetSEVInfo(virConnectPtr conn, return rv; } =20 +static int +remoteNodeGetMKTMEInfo(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int rv =3D -1; + remote_node_get_mktme_info_args args; + remote_node_get_mktme_info_ret ret; + struct private_data *priv =3D conn->privateData; + + remoteDriverLock(priv); + + args.flags =3D flags; + + memset(&ret, 0, sizeof(ret)); + if (call(conn, priv, 0, REMOTE_PROC_NODE_GET_MKTME_INFO, + (xdrproc_t)xdr_remote_node_get_mktme_info_args, (char *)&args, + (xdrproc_t)xdr_remote_node_get_mktme_info_ret, (char *)&ret) =3D=3D -1) + goto done; + + if (virTypedParamsDeserialize((virTypedParameterRemotePtr)ret.params.para= ms_val, + ret.params.params_len, + REMOTE_NODE_MKTME_INFO_MAX, + params, + nparams) < 0) + goto cleanup; + + rv =3D 0; + +cleanup: + xdr_free((xdrproc_t)xdr_remote_node_get_mktme_info_ret, (char *)&ret); +done: + remoteDriverUnlock(priv); + return rv; +} + =20 static int remoteNodeGetCPUMap(virConnectPtr conn, @@ -8516,7 +8553,8 @@ static virHypervisorDriver hypervisor_driver =3D { .connectCompareHypervisorCPU =3D remoteConnectCompareHypervisorCPU, /*= 4.4.0 */ .connectBaselineHypervisorCPU =3D remoteConnectBaselineHypervisorCPU, = /* 4.4.0 */ .nodeGetSEVInfo =3D remoteNodeGetSEVInfo, /* 4.5.0 */ - .domainGetLaunchSecurityInfo =3D remoteDomainGetLaunchSecurityInfo /* = 4.5.0 */ + .domainGetLaunchSecurityInfo =3D remoteDomainGetLaunchSecurityInfo, /*= 4.5.0 */ + .nodeGetMKTMEInfo =3D remoteNodeGetMKTMEInfo /* 5.3.0 */ }; =20 static virNetworkDriver network_driver =3D { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 11f44ee267..b7806f42fa 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -260,6 +260,9 @@ const REMOTE_DOMAIN_IOTHREAD_PARAMS_MAX =3D 64; /* Upper limit on number of SEV parameters */ const REMOTE_NODE_SEV_INFO_MAX =3D 64; =20 +/* Upper limit on number of MKTME parameters */ +const REMOTE_NODE_MKTME_INFO_MAX =3D 64; + /* Upper limit on number of launch security information entries */ const REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX =3D 64; =20 @@ -3573,6 +3576,16 @@ struct remote_connect_get_storage_pool_capabilities_= ret { remote_nonnull_string capabilities; }; =20 +struct remote_node_get_mktme_info_args { + int nparams; + unsigned int flags; +}; + +struct remote_node_get_mktme_info_ret { + remote_typed_param params; + int nparams; +}; + /*----- Protocol. -----*/ =20 /* Define the program number, protocol version and procedure numbers here.= */ @@ -6342,5 +6355,11 @@ enum remote_procedure { * @generate: both * @acl: connect:read */ - REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES =3D 403 + REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES =3D 403, + + /** + * @generate: none + * @acl: connect:read + */ + REMOTE_PROC_NODE_GET_MKTME_INFO =3D 404 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 768189c573..0f469d68a1 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2981,6 +2981,17 @@ struct remote_connect_get_storage_pool_capabilities_= args { struct remote_connect_get_storage_pool_capabilities_ret { remote_nonnull_string capabilities; }; +struct remote_node_get_mktme_info_args { + int nparams; + u_int flags; +}; +struct remote_node_get_mktme_info_ret { + struct { + u_int params_len; + remote_typed_param * params_val; + } params; + int nparams; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN =3D 1, REMOTE_PROC_CONNECT_CLOSE =3D 2, @@ -3385,4 +3396,5 @@ enum remote_procedure { REMOTE_PROC_CONNECT_LIST_ALL_NWFILTER_BINDINGS =3D 401, REMOTE_PROC_DOMAIN_SET_IOTHREAD_PARAMS =3D 402, REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES =3D 403, + REMOTE_PROC_NODE_GET_MKTME_INFO =3D 404, }; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index c757f5a6ae..ad4aa89873 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -228,6 +228,8 @@ UTIL_SOURCES =3D \ util/virmdev.h \ util/virfilecache.c \ util/virfilecache.h \ + util/virmktme.c \ + util/virmktme.h \ $(NULL) =20 =20 diff --git a/src/util/virmktme.c b/src/util/virmktme.c new file mode 100644 index 0000000000..714f4e8a2e --- /dev/null +++ b/src/util/virmktme.c @@ -0,0 +1,112 @@ +/* +* virmktme.c: interaction with processes +* +* Copyright (C) 2010-2015 Red Hat, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library. If not, see +* . +* +*/ +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#endif +#include "virerror.h" +#include "virlog.h" +#include "viraudit.h" +#include "virfile.h" +#include "viralloc.h" +#include "virutil.h" +#include "virstring.h" +#include "virmktme.h" + +VIR_LOG_INIT("util.mktme"); +// Libvirt thread specific dest keyring +#define VIR_FROM_THIS VIR_FROM_NONE + +/** +* virGetMktmeKey: +* @id: mktme id-string +* @type : mktme key type +* @key : user key value +* @encyption_algorithm : encryption algorithm +* +* returns mktme key-handle , this handle is used to encrypt the memory +* return -1 in case of failue +*/ + +#ifdef __linux__ +#define GET_MKTME_DEST_RING() \ +{ \ + destringid =3D syscall(__NR_request_key,"keyring", \ + LIBVIRT_MKTME_KEY_RING_NAME, KEY_SPEC_PROCESS_KEYRING); \ +} +#else +#define GET_MKTME_DEST_RING() +#endif + +int +virGetMktmeKeyHandle(const char* id, + const char* type, + const char* key, + const char *algorithm) +{ + char *callout =3D NULL; + int destringid =3D -1; + + int ret =3D -1; + + if (!id || !type || !algorithm ) + return -1; + + GET_MKTME_DEST_RING(); + if(destringid < 0) + return -1; + + if (key) { + if (virAsprintf(&callout, "type=3D%s algorithm=3D%s key=3D%s", + type, algorithm, key) < 0) + return -1; + } + else { + if (virAsprintf(&callout, "type=3D%s algorithm=3D%s", type, algorithm= ) < 0) + return -1; + } + +#ifdef __linux__ + ret =3D syscall(__NR_request_key,"mktme", id, callout, destringid); + VIR_FREE(callout); +#endif + return ret; +} + +/** +* virMktmeIsEnabled: +* +* Returns MKTME initialization status +*/ +int +virMktmeIsEnabled(void) +{ + int destringid =3D -1; + GET_MKTME_DEST_RING(); + if(destringid < 0) + return 0; + + return 1; +} diff --git a/src/util/virmktme.h b/src/util/virmktme.h new file mode 100644 index 0000000000..d698f6bfe4 --- /dev/null +++ b/src/util/virmktme.h @@ -0,0 +1,33 @@ +/* +* virmktme.h: MKTME kernel calls +* +* Copyright (C) 2016 Red Hat, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library. If not, see +* . +*/ + + +#ifndef LIBVIRT_VIRMKTME_H +#define LIBVIRT_VIRMKTME_H + +int +virGetMktmeKeyHandle(const char* id, const char* type, + const char* key, const char *algorithm); + +int +virMktmeIsEnabled(void); + +#define LIBVIRT_MKTME_KEY_RING_NAME "mktme_key_ring_service" +#endif diff --git a/tests/domaincapsschemadata/bhyve_basic.x86_64.xml b/tests/doma= incapsschemadata/bhyve_basic.x86_64.xml index bdf2c4eee8..8db3340b38 100644 --- a/tests/domaincapsschemadata/bhyve_basic.x86_64.xml +++ b/tests/domaincapsschemadata/bhyve_basic.x86_64.xml @@ -32,5 +32,6 @@ + diff --git a/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml b/tests/domai= ncapsschemadata/bhyve_fbuf.x86_64.xml index f998c457c1..397c7c7ae2 100644 --- a/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml +++ b/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml @@ -49,5 +49,6 @@ + diff --git a/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml b/tests/domai= ncapsschemadata/bhyve_uefi.x86_64.xml index 18f90023d5..f5c2c67fd8 100644 --- a/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml +++ b/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml @@ -41,5 +41,6 @@ + diff --git a/tests/domaincapsschemadata/empty.xml b/tests/domaincapsschemad= ata/empty.xml index 6c3f5f54fd..2ebefe8a05 100644 --- a/tests/domaincapsschemadata/empty.xml +++ b/tests/domaincapsschemadata/empty.xml @@ -12,5 +12,6 @@ + diff --git a/tests/domaincapsschemadata/libxl-xenfv.xml b/tests/domaincapss= chemadata/libxl-xenfv.xml index 4efc137c97..09c04374b9 100644 --- a/tests/domaincapsschemadata/libxl-xenfv.xml +++ b/tests/domaincapsschemadata/libxl-xenfv.xml @@ -75,5 +75,6 @@ + diff --git a/tests/domaincapsschemadata/libxl-xenpv.xml b/tests/domaincapss= chemadata/libxl-xenpv.xml index 70e598fe9e..aac2a2cba6 100644 --- a/tests/domaincapsschemadata/libxl-xenpv.xml +++ b/tests/domaincapsschemadata/libxl-xenpv.xml @@ -65,5 +65,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_1.7.0.x86_64.xml index 06908cc61e..8e55093e39 100644 --- a/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml @@ -122,5 +122,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.12.0-virt.aarch64.xml b/test= s/domaincapsschemadata/qemu_2.12.0-virt.aarch64.xml index 5983a60887..ff0d410846 100644 --- a/tests/domaincapsschemadata/qemu_2.12.0-virt.aarch64.xml +++ b/tests/domaincapsschemadata/qemu_2.12.0-virt.aarch64.xml @@ -130,5 +130,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.12.0.ppc64.xml b/tests/domai= ncapsschemadata/qemu_2.12.0.ppc64.xml index 42c67623f4..158827f607 100644 --- a/tests/domaincapsschemadata/qemu_2.12.0.ppc64.xml +++ b/tests/domaincapsschemadata/qemu_2.12.0.ppc64.xml @@ -90,5 +90,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.12.0.s390x.xml b/tests/domai= ncapsschemadata/qemu_2.12.0.s390x.xml index 4804c13329..71beea4258 100644 --- a/tests/domaincapsschemadata/qemu_2.12.0.s390x.xml +++ b/tests/domaincapsschemadata/qemu_2.12.0.s390x.xml @@ -182,5 +182,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml b/tests/doma= incapsschemadata/qemu_2.12.0.x86_64.xml index f5f54cb484..559bbdda0b 100644 --- a/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml @@ -158,5 +158,6 @@ 47 1 + diff --git a/tests/domaincapsschemadata/qemu_2.6.0-virt.aarch64.xml b/tests= /domaincapsschemadata/qemu_2.6.0-virt.aarch64.xml index 99ee16e4bb..30f70cd80d 100644 --- a/tests/domaincapsschemadata/qemu_2.6.0-virt.aarch64.xml +++ b/tests/domaincapsschemadata/qemu_2.6.0-virt.aarch64.xml @@ -127,5 +127,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml b/tests/doma= incapsschemadata/qemu_2.6.0.aarch64.xml index 61fdae009a..293dd3d4f5 100644 --- a/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml +++ b/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml @@ -121,5 +121,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.6.0.ppc64.xml b/tests/domain= capsschemadata/qemu_2.6.0.ppc64.xml index a33960a2af..dedd4ed799 100644 --- a/tests/domaincapsschemadata/qemu_2.6.0.ppc64.xml +++ b/tests/domaincapsschemadata/qemu_2.6.0.ppc64.xml @@ -94,5 +94,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_2.6.0.x86_64.xml index 94fe08bc92..a5fc6d46ee 100644 --- a/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml @@ -129,5 +129,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.7.0.s390x.xml b/tests/domain= capsschemadata/qemu_2.7.0.s390x.xml index 1057573681..ea51c0aee9 100644 --- a/tests/domaincapsschemadata/qemu_2.7.0.s390x.xml +++ b/tests/domaincapsschemadata/qemu_2.7.0.s390x.xml @@ -87,5 +87,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml b/tests/d= omaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml index 39f3bd6d9f..2505bfe316 100644 --- a/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml @@ -130,5 +130,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.8.0.s390x.xml b/tests/domain= capsschemadata/qemu_2.8.0.s390x.xml index 9ae9a1a8bc..fa7e0d2fb5 100644 --- a/tests/domaincapsschemadata/qemu_2.8.0.s390x.xml +++ b/tests/domaincapsschemadata/qemu_2.8.0.s390x.xml @@ -168,5 +168,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_2.8.0.x86_64.xml index 1770c81fdb..deb8210590 100644 --- a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml @@ -130,5 +130,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.9.0-q35.x86_64.xml b/tests/d= omaincapsschemadata/qemu_2.9.0-q35.x86_64.xml index e2ec30fda7..89d3038557 100644 --- a/tests/domaincapsschemadata/qemu_2.9.0-q35.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.9.0-q35.x86_64.xml @@ -139,5 +139,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml b/tests/d= omaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml index 65226ee284..9aaa3e41c8 100644 --- a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml @@ -162,5 +162,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_2.9.0.x86_64.xml index 0093877a0b..0f9d1400a1 100644 --- a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml @@ -139,5 +139,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_3.0.0.s390x.xml b/tests/domain= capsschemadata/qemu_3.0.0.s390x.xml index c8efefc5ba..af2217f05b 100644 --- a/tests/domaincapsschemadata/qemu_3.0.0.s390x.xml +++ b/tests/domaincapsschemadata/qemu_3.0.0.s390x.xml @@ -188,5 +188,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_3.1.0.x86_64.xml index ca3baab88c..e00c816980 100644 --- a/tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml @@ -157,5 +157,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_4.0.0.x86_64.xml index 42d8949e61..53d1663368 100644 --- a/tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml +++ b/tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml @@ -157,5 +157,6 @@ + diff --git a/tests/domaincapsschemadata/qemu_5.0.0.x86_64.xml b/tests/domai= ncapsschemadata/qemu_5.0.0.x86_64.xml new file mode 100644 index 0000000000..3d0c70faab --- /dev/null +++ b/tests/domaincapsschemadata/qemu_5.0.0.x86_64.xml @@ -0,0 +1,164 @@ + + /usr/bin/qemu-system-x86_64 + kvm + pc-i440fx-4.0 + x86_64 + + + + + bios + efi + + + /usr/share/AAVMF/AAVMF_CODE.fd + /usr/share/AAVMF/AAVMF32_CODE.fd + /usr/share/OVMF/OVMF_CODE.fd + + rom + pflash + + + yes + no + + + no + + + + + + + Skylake-Client-IBRS + Intel + + + + + + + + + + + + + qemu64 + qemu32 + phenom + pentium3 + pentium2 + pentium + n270 + kvm64 + kvm32 + coreduo + core2duo + athlon + Westmere-IBRS + Westmere + Skylake-Server-IBRS + Skylake-Server + Skylake-Client-IBRS + Skylake-Client + SandyBridge-IBRS + SandyBridge + Penryn + Opteron_G5 + Opteron_G4 + Opteron_G3 + Opteron_G2 + Opteron_G1 + Nehalem-IBRS + Nehalem + IvyBridge-IBRS + IvyBridge + Icelake-Server + Icelake-Client + Haswell-noTSX-IBRS + Haswell-noTSX + Haswell-IBRS + Haswell + EPYC-IBPB + EPYC + Conroe + Cascadelake-Server + Broadwell-noTSX-IBRS + Broadwell-noTSX + Broadwell-IBRS + Broadwell + 486 + + + + + + disk + cdrom + floppy + lun + + + ide + fdc + scsi + virtio + usb + sata + + + virtio + virtio-transitional + virtio-non-transitional + + + + + sdl + vnc + spice + + + + + + subsystem + + + default + mandatory + requisite + optional + + + usb + pci + scsi + + + + default + kvm + vfio + + + + + + + + + + 15 + + + diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index f87a1d63fb..dc6eb9ba07 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -449,6 +449,10 @@ mymain(void) DO_TEST_QEMU("4.0.0", "caps_4.0.0", "/usr/bin/qemu-system-x86_64", NULL, "x86_64", VIR_DOMAIN_VIRT_KVM); + + DO_TEST_QEMU("5.0.0", "caps_5.0.0", + "/usr/bin/qemu-system-x86_64", NULL, + "x86_64", VIR_DOMAIN_VIRT_KVM); virObjectUnref(cfg); =20 virFileWrapperClearPrefixes(); diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemuc= apabilitiesdata/caps_5.0.0.x86_64.xml new file mode 100644 index 0000000000..4bd9209147 --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -0,0 +1,1389 @@ + + 0 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3001050 + 0 + 43100758 + v3.1.0-1445-ga61faa3d02 + x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 15 + + --=20 2.21.0.windows.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list