[libvirt] [PATCH 0/7] x86: Multi-key Total Memory Encryption (Intel)

This patch series provides support for launching an encrypted guest using Intel's Multi-key Total Memory Encryption (MKTME) feature. The purpose of this review is to get initial feedback and to get on par with libvirt development process. Considering we have not added tests, this is a preliminary patch and based on the community feedback, we expect more updates to follow. Total Memory Encryption (TME) 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 virConnectGetDomainCapabilities which calls virNodeGetMKTMEInfo. This returns an XML document that includes the following: <feature> ... <mktme supported='yes'> <keys_supported> </keys_supported> </mktme> </feature> 2. If MKTME is supported management tool requests to start a guest calling virCreateXML(). The xml would include: <launchSecurity type='mktme'> <id>m0</id> <key_type>user</key_type> <key>samplekey</key> <encryption_algorithm>aes-xts-128</encryption_algorithm> </launchSecurity> 3. Libvirt makes system call with the provided information to generate a key 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: # Qemu ...\ -machine pc,memory-encryption=m0 -object mktme-guest,id=m0,handle=${serial} Intel MKTME spec: https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total... TODO: Add tests for launch security of type mktme. WIP: Qemu and KVM patch to support Intel MKTME are in the process of upstreaming. The complete git tree is available at: https://github.com/larkinscarvalho/libvirt/tree/intel-mktme-patch-series Larkins Carvalho (7): qemu: provide support to query the MKTME capability conf: Add MKTME feature in domain capabilities libvirt: add new public API to get MKTME Info remote: implement the remote protocol for virNodeMKTMEInfo() qemu: Add support to get the MKTME info conf: introduce launchSecurity element type mktme in domain qemu: add support to launch MKTME guest docs/formatdomain.html.in | 64 +- docs/formatdomaincaps.html.in | 20 + docs/schemas/domaincaps.rng | 14 + docs/schemas/domaincommon.rng | 87 +- include/libvirt/libvirt-host.h | 18 + src/conf/domain_capabilities.c | 30 + src/conf/domain_capabilities.h | 12 + src/conf/domain_conf.c | 112 +- src/conf/domain_conf.h | 14 + src/conf/virconftypes.h | 3 + src/driver-hypervisor.h | 7 + src/libvirt-host.c | 49 + src/libvirt_private.syms | 4 + src/libvirt_public.syms | 5 + src/qemu/qemu_capabilities.c | 140 +- 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 | 10 + src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 61 + src/qemu/qemu_monitor_json.h | 3 + src/remote/remote_daemon_dispatch.c | 44 + src/remote/remote_driver.c | 41 +- src/remote/remote_protocol.x | 21 +- src/remote_protocol-structs | 12 + src/util/Makefile.inc.am | 2 + src/util/virmktme.c | 127 ++ src/util/virmktme.h | 34 + .../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 + .../domaincapsschemadata/qemu_4.0.0.s390x.xml | 1 + .../qemu_4.0.0.x86_64.xml | 1 + .../qemu_5.3.0.x86_64.xml | 164 ++ tests/domaincapstest.c | 5 + .../caps_5.3.0.x86_64.xml | 1377 +++++++++++++++++ 59 files changed, 2579 insertions(+), 41 deletions(-) create mode 100644 src/util/virmktme.c create mode 100644 src/util/virmktme.h create mode 100644 tests/domaincapsschemadata/qemu_5.3.0.x86_64.xml create mode 100644 tests/qemucapabilitiesdata/caps_5.3.0.x86_64.xml

This patch adds support to query the MKTME capability from the qemu. --- src/conf/domain_capabilities.c | 10 ++++++ src/conf/domain_capabilities.h | 11 ++++++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 36 ++++++++++++++++++++ src/qemu/qemu_capabilities.h | 4 +++ src/qemu/qemu_capspriv.h | 4 +++ src/qemu/qemu_monitor.c | 10 ++++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 61 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 10 files changed, 143 insertions(+) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 2e7e1c206b..db39c39120 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -79,6 +79,16 @@ virSEVCapabilitiesFree(virSEVCapability *cap) } +void +virMKTMECapabilitiesFree(virMKTMECapability *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 cd09d50cee..a6ad849950 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -150,6 +150,12 @@ struct _virSEVCapability { unsigned int reduced_phys_bits; }; +typedef struct _virMKTMECapability virMKTMECapability; +typedef virMKTMECapability *virMKTMECapabilityPtr; +struct _virMKTMECapability { + unsigned int keys_supported; +}; + struct _virDomainCaps { virObjectLockable parent; @@ -222,4 +228,9 @@ virSEVCapabilitiesFree(virSEVCapability *capabilities); VIR_DEFINE_AUTOPTR_FUNC(virSEVCapability, virSEVCapabilitiesFree); +void +virMKTMECapabilitiesFree(virMKTMECapability *capabilities); + +VIR_DEFINE_AUTOPTR_FUNC(virMKTMECapability, virMKTMECapabilitiesFree); + #endif /* LIBVIRT_DOMAIN_CAPABILITIES_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 909975750c..1b83e44b15 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -189,6 +189,7 @@ virDomainCapsEnumClear; virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; +virMKTMECapabilitiesFree; virSEVCapabilitiesFree; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a827bd24e3..49ee802479 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", ); @@ -595,6 +596,8 @@ struct _virQEMUCaps { virSEVCapability *sevCapabilities; + virMKTMECapability *mktmeCapabilities; + virQEMUCapsHostCPUData kvmCPU; virQEMUCapsHostCPUData tcgCPU; }; @@ -1113,6 +1116,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "virtio-scsi-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL }, { "virtio-serial-pci-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL }, { "virtio-serial-pci-non-transitional", QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL }, + { "mktme-guest", QEMU_CAPS_MKTME_GUEST }, }; static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = { @@ -2103,6 +2107,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps) } +virMKTMECapabilityPtr +virQEMUCapsGetMKTMECapabilities(virQEMUCapsPtr qemuCaps) +{ + return qemuCaps->mktmeCapabilities; +} + + static int virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon) @@ -2811,6 +2822,29 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCapsPtr qemuCaps, } +static int +virQEMUCapsProbeQMPMKTMECapabilities(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon) +{ + int rc = -1; + virMKTMECapability *caps = NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MKTME_GUEST)) + return 0; + if ((rc = qemuMonitorGetMKTMECapabilities(mon, &caps)) < 0) + return -1; + + if (rc == 0) { + virQEMUCapsClear(qemuCaps, QEMU_CAPS_MKTME_GUEST); + return 0; + } + + virMKTMECapabilitiesFree(qemuCaps->mktmeCapabilities); + qemuCaps->mktmeCapabilities = caps; + return 0; +} + + bool virQEMUCapsCPUFilterFeatures(const char *name, void *opaque) @@ -4417,6 +4451,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, return -1; if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0) return -1; + if (virQEMUCapsProbeQMPMKTMECapabilities(qemuCaps, mon) < 0) + return -1; virQEMUCapsInitProcessCaps(qemuCaps); 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,... */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; @@ -644,6 +645,9 @@ bool virQEMUCapsCPUFilterFeatures(const char *name, virSEVCapabilityPtr virQEMUCapsGetSEVCapabilities(virQEMUCapsPtr qemuCaps); +virMKTMECapabilityPtr +virQEMUCapsGetMKTMECapabilities(virQEMUCapsPtr qemuCaps); + virArch virQEMUCapsArchFromString(const char *arch); const char *virQEMUCapsArchToString(virArch arch); diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h index 2d059bee8c..4e1559d13f 100644 --- a/src/qemu/qemu_capspriv.h +++ b/src/qemu/qemu_capspriv.h @@ -95,6 +95,10 @@ void virQEMUCapsSetSEVCapabilities(virQEMUCapsPtr qemuCaps, virSEVCapability *capabilities); +void +virQEMUCapsSetMKTMECapabilities(virQEMUCapsPtr qemuCaps, + virMKTMECapability *capabilities); + int virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index e1fcbac13f..918a9d1c5d 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3922,6 +3922,16 @@ qemuMonitorGetSEVCapabilities(qemuMonitorPtr mon, } +int +qemuMonitorGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities) +{ + QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONGetMKTMECapabilities(mon, capabilities); +} + + int qemuMonitorNBDServerStart(qemuMonitorPtr mon, const char *host, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 9242d37407..ef4f5326bc 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -761,6 +761,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon, int qemuMonitorGetSEVCapabilities(qemuMonitorPtr mon, virSEVCapability **capabilities); +int qemuMonitorGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities); + typedef enum { QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0, QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 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..eca4d82c24 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6654,6 +6654,67 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon, return ret; } +/** + * qemuMonitorJSONGetMKTMECapabilities: + * @mon: qemu monitor object + * @capabilities: pointer to pointer to a MKTME capability structure to be filled + * + * This function queries and fills in Intel's MKTME platform-specific data. + * + * Returns -1 on error, 0 if MKTME is not supported, and 1 if MKTME is supported on + * the platform. + */ +int +qemuMonitorJSONGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities) +{ + int ret = -1; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr caps; + unsigned int keys_supported; + VIR_AUTOPTR(virMKTMECapability) capability = NULL; + + *capabilities = NULL; + + /* Query may change*/ + if (!(cmd = qemuMonitorJSONMakeCommand("query-mktme-capabilities", + NULL))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONHasError(reply, "GenericError")) { + ret = 0; + goto cleanup; + } + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + caps = virJSONValueObjectGetObject(reply, "return"); + + if (virJSONValueObjectGetNumberUint(caps, "keys_supported", &keys_supported) < 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 = keys_supported; + VIR_STEAL_PTR(*capabilities, capability); + ret = 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..5094d91195 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -158,6 +158,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon, int qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon, virSEVCapability **capabilities); +int qemuMonitorJSONGetMKTMECapabilities(qemuMonitorPtr mon, + virMKTMECapability **capabilities); + int qemuMonitorJSONMigrate(qemuMonitorPtr mon, unsigned int flags, const char *uri); -- 2.21.0.windows.1

Expose mktme capability info to hypervisor. If mktme is supported, support launching of encrypted VM on Intel platform. Also, save the copy of mktme info into qemuCaps cache. --- docs/formatdomaincaps.html.in | 20 + docs/schemas/domaincaps.rng | 14 + src/conf/domain_capabilities.c | 20 + src/conf/domain_capabilities.h | 1 + src/qemu/qemu_capabilities.c | 104 +- .../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 + .../domaincapsschemadata/qemu_4.0.0.s390x.xml | 1 + .../qemu_4.0.0.x86_64.xml | 1 + .../qemu_5.3.0.x86_64.xml | 164 ++ tests/domaincapstest.c | 5 + .../caps_5.3.0.x86_64.xml | 1377 +++++++++++++++++ 34 files changed, 1730 insertions(+), 1 deletion(-) create mode 100644 tests/domaincapsschemadata/qemu_5.3.0.x86_64.xml create mode 100644 tests/qemucapabilitiesdata/caps_5.3.0.x86_64.xml diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in index b31b1729f4..3da31b3a52 100644 --- a/docs/formatdomaincaps.html.in +++ b/docs/formatdomaincaps.html.in @@ -530,5 +530,25 @@ address space. The number of bits we lose is hypervisor dependent.</dd> </dl> + <h4><a id="elementsMKTME">MKTME capabilities</a></h4> + + <p> + Intel Multi-key Total Memory Encryption (MKTME) capabilities are exposed under + the <code>mktme</code> element. + Total Memory Encryption (TME) ��� 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. + </p> + + <p> + For more details on MKTME feature see: + <a href="https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total-Memory-Encryption-Spec.pdf">MKTME spec</a> + </p> + + <dl> + <dt><code>keys_supported</code></dt> + <dd>When mktme is enabled, platform provides information about the total number of keys supported</dd> + </dl> + </body> </html> 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 @@ <optional> <ref name='sev'/> </optional> + <optional> + <ref name='mktme'/> + </optional> </element> </define> @@ -236,6 +239,17 @@ </element> </define> + <define name='mktme'> + <element name='mktme'> + <ref name='supported'/> + <optional> + <element name='keys_supported'> + <data type='unsignedInt'/> + </element> + </optional> + </element> + </define> + <define name='value'> <zeroOrMore> <element name='value'> diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index db39c39120..c150a9facc 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -99,6 +99,7 @@ virDomainCapsDispose(void *obj) virObjectUnref(caps->cpu.custom); virCPUDefFree(caps->cpu.hostModel); virSEVCapabilitiesFree(caps->sev); + virMKTMECapabilitiesFree(caps->mktme); virDomainCapsStringValuesFree(&caps->os.loader.values); } @@ -604,6 +605,24 @@ virDomainCapsFeatureSEVFormat(virBufferPtr buf, } +static void +virDomainCapsFeatureMKTMEFormat(virBufferPtr buf, + virMKTMECapabilityPtr const mktme) +{ + if (!mktme) { + virBufferAddLit(buf, "<mktme supported='no'/>\n"); + } else { + virBufferAddLit(buf, "<mktme supported='yes'>\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<keys_supported>%d</keys_supported>\n", mktme->keys_supported); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</mktme>\n"); + } + + return; +} + + char * virDomainCapsFormat(virDomainCapsPtr const caps) { @@ -646,6 +665,7 @@ virDomainCapsFormat(virDomainCapsPtr const caps) FORMAT_SINGLE("vmcoreinfo", caps->vmcoreinfo); FORMAT_SINGLE("genid", caps->genid); virDomainCapsFeatureSEVFormat(&buf, caps->sev); + virDomainCapsFeatureMKTMEFormat(&buf, caps->mktme); virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</features>\n"); diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index a6ad849950..6803a5ca0b 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -180,6 +180,7 @@ struct _virDomainCaps { virTristateBool vmcoreinfo; virTristateBool genid; virSEVCapabilityPtr sev; + virMKTMECapabilityPtr mktme; /* add new domain features here */ }; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 49ee802479..54b648be4f 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1549,6 +1549,22 @@ virQEMUCapsSEVInfoCopy(virSEVCapabilityPtr *dst, } +static int +virQEMUCapsMKTMEInfoCopy(virMKTMECapabilityPtr *dst, + virMKTMECapabilityPtr src) +{ + VIR_AUTOPTR(virMKTMECapability) tmp = NULL; + + if (VIR_ALLOC(tmp) < 0) + return -1; + + tmp->keys_supported = src->keys_supported; + + VIR_STEAL_PTR(*dst, tmp); + return 0; +} + + virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) { virQEMUCapsPtr ret = virQEMUCapsNew(); @@ -1619,6 +1635,11 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) qemuCaps->sevCapabilities) < 0) goto error; + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MKTME_GUEST) && + virQEMUCapsMKTMEInfoCopy(&ret->mktmeCapabilities, + qemuCaps->mktmeCapabilities) < 0) + goto error; + return ret; error: @@ -3474,6 +3495,36 @@ virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt) } +static int +virQEMUCapsParseMKTMEInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt) +{ + VIR_AUTOPTR(virMKTMECapability) mktme = NULL; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MKTME_GUEST)) + return 0; + + if (virXPathBoolean("boolean(./mktme)", ctxt) == 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_supported) < 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; +} + + /* * Parsing a doc that looks like * @@ -3726,6 +3777,9 @@ virQEMUCapsLoadCache(virArch hostArch, if (virQEMUCapsParseSEVInfo(qemuCaps, ctxt) < 0) goto cleanup; + if (virQEMUCapsParseMKTMEInfo(qemuCaps, ctxt) < 0) + goto cleanup; + virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM); virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU); @@ -3863,6 +3917,19 @@ virQEMUCapsFormatSEVInfo(virQEMUCapsPtr qemuCaps, virBufferPtr buf) } +static void +virQEMUCapsFormatMKTMEInfo(virQEMUCapsPtr qemuCaps, virBufferPtr buf) +{ + virMKTMECapabilityPtr mktme = virQEMUCapsGetMKTMECapabilities(qemuCaps); + + virBufferAddLit(buf, "<mktme>\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<keys_supported>%u</keys_supported>\n", mktme->keys_supported); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</mktme>\n"); +} + + char * virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) { @@ -3947,6 +4014,9 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps) if (qemuCaps->sevCapabilities) virQEMUCapsFormatSEVInfo(qemuCaps, &buf); + if (qemuCaps->mktmeCapabilities) + virQEMUCapsFormatMKTMEInfo(qemuCaps, &buf); + if (qemuCaps->kvmSupportsNesting) virBufferAddLit(&buf, "<kvmSupportsNesting/>\n"); @@ -5406,6 +5476,37 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCapsPtr qemuCaps, } +/** +* virQEMUCapsFillDomainFeatureMKTMECaps: +* @qemuCaps: QEMU capabilities +* @domCaps: domain capabilities +* +* Take the information about MKTME capabilities that has been obtained +* using the 'query-mktme-capabilities' QMP command and stored in @qemuCaps +* and convert it to a form suitable for @domCaps. +* +* Returns: 0 on success, -1 on failure +*/ +static int +virQEMUCapsFillDomainFeatureMKTMECaps(virQEMUCapsPtr qemuCaps, + virDomainCapsPtr domCaps) +{ + virMKTMECapability *cap = qemuCaps->mktmeCapabilities; + VIR_AUTOPTR(virMKTMECapability) mktme = NULL; + + if (!cap) + return 0; + + if (VIR_ALLOC(mktme) < 0) + return -1; + + mktme->keys_supported = cap->keys_supported; + VIR_STEAL_PTR(domCaps->mktme, mktme); + + return 0; +} + + int virQEMUCapsFillDomainCaps(virCapsPtr caps, virDomainCapsPtr domCaps, @@ -5450,7 +5551,8 @@ virQEMUCapsFillDomainCaps(virCapsPtr caps, virQEMUCapsFillDomainDeviceVideoCaps(qemuCaps, video) < 0 || virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0 || virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps) < 0 || - virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps) < 0) + virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps) < 0 || + virQEMUCapsFillDomainFeatureMKTMECaps(qemuCaps, domCaps) < 0) return -1; return 0; diff --git a/tests/domaincapsschemadata/bhyve_basic.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/empty.xml b/tests/domaincapsschemadata/empty.xml index 6c3f5f54fd..2ebefe8a05 100644 --- a/tests/domaincapsschemadata/empty.xml +++ b/tests/domaincapsschemadata/empty.xml @@ -12,5 +12,6 @@ </devices> <features> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/libxl-xenfv.xml b/tests/domaincapsschemadata/libxl-xenfv.xml index 4efc137c97..09c04374b9 100644 --- a/tests/domaincapsschemadata/libxl-xenfv.xml +++ b/tests/domaincapsschemadata/libxl-xenfv.xml @@ -75,5 +75,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/libxl-xenpv.xml b/tests/domaincapsschemadata/libxl-xenpv.xml index 70e598fe9e..aac2a2cba6 100644 --- a/tests/domaincapsschemadata/libxl-xenpv.xml +++ b/tests/domaincapsschemadata/libxl-xenpv.xml @@ -65,5 +65,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_1.7.0.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.12.0-virt.aarch64.xml b/tests/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 @@ <vmcoreinfo supported='yes'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.12.0.ppc64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.12.0.s390x.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.12.0.x86_64.xml b/tests/domaincapsschemadata/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 @@ <cbitpos>47</cbitpos> <reducedPhysBits>1</reducedPhysBits> </sev> + <mktme supported='no'/> </features> </domainCapabilities> 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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.6.0.aarch64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.6.0.ppc64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.6.0.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.7.0.s390x.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.8.0-tcg.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.8.0.s390x.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.8.0.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.9.0-q35.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='yes'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.9.0-tcg.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='yes'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_2.9.0.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='yes'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_3.0.0.s390x.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_3.1.0.x86_64.xml b/tests/domaincapsschemadata/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 @@ <vmcoreinfo supported='yes'/> <genid supported='yes'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_4.0.0.s390x.xml b/tests/domaincapsschemadata/qemu_4.0.0.s390x.xml index edade48ad0..e09610572c 100644 --- a/tests/domaincapsschemadata/qemu_4.0.0.s390x.xml +++ b/tests/domaincapsschemadata/qemu_4.0.0.s390x.xml @@ -194,5 +194,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml b/tests/domaincapsschemadata/qemu_4.0.0.x86_64.xml index cba841d844..656c70133c 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 @@ <vmcoreinfo supported='yes'/> <genid supported='yes'/> <sev supported='no'/> + <mktme supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsschemadata/qemu_5.3.0.x86_64.xml b/tests/domaincapsschemadata/qemu_5.3.0.x86_64.xml new file mode 100644 index 0000000000..5d86a249c9 --- /dev/null +++ b/tests/domaincapsschemadata/qemu_5.3.0.x86_64.xml @@ -0,0 +1,164 @@ +<domainCapabilities> + <path>/usr/bin/qemu-system-x86_64</path> + <domain>kvm</domain> + <machine>pc-i440fx-5.3</machine> + <arch>x86_64</arch> + <vcpu max='255'/> + <iothreads supported='yes'/> + <os supported='yes'> + <enum name='firmware'> + <value>bios</value> + <value>efi</value> + </enum> + <loader supported='yes'> + <value>/usr/share/AAVMF/AAVMF_CODE.fd</value> + <value>/usr/share/AAVMF/AAVMF32_CODE.fd</value> + <value>/usr/share/OVMF/OVMF_CODE.fd</value> + <enum name='type'> + <value>rom</value> + <value>pflash</value> + </enum> + <enum name='readonly'> + <value>yes</value> + <value>no</value> + </enum> + <enum name='secure'> + <value>no</value> + </enum> + </loader> + </os> + <cpu> + <mode name='host-passthrough' supported='yes'/> + <mode name='host-model' supported='yes'> + <model fallback='forbid'>Skylake-Client-IBRS</model> + <vendor>Intel</vendor> + <feature policy='require' name='ss'/> + <feature policy='require' name='vmx'/> + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='tsc_adjust'/> + <feature policy='require' name='clflushopt'/> + <feature policy='require' name='umip'/> + <feature policy='require' name='ssbd'/> + <feature policy='require' name='xsaves'/> + <feature policy='require' name='pdpe1gb'/> + <feature policy='require' name='invtsc'/> + </mode> + <mode name='custom' supported='yes'> + <model usable='yes'>qemu64</model> + <model usable='yes'>qemu32</model> + <model usable='no'>phenom</model> + <model usable='yes'>pentium3</model> + <model usable='yes'>pentium2</model> + <model usable='yes'>pentium</model> + <model usable='yes'>n270</model> + <model usable='yes'>kvm64</model> + <model usable='yes'>kvm32</model> + <model usable='yes'>coreduo</model> + <model usable='yes'>core2duo</model> + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> + <model usable='yes'>Skylake-Client-IBRS</model> + <model usable='yes'>Skylake-Client</model> + <model usable='yes'>SandyBridge-IBRS</model> + <model usable='yes'>SandyBridge</model> + <model usable='yes'>Penryn</model> + <model usable='no'>Opteron_G5</model> + <model usable='no'>Opteron_G4</model> + <model usable='no'>Opteron_G3</model> + <model usable='yes'>Opteron_G2</model> + <model usable='yes'>Opteron_G1</model> + <model usable='yes'>Nehalem-IBRS</model> + <model usable='yes'>Nehalem</model> + <model usable='yes'>IvyBridge-IBRS</model> + <model usable='yes'>IvyBridge</model> + <model usable='no'>Icelake-Server</model> + <model usable='no'>Icelake-Client</model> + <model usable='yes'>Haswell-noTSX-IBRS</model> + <model usable='yes'>Haswell-noTSX</model> + <model usable='yes'>Haswell-IBRS</model> + <model usable='yes'>Haswell</model> + <model usable='no'>EPYC-IBPB</model> + <model usable='no'>EPYC</model> + <model usable='yes'>Conroe</model> + <model usable='no'>Cascadelake-Server</model> + <model usable='yes'>Broadwell-noTSX-IBRS</model> + <model usable='yes'>Broadwell-noTSX</model> + <model usable='yes'>Broadwell-IBRS</model> + <model usable='yes'>Broadwell</model> + <model usable='yes'>486</model> + </mode> + </cpu> + <devices> + <disk supported='yes'> + <enum name='diskDevice'> + <value>disk</value> + <value>cdrom</value> + <value>floppy</value> + <value>lun</value> + </enum> + <enum name='bus'> + <value>ide</value> + <value>fdc</value> + <value>scsi</value> + <value>virtio</value> + <value>usb</value> + <value>sata</value> + </enum> + <enum name='model'> + <value>virtio</value> + <value>virtio-transitional</value> + <value>virtio-non-transitional</value> + </enum> + </disk> + <graphics supported='yes'> + <enum name='type'> + <value>sdl</value> + <value>vnc</value> + <value>spice</value> + </enum> + </graphics> + <video supported='yes'> + <enum name='modelType'> + <value>vga</value> + <value>cirrus</value> + <value>vmvga</value> + <value>qxl</value> + <value>virtio</value> + </enum> + </video> + <hostdev supported='yes'> + <enum name='mode'> + <value>subsystem</value> + </enum> + <enum name='startupPolicy'> + <value>default</value> + <value>mandatory</value> + <value>requisite</value> + <value>optional</value> + </enum> + <enum name='subsysType'> + <value>usb</value> + <value>pci</value> + <value>scsi</value> + </enum> + <enum name='capsType'/> + <enum name='pciBackend'> + <value>default</value> + <value>kvm</value> + <value>vfio</value> + </enum> + </hostdev> + </devices> + <features> + <gic supported='no'/> + <vmcoreinfo supported='yes'/> + <genid supported='yes'/> + <sev supported='no'/> + <mktme supported='yes'> + <keys_supported>15</keys_supported> + </mktme> + </features> +</domainCapabilities> diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index 5dba1d1ba4..357b140cf8 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -453,6 +453,11 @@ mymain(void) DO_TEST_QEMU("4.0.0", "caps_4.0.0", "/usr/bin/qemu-system-s390x", NULL, "s390x", VIR_DOMAIN_VIRT_KVM); + + DO_TEST_QEMU("5.3.0", "caps_5.3.0", + "/usr/bin/qemu-system-x86_64", NULL, + "x86_64", VIR_DOMAIN_VIRT_KVM); + virObjectUnref(cfg); virFileWrapperClearPrefixes(); diff --git a/tests/qemucapabilitiesdata/caps_5.3.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.3.0.x86_64.xml new file mode 100644 index 0000000000..d31f39bb24 --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_5.3.0.x86_64.xml @@ -0,0 +1,1377 @@ +<qemuCaps> + <qemuctime>0</qemuctime> + <selfctime>0</selfctime> + <selfvers>0</selfvers> + <flag name='kvm'/> + <flag name='no-hpet'/> + <flag name='spice'/> + <flag name='hda-duplex'/> + <flag name='ccid-emulated'/> + <flag name='ccid-passthru'/> + <flag name='virtio-tx-alg'/> + <flag name='virtio-blk-pci.ioeventfd'/> + <flag name='sga'/> + <flag name='virtio-blk-pci.event_idx'/> + <flag name='virtio-net-pci.event_idx'/> + <flag name='piix3-usb-uhci'/> + <flag name='piix4-usb-uhci'/> + <flag name='usb-ehci'/> + <flag name='ich9-usb-ehci1'/> + <flag name='vt82c686b-usb-uhci'/> + <flag name='pci-ohci'/> + <flag name='usb-redir'/> + <flag name='usb-hub'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='scsi-disk.channel'/> + <flag name='scsi-block'/> + <flag name='hda-micro'/> + <flag name='dump-guest-memory'/> + <flag name='nec-usb-xhci'/> + <flag name='lsi'/> + <flag name='virtio-scsi-pci'/> + <flag name='blockio'/> + <flag name='disable-s3'/> + <flag name='disable-s4'/> + <flag name='usb-redir.filter'/> + <flag name='ide-drive.wwn'/> + <flag name='scsi-disk.wwn'/> + <flag name='seccomp-sandbox'/> + <flag name='reboot-timeout'/> + <flag name='vnc'/> + <flag name='qxl'/> + <flag name='VGA'/> + <flag name='cirrus-vga'/> + <flag name='vmware-svga'/> + <flag name='device-video-primary'/> + <flag name='usb-serial'/> + <flag name='nbd-server'/> + <flag name='virtio-rng'/> + <flag name='rng-random'/> + <flag name='rng-egd'/> + <flag name='megasas'/> + <flag name='tpm-passthrough'/> + <flag name='tpm-tis'/> + <flag name='pci-bridge'/> + <flag name='vfio-pci'/> + <flag name='mem-merge'/> + <flag name='drive-discard'/> + <flag name='dmi-to-pci-bridge'/> + <flag name='i440fx-pci-hole64-size'/> + <flag name='q35-pci-hole64-size'/> + <flag name='usb-storage'/> + <flag name='usb-storage.removable'/> + <flag name='ich9-intel-hda'/> + <flag name='kvm-pit-lost-tick-policy'/> + <flag name='boot-strict'/> + <flag name='pvpanic'/> + <flag name='spice-file-xfer-disable'/> + <flag name='usb-kbd'/> + <flag name='msg-timestamp'/> + <flag name='active-commit'/> + <flag name='change-backing-file'/> + <flag name='memory-backend-ram'/> + <flag name='numa'/> + <flag name='memory-backend-file'/> + <flag name='usb-audio'/> + <flag name='rtc-reset-reinjection'/> + <flag name='splash-timeout'/> + <flag name='iothread'/> + <flag name='migrate-rdma'/> + <flag name='drive-iotune-max'/> + <flag name='VGA.vgamem_mb'/> + <flag name='vmware-svga.vgamem_mb'/> + <flag name='qxl.vgamem_mb'/> + <flag name='pc-dimm'/> + <flag name='machine-vmport-opt'/> + <flag name='aes-key-wrap'/> + <flag name='dea-key-wrap'/> + <flag name='pci-serial'/> + <flag name='vhost-user-multiqueue'/> + <flag name='migration-event'/> + <flag name='ioh3420'/> + <flag name='x3130-upstream'/> + <flag name='xio3130-downstream'/> + <flag name='rtl8139'/> + <flag name='e1000'/> + <flag name='virtio-net'/> + <flag name='gic-version'/> + <flag name='incoming-defer'/> + <flag name='virtio-gpu'/> + <flag name='virtio-gpu.virgl'/> + <flag name='virtio-keyboard'/> + <flag name='virtio-mouse'/> + <flag name='virtio-tablet'/> + <flag name='virtio-input-host'/> + <flag name='chardev-file-append'/> + <flag name='ich9-disable-s3'/> + <flag name='ich9-disable-s4'/> + <flag name='vserport-change-event'/> + <flag name='virtio-balloon-pci.deflate-on-oom'/> + <flag name='mptsas1068'/> + <flag name='spice-gl'/> + <flag name='qxl.vram64_size_mb'/> + <flag name='chardev-logfile'/> + <flag name='debug-threads'/> + <flag name='secret'/> + <flag name='pxb'/> + <flag name='pxb-pcie'/> + <flag name='nec-usb-xhci-ports'/> + <flag name='virtio-scsi-pci.iothread'/> + <flag name='name-guest'/> + <flag name='qxl.max_outputs'/> + <flag name='spice-unix'/> + <flag name='drive-detect-zeroes'/> + <flag name='tls-creds-x509'/> + <flag name='intel-iommu'/> + <flag name='smm'/> + <flag name='virtio-pci-disable-legacy'/> + <flag name='query-hotpluggable-cpus'/> + <flag name='virtio-net.rx_queue_size'/> + <flag name='virtio-vga'/> + <flag name='drive-iotune-max-length'/> + <flag name='ivshmem-plain'/> + <flag name='ivshmem-doorbell'/> + <flag name='query-qmp-schema'/> + <flag name='gluster.debug_level'/> + <flag name='vhost-scsi'/> + <flag name='drive-iotune-group'/> + <flag name='query-cpu-model-expansion'/> + <flag name='virtio-net.host_mtu'/> + <flag name='spice-rendernode'/> + <flag name='nvdimm'/> + <flag name='pcie-root-port'/> + <flag name='query-cpu-definitions'/> + <flag name='block-write-threshold'/> + <flag name='query-named-block-nodes'/> + <flag name='cpu-cache'/> + <flag name='qemu-xhci'/> + <flag name='kernel-irqchip'/> + <flag name='kernel-irqchip.split'/> + <flag name='intel-iommu.intremap'/> + <flag name='intel-iommu.caching-mode'/> + <flag name='intel-iommu.eim'/> + <flag name='intel-iommu.device-iotlb'/> + <flag name='virtio.iommu_platform'/> + <flag name='virtio.ats'/> + <flag name='loadparm'/> + <flag name='vnc-multi-servers'/> + <flag name='virtio-net.tx_queue_size'/> + <flag name='chardev-reconnect'/> + <flag name='virtio-gpu.max_outputs'/> + <flag name='vxhs'/> + <flag name='virtio-blk.num-queues'/> + <flag name='vmcoreinfo'/> + <flag name='numa.dist'/> + <flag name='disk-share-rw'/> + <flag name='iscsi.password-secret'/> + <flag name='isa-serial'/> + <flag name='dump-completed'/> + <flag name='qcow2-luks'/> + <flag name='pcie-pci-bridge'/> + <flag name='seccomp-blacklist'/> + <flag name='query-cpus-fast'/> + <flag name='disk-write-cache'/> + <flag name='nbd-tls'/> + <flag name='tpm-crb'/> + <flag name='pr-manager-helper'/> + <flag name='qom-list-properties'/> + <flag name='memory-backend-file.discard-data'/> + <flag name='sdl-gl'/> + <flag name='screendump_device'/> + <flag name='hda-output'/> + <flag name='blockdev-del'/> + <flag name='vmgenid'/> + <flag name='vhost-vsock'/> + <flag name='chardev-fd-pass'/> + <flag name='tpm-emulator'/> + <flag name='mch'/> + <flag name='mch.extended-tseg-mbytes'/> + <flag name='usb-storage.werror'/> + <flag name='egl-headless'/> + <flag name='vfio-pci.display'/> + <flag name='memory-backend-memfd'/> + <flag name='memory-backend-memfd.hugetlb'/> + <flag name='iothread.poll-max-ns'/> + <flag name='egl-headless.rendernode'/> + <flag name='memory-backend-file.align'/> + <flag name='memory-backend-file.pmem'/> + <flag name='nvdimm.unarmed'/> + <flag name='scsi-disk.device_id'/> + <flag name='virtio-pci-non-transitional'/> + <flag name='overcommit'/> + <flag name='query-current-machine'/> + <flag name='mktme-guest'/> + <version>4000000</version> + <kvmVersion>0</kvmVersion> + <microcodeVersion>43100758</microcodeVersion> + <package>v4.0.0</package> + <arch>x86_64</arch> + <hostCPU type='kvm' model='base' migratability='yes'> + <property name='phys-bits' type='number' value='0'/> + <property name='core-id' type='number' value='-1'/> + <property name='xlevel' type='number' value='2147483656'/> + <property name='cmov' type='boolean' value='true' migratable='yes'/> + <property name='ia64' type='boolean' value='false'/> + <property name='ssb-no' type='boolean' value='false'/> + <property name='aes' type='boolean' value='true' migratable='yes'/> + <property name='mmx' type='boolean' value='true' migratable='yes'/> + <property name='rdpid' type='boolean' value='false'/> + <property name='arat' type='boolean' value='true' migratable='yes'/> + <property name='gfni' type='boolean' value='false'/> + <property name='ibrs-all' type='boolean' value='false'/> + <property name='pause-filter' type='boolean' value='false'/> + <property name='xsavec' type='boolean' value='true' migratable='yes'/> + <property name='intel-pt' type='boolean' value='false'/> + <property name='hv-frequencies' type='boolean' value='false'/> + <property name='tsc-frequency' type='number' value='0'/> + <property name='xd' type='boolean' value='true' migratable='yes'/> + <property name='x-intel-pt-auto-level' type='boolean' value='true' migratable='yes'/> + <property name='hv-vendor-id' type='string' value=''/> + <property name='kvm-asyncpf' type='boolean' value='true' migratable='yes'/> + <property name='kvm_asyncpf' type='boolean' value='true' migratable='yes'/> + <property name='perfctr_core' type='boolean' value='false'/> + <property name='perfctr-core' type='boolean' value='false'/> + <property name='mpx' type='boolean' value='true' migratable='yes'/> + <property name='pbe' type='boolean' value='false'/> + <property name='decodeassists' type='boolean' value='false'/> + <property name='avx512cd' type='boolean' value='false'/> + <property name='sse4_1' type='boolean' value='true' migratable='yes'/> + <property name='sse4.1' type='boolean' value='true' migratable='yes'/> + <property name='sse4-1' type='boolean' value='true' migratable='yes'/> + <property name='family' type='number' value='6'/> + <property name='legacy-cache' type='boolean' value='true' migratable='yes'/> + <property name='host-phys-bits-limit' type='number' value='0'/> + <property name='vmware-cpuid-freq' type='boolean' value='true' migratable='yes'/> + <property name='wbnoinvd' type='boolean' value='false'/> + <property name='avx512f' type='boolean' value='false'/> + <property name='msr' type='boolean' value='true' migratable='yes'/> + <property name='mce' type='boolean' value='true' migratable='yes'/> + <property name='mca' type='boolean' value='true' migratable='yes'/> + <property name='hv-runtime' type='boolean' value='false'/> + <property name='xcrypt' type='boolean' value='false'/> + <property name='thread-id' type='number' value='-1'/> + <property name='min-level' type='number' value='13'/> + <property name='xgetbv1' type='boolean' value='true' migratable='yes'/> + <property name='cid' type='boolean' value='false'/> + <property name='hv-relaxed' type='boolean' value='false'/> + <property name='hv-crash' type='boolean' value='false'/> + <property name='ds' type='boolean' value='false'/> + <property name='fxsr' type='boolean' value='true' migratable='yes'/> + <property name='xsaveopt' type='boolean' value='true' migratable='yes'/> + <property name='xtpr' type='boolean' value='false'/> + <property name='hv-evmcs' type='boolean' value='false'/> + <property name='avx512vl' type='boolean' value='false'/> + <property name='avx512-vpopcntdq' type='boolean' value='false'/> + <property name='phe' type='boolean' value='false'/> + <property name='extapic' type='boolean' value='false'/> + <property name='3dnowprefetch' type='boolean' value='true' migratable='yes'/> + <property name='avx512vbmi2' type='boolean' value='false'/> + <property name='cr8legacy' type='boolean' value='false'/> + <property name='stibp' type='boolean' value='false'/> + <property name='cpuid-0xb' type='boolean' value='true' migratable='yes'/> + <property name='xcrypt-en' type='boolean' value='false'/> + <property name='kvm_pv_eoi' type='boolean' value='true' migratable='yes'/> + <property name='apic-id' type='number' value='4294967295'/> + <property name='rsba' type='boolean' value='false'/> + <property name='pn' type='boolean' value='false'/> + <property name='dca' type='boolean' value='false'/> + <property name='vendor' type='string' value='GenuineIntel'/> + <property name='hv-ipi' type='boolean' value='false'/> + <property name='pku' type='boolean' value='false'/> + <property name='smx' type='boolean' value='false'/> + <property name='cmp_legacy' type='boolean' value='false'/> + <property name='cmp-legacy' type='boolean' value='false'/> + <property name='node-id' type='number' value='-1'/> + <property name='avx512-4fmaps' type='boolean' value='false'/> + <property name='vmcb_clean' type='boolean' value='false'/> + <property name='vmcb-clean' type='boolean' value='false'/> + <property name='3dnowext' type='boolean' value='false'/> + <property name='amd-no-ssb' type='boolean' value='false'/> + <property name='hle' type='boolean' value='true' migratable='yes'/> + <property name='npt' type='boolean' value='false'/> + <property name='rdctl-no' type='boolean' value='false'/> + <property name='memory' type='string' value='/machine/unattached/system[0]'/> + <property name='clwb' type='boolean' value='false'/> + <property name='lbrv' type='boolean' value='false'/> + <property name='adx' type='boolean' value='true' migratable='yes'/> + <property name='ss' type='boolean' value='true' migratable='yes'/> + <property name='pni' type='boolean' value='true' migratable='yes'/> + <property name='svm_lock' type='boolean' value='false'/> + <property name='svm-lock' type='boolean' value='false'/> + <property name='pfthreshold' type='boolean' value='false'/> + <property name='smep' type='boolean' value='true' migratable='yes'/> + <property name='smap' type='boolean' value='true' migratable='yes'/> + <property name='x2apic' type='boolean' value='true' migratable='yes'/> + <property name='avx512vbmi' type='boolean' value='false'/> + <property name='avx512vnni' type='boolean' value='false'/> + <property name='hv-stimer' type='boolean' value='false'/> + <property name='x-hv-synic-kvm-only' type='boolean' value='false'/> + <property name='i64' type='boolean' value='true' migratable='yes'/> + <property name='flushbyasid' type='boolean' value='false'/> + <property name='f16c' type='boolean' value='true' migratable='yes'/> + <property name='ace2-en' type='boolean' value='false'/> + <property name='pat' type='boolean' value='true' migratable='yes'/> + <property name='pae' type='boolean' value='true' migratable='yes'/> + <property name='sse' type='boolean' value='true' migratable='yes'/> + <property name='phe-en' type='boolean' value='false'/> + <property name='kvm_nopiodelay' type='boolean' value='true' migratable='yes'/> + <property name='kvm-nopiodelay' type='boolean' value='true' migratable='yes'/> + <property name='tm' type='boolean' value='false'/> + <property name='kvmclock-stable-bit' type='boolean' value='true' migratable='yes'/> + <property name='hypervisor' type='boolean' value='true' migratable='yes'/> + <property name='socket-id' type='number' value='-1'/> + <property name='pcommit' type='boolean' value='false'/> + <property name='syscall' type='boolean' value='true' migratable='yes'/> + <property name='level' type='number' value='13'/> + <property name='avx512dq' type='boolean' value='false'/> + <property name='x-migrate-smi-count' type='boolean' value='true' migratable='yes'/> + <property name='svm' type='boolean' value='false'/> + <property name='full-cpuid-auto-level' type='boolean' value='true' migratable='yes'/> + <property name='hv-reset' type='boolean' value='false'/> + <property name='invtsc' type='boolean' value='true' migratable='no'/> + <property name='sse3' type='boolean' value='true' migratable='yes'/> + <property name='sse2' type='boolean' value='true' migratable='yes'/> + <property name='ssbd' type='boolean' value='true' migratable='yes'/> + <property name='est' type='boolean' value='false'/> + <property name='avx512ifma' type='boolean' value='false'/> + <property name='tm2' type='boolean' value='false'/> + <property name='kvm-pv-ipi' type='boolean' value='true' migratable='yes'/> + <property name='kvm-pv-eoi' type='boolean' value='true' migratable='yes'/> + <property name='cx8' type='boolean' value='true' migratable='yes'/> + <property name='cldemote' type='boolean' value='false'/> + <property name='hv-reenlightenment' type='boolean' value='false'/> + <property name='kvm_mmu' type='boolean' value='false'/> + <property name='kvm-mmu' type='boolean' value='false'/> + <property name='sse4_2' type='boolean' value='true' migratable='yes'/> + <property name='sse4.2' type='boolean' value='true' migratable='yes'/> + <property name='sse4-2' type='boolean' value='true' migratable='yes'/> + <property name='pge' type='boolean' value='true' migratable='yes'/> + <property name='fill-mtrr-mask' type='boolean' value='true' migratable='yes'/> + <property name='avx512bitalg' type='boolean' value='false'/> + <property name='nodeid_msr' type='boolean' value='false'/> + <property name='pdcm' type='boolean' value='false'/> + <property name='movbe' type='boolean' value='true' migratable='yes'/> + <property name='model' type='number' value='94'/> + <property name='nrip_save' type='boolean' value='false'/> + <property name='nrip-save' type='boolean' value='false'/> + <property name='kvm_pv_unhalt' type='boolean' value='true' migratable='yes'/> + <property name='ssse3' type='boolean' value='true' migratable='yes'/> + <property name='sse4a' type='boolean' value='false'/> + <property name='invpcid' type='boolean' value='true' migratable='yes'/> + <property name='pdpe1gb' type='boolean' value='true' migratable='yes'/> + <property name='tsc-deadline' type='boolean' value='true' migratable='yes'/> + <property name='skip-l1dfl-vmentry' type='boolean' value='true' migratable='yes'/> + <property name='fma' type='boolean' value='true' migratable='yes'/> + <property name='cx16' type='boolean' value='true' migratable='yes'/> + <property name='de' type='boolean' value='true' migratable='yes'/> + <property name='enforce' type='boolean' value='false'/> + <property name='stepping' type='number' value='3'/> + <property name='xsave' type='boolean' value='true' migratable='yes'/> + <property name='clflush' type='boolean' value='true' migratable='yes'/> + <property name='skinit' type='boolean' value='false'/> + <property name='tsc' type='boolean' value='true' migratable='yes'/> + <property name='tce' type='boolean' value='false'/> + <property name='fpu' type='boolean' value='true' migratable='yes'/> + <property name='ibs' type='boolean' value='false'/> + <property name='ds_cpl' type='boolean' value='false'/> + <property name='ds-cpl' type='boolean' value='false'/> + <property name='host-phys-bits' type='boolean' value='false'/> + <property name='fma4' type='boolean' value='false'/> + <property name='la57' type='boolean' value='false'/> + <property name='osvw' type='boolean' value='false'/> + <property name='check' type='boolean' value='true' migratable='yes'/> + <property name='hv-spinlocks' type='number' value='-1'/> + <property name='pmu' type='boolean' value='false'/> + <property name='pmm' type='boolean' value='false'/> + <property name='apic' type='boolean' value='true' migratable='yes'/> + <property name='spec-ctrl' type='boolean' value='true' migratable='yes'/> + <property name='min-xlevel2' type='number' value='0'/> + <property name='tsc-adjust' type='boolean' value='true' migratable='yes'/> + <property name='tsc_adjust' type='boolean' value='true' migratable='yes'/> + <property name='kvm-steal-time' type='boolean' value='true' migratable='yes'/> + <property name='kvm_steal_time' type='boolean' value='true' migratable='yes'/> + <property name='kvmclock' type='boolean' value='true' migratable='yes'/> + <property name='l3-cache' type='boolean' value='true' migratable='yes'/> + <property name='lwp' type='boolean' value='false'/> + <property name='amd-ssbd' type='boolean' value='false'/> + <property name='ibpb' type='boolean' value='false'/> + <property name='xop' type='boolean' value='false'/> + <property name='avx' type='boolean' value='true' migratable='yes'/> + <property name='movdiri' type='boolean' value='false'/> + <property name='ace2' type='boolean' value='false'/> + <property name='avx512bw' type='boolean' value='false'/> + <property name='acpi' type='boolean' value='false'/> + <property name='hv-vapic' type='boolean' value='false'/> + <property name='fsgsbase' type='boolean' value='true' migratable='yes'/> + <property name='ht' type='boolean' value='false'/> + <property name='nx' type='boolean' value='true' migratable='yes'/> + <property name='pclmulqdq' type='boolean' value='true' migratable='yes'/> + <property name='mmxext' type='boolean' value='false'/> + <property name='vaes' type='boolean' value='false'/> + <property name='popcnt' type='boolean' value='true' migratable='yes'/> + <property name='xsaves' type='boolean' value='true' migratable='yes'/> + <property name='movdir64b' type='boolean' value='false'/> + <property name='tcg-cpuid' type='boolean' value='true' migratable='yes'/> + <property name='lm' type='boolean' value='true' migratable='yes'/> + <property name='umip' type='boolean' value='true' migratable='yes'/> + <property name='pse' type='boolean' value='true' migratable='yes'/> + <property name='avx2' type='boolean' value='true' migratable='yes'/> + <property name='sep' type='boolean' value='true' migratable='yes'/> + <property name='pclmuldq' type='boolean' value='true' migratable='yes'/> + <property name='virt-ssbd' type='boolean' value='false'/> + <property name='x-hv-max-vps' type='number' value='-1'/> + <property name='nodeid-msr' type='boolean' value='false'/> + <property name='kvm' type='boolean' value='true' migratable='yes'/> + <property name='misalignsse' type='boolean' value='false'/> + <property name='min-xlevel' type='number' value='2147483656'/> + <property name='kvm-pv-unhalt' type='boolean' value='true' migratable='yes'/> + <property name='bmi2' type='boolean' value='true' migratable='yes'/> + <property name='bmi1' type='boolean' value='true' migratable='yes'/> + <property name='realized' type='boolean' value='false'/> + <property name='tsc_scale' type='boolean' value='false'/> + <property name='tsc-scale' type='boolean' value='false'/> + <property name='topoext' type='boolean' value='false'/> + <property name='hv-vpindex' type='boolean' value='false'/> + <property name='xlevel2' type='number' value='0'/> + <property name='clflushopt' type='boolean' value='true' migratable='yes'/> + <property name='kvm-no-smi-migration' type='boolean' value='false'/> + <property name='monitor' type='boolean' value='false'/> + <property name='avx512er' type='boolean' value='false'/> + <property name='pmm-en' type='boolean' value='false'/> + <property name='pcid' type='boolean' value='true' migratable='yes'/> + <property name='arch-capabilities' type='boolean' value='false'/> + <property name='3dnow' type='boolean' value='false'/> + <property name='erms' type='boolean' value='true' migratable='yes'/> + <property name='lahf-lm' type='boolean' value='true' migratable='yes'/> + <property name='lahf_lm' type='boolean' value='true' migratable='yes'/> + <property name='vpclmulqdq' type='boolean' value='false'/> + <property name='fxsr-opt' type='boolean' value='false'/> + <property name='hv-synic' type='boolean' value='false'/> + <property name='xstore' type='boolean' value='false'/> + <property name='fxsr_opt' type='boolean' value='false'/> + <property name='kvm-hint-dedicated' type='boolean' value='false'/> + <property name='rtm' type='boolean' value='true' migratable='yes'/> + <property name='lmce' type='boolean' value='true' migratable='yes'/> + <property name='hv-time' type='boolean' value='false'/> + <property name='perfctr-nb' type='boolean' value='false'/> + <property name='perfctr_nb' type='boolean' value='false'/> + <property name='ffxsr' type='boolean' value='false'/> + <property name='hv-tlbflush' type='boolean' value='false'/> + <property name='rdrand' type='boolean' value='true' migratable='yes'/> + <property name='rdseed' type='boolean' value='true' migratable='yes'/> + <property name='avx512-4vnniw' type='boolean' value='false'/> + <property name='vmx' type='boolean' value='true' migratable='yes'/> + <property name='vme' type='boolean' value='true' migratable='yes'/> + <property name='dtes64' type='boolean' value='false'/> + <property name='mtrr' type='boolean' value='true' migratable='yes'/> + <property name='rdtscp' type='boolean' value='true' migratable='yes'/> + <property name='pse36' type='boolean' value='true' migratable='yes'/> + <property name='kvm-pv-tlb-flush' type='boolean' value='true' migratable='yes'/> + <property name='tbm' type='boolean' value='false'/> + <property name='wdt' type='boolean' value='false'/> + <property name='pause_filter' type='boolean' value='false'/> + <property name='sha-ni' type='boolean' value='false'/> + <property name='model-id' type='string' value='Intel(R) Xeon(R) CPU E3-1245 v5 @ 3.50GHz'/> + <property name='abm' type='boolean' value='true' migratable='yes'/> + <property name='avx512pf' type='boolean' value='false'/> + <property name='xstore-en' type='boolean' value='false'/> + </hostCPU> + <hostCPU type='tcg' model='base' migratability='yes'> + <property name='phys-bits' type='number' value='0'/> + <property name='core-id' type='number' value='-1'/> + <property name='xlevel' type='number' value='2147483658'/> + <property name='cmov' type='boolean' value='true' migratable='yes'/> + <property name='ia64' type='boolean' value='false'/> + <property name='ssb-no' type='boolean' value='false'/> + <property name='aes' type='boolean' value='true' migratable='yes'/> + <property name='mmx' type='boolean' value='true' migratable='yes'/> + <property name='rdpid' type='boolean' value='false'/> + <property name='arat' type='boolean' value='true' migratable='yes'/> + <property name='gfni' type='boolean' value='false'/> + <property name='ibrs-all' type='boolean' value='false'/> + <property name='pause-filter' type='boolean' value='false'/> + <property name='xsavec' type='boolean' value='false'/> + <property name='intel-pt' type='boolean' value='false'/> + <property name='hv-frequencies' type='boolean' value='false'/> + <property name='tsc-frequency' type='number' value='0'/> + <property name='xd' type='boolean' value='true' migratable='yes'/> + <property name='x-intel-pt-auto-level' type='boolean' value='true' migratable='yes'/> + <property name='hv-vendor-id' type='string' value=''/> + <property name='kvm-asyncpf' type='boolean' value='false'/> + <property name='kvm_asyncpf' type='boolean' value='false'/> + <property name='perfctr_core' type='boolean' value='false'/> + <property name='perfctr-core' type='boolean' value='false'/> + <property name='mpx' type='boolean' value='true' migratable='yes'/> + <property name='pbe' type='boolean' value='false'/> + <property name='decodeassists' type='boolean' value='false'/> + <property name='avx512cd' type='boolean' value='false'/> + <property name='sse4_1' type='boolean' value='true' migratable='yes'/> + <property name='sse4.1' type='boolean' value='true' migratable='yes'/> + <property name='sse4-1' type='boolean' value='true' migratable='yes'/> + <property name='family' type='number' value='6'/> + <property name='legacy-cache' type='boolean' value='true' migratable='yes'/> + <property name='host-phys-bits-limit' type='number' value='0'/> + <property name='vmware-cpuid-freq' type='boolean' value='true' migratable='yes'/> + <property name='wbnoinvd' type='boolean' value='false'/> + <property name='avx512f' type='boolean' value='false'/> + <property name='msr' type='boolean' value='true' migratable='yes'/> + <property name='mce' type='boolean' value='true' migratable='yes'/> + <property name='mca' type='boolean' value='true' migratable='yes'/> + <property name='hv-runtime' type='boolean' value='false'/> + <property name='xcrypt' type='boolean' value='false'/> + <property name='thread-id' type='number' value='-1'/> + <property name='min-level' type='number' value='13'/> + <property name='xgetbv1' type='boolean' value='true' migratable='yes'/> + <property name='cid' type='boolean' value='false'/> + <property name='hv-relaxed' type='boolean' value='false'/> + <property name='hv-crash' type='boolean' value='false'/> + <property name='ds' type='boolean' value='false'/> + <property name='fxsr' type='boolean' value='true' migratable='yes'/> + <property name='xsaveopt' type='boolean' value='true' migratable='yes'/> + <property name='xtpr' type='boolean' value='false'/> + <property name='hv-evmcs' type='boolean' value='false'/> + <property name='avx512vl' type='boolean' value='false'/> + <property name='avx512-vpopcntdq' type='boolean' value='false'/> + <property name='phe' type='boolean' value='false'/> + <property name='extapic' type='boolean' value='false'/> + <property name='3dnowprefetch' type='boolean' value='false'/> + <property name='avx512vbmi2' type='boolean' value='false'/> + <property name='cr8legacy' type='boolean' value='true' migratable='yes'/> + <property name='stibp' type='boolean' value='false'/> + <property name='cpuid-0xb' type='boolean' value='true' migratable='yes'/> + <property name='xcrypt-en' type='boolean' value='false'/> + <property name='kvm_pv_eoi' type='boolean' value='false'/> + <property name='apic-id' type='number' value='4294967295'/> + <property name='rsba' type='boolean' value='false'/> + <property name='pn' type='boolean' value='false'/> + <property name='dca' type='boolean' value='false'/> + <property name='vendor' type='string' value='AuthenticAMD'/> + <property name='hv-ipi' type='boolean' value='false'/> + <property name='pku' type='boolean' value='true' migratable='yes'/> + <property name='smx' type='boolean' value='false'/> + <property name='cmp_legacy' type='boolean' value='false'/> + <property name='cmp-legacy' type='boolean' value='false'/> + <property name='node-id' type='number' value='-1'/> + <property name='avx512-4fmaps' type='boolean' value='false'/> + <property name='vmcb_clean' type='boolean' value='false'/> + <property name='vmcb-clean' type='boolean' value='false'/> + <property name='3dnowext' type='boolean' value='true' migratable='yes'/> + <property name='amd-no-ssb' type='boolean' value='false'/> + <property name='hle' type='boolean' value='false'/> + <property name='npt' type='boolean' value='true' migratable='yes'/> + <property name='rdctl-no' type='boolean' value='false'/> + <property name='memory' type='string' value='/machine/unattached/system[0]'/> + <property name='clwb' type='boolean' value='true' migratable='yes'/> + <property name='lbrv' type='boolean' value='false'/> + <property name='adx' type='boolean' value='true' migratable='yes'/> + <property name='ss' type='boolean' value='true' migratable='yes'/> + <property name='pni' type='boolean' value='true' migratable='yes'/> + <property name='svm_lock' type='boolean' value='false'/> + <property name='svm-lock' type='boolean' value='false'/> + <property name='pfthreshold' type='boolean' value='false'/> + <property name='smep' type='boolean' value='true' migratable='yes'/> + <property name='smap' type='boolean' value='true' migratable='yes'/> + <property name='x2apic' type='boolean' value='false'/> + <property name='avx512vbmi' type='boolean' value='false'/> + <property name='avx512vnni' type='boolean' value='false'/> + <property name='hv-stimer' type='boolean' value='false'/> + <property name='x-hv-synic-kvm-only' type='boolean' value='false'/> + <property name='i64' type='boolean' value='true' migratable='yes'/> + <property name='flushbyasid' type='boolean' value='false'/> + <property name='f16c' type='boolean' value='false'/> + <property name='ace2-en' type='boolean' value='false'/> + <property name='pat' type='boolean' value='true' migratable='yes'/> + <property name='pae' type='boolean' value='true' migratable='yes'/> + <property name='sse' type='boolean' value='true' migratable='yes'/> + <property name='phe-en' type='boolean' value='false'/> + <property name='kvm_nopiodelay' type='boolean' value='false'/> + <property name='kvm-nopiodelay' type='boolean' value='false'/> + <property name='tm' type='boolean' value='false'/> + <property name='kvmclock-stable-bit' type='boolean' value='false'/> + <property name='hypervisor' type='boolean' value='true' migratable='yes'/> + <property name='socket-id' type='number' value='-1'/> + <property name='pcommit' type='boolean' value='true' migratable='yes'/> + <property name='syscall' type='boolean' value='true' migratable='yes'/> + <property name='level' type='number' value='13'/> + <property name='avx512dq' type='boolean' value='false'/> + <property name='x-migrate-smi-count' type='boolean' value='true' migratable='yes'/> + <property name='svm' type='boolean' value='true' migratable='yes'/> + <property name='full-cpuid-auto-level' type='boolean' value='true' migratable='yes'/> + <property name='hv-reset' type='boolean' value='false'/> + <property name='invtsc' type='boolean' value='false'/> + <property name='sse3' type='boolean' value='true' migratable='yes'/> + <property name='sse2' type='boolean' value='true' migratable='yes'/> + <property name='ssbd' type='boolean' value='false'/> + <property name='est' type='boolean' value='false'/> + <property name='avx512ifma' type='boolean' value='false'/> + <property name='tm2' type='boolean' value='false'/> + <property name='kvm-pv-ipi' type='boolean' value='false'/> + <property name='kvm-pv-eoi' type='boolean' value='false'/> + <property name='cx8' type='boolean' value='true' migratable='yes'/> + <property name='cldemote' type='boolean' value='false'/> + <property name='hv-reenlightenment' type='boolean' value='false'/> + <property name='kvm_mmu' type='boolean' value='false'/> + <property name='kvm-mmu' type='boolean' value='false'/> + <property name='sse4_2' type='boolean' value='true' migratable='yes'/> + <property name='sse4.2' type='boolean' value='true' migratable='yes'/> + <property name='sse4-2' type='boolean' value='true' migratable='yes'/> + <property name='pge' type='boolean' value='true' migratable='yes'/> + <property name='fill-mtrr-mask' type='boolean' value='true' migratable='yes'/> + <property name='avx512bitalg' type='boolean' value='false'/> + <property name='nodeid_msr' type='boolean' value='false'/> + <property name='pdcm' type='boolean' value='false'/> + <property name='movbe' type='boolean' value='true' migratable='yes'/> + <property name='model' type='number' value='6'/> + <property name='nrip_save' type='boolean' value='false'/> + <property name='nrip-save' type='boolean' value='false'/> + <property name='kvm_pv_unhalt' type='boolean' value='false'/> + <property name='ssse3' type='boolean' value='true' migratable='yes'/> + <property name='sse4a' type='boolean' value='true' migratable='yes'/> + <property name='invpcid' type='boolean' value='false'/> + <property name='pdpe1gb' type='boolean' value='true' migratable='yes'/> + <property name='tsc-deadline' type='boolean' value='false'/> + <property name='skip-l1dfl-vmentry' type='boolean' value='false'/> + <property name='fma' type='boolean' value='false'/> + <property name='cx16' type='boolean' value='true' migratable='yes'/> + <property name='de' type='boolean' value='true' migratable='yes'/> + <property name='enforce' type='boolean' value='false'/> + <property name='stepping' type='number' value='3'/> + <property name='xsave' type='boolean' value='true' migratable='yes'/> + <property name='clflush' type='boolean' value='true' migratable='yes'/> + <property name='skinit' type='boolean' value='false'/> + <property name='tsc' type='boolean' value='true' migratable='yes'/> + <property name='tce' type='boolean' value='false'/> + <property name='fpu' type='boolean' value='true' migratable='yes'/> + <property name='ibs' type='boolean' value='false'/> + <property name='ds_cpl' type='boolean' value='false'/> + <property name='ds-cpl' type='boolean' value='false'/> + <property name='host-phys-bits' type='boolean' value='false'/> + <property name='fma4' type='boolean' value='false'/> + <property name='la57' type='boolean' value='true' migratable='yes'/> + <property name='osvw' type='boolean' value='false'/> + <property name='check' type='boolean' value='true' migratable='yes'/> + <property name='hv-spinlocks' type='number' value='-1'/> + <property name='pmu' type='boolean' value='false'/> + <property name='pmm' type='boolean' value='false'/> + <property name='apic' type='boolean' value='true' migratable='yes'/> + <property name='spec-ctrl' type='boolean' value='false'/> + <property name='min-xlevel2' type='number' value='0'/> + <property name='tsc-adjust' type='boolean' value='false'/> + <property name='tsc_adjust' type='boolean' value='false'/> + <property name='kvm-steal-time' type='boolean' value='false'/> + <property name='kvm_steal_time' type='boolean' value='false'/> + <property name='kvmclock' type='boolean' value='false'/> + <property name='l3-cache' type='boolean' value='true' migratable='yes'/> + <property name='lwp' type='boolean' value='false'/> + <property name='amd-ssbd' type='boolean' value='false'/> + <property name='ibpb' type='boolean' value='false'/> + <property name='xop' type='boolean' value='false'/> + <property name='avx' type='boolean' value='false'/> + <property name='movdiri' type='boolean' value='false'/> + <property name='ace2' type='boolean' value='false'/> + <property name='avx512bw' type='boolean' value='false'/> + <property name='acpi' type='boolean' value='true' migratable='yes'/> + <property name='hv-vapic' type='boolean' value='false'/> + <property name='fsgsbase' type='boolean' value='true' migratable='yes'/> + <property name='ht' type='boolean' value='false'/> + <property name='nx' type='boolean' value='true' migratable='yes'/> + <property name='pclmulqdq' type='boolean' value='true' migratable='yes'/> + <property name='mmxext' type='boolean' value='true' migratable='yes'/> + <property name='vaes' type='boolean' value='false'/> + <property name='popcnt' type='boolean' value='true' migratable='yes'/> + <property name='xsaves' type='boolean' value='false'/> + <property name='movdir64b' type='boolean' value='false'/> + <property name='tcg-cpuid' type='boolean' value='true' migratable='yes'/> + <property name='lm' type='boolean' value='true' migratable='yes'/> + <property name='umip' type='boolean' value='false'/> + <property name='pse' type='boolean' value='true' migratable='yes'/> + <property name='avx2' type='boolean' value='false'/> + <property name='sep' type='boolean' value='true' migratable='yes'/> + <property name='pclmuldq' type='boolean' value='true' migratable='yes'/> + <property name='virt-ssbd' type='boolean' value='false'/> + <property name='x-hv-max-vps' type='number' value='-1'/> + <property name='nodeid-msr' type='boolean' value='false'/> + <property name='kvm' type='boolean' value='true' migratable='yes'/> + <property name='misalignsse' type='boolean' value='false'/> + <property name='min-xlevel' type='number' value='2147483658'/> + <property name='kvm-pv-unhalt' type='boolean' value='false'/> + <property name='bmi2' type='boolean' value='true' migratable='yes'/> + <property name='bmi1' type='boolean' value='true' migratable='yes'/> + <property name='realized' type='boolean' value='false'/> + <property name='tsc_scale' type='boolean' value='false'/> + <property name='tsc-scale' type='boolean' value='false'/> + <property name='topoext' type='boolean' value='false'/> + <property name='hv-vpindex' type='boolean' value='false'/> + <property name='xlevel2' type='number' value='0'/> + <property name='clflushopt' type='boolean' value='true' migratable='yes'/> + <property name='kvm-no-smi-migration' type='boolean' value='false'/> + <property name='monitor' type='boolean' value='true' migratable='yes'/> + <property name='avx512er' type='boolean' value='false'/> + <property name='pmm-en' type='boolean' value='false'/> + <property name='pcid' type='boolean' value='false'/> + <property name='arch-capabilities' type='boolean' value='false'/> + <property name='3dnow' type='boolean' value='true' migratable='yes'/> + <property name='erms' type='boolean' value='true' migratable='yes'/> + <property name='lahf-lm' type='boolean' value='true' migratable='yes'/> + <property name='lahf_lm' type='boolean' value='true' migratable='yes'/> + <property name='vpclmulqdq' type='boolean' value='false'/> + <property name='fxsr-opt' type='boolean' value='false'/> + <property name='hv-synic' type='boolean' value='false'/> + <property name='xstore' type='boolean' value='false'/> + <property name='fxsr_opt' type='boolean' value='false'/> + <property name='kvm-hint-dedicated' type='boolean' value='false'/> + <property name='rtm' type='boolean' value='false'/> + <property name='lmce' type='boolean' value='false'/> + <property name='hv-time' type='boolean' value='false'/> + <property name='perfctr-nb' type='boolean' value='false'/> + <property name='perfctr_nb' type='boolean' value='false'/> + <property name='ffxsr' type='boolean' value='false'/> + <property name='hv-tlbflush' type='boolean' value='false'/> + <property name='rdrand' type='boolean' value='false'/> + <property name='rdseed' type='boolean' value='false'/> + <property name='avx512-4vnniw' type='boolean' value='false'/> + <property name='vmx' type='boolean' value='false'/> + <property name='vme' type='boolean' value='false'/> + <property name='dtes64' type='boolean' value='false'/> + <property name='mtrr' type='boolean' value='true' migratable='yes'/> + <property name='rdtscp' type='boolean' value='true' migratable='yes'/> + <property name='pse36' type='boolean' value='true' migratable='yes'/> + <property name='kvm-pv-tlb-flush' type='boolean' value='false'/> + <property name='tbm' type='boolean' value='false'/> + <property name='wdt' type='boolean' value='false'/> + <property name='pause_filter' type='boolean' value='false'/> + <property name='sha-ni' type='boolean' value='false'/> + <property name='model-id' type='string' value='QEMU TCG CPU version 2.5+'/> + <property name='abm' type='boolean' value='true' migratable='yes'/> + <property name='avx512pf' type='boolean' value='false'/> + <property name='xstore-en' type='boolean' value='false'/> + </hostCPU> + <cpu type='kvm' name='max' usable='yes'/> + <cpu type='kvm' name='host' usable='yes'/> + <cpu type='kvm' name='base' usable='yes'/> + <cpu type='kvm' name='qemu64' usable='yes'/> + <cpu type='kvm' name='qemu32' usable='yes'/> + <cpu type='kvm' name='phenom' usable='no'> + <blocker name='mmxext'/> + <blocker name='fxsr-opt'/> + <blocker name='3dnowext'/> + <blocker name='3dnow'/> + <blocker name='sse4a'/> + <blocker name='npt'/> + </cpu> + <cpu type='kvm' name='pentium3' usable='yes'/> + <cpu type='kvm' name='pentium2' usable='yes'/> + <cpu type='kvm' name='pentium' usable='yes'/> + <cpu type='kvm' name='n270' usable='yes'/> + <cpu type='kvm' name='kvm64' usable='yes'/> + <cpu type='kvm' name='kvm32' usable='yes'/> + <cpu type='kvm' name='coreduo' usable='yes'/> + <cpu type='kvm' name='core2duo' usable='yes'/> + <cpu type='kvm' name='athlon' usable='no'> + <blocker name='mmxext'/> + <blocker name='3dnowext'/> + <blocker name='3dnow'/> + </cpu> + <cpu type='kvm' name='Westmere-IBRS' usable='yes'/> + <cpu type='kvm' name='Westmere' usable='yes'/> + <cpu type='kvm' name='Skylake-Server-IBRS' usable='no'> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='clwb'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='pku'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='pku'/> + </cpu> + <cpu type='kvm' name='Skylake-Server' usable='no'> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='clwb'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='pku'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='pku'/> + </cpu> + <cpu type='kvm' name='Skylake-Client-IBRS' usable='yes'/> + <cpu type='kvm' name='Skylake-Client' usable='yes'/> + <cpu type='kvm' name='SandyBridge-IBRS' usable='yes'/> + <cpu type='kvm' name='SandyBridge' usable='yes'/> + <cpu type='kvm' name='Penryn' usable='yes'/> + <cpu type='kvm' name='Opteron_G5' usable='no'> + <blocker name='sse4a'/> + <blocker name='misalignsse'/> + <blocker name='xop'/> + <blocker name='fma4'/> + <blocker name='tbm'/> + <blocker name='npt'/> + <blocker name='nrip-save'/> + </cpu> + <cpu type='kvm' name='Opteron_G4' usable='no'> + <blocker name='sse4a'/> + <blocker name='misalignsse'/> + <blocker name='xop'/> + <blocker name='fma4'/> + <blocker name='npt'/> + <blocker name='nrip-save'/> + </cpu> + <cpu type='kvm' name='Opteron_G3' usable='no'> + <blocker name='sse4a'/> + <blocker name='misalignsse'/> + </cpu> + <cpu type='kvm' name='Opteron_G2' usable='yes'/> + <cpu type='kvm' name='Opteron_G1' usable='yes'/> + <cpu type='kvm' name='Nehalem-IBRS' usable='yes'/> + <cpu type='kvm' name='Nehalem' usable='yes'/> + <cpu type='kvm' name='KnightsMill' usable='no'> + <blocker name='avx512f'/> + <blocker name='avx512pf'/> + <blocker name='avx512er'/> + <blocker name='avx512cd'/> + <blocker name='avx512-vpopcntdq'/> + <blocker name='avx512-4vnniw'/> + <blocker name='avx512-4fmaps'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + </cpu> + <cpu type='kvm' name='IvyBridge-IBRS' usable='yes'/> + <cpu type='kvm' name='IvyBridge' usable='yes'/> + <cpu type='kvm' name='Icelake-Server' usable='no'> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='clwb'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='avx512vbmi'/> + <blocker name='pku'/> + <blocker name='avx512vbmi2'/> + <blocker name='gfni'/> + <blocker name='vaes'/> + <blocker name='vpclmulqdq'/> + <blocker name='avx512vnni'/> + <blocker name='avx512bitalg'/> + <blocker name='avx512-vpopcntdq'/> + <blocker name='la57'/> + <blocker name='wbnoinvd'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='pku'/> + </cpu> + <cpu type='kvm' name='Icelake-Client' usable='no'> + <blocker name='avx512vbmi'/> + <blocker name='pku'/> + <blocker name='avx512vbmi2'/> + <blocker name='gfni'/> + <blocker name='vaes'/> + <blocker name='vpclmulqdq'/> + <blocker name='avx512vnni'/> + <blocker name='avx512bitalg'/> + <blocker name='avx512-vpopcntdq'/> + <blocker name='wbnoinvd'/> + <blocker name='pku'/> + </cpu> + <cpu type='kvm' name='Haswell-noTSX-IBRS' usable='yes'/> + <cpu type='kvm' name='Haswell-noTSX' usable='yes'/> + <cpu type='kvm' name='Haswell-IBRS' usable='yes'/> + <cpu type='kvm' name='Haswell' usable='yes'/> + <cpu type='kvm' name='EPYC-IBPB' usable='no'> + <blocker name='sha-ni'/> + <blocker name='mmxext'/> + <blocker name='fxsr-opt'/> + <blocker name='cr8legacy'/> + <blocker name='sse4a'/> + <blocker name='misalignsse'/> + <blocker name='osvw'/> + <blocker name='ibpb'/> + <blocker name='npt'/> + <blocker name='nrip-save'/> + </cpu> + <cpu type='kvm' name='EPYC' usable='no'> + <blocker name='sha-ni'/> + <blocker name='mmxext'/> + <blocker name='fxsr-opt'/> + <blocker name='cr8legacy'/> + <blocker name='sse4a'/> + <blocker name='misalignsse'/> + <blocker name='osvw'/> + <blocker name='npt'/> + <blocker name='nrip-save'/> + </cpu> + <cpu type='kvm' name='Conroe' usable='yes'/> + <cpu type='kvm' name='Cascadelake-Server' usable='no'> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='clwb'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='pku'/> + <blocker name='avx512vnni'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='avx512f'/> + <blocker name='pku'/> + </cpu> + <cpu type='kvm' name='Broadwell-noTSX-IBRS' usable='yes'/> + <cpu type='kvm' name='Broadwell-noTSX' usable='yes'/> + <cpu type='kvm' name='Broadwell-IBRS' usable='yes'/> + <cpu type='kvm' name='Broadwell' usable='yes'/> + <cpu type='kvm' name='486' usable='yes'/> + <cpu type='tcg' name='max' usable='yes'/> + <cpu type='tcg' name='host' usable='no'> + <blocker name='kvm'/> + </cpu> + <cpu type='tcg' name='base' usable='yes'/> + <cpu type='tcg' name='qemu64' usable='yes'/> + <cpu type='tcg' name='qemu32' usable='yes'/> + <cpu type='tcg' name='phenom' usable='no'> + <blocker name='fxsr-opt'/> + </cpu> + <cpu type='tcg' name='pentium3' usable='yes'/> + <cpu type='tcg' name='pentium2' usable='yes'/> + <cpu type='tcg' name='pentium' usable='yes'/> + <cpu type='tcg' name='n270' usable='yes'/> + <cpu type='tcg' name='kvm64' usable='yes'/> + <cpu type='tcg' name='kvm32' usable='yes'/> + <cpu type='tcg' name='coreduo' usable='yes'/> + <cpu type='tcg' name='core2duo' usable='yes'/> + <cpu type='tcg' name='athlon' usable='yes'/> + <cpu type='tcg' name='Westmere-IBRS' usable='no'> + <blocker name='spec-ctrl'/> + </cpu> + <cpu type='tcg' name='Westmere' usable='yes'/> + <cpu type='tcg' name='Skylake-Server-IBRS' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='rdseed'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='spec-ctrl'/> + <blocker name='3dnowprefetch'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Skylake-Server' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='rdseed'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='3dnowprefetch'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Skylake-Client-IBRS' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='rdseed'/> + <blocker name='spec-ctrl'/> + <blocker name='3dnowprefetch'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Skylake-Client' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='rdseed'/> + <blocker name='3dnowprefetch'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='SandyBridge-IBRS' usable='no'> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='spec-ctrl'/> + </cpu> + <cpu type='tcg' name='SandyBridge' usable='no'> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + </cpu> + <cpu type='tcg' name='Penryn' usable='yes'/> + <cpu type='tcg' name='Opteron_G5' usable='no'> + <blocker name='fma'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='misalignsse'/> + <blocker name='3dnowprefetch'/> + <blocker name='xop'/> + <blocker name='fma4'/> + <blocker name='tbm'/> + <blocker name='nrip-save'/> + </cpu> + <cpu type='tcg' name='Opteron_G4' usable='no'> + <blocker name='avx'/> + <blocker name='misalignsse'/> + <blocker name='3dnowprefetch'/> + <blocker name='xop'/> + <blocker name='fma4'/> + <blocker name='nrip-save'/> + </cpu> + <cpu type='tcg' name='Opteron_G3' usable='no'> + <blocker name='misalignsse'/> + </cpu> + <cpu type='tcg' name='Opteron_G2' usable='yes'/> + <cpu type='tcg' name='Opteron_G1' usable='yes'/> + <cpu type='tcg' name='Nehalem-IBRS' usable='no'> + <blocker name='spec-ctrl'/> + </cpu> + <cpu type='tcg' name='Nehalem' usable='yes'/> + <cpu type='tcg' name='KnightsMill' usable='no'> + <blocker name='fma'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='avx512f'/> + <blocker name='rdseed'/> + <blocker name='avx512pf'/> + <blocker name='avx512er'/> + <blocker name='avx512cd'/> + <blocker name='avx512-vpopcntdq'/> + <blocker name='avx512-4vnniw'/> + <blocker name='avx512-4fmaps'/> + <blocker name='3dnowprefetch'/> + </cpu> + <cpu type='tcg' name='IvyBridge-IBRS' usable='no'> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='spec-ctrl'/> + </cpu> + <cpu type='tcg' name='IvyBridge' usable='no'> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + </cpu> + <cpu type='tcg' name='Icelake-Server' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='rdseed'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='avx512vbmi'/> + <blocker name='umip'/> + <blocker name='avx512vbmi2'/> + <blocker name='gfni'/> + <blocker name='vaes'/> + <blocker name='vpclmulqdq'/> + <blocker name='avx512vnni'/> + <blocker name='avx512bitalg'/> + <blocker name='avx512-vpopcntdq'/> + <blocker name='spec-ctrl'/> + <blocker name='ssbd'/> + <blocker name='3dnowprefetch'/> + <blocker name='wbnoinvd'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Icelake-Client' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='rdseed'/> + <blocker name='avx512vbmi'/> + <blocker name='umip'/> + <blocker name='avx512vbmi2'/> + <blocker name='gfni'/> + <blocker name='vaes'/> + <blocker name='vpclmulqdq'/> + <blocker name='avx512vnni'/> + <blocker name='avx512bitalg'/> + <blocker name='avx512-vpopcntdq'/> + <blocker name='spec-ctrl'/> + <blocker name='ssbd'/> + <blocker name='3dnowprefetch'/> + <blocker name='wbnoinvd'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Haswell-noTSX-IBRS' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='spec-ctrl'/> + </cpu> + <cpu type='tcg' name='Haswell-noTSX' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + </cpu> + <cpu type='tcg' name='Haswell-IBRS' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='spec-ctrl'/> + </cpu> + <cpu type='tcg' name='Haswell' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + </cpu> + <cpu type='tcg' name='EPYC-IBPB' usable='no'> + <blocker name='fma'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='rdseed'/> + <blocker name='sha-ni'/> + <blocker name='fxsr-opt'/> + <blocker name='misalignsse'/> + <blocker name='3dnowprefetch'/> + <blocker name='osvw'/> + <blocker name='topoext'/> + <blocker name='ibpb'/> + <blocker name='nrip-save'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='EPYC' usable='no'> + <blocker name='fma'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='rdseed'/> + <blocker name='sha-ni'/> + <blocker name='fxsr-opt'/> + <blocker name='misalignsse'/> + <blocker name='3dnowprefetch'/> + <blocker name='osvw'/> + <blocker name='topoext'/> + <blocker name='nrip-save'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Conroe' usable='yes'/> + <cpu type='tcg' name='Cascadelake-Server' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='avx512f'/> + <blocker name='avx512dq'/> + <blocker name='rdseed'/> + <blocker name='avx512cd'/> + <blocker name='avx512bw'/> + <blocker name='avx512vl'/> + <blocker name='avx512vnni'/> + <blocker name='spec-ctrl'/> + <blocker name='ssbd'/> + <blocker name='3dnowprefetch'/> + <blocker name='xsavec'/> + </cpu> + <cpu type='tcg' name='Broadwell-noTSX-IBRS' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rdseed'/> + <blocker name='spec-ctrl'/> + <blocker name='3dnowprefetch'/> + </cpu> + <cpu type='tcg' name='Broadwell-noTSX' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rdseed'/> + <blocker name='3dnowprefetch'/> + </cpu> + <cpu type='tcg' name='Broadwell-IBRS' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='rdseed'/> + <blocker name='spec-ctrl'/> + <blocker name='3dnowprefetch'/> + </cpu> + <cpu type='tcg' name='Broadwell' usable='no'> + <blocker name='fma'/> + <blocker name='pcid'/> + <blocker name='x2apic'/> + <blocker name='tsc-deadline'/> + <blocker name='avx'/> + <blocker name='f16c'/> + <blocker name='rdrand'/> + <blocker name='hle'/> + <blocker name='avx2'/> + <blocker name='invpcid'/> + <blocker name='rtm'/> + <blocker name='rdseed'/> + <blocker name='3dnowprefetch'/> + </cpu> + <cpu type='tcg' name='486' usable='yes'/> + <machine name='pc-i440fx-5.3' alias='pc' hotplugCpus='yes' maxCpus='255' default='yes'/> + <machine name='pc-i440fx-4.0' alias='pc' hotplugCpus='yes' maxCpus='255' default='yes'/> + <machine name='isapc' hotplugCpus='yes' maxCpus='1'/> + <machine name='pc-1.1' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-1.2' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-1.3' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.8' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-1.0' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.9' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.6' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.7' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.3' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.4' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.5' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.1' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.2' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-3.1' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-i440fx-2.0' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.11' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-q35-2.12' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-q35-3.0' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-q35-2.10' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-i440fx-1.7' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.9' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-0.15' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-1.5' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.7' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-1.6' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.11' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.8' hotplugCpus='yes' maxCpus='288'/> + <machine name='pc-0.13' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.12' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-0.14' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-3.0' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-3.1' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.4' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.5' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-2.6' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-2.10' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-i440fx-1.4' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-0.12' hotplugCpus='yes' maxCpus='255'/> + <machine name='pc-q35-4.0' alias='q35' hotplugCpus='yes' maxCpus='288'/> + <mktme> + <keys_supported>15</keys_supported> + </mktme> +</qemuCaps> -- 2.21.0.windows.1

The API can be used to get platform specific key supported info --- include/libvirt/libvirt-host.h | 18 +++++++++++++ src/driver-hypervisor.h | 7 +++++ src/libvirt-host.c | 49 ++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 79 insertions(+) diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 7debb5f829..292cbbc388 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); +/** +* +* 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/driver-hypervisor.h b/src/driver-hypervisor.h index 5315e33dde..0bbb90b321 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1322,6 +1322,12 @@ typedef int int *nparams, unsigned int flags); +typedef int +(*virDrvNodeGetMKTMEInfo)(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags); + typedef int (*virDrvDomainGetLaunchSecurityInfo)(virDomainPtr domain, virTypedParameterPtr *params, @@ -1580,6 +1586,7 @@ struct _virHypervisorDriver { virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; virDrvNodeGetSEVInfo nodeGetSEVInfo; virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo; + virDrvNodeGetMKTMEInfo nodeGetMKTMEInfo; }; diff --git a/src/libvirt-host.c b/src/libvirt-host.c index e20d6ee250..92b9973560 100644 --- a/src/libvirt-host.c +++ b/src/libvirt-host.c @@ -1688,3 +1688,52 @@ 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=%p, params=%p, nparams=%p, flags=0x%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 |= VIR_TYPED_PARAM_STRING_OKAY; + + if (conn->driver->nodeGetMKTMEInfo) { + int ret; + ret = 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_public.syms b/src/libvirt_public.syms index dbce3336d5..7aa6a60b11 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -819,4 +819,9 @@ LIBVIRT_5.2.0 { virConnectGetStoragePoolCapabilities; } LIBVIRT_4.10.0; +LIBVIRT_5.3.0 { + global: + virNodeGetMKTMEInfo; +} LIBVIRT_5.2.0; + # .... define new API here using predicted next version number .... -- 2.21.0.windows.1

Add remote support for virNodeMKTMEInfo(). --- src/remote/remote_daemon_dispatch.c | 44 +++++++++++++++++++++++++++++ src/remote/remote_driver.c | 41 ++++++++++++++++++++++++++- src/remote/remote_protocol.x | 21 +++++++++++++- src/remote_protocol-structs | 12 ++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index df28259042..78591791cc 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -5230,6 +5230,50 @@ remoteDispatchNodeGetSevInfo(virNetServerPtr server ATTRIBUTE_UNUSED, } +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 = NULL; + int nparams = 0; + int rv = -1; + struct daemonClientPrivate *priv = + 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 = 0; + + cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + virTypedParamsFree(params, nparams); + return rv; +} + + static int remoteDispatchNodeGetMemoryParameters(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 5c4dd41227..af2f7a8223 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6825,6 +6825,44 @@ remoteNodeGetSEVInfo(virConnectPtr conn, } +static int +remoteNodeGetMKTMEInfo(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int rv = -1; + remote_node_get_mktme_info_args args; + remote_node_get_mktme_info_ret ret; + struct private_data *priv = conn->privateData; + + remoteDriverLock(priv); + + args.flags = 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) == -1) + goto done; + + if (virTypedParamsDeserialize((virTypedParameterRemotePtr)ret.params.params_val, + ret.params.params_len, + REMOTE_NODE_MKTME_INFO_MAX, + params, + nparams) < 0) + goto cleanup; + + rv = 0; + + cleanup: + xdr_free((xdrproc_t)xdr_remote_node_get_mktme_info_ret, (char *)&ret); + done: + remoteDriverUnlock(priv); + return rv; +} + + static int remoteNodeGetCPUMap(virConnectPtr conn, unsigned char **cpumap, @@ -8516,7 +8554,8 @@ static virHypervisorDriver hypervisor_driver = { .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */ .connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */ .nodeGetSEVInfo = remoteNodeGetSEVInfo, /* 4.5.0 */ - .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo /* 4.5.0 */ + .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo, /* 4.5.0 */ + .nodeGetMKTMEInfo = remoteNodeGetMKTMEInfo /* 5.3.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 11f44ee267..391e3be66f 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -263,6 +263,9 @@ const REMOTE_NODE_SEV_INFO_MAX = 64; /* Upper limit on number of launch security information entries */ const REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX = 64; +/* Upper limit on number of MKTME parameters */ +const REMOTE_NODE_MKTME_INFO_MAX = 64; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -3514,6 +3517,16 @@ struct remote_node_get_sev_info_ret { int nparams; }; +struct remote_node_get_mktme_info_args { + int nparams; + unsigned int flags; +}; + +struct remote_node_get_mktme_info_ret { + remote_typed_param params<REMOTE_NODE_MKTME_INFO_MAX>; + int nparams; +}; + struct remote_domain_get_launch_security_info_args { remote_nonnull_domain dom; unsigned int flags; @@ -6342,5 +6355,11 @@ enum remote_procedure { * @generate: both * @acl: connect:read */ - REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403 + REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403, + + /** + * @generate: none + * @acl: connect:read + */ + REMOTE_PROC_NODE_GET_MKTME_INFO = 404 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 768189c573..7a3489c004 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2931,6 +2931,17 @@ struct remote_node_get_sev_info_ret { } params; int nparams; }; +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; +}; struct remote_domain_get_launch_security_info_args { remote_nonnull_domain dom; u_int flags; @@ -3385,4 +3396,5 @@ enum remote_procedure { REMOTE_PROC_CONNECT_LIST_ALL_NWFILTER_BINDINGS = 401, REMOTE_PROC_DOMAIN_SET_IOTHREAD_PARAMS = 402, REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403, + REMOTE_PROC_NODE_GET_MKTME_INFO = 404, }; -- 2.21.0.windows.1

--- src/qemu/qemu_driver.c | 63 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0a425b82e5..56bca8c2c4 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -22258,6 +22258,68 @@ qemuNodeGetSEVInfo(virConnectPtr conn, } +static int +qemuGetMKTMEInfoToParams(virQEMUCapsPtr qemuCaps, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + int maxpar = 0; + int n = 0; + virMKTMECapabilityPtr mktme = virQEMUCapsGetMKTMECapabilities(qemuCaps); + virTypedParameterPtr mktmeParams = 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 = n; + return 0; + + cleanup: + virTypedParamsFree(mktmeParams, n); + return -1; +} + + +static int +qemuNodeGetMKTMEInfo(virConnectPtr conn, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ + virQEMUDriverPtr driver = conn->privateData; + virQEMUCapsPtr qemucaps = NULL; + int ret = -1; + + if (virNodeGetMktmeInfoEnsureACL(conn) < 0) + return ret; + + qemucaps = 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 = 0; + + cleanup: + virObjectUnref(qemucaps); + return ret; +} + + static int qemuDomainGetSEVMeasurement(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -22552,6 +22614,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .connectBaselineHypervisorCPU = qemuConnectBaselineHypervisorCPU, /* 4.4.0 */ .nodeGetSEVInfo = qemuNodeGetSEVInfo, /* 4.5.0 */ .domainGetLaunchSecurityInfo = qemuDomainGetLaunchSecurityInfo, /* 4.5.0 */ + .nodeGetMKTMEInfo = qemuNodeGetMKTMEInfo, /* 5.3.0 */ }; -- 2.21.0.windows.1

The launch-security element can be used to define the security model to use when launching a domain. When 'mktme' is used, the VM will be launched with Intel MKTME feature enabled. MKTME feature supports running encrypted guest. --- docs/formatdomain.html.in | 64 +++++++++++++++++-- docs/schemas/domaincommon.rng | 87 +++++++++++++++++--------- src/conf/domain_conf.c | 112 +++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 14 +++++ src/conf/virconftypes.h | 3 + 5 files changed, 242 insertions(+), 38 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e1da878fcc..10d512ccd1 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8924,13 +8924,16 @@ qemu-kvm -net nic,model=? /dev/null <p>Note: DEA/TDEA is synonymous with DES/TDES.</p> - <h3><a id="sev">Launch Security</a></h3> + <h3><a id="launchsecurity">Launch Security</a></h3> <p> - The contents of the <code><launchSecurity type='sev'></code> element - is used to provide the guest owners input used for creating an encrypted - VM using the AMD SEV feature (Secure Encrypted Virtualization). - + The contents of the <code>launchSecurity</code> element is used + to provide the guest owners input used for creating an encrypted + VM using the AMD SEV feature (Secure Encrypted Virtualization) + and Intel MKTME (Multi-Key Total Memory Encryption). + </p> + <h4><a id="sev">SEV</a></h4> + <p> 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 guest @@ -8942,7 +8945,7 @@ qemu-kvm -net nic,model=? /dev/null For more information see various input parameters and its format see the <a href="https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf">SEV API spec</a> <span class="since">Since 4.4.0</span> - </p> + </p> <pre> <domain> ... @@ -9039,6 +9042,55 @@ qemu-kvm -net nic,model=? /dev/null </dd> </dl> + <h4><a id="mktme">MKTME</a></h4> + <p> + Total Memory Encryption (TME) ��� 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. + + 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 an 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 + <a href="https://software.intel.com/sites/default/files/managed/a5/16/Multi-Key-Total-Memory-Encryption-Spec.pdf">MKTME spec</a> + <span class="since">Since 5.3.0</span> + </p> +<pre> +<domain> + ... + <launchSecurity type='mktme'> + <id>mktme-0</id> + <key_type>samplekey</key_type> + <type>user</type> + <encryption_algorithm>aes-xts-128</encryption_algorithm> + </launchSecurity> + ... +</domain> +</pre> + <dl> + <dt><code>id</code></dt> + <dd>The required <code>id</code> element provides ability to map the key handle. + If the id exists, system returns the existing key handle which can be used to + encrpyt a different guest. + </dd> + <dt><code>key_type</code></dt> + <dd>MKTME supports user and cpu generated keys. The required <code>key_type</code> + element provides the type of key used for the encryption. + </dd> + <dt><code>key</code></dt> + <dd>The optional <code>key</code> element provides the key used for the encryption. + Required only when the key type is of user. + </dd> + <dt><code>encryption_algorithm</code></dt> + <dd>The required <code>encyption_algorithm</code> element provides the type of + encryption algorithm. Currently, MKTME supports aes-xts-128 only. + </dd> + </dl> + <h2><a id="examples">Example configs</a></h2> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 111b85c36f..5e6847d64e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -457,35 +457,64 @@ <define name="launchSecurity"> <element name="launchSecurity"> - <attribute name="type"> - <value>sev</value> - </attribute> - <interleave> - <element name="cbitpos"> - <data type='unsignedInt'/> - </element> - <element name="reducedPhysBits"> - <data type='unsignedInt'/> - </element> - <element name="policy"> - <ref name='hexuint'/> - </element> - <optional> - <element name="handle"> - <ref name='unsignedInt'/> - </element> - </optional> - <optional> - <element name="dhCert"> - <data type="string"/> - </element> - </optional> - <optional> - <element name="session"> - <data type="string"/> - </element> - </optional> - </interleave> + <choice> + <group> + <optional> + <attribute name="type"> + <value>sev</value> + </attribute> + </optional> + <interleave> + <element name="cbitpos"> + <data type='unsignedInt'/> + </element> + <element name="reducedPhysBits"> + <data type='unsignedInt'/> + </element> + <element name="policy"> + <ref name='hexuint'/> + </element> + <optional> + <element name="handle"> + <ref name='unsignedInt'/> + </element> + </optional> + <optional> + <element name="dhCert"> + <data type="string"/> + </element> + </optional> + <optional> + <element name="session"> + <data type="string"/> + </element> + </optional> + </interleave> + </group> + <group> + <optional> + <attribute name="type"> + <value>mktme</value> + </attribute> + </optional> + <interleave> + <element name="id"> + <data type="string"/> + </element> + <element name="key_type"> + <data type="string"/> + </element> + <element name="encryption_algorithm"> + <data type="string"/> + </element> + <optional> + <element name="key"> + <data type="string"/> + </element> + </optional> + </interleave> + </group> + </choice> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a3a514136b..7420a3f00d 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", ); static virClassPtr virDomainObjClass; @@ -3282,6 +3283,21 @@ virDomainSEVDefFree(virDomainSEVDefPtr def) } +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); +} + + void virDomainDefFree(virDomainDefPtr def) { size_t i; @@ -3466,6 +3482,7 @@ void virDomainDefFree(virDomainDefPtr def) (def->ns.free)(def->namespaceData); virDomainSEVDefFree(def->sev); + virDomainMKTMEDefFree(def->mktme); xmlFreeNode(def->metadata); @@ -15940,6 +15957,44 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, } +static int +virDomainGetLaunchSecurityType(xmlNodePtr node) +{ + VIR_AUTOFREE(char *) type = NULL; + + if (!(type = virXMLPropString(node, "type"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing launch security type")); + return -1; + } + + return virDomainLaunchSecurityTypeFromString(type); +} + + +static virDomainMKTMEDefPtr +virDomainMKTMEDefParseXML(xmlNodePtr mktmeNode, + xmlXPathContextPtr ctxt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + virDomainMKTMEDefPtr def; + + if (VIR_ALLOC(def) < 0) + return NULL; + + ctxt->node = mktmeNode; + + def->sectype = VIR_DOMAIN_LAUNCH_SECURITY_MKTME; + + def->id = virXPathString("string(./id)", ctxt); + def->key_type = virXPathString("string(./key_type)", ctxt); + def->key = virXPathString("string(./key)", ctxt); + def->encryption_algorithm = virXPathString("string(./encryption_algorithm)", ctxt); + + return def; +} + + static virDomainSEVDefPtr virDomainSEVDefParseXML(xmlNodePtr sevNode, xmlXPathContextPtr ctxt) @@ -15965,6 +16020,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, @@ -21127,11 +21183,33 @@ virDomainDefParseXML(xmlDocPtr xml, ctxt->node = node; VIR_FREE(nodes); - /* Check for SEV feature */ + /* Check for launch security (MKTME/SEV) feature */ if ((node = virXPathNode("./launchSecurity", ctxt)) != NULL) { - def->sev = virDomainSEVDefParseXML(node, ctxt); - if (!def->sev) + int sectype = virDomainGetLaunchSecurityType(node); + + if (sectype < 0) goto error; + + switch ((virDomainLaunchSecurity)sectype) { + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + /* Optimize virDomainSEVDefParseXML; since we are already checking for sectype*/ + def->sev = virDomainSEVDefParseXML(node, ctxt); + if (!def->sev) + goto error; + break; + case VIR_DOMAIN_LAUNCH_SECURITY_MKTME: + def->mktme = 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; + } } /* analysis of memory devices */ @@ -27268,6 +27346,33 @@ virDomainSEVDefFormat(virBufferPtr buf, virDomainSEVDefPtr sev) } +static void +virDomainMKTMEDefFormat(virBufferPtr buf, virDomainMKTMEDefPtr mktme) +{ + if (!mktme) + return; + + virBufferAsprintf(buf, "<launchSecurity type='%s'>\n", + virDomainLaunchSecurityTypeToString(mktme->sectype)); + virBufferAdjustIndent(buf, 2); + + if (mktme->id) + virBufferEscapeString(buf, "<id>%s</id>\n", mktme->id); + + if (mktme->key_type) + virBufferEscapeString(buf, "<key_type>%s</key_type>\n", mktme->key_type); + + if (mktme->key) + virBufferEscapeString(buf, "<key>%s</key>\n", mktme->key); + + if (mktme->encryption_algorithm) + virBufferEscapeString(buf, "<encryption_algorithm>%s</encryption_algorithm>\n", mktme->encryption_algorithm); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</launchSecurity>\n"); +} + + static void virDomainPerfDefFormat(virBufferPtr buf, virDomainPerfDefPtr perf) { @@ -28640,6 +28745,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virDomainKeyWrapDefFormat(buf, def->keywrap); virDomainSEVDefFormat(buf, def->sev); + virDomainMKTMEDefFormat(buf, def->mktme); virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</domain>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fa0756b634..b86d02376c 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, VIR_DOMAIN_LAUNCH_SECURITY_LAST, } virDomainLaunchSecurity; @@ -2294,6 +2295,16 @@ struct _virDomainSEVDef { }; +struct _virDomainMKTMEDef { + int sectype; /* enum virDomainLaunchSecurity */ + char *id; + char *key_type; + char *key; + char *encryption_algorithm; + int key_handle; +}; + + typedef enum { VIR_DOMAIN_IOMMU_MODEL_INTEL, @@ -2491,6 +2502,9 @@ struct _virDomainDef { /* SEV-specific domain */ virDomainSEVDefPtr sev; + /* MKTME- domain info*/ + virDomainMKTMEDefPtr mktme; + /* Application-specific custom metadata */ xmlNodePtr metadata; diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index 6a8267c422..c432e4493f 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -277,6 +277,9 @@ typedef virDomainResourceDef *virDomainResourceDefPtr; typedef struct _virDomainSEVDef virDomainSEVDef; typedef virDomainSEVDef *virDomainSEVDefPtr; +typedef struct _virDomainMKTMEDef virDomainMKTMEDef; +typedef virDomainMKTMEDef *virDomainMKTMEDefPtr; + typedef struct _virDomainShmemDef virDomainShmemDef; typedef virDomainShmemDef *virDomainShmemDefPtr; -- 2.21.0.windows.1

QEMU provides 'mktme-guest' object which is used to launch encrypted VMs on Intel platform using MKTME feature. The various inputs required to launch MKTME guest is provided through the <launchSecurity> tag. MKTME guest launch command: # Qemu ...\ -machine pc,memory-encryption=m0 -object mktme-guest,id=m0,handle=${serial} Using system call to generate mktme handle. Required input to generate MKTME key which returns key handle: CPU Mode: type=cpu algorithm=ats-xts-128 User Mode: type=user algorithm=ats-xts-128 key=1234567887654321 tweak=1234567887654321 --- src/libvirt_private.syms | 3 + src/qemu/qemu_command.c | 40 ++++++++++++ src/util/Makefile.inc.am | 2 + src/util/virmktme.c | 127 +++++++++++++++++++++++++++++++++++++++ src/util/virmktme.h | 34 +++++++++++ 5 files changed, 206 insertions(+) create mode 100644 src/util/virmktme.c create mode 100644 src/util/virmktme.h diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1b83e44b15..90f98097ef 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2353,6 +2353,9 @@ virMediatedDeviceSetUsedBy; virMediatedDeviceTypeFree; virMediatedDeviceTypeReadAttrs; +# util/virmktme.h +virGetMktmeKeyHandle; +virIsMktmeEnabled; # util/virmodule.h virModuleLoad; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index aae2f43044..2b35a1116e 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 <linux/capability.h> #endif @@ -7788,6 +7789,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, if (def->sev) virBufferAddLit(&buf, ",memory-encryption=sev0"); + if (def->mktme) + virBufferAddLit(&buf, ",memory-encryption=m0"); + virCommandAddArgBuffer(cmd, &buf); ret = 0; @@ -10291,6 +10295,39 @@ qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd, return ret; } + +static int +qemuBuildMKTMECommandLine(virCommandPtr cmd, + virDomainMKTMEDefPtr mktme) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + int ret = -1; + + if (!mktme) + return 0; + + if ((mktme->key_handle = virGetMktmeKeyHandle(mktme->id, mktme->key_type, + 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=%s key_type=%s key_handle=0x%x", + mktme->id, mktme->key_type, mktme->key_handle); + + virBufferAsprintf(&buf, "mktme-guest,id=m0,handle=%d", mktme->key_handle); + + virCommandAddArg(cmd, "-object"); + virCommandAddArgBuffer(cmd, &buf); + ret = 0; + + virBufferFreeAndReset(&buf); + return ret; +} + + static int qemuBuildVMCoreInfoCommandLine(virCommandPtr cmd, const virDomainDef *def, @@ -10911,6 +10948,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildSEVCommandLine(vm, cmd, def->sev) < 0) goto error; + if (qemuBuildMKTMECommandLine(cmd, def->mktme) < 0) + goto error; + if (snapshot) virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL); diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index c757f5a6ae..2dc920f47c 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -228,6 +228,8 @@ UTIL_SOURCES = \ util/virmdev.h \ util/virfilecache.c \ util/virfilecache.h \ + util/virmktme.c \ + util/virmktme.h \ $(NULL) diff --git a/src/util/virmktme.c b/src/util/virmktme.c new file mode 100644 index 0000000000..f78d5de8d6 --- /dev/null +++ b/src/util/virmktme.c @@ -0,0 +1,127 @@ +/* + * virmktme.c: interaction with mktme key ring services + * + * 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 + * <http://www.gnu.org/licenses/>. + * + */ + +#ifdef __linux__ +#include <config.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <asm/unistd.h> +#include <linux/keyctl.h> +#endif +#include "virerror.h" +#include "virlog.h" +#include "viraudit.h" +#include "virfile.h" +#include "viralloc.h" +#include "virutil.h" +#include "virstring.h" +#include "virrandom.h" +#include "virmktme.h" + +VIR_LOG_INIT("util.mktme"); + +#define VIR_FROM_THIS VIR_FROM_NONE + +#define MKTME_AES_XTS_SIZE 16 + +#ifdef __linux__ +#define GET_MKTME_DEST_RING() \ + { \ + destringid = syscall(__NR_request_key, \ + "keyring", \ + LIBVIRT_MKTME_KEY_RING_NAME, \ + KEY_SPEC_PROCESS_KEYRING); \ + } +#else +#define GET_MKTME_DEST_RING() +#endif + +/** + * virGetMktmeKey: + * @id: mktme id-string + * @type: mktme key type + * @key: user key value + * @encyption_algorithm: encryption algorithm + * + * Request's a key handle, which is required to launch a encrypted guest + * + * Returns mktme key handle in case of success, and -1 in case of failure + */ +int +virGetMktmeKeyHandle(const char *id, + const char *type, + const char *key, + const char *algorithm) +{ + char *callout = NULL; + int destringid = -1; + unsigned char kern_entropy[MKTME_AES_XTS_SIZE]; + + int ret = -1; + + if (!id || !type || !algorithm) + return -1; + + GET_MKTME_DEST_RING(); + if (destringid < 0) + return -1; + + if (key) { + if (sizeof(key) != MKTME_AES_XTS_SIZE) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Invalid MKTME key length")); + return -1; + } + if (virRandomBytes(kern_entropy, MKTME_AES_XTS_SIZE) < 0) + return -1; + if (virAsprintf(&callout, "type=%s algorithm=%s key=%s tweak=%s", + type, algorithm, key, kern_entropy) < 0) + return -1; + } else { + if (virAsprintf(&callout, "type=%s algorithm=%s", type, algorithm) < 0) + return -1; + } + +#ifdef __linux__ + ret = syscall(__NR_request_key, "mktme", id, callout, destringid); + VIR_FREE(callout); +#endif + return ret; +} + +/** + * virIsMktmeEnabled: + * + * Check if mktme key ring exists. + * + * Returns 0 in case mktme key ring exists, and -1 in case not present + */ +int +virIsMktmeEnabled(void) +{ + int destringid = -1; + GET_MKTME_DEST_RING(); + if (destringid < 0) + return -1; + + return 0; +} diff --git a/src/util/virmktme.h b/src/util/virmktme.h new file mode 100644 index 0000000000..e417e6eb67 --- /dev/null +++ b/src/util/virmktme.h @@ -0,0 +1,34 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBVIRT_VIRMKTME_H +# define LIBVIRT_VIRMKTME_H + +int +virGetMktmeKeyHandle(const char *id, + const char *type, + const char *key, + const char *algorithm); + +int +virIsMktmeEnabled(void); + +# define LIBVIRT_MKTME_KEY_RING_NAME "mktme_key_ring_service" +#endif /* LIBVIRT_VIRMKTME_H */ -- 2.21.0.windows.1
participants (1)
-
Larkins Carvalho