SEV-SNP is an enhancement of SEV/SEV-ES and thus it shares some fields with it. Nevertheless, on XML level, it's yet another type of <launchSecurity/>. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- docs/formatdomain.rst | 108 ++++++++++++++++++ src/conf/domain_conf.c | 73 ++++++++++++ src/conf/domain_conf.h | 15 +++ src/conf/domain_validate.c | 44 +++++++ src/conf/schemas/domaincommon.rng | 49 ++++++++ src/conf/virconftypes.h | 2 + src/qemu/qemu_cgroup.c | 1 + src/qemu/qemu_command.c | 4 + src/qemu/qemu_driver.c | 1 + src/qemu/qemu_firmware.c | 3 + src/qemu/qemu_namespace.c | 1 + src/qemu/qemu_process.c | 3 + src/qemu/qemu_validate.c | 9 ++ src/security/security_dac.c | 2 + ...launch-security-sev-snp.x86_64-latest.args | 34 ++++++ .../launch-security-sev-snp.x86_64-latest.xml | 1 + .../launch-security-sev-snp.xml | 47 ++++++++ tests/qemuxmlconftest.c | 2 + 18 files changed, 399 insertions(+) create mode 100644 tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args create mode 120000 tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/launch-security-sev-snp.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 00f861e385..5c09b87d2b 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -8867,6 +8867,114 @@ spec <https://support.amd.com/TechDocs/55766_SEV-KM_API_Specification.pdf>`__ session blob defined in the SEV API spec. See SEV spec LAUNCH_START section for the session blob format. + +Some modern AMD processors support Secure Encrypted Virtualization with Secure +Nested Paging enhancement, also known as SEV-SNP. :since:`Since 10.5.0` To +enable it ``<launchSecurity type='sev-snp'>`` should be used. It shares some +attributes and elements with ``type='sev'`` but differs in others. Example configuration: + +:: + + <domain> + ... + <launchSecurity type='sev-snp' authorKey='yes' vcek='no'> + <cbitpos>47</cbitpos> + <reducedPhysBits>1</reducedPhysBits> + <policy>0x00030000</policy> + <guestVisibleWorkarounds>...</guestVisibleWorkarounds> + <idBlock>...</idBlock> + <idAuth>...</idAuth> + <hostData>.../hostData> + </launchSecurity> + ... + </domain> + +The ``<launchSecurity/>`` element accepts the following attributes: + +``kernelHashes`` + The optional ``kernelHashes`` attribute indicates whether the + hashes of the kernel, ramdisk and command line should be included + in the measurement done by the firmware. This is only valid if + using direct kernel boot. + +``authorKey`` + The optional ``authorKey`` attribute indicates whether ``<idAuth/>`` element + contains the 'AUTHOR_KEY' field defined SEV-SNP firmware ABI. + +``vcek`` + The optional ``vcek`` attribute indicates whether the guest is allowed to + chose between VLEK (Versioned Loaded Endorsement Key) or VCEK (Versioned + Chip Endorsement Key) when requesting attestation reports from firmware. + Set this to ``no`` to disable the use of VCEK. + +Aforementioned SEV-SNP firmware ABI can be found here: +`<https://www.amd.com/system/files/TechDocs/56860.pdf>`__ + +The ``<launchSecurity/>`` element then accepts the following child elements: + +``cbitpos`` + The required ``cbitpos`` element provides the C-bit (aka encryption bit) + location in guest page table entry. The value of ``cbitpos`` is hypervisor + dependent and can be obtained through the ``sev`` element from the domain + capabilities. +``reducedPhysBits`` + The required ``reducedPhysBits`` element provides the physical address bit + reduction. Similar to ``cbitpos`` the value of ``reduced-phys-bit`` is + hypervisor dependent and can be obtained through the ``sev`` element from the + domain capabilities. +``policy`` + The required ``policy`` element provides the guest policy which must be + maintained by the SEV-SNP firmware. This policy is enforced by the firmware + and restricts what configuration and operational commands can be performed + on this guest by the hypervisor. The guest policy provided during guest + launch is bound to the guest and cannot be changed throughout the lifetime + of the guest. The policy is also transmitted during snapshot and migration + flows and enforced on the destination platform. The guest policy is a 64bit + unsigned number with the fields shown in table (See section `4.3 Guest + Policy` in aforementioned firmware ABI specification): + + ====== ========================================================================================= + Bit(s) Description + ====== ========================================================================================= + 63:25 Reserved. Must be zero. + 24 Ciphertext hiding must be enabled when set, otherwise may be enabled or disabled. + 23 Running Average Power Limit (RAPL) must be disabled when set. + 22 Require AES 256 XTS for memory encryption when set, otherwise AES 128 XEX may be allowed. + 21 CXL can be populated with devices or memory when set. + 20 Guest can be activated only on one socket when set. + 19 Debugging is allowed when set. + 18 Association with a migration agent is allowed when set. + 17 Reserved. Must be set. + 16 SMT is allowed. + 15:8 The minimum ABI major version required for this guest to run. + 7:0 The minimum ABI minor version required for this guest to run. + ====== ========================================================================================= + + The default value is hypervisor dependant and QEMU defaults to value 0x30000 + meaning no minimum ABI major/minor version is required and SMT is allowed. + +``guestVisibleWorkarounds`` + The optional ``guestVisibleWorkarounds`` element is a 16-byte, + base64-encoded blob to report hypervisor-defined workarounds, corresponding + to the 'GOSVW' parameter of the SNP_LAUNCH_START command defined in the + SEV-SNP firmware ABI. + +``idBlock`` + The optional ``idBlock`` element is a 96-byte, base64-encoded blob to + provide the 'ID Block' structure for the SNP_LAUNCH_FINISH command defined + in the SEV-SNP firmware ABI. + +``idAuth`` + The optional ``idAuth`` element is a 4096-byte, base64-encoded blob to + provide the 'ID Authentication Information Structure' for the + SNP_LAUNCH_FINISH command defined in the SEV-SNP firmware ABI. + +``hostData`` + The optional ``hostData`` element is a 32-byte, base64-encoded, user-defined + blob to provide to the guest, as documented for the 'HOST_DATA' parameter of + the SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI. + + Example configs =============== diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 102a011be8..cb1154b23f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1509,6 +1509,7 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity, VIR_DOMAIN_LAUNCH_SECURITY_LAST, "", "sev", + "sev-snp", "s390-pv", ); @@ -3835,6 +3836,12 @@ virDomainSecDefFree(virDomainSecDef *def) g_free(def->data.sev.dh_cert); g_free(def->data.sev.session); break; + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + g_free(def->data.sev_snp.guest_visible_workarounds); + g_free(def->data.sev_snp.id_block); + g_free(def->data.sev_snp.id_auth); + g_free(def->data.sev_snp.host_data); + break; case VIR_DOMAIN_LAUNCH_SECURITY_PV: case VIR_DOMAIN_LAUNCH_SECURITY_NONE: case VIR_DOMAIN_LAUNCH_SECURITY_LAST: @@ -13676,6 +13683,36 @@ virDomainSEVDefParseXML(virDomainSEVDef *def, } +static int +virDomainSEVSNPDefParseXML(virDomainSEVSNPDef *def, + xmlXPathContextPtr ctxt) +{ + if (virDomainSEVCommonDefParseXML(&def->common, ctxt) < 0) + return -1; + + if (virXMLPropTristateBool(ctxt->node, "authorKey", VIR_XML_PROP_NONE, + &def->author_key) < 0) + return -1; + + if (virXMLPropTristateBool(ctxt->node, "vcek", VIR_XML_PROP_NONE, + &def->vcek) < 0) + return -1; + + if (virXPathULongLongBase("string(./policy)", ctxt, 16, &def->policy) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("failed to get launch security policy")); + return -1; + } + + def->guest_visible_workarounds = virXPathString("string(./guestVisibleWorkarounds)", ctxt); + def->id_block = virXPathString("string(./idBlock)", ctxt); + def->id_auth = virXPathString("string(./idAuth)", ctxt); + def->host_data = virXPathString("string(./hostData)", ctxt); + + return 0; +} + + static virDomainSecDef * virDomainSecDefParseXML(xmlNodePtr lsecNode, xmlXPathContextPtr ctxt) @@ -13695,6 +13732,10 @@ virDomainSecDefParseXML(xmlNodePtr lsecNode, if (virDomainSEVDefParseXML(&sec->data.sev, ctxt) < 0) return NULL; break; + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + if (virDomainSEVSNPDefParseXML(&sec->data.sev_snp, ctxt) < 0) + return NULL; + break; case VIR_DOMAIN_LAUNCH_SECURITY_PV: break; case VIR_DOMAIN_LAUNCH_SECURITY_NONE: @@ -26683,6 +26724,34 @@ virDomainSEVDefFormat(virBuffer *attrBuf, } +static void +virDomainSEVSNPDefFormat(virBuffer *attrBuf, + virBuffer *childBuf, + virDomainSEVSNPDef *def) +{ + virDomainSEVCommonDefFormat(attrBuf, childBuf, &def->common); + + if (def->author_key != VIR_TRISTATE_BOOL_ABSENT) { + virBufferAsprintf(attrBuf, " authorKey='%s'", + virTristateBoolTypeToString(def->author_key)); + } + + if (def->vcek != VIR_TRISTATE_BOOL_ABSENT) { + virBufferAsprintf(attrBuf, " vcek='%s'", + virTristateBoolTypeToString(def->vcek)); + } + + virBufferAsprintf(childBuf, "<policy>0x%08llx</policy>\n", def->policy); + + virBufferEscapeString(childBuf, + "<guestVisibleWorkarounds>%s</guestVisibleWorkarounds>\n", + def->guest_visible_workarounds); + virBufferEscapeString(childBuf, "<idBlock>%s</idBlock>\n", def->id_block); + virBufferEscapeString(childBuf, "<idAuth>%s</idAuth>\n", def->id_auth); + virBufferEscapeString(childBuf, "<hostData>%s</hostData>\n", def->host_data); +} + + static void virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) { @@ -26700,6 +26769,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) virDomainSEVDefFormat(&attrBuf, &childBuf, &sec->data.sev); break; + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + virDomainSEVSNPDefFormat(&attrBuf, &childBuf, &sec->data.sev_snp); + break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c6c3c2e2a5..2818a9f1f5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2860,6 +2860,7 @@ struct _virDomainKeyWrapDef { typedef enum { VIR_DOMAIN_LAUNCH_SECURITY_NONE, VIR_DOMAIN_LAUNCH_SECURITY_SEV, + VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP, VIR_DOMAIN_LAUNCH_SECURITY_PV, VIR_DOMAIN_LAUNCH_SECURITY_LAST, @@ -2882,10 +2883,24 @@ struct _virDomainSEVDef { unsigned int policy; }; + +struct _virDomainSEVSNPDef { + virDomainSEVCommonDef common; + unsigned long long policy; + char *guest_visible_workarounds; + char *id_block; + char *id_auth; + char *host_data; + virTristateBool author_key; + virTristateBool vcek; +}; + + struct _virDomainSecDef { virDomainLaunchSecurity sectype; union { virDomainSEVDef sev; + virDomainSEVSNPDef sev_snp; } data; }; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 395e036e8f..0661caef68 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1800,6 +1800,47 @@ virDomainDefValidateIOThreads(const virDomainDef *def) } +#define CHECK_BASE64_LEN(val, elemName, exp_len) \ +{ \ + size_t len; \ + g_autofree unsigned char *tmp = NULL; \ + if (val && (tmp = g_base64_decode(val, &len)) && len != exp_len) { \ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \ + _("Unexpected length of '%1$s', expected %2$u got %3$zu"), \ + elemName, exp_len, len); \ + return -1; \ + } \ +} + +static int +virDomainDefLaunchSecurityValidate(const virDomainDef *def) +{ + virDomainSEVSNPDef *sev_snp; + + if (!def->sec) + return 0; + + switch (def->sec->sectype) { + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + sev_snp = &def->sec->data.sev_snp; + + CHECK_BASE64_LEN(sev_snp->guest_visible_workarounds, "guestVisibleWorkarounds", 16); + CHECK_BASE64_LEN(sev_snp->id_block, "idBlock", 96); + CHECK_BASE64_LEN(sev_snp->id_auth, "idAuth", 4096); + CHECK_BASE64_LEN(sev_snp->host_data, "hostData", 32); + break; + + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + case VIR_DOMAIN_LAUNCH_SECURITY_LAST: + } + + return 0; +} + +#undef CHECK_BASE64_LEN + static int virDomainDefValidateInternal(const virDomainDef *def, virDomainXMLOption *xmlopt) @@ -1855,6 +1896,9 @@ virDomainDefValidateInternal(const virDomainDef *def, if (virDomainDefValidateIOThreads(def) < 0) return -1; + if (virDomainDefLaunchSecurityValidate(def) < 0) + return -1; + return 0; } diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 9a7649df1c..844a931deb 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -515,6 +515,9 @@ <group> <ref name="launchSecuritySEV"/> </group> + <group> + <ref name="launchSecuritySEVSNP"/> + </group> <group> <attribute name="type"> <value>s390-pv</value> @@ -569,6 +572,52 @@ </interleave> </define> + <define name="launchSecuritySEVSNP"> + <attribute name="type"> + <value>sev-snp</value> + </attribute> + <optional> + <attribute name="kernelHashes"> + <ref name="virYesNo"/> + </attribute> + </optional> + <optional> + <attribute name="authorKey"> + <ref name="virYesNo"/> + </attribute> + </optional> + <optional> + <attribute name="vcek"> + <ref name="virYesNo"/> + </attribute> + </optional> + <interleave> + <ref name="launchSecuritySEVCommon"/> + <element name="policy"> + <ref name="hexuint"/> + </element> + <optional> + <element name="guestVisibleWorkarounds"> + <data type="string"/> + </element> + </optional> + <optional> + <element name="idBlock"> + <data type="string"/> + </element> + </optional> + <optional> + <element name="idAuth"> + <data type="string"/> + </element> + </optional> + <optional> + <element name="hostData"> + <data type="string"/> + </element> + </optional> + </interleave> + </define> <!-- Enable or disable perf events for the domain. For each of the events the following rules apply: diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index 34bb1e262f..d8e7c5278c 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -214,6 +214,8 @@ typedef struct _virDomainSEVCommonDef virDomainSEVCommonDef; typedef struct _virDomainSEVDef virDomainSEVDef; +typedef struct _virDomainSEVSNPDef virDomainSEVSNPDef; + typedef struct _virDomainSecDef virDomainSecDef; typedef struct _virDomainShmemDef virDomainShmemDef; diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 9e559c7c4f..23b7e6b4e8 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -848,6 +848,7 @@ qemuSetupDevicesCgroup(virDomainObj *vm) if (vm->def->sec) { switch (vm->def->sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: if (qemuSetupSEVCgroup(vm) < 0) return -1; break; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1879fa608c..8d83417bb6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7062,6 +7062,8 @@ qemuBuildMachineCommandLine(virCommand *cmd, virBufferAddLit(&buf, ",memory-encryption=lsec0"); } break; + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + break; case VIR_DOMAIN_LAUNCH_SECURITY_PV: virBufferAddLit(&buf, ",confidential-guest-support=lsec0"); break; @@ -9781,6 +9783,8 @@ qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd, case VIR_DOMAIN_LAUNCH_SECURITY_SEV: return qemuBuildSEVCommandLine(vm, cmd, &sec->data.sev); break; + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + break; case VIR_DOMAIN_LAUNCH_SECURITY_PV: return qemuBuildPVCommandLine(vm, cmd); break; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1a71857147..fc1704f4fc 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -19128,6 +19128,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain, switch (vm->def->sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: if (qemuDomainGetSEVInfo(vm, params, nparams, flags) < 0) goto cleanup; break; diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 8946dc1aa5..262eeecc5c 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1338,6 +1338,9 @@ qemuFirmwareMatchDomain(const virDomainDef *def, return false; } break; + + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + break; case VIR_DOMAIN_LAUNCH_SECURITY_PV: break; case VIR_DOMAIN_LAUNCH_SECURITY_NONE: diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c index fb7c9329dd..bbe3d5a1f7 100644 --- a/src/qemu/qemu_namespace.c +++ b/src/qemu/qemu_namespace.c @@ -653,6 +653,7 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm, switch (sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: VIR_DEBUG("Setting up launch security for SEV"); *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_SEV)); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d14975180a..b9b6ccf1de 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -6744,6 +6744,7 @@ qemuProcessPrepareDomain(virQEMUDriver *driver, if (vm->def->sec) { switch (vm->def->sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: VIR_DEBUG("Updating SEV platform info"); if (qemuProcessUpdateSEVInfo(vm) < 0) return -1; @@ -6818,6 +6819,8 @@ qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj *vm) switch (sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: return qemuProcessPrepareSEVGuestInput(vm); + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + break; case VIR_DOMAIN_LAUNCH_SECURITY_PV: return 0; case VIR_DOMAIN_LAUNCH_SECURITY_NONE: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 05ee477456..3cfcceafc9 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1325,6 +1325,15 @@ qemuValidateDomainDef(const virDomainDef *def, return -1; } break; + + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_SNP_GUEST)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("SEV SNP launch security is not supported with this QEMU binary")); + return -1; + } + break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT) || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_S390_PV_GUEST)) { diff --git a/src/security/security_dac.c b/src/security/security_dac.c index d0864313c1..1a3b51a298 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1954,6 +1954,7 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr, if (def->sec) { switch (def->sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: if (virSecurityDACRestoreSEVLabel(mgr, def) < 0) rc = -1; break; @@ -2187,6 +2188,7 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr, if (def->sec) { switch (def->sec->sectype) { case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + case VIR_DOMAIN_LAUNCH_SECURITY_SEV_SNP: if (virSecurityDACSetSEVLabel(mgr, def) < 0) return -1; break; diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args new file mode 100644 index 0000000000..37ac58edb8 --- /dev/null +++ b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.args @@ -0,0 +1,34 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \ +-accel kvm \ +-cpu qemu64 \ +-m size=219136k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \ +-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-storage","id":"ide0-0-0","bootindex":1}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml new file mode 120000 index 0000000000..0159cc057b --- /dev/null +++ b/tests/qemuxmlconfdata/launch-security-sev-snp.x86_64-latest.xml @@ -0,0 +1 @@ +launch-security-sev-snp.xml \ No newline at end of file diff --git a/tests/qemuxmlconfdata/launch-security-sev-snp.xml b/tests/qemuxmlconfdata/launch-security-sev-snp.xml new file mode 100644 index 0000000000..b277d7de1b --- /dev/null +++ b/tests/qemuxmlconfdata/launch-security-sev-snp.xml @@ -0,0 +1,47 @@ +<domain type='kvm'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='none'/> + </devices> + <launchSecurity type='sev-snp' authorKey='yes' vcek='no'> + <cbitpos>47</cbitpos> + <reducedPhysBits>1</reducedPhysBits> + <policy>0x00030000</policy> + <guestVisibleWorkarounds>bGlidmlydGxpYnZpcnRsaQ==</guestVisibleWorkarounds> + <idBlock>bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZp</idBlock> + <idAuth>bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnZpcnRsaWJ2aXJ0bA==</idAuth> + <hostData>bGlidmlydGxpYnZpcnRsaWJ2aXJ0bGlidmlydGxpYnY=</hostData> + </launchSecurity> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 5700ea314f..6733e73479 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -2849,6 +2849,8 @@ mymain(void) QEMU_CAPS_SEV_GUEST, QEMU_CAPS_LAST); + DO_TEST_CAPS_ARCH_LATEST("launch-security-sev-snp", "x86_64"); + DO_TEST_CAPS_ARCH_LATEST("launch-security-s390-pv", "s390x"); DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory"); -- 2.44.2