[PATCH 09/12] conf: Introduce SEV-SNP support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux