On 5/19/21 2:40 PM, Boris Fiuczynski wrote:
To allow other types of launch security the SEV type specific
parameters like e.g. policy need to be optional and be separated
from other new launch security types.
A test is added to ensure the previously required and now optional
launch security policy remains required when launch security type
is SEV.


I think you missed a breakline up there.


Reviewed-by: Daniel Henrique Barboza <danielhb...@gmail.com>

Signed-off-by: Boris Fiuczynski <fiu...@linux.ibm.com>
---
  docs/schemas/domaincommon.rng                 |  12 +-
  src/conf/domain_conf.c                        | 156 +++++++++++-------
  src/conf/domain_conf.h                        |  13 +-
  src/conf/virconftypes.h                       |   2 +
  src/qemu/qemu_cgroup.c                        |   4 +-
  src/qemu/qemu_command.c                       |  38 ++++-
  src/qemu/qemu_driver.c                        |   2 +-
  src/qemu/qemu_firmware.c                      |   4 +-
  src/qemu/qemu_namespace.c                     |  20 ++-
  src/qemu/qemu_process.c                       |  35 +++-
  src/qemu/qemu_validate.c                      |  22 ++-
  src/security/security_dac.c                   |   4 +-
  ...urity-sev-missing-policy.x86_64-2.12.0.err |   1 +
  .../launch-security-sev-missing-policy.xml    |  34 ++++
  tests/qemuxml2argvtest.c                      |   1 +
  15 files changed, 253 insertions(+), 95 deletions(-)
  create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err
  create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a2e5c50c1d..3df13a0cf1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -483,7 +483,9 @@
    <define name="launchSecurity">
      <element name="launchSecurity">
        <attribute name="type">
-        <value>sev</value>
+        <choice>
+          <value>sev</value>
+        </choice>
        </attribute>
        <interleave>
          <optional>
@@ -496,9 +498,11 @@
              <data type="unsignedInt"/>
            </element>
          </optional>
-        <element name="policy">
-          <ref name="hexuint"/>
-        </element>
+        <optional>
+          <element name="policy">
+            <ref name="hexuint"/>
+          </element>
+        </optional>
          <optional>
            <element name="handle">
              <ref name="unsignedInt"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b3ed3a9c5a..228de5d715 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3481,8 +3481,7 @@ virDomainResctrlDefFree(virDomainResctrlDef *resctrl)
  }
-static void
-virDomainSEVDefFree(virDomainSEVDef *def)
+void virDomainSEVDefFree(virDomainSEVDef *def)
  {
      if (!def)
          return;
@@ -3493,6 +3492,17 @@ virDomainSEVDefFree(virDomainSEVDef *def)
      g_free(def);
  }
+void virDomainSecDefFree(virDomainSecDef *def)
+{
+    if (!def)
+        return;
+
+    virDomainSEVDefFree(def->sev);
+
+    g_free(def);
+}
+
+
  static void
  virDomainOSDefClear(virDomainOSDef *os)
  {
@@ -3694,7 +3704,7 @@ void virDomainDefFree(virDomainDef *def)
      if (def->namespaceData && def->ns.free)
          (def->ns.free)(def->namespaceData);
- virDomainSEVDefFree(def->sev);
+    virDomainSecDefFree(def->sec);
xmlFreeNode(def->metadata); @@ -14688,72 +14698,80 @@ virDomainSEVDefParseXML(xmlNodePtr sevNode,
                          xmlXPathContextPtr ctxt)
  {
      VIR_XPATH_NODE_AUTORESTORE(ctxt)
-    virDomainSEVDef *def;
+    g_autoptr(virDomainSEVDef) sev = g_new0(virDomainSEVDef, 1);
      unsigned long policy;
-    g_autofree char *type = NULL;
      int rc = -1;
- def = g_new0(virDomainSEVDef, 1);
-
      ctxt->node = sevNode;
- if (!(type = virXMLPropString(sevNode, "type"))) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("missing launch security type"));
-        goto error;
-    }
-
-    def->sectype = virDomainLaunchSecurityTypeFromString(type);
-    switch ((virDomainLaunchSecurity) def->sectype) {
-    case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
-        break;
-    case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
-    case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
-    default:
-        virReportError(VIR_ERR_XML_ERROR,
-                       _("unsupported launch security type '%s'"),
-                       type);
-        goto error;
-    }
-
      if (virXPathULongHex("string(./policy)", ctxt, &policy) < 0) {
          virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("failed to get launch security policy"));
-        goto error;
+                       _("Failed to get launch security policy for "
+                         "launch security type SEV"));
+        return NULL;
      }
/* the following attributes are platform dependent and if missing, we can
       * autofill them from domain capabilities later
       */
-    rc = virXPathUInt("string(./cbitpos)", ctxt, &def->cbitpos);
+    rc = virXPathUInt("string(./cbitpos)", ctxt, &sev->cbitpos);
      if (rc == 0) {
-        def->haveCbitpos = true;
+        sev->haveCbitpos = true;
      } else if (rc == -2) {
          virReportError(VIR_ERR_XML_ERROR, "%s",
                         _("Invalid format for launch security cbitpos"));
-        goto error;
+        return NULL;
      }
rc = virXPathUInt("string(./reducedPhysBits)", ctxt,
-                      &def->reduced_phys_bits);
+                      &sev->reduced_phys_bits);
      if (rc == 0) {
-        def->haveReducedPhysBits = true;
+        sev->haveReducedPhysBits = true;
      } else if (rc == -2) {
          virReportError(VIR_ERR_XML_ERROR, "%s",
                         _("Invalid format for launch security "
                           "reduced-phys-bits"));
-        goto error;
+        return NULL;
      }
- def->policy = policy;
-    def->dh_cert = virXPathString("string(./dhCert)", ctxt);
-    def->session = virXPathString("string(./session)", ctxt);
+    sev->policy = policy;
+    sev->dh_cert = virXPathString("string(./dhCert)", ctxt);
+    sev->session = virXPathString("string(./session)", ctxt);
- return def;
+    return g_steal_pointer(&sev);
+}
- error:
-    virDomainSEVDefFree(def);
-    return NULL;
+
+static virDomainSecDef *
+virDomainSecDefParseXML(xmlNodePtr lsecNode,
+                        xmlXPathContextPtr ctxt)
+{
+    g_autoptr(virDomainSecDef) sec = g_new0(virDomainSecDef, 1);
+    g_autofree char *type = NULL;
+
+    if (!(type = virXMLPropString(lsecNode, "type"))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing launch security type"));
+        return NULL;
+    }
+
+    sec->sectype = virDomainLaunchSecurityTypeFromString(type);
+    switch ((virDomainLaunchSecurity) sec->sectype) {
+    case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+        sec->sev = virDomainSEVDefParseXML(lsecNode, ctxt);
+        if (!sec->sev)
+            return NULL;
+        break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+    case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+    default:
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("unsupported launch security type '%s'"),
+                       type);
+        return NULL;
+    }
+
+    return g_steal_pointer(&sec);
  }
@@ -20117,10 +20135,10 @@ virDomainDefParseXML(xmlDocPtr xml,
      ctxt->node = node;
      VIR_FREE(nodes);
- /* Check for SEV feature */
+    /* Check for launch security e.g. SEV feature */
      if ((node = virXPathNode("./launchSecurity", ctxt)) != NULL) {
-        def->sev = virDomainSEVDefParseXML(node, ctxt);
-        if (!def->sev)
+        def->sec = virDomainSecDefParseXML(node, ctxt);
+        if (!def->sec)
              goto error;
      }
@@ -26845,30 +26863,44 @@ virDomainKeyWrapDefFormat(virBuffer *buf, virDomainKeyWrapDef *keywrap) static void
-virDomainSEVDefFormat(virBuffer *buf, virDomainSEVDef *sev)
+virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec)
  {
-    if (!sev)
+    if (!sec)
          return;
- virBufferAsprintf(buf, "<launchSecurity type='%s'>\n",
-                      virDomainLaunchSecurityTypeToString(sev->sectype));
-    virBufferAdjustIndent(buf, 2);
+    switch ((virDomainLaunchSecurity) sec->sectype) {
+    case VIR_DOMAIN_LAUNCH_SECURITY_SEV: {
+        virDomainSEVDef *sev = sec->sev;
+        if (!sev)
+            return;
- if (sev->haveCbitpos)
-        virBufferAsprintf(buf, "<cbitpos>%d</cbitpos>\n", sev->cbitpos);
+        virBufferAsprintf(buf, "<launchSecurity type='%s'>\n",
+                          virDomainLaunchSecurityTypeToString(sec->sectype));
+        virBufferAdjustIndent(buf, 2);
- if (sev->haveReducedPhysBits)
-        virBufferAsprintf(buf, "<reducedPhysBits>%d</reducedPhysBits>\n",
-                          sev->reduced_phys_bits);
-    virBufferAsprintf(buf, "<policy>0x%04x</policy>\n", sev->policy);
-    if (sev->dh_cert)
-        virBufferEscapeString(buf, "<dhCert>%s</dhCert>\n", sev->dh_cert);
+        if (sev->haveCbitpos)
+            virBufferAsprintf(buf, "<cbitpos>%d</cbitpos>\n", sev->cbitpos);
- if (sev->session)
-        virBufferEscapeString(buf, "<session>%s</session>\n", sev->session);
+        if (sev->haveReducedPhysBits)
+            virBufferAsprintf(buf, "<reducedPhysBits>%d</reducedPhysBits>\n",
+                              sev->reduced_phys_bits);
+        virBufferAsprintf(buf, "<policy>0x%04x</policy>\n", sev->policy);
+        if (sev->dh_cert)
+            virBufferEscapeString(buf, "<dhCert>%s</dhCert>\n", sev->dh_cert);
+
+        if (sev->session)
+            virBufferEscapeString(buf, "<session>%s</session>\n", 
sev->session);
+
+        virBufferAdjustIndent(buf, -2);
+        virBufferAddLit(buf, "</launchSecurity>\n");
+        break;
+    }
+
+    case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+    case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+        break;
+    }
- virBufferAdjustIndent(buf, -2);
-    virBufferAddLit(buf, "</launchSecurity>\n");
  }
@@ -28306,7 +28338,7 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
      if (def->keywrap)
          virDomainKeyWrapDefFormat(buf, def->keywrap);
- virDomainSEVDefFormat(buf, def->sev);
+    virDomainSecDefFormat(buf, def->sec);
if (def->namespaceData && def->ns.format) {
          if ((def->ns.format)(buf, def->namespaceData) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cf8481f1f6..dd78f30ace 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2637,7 +2637,6 @@ typedef enum {
struct _virDomainSEVDef {
-    int sectype; /* enum virDomainLaunchSecurity */
      char *dh_cert;
      char *session;
      unsigned int policy;
@@ -2647,6 +2646,10 @@ struct _virDomainSEVDef {
      unsigned int reduced_phys_bits;
  };
+struct _virDomainSecDef {
+    int sectype; /* enum virDomainLaunchSecurity */
+    virDomainSEVDef *sev;
+};
typedef enum {
      VIR_DOMAIN_IOMMU_MODEL_INTEL,
@@ -2857,8 +2860,8 @@ struct _virDomainDef {
virDomainKeyWrapDef *keywrap; - /* SEV-specific domain */
-    virDomainSEVDef *sev;
+    /* launch security e.g. SEV */
+    virDomainSecDef *sec;
/* Application-specific custom metadata */
      xmlNodePtr metadata;
@@ -3271,6 +3274,10 @@ void virDomainRedirdevDefFree(virDomainRedirdevDef *def);
  void virDomainRedirFilterDefFree(virDomainRedirFilterDef *def);
  void virDomainShmemDefFree(virDomainShmemDef *def);
  G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainShmemDef, virDomainShmemDefFree);
+void virDomainSEVDefFree(virDomainSEVDef *def);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSEVDef, virDomainSEVDefFree);
+void virDomainSecDefFree(virDomainSecDef *def);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainSecDef, virDomainSecDefFree);
  void virDomainDeviceDefFree(virDomainDeviceDef *def);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainDeviceDef, virDomainDeviceDefFree);
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index ff5d8145c3..1459bea191 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -204,6 +204,8 @@ typedef struct _virDomainResourceDef virDomainResourceDef;
typedef struct _virDomainSEVDef virDomainSEVDef; +typedef struct _virDomainSecDef virDomainSecDef;
+
  typedef struct _virDomainShmemDef virDomainShmemDef;
typedef struct _virDomainSmartcardDef virDomainSmartcardDef;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 0e8835fb86..72bff2cbed 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -854,7 +854,9 @@ qemuSetupDevicesCgroup(virDomainObj *vm)
              return -1;
      }
- if (vm->def->sev && qemuSetupSEVCgroup(vm) < 0)
+    if (vm->def->sec &&
+        vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV &&
+        qemuSetupSEVCgroup(vm) < 0)
          return -1;
return 0;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d6c5308ef0..10dcf11d5b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6987,8 +6987,18 @@ qemuBuildMachineCommandLine(virCommand *cmd,
      if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_LOADPARM))
          qemuAppendLoadparmMachineParm(&buf, def);
- if (def->sev)
-        virBufferAddLit(&buf, ",memory-encryption=sev0");
+    if (def->sec) {
+        switch ((virDomainLaunchSecurity) def->sec->sectype) {
+        case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+            virBufferAddLit(&buf, ",memory-encryption=sev0");
+            break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+            break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+            virReportEnumRangeError(virDomainLaunchSecurity, 
def->sec->sectype);
+            return -1;
+        }
+    }
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
          if (priv->pflash0)
@@ -9868,6 +9878,28 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand 
*cmd,
      return 0;
  }
+
+static int
+qemuBuildSecCommandLine(virDomainObj *vm, virCommand *cmd,
+                        virDomainSecDef *sec)
+{
+    if (!sec)
+        return 0;
+
+    switch ((virDomainLaunchSecurity) sec->sectype) {
+    case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+        return qemuBuildSEVCommandLine(vm, cmd, sec->sev);
+        break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+        break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+        virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
+        return -1;
+    }
+
+    return 0;
+}
+
  static int
  qemuBuildVMCoreInfoCommandLine(virCommand *cmd,
                                 const virDomainDef *def)
@@ -10567,7 +10599,7 @@ qemuBuildCommandLine(virQEMUDriver *driver,
      if (qemuBuildVMCoreInfoCommandLine(cmd, def) < 0)
          return NULL;
- if (qemuBuildSEVCommandLine(vm, cmd, def->sev) < 0)
+    if (qemuBuildSecCommandLine(vm, cmd, def->sec) < 0)
          return NULL;
if (snapshot)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c90d52edc0..c3deec439c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19853,7 +19853,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
      if (virDomainGetLaunchSecurityInfoEnsureACL(domain->conn, vm->def) < 0)
          goto cleanup;
- if (vm->def->sev) {
+    if (vm->def->sec && vm->def->sec->sectype == 
VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
          if (qemuDomainGetSEVMeasurement(driver, vm, params, nparams, flags) < 
0)
              goto cleanup;
      }
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 2aeac635da..277ecc4b5b 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1042,8 +1042,8 @@ qemuFirmwareMatchDomain(const virDomainDef *def,
          return false;
      }
- if (def->sev &&
-        def->sev->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV &&
+    if (def->sec &&
+        def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV &&
          !supportsSEV) {
          VIR_DEBUG("Domain requires SEV, firmware '%s' doesn't support it", 
path);
          return false;
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 6a97863d92..0dd1291c5d 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -594,16 +594,26 @@ static int
  qemuDomainSetupLaunchSecurity(virDomainObj *vm,
                                GSList **paths)
  {
-    virDomainSEVDef *sev = vm->def->sev;
+    virDomainSecDef *sec = vm->def->sec;
- if (!sev || sev->sectype != VIR_DOMAIN_LAUNCH_SECURITY_SEV)
+    if (!sec)
          return 0;
- VIR_DEBUG("Setting up launch security");
+    switch ((virDomainLaunchSecurity) sec->sectype) {
+    case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+        VIR_DEBUG("Setting up launch security for SEV");
- *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_SEV));
+        *paths = g_slist_prepend(*paths, g_strdup(QEMU_DEV_SEV));
+
+        VIR_DEBUG("Set up launch security for SEV");
+        break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+        break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+        virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
+        return -1;
+    }
- VIR_DEBUG("Set up launch security");
      return 0;
  }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index b69a9d1927..a7d88015ba 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6410,7 +6410,7 @@ qemuProcessUpdateSEVInfo(virDomainObj *vm)
  {
      qemuDomainObjPrivate *priv = vm->privateData;
      virQEMUCaps *qemuCaps = priv->qemuCaps;
-    virDomainSEVDef *sev = vm->def->sev;
+    virDomainSEVDef *sev = vm->def->sec->sev;
      virSEVCapability *sevCaps = NULL;
/* if platform specific info like 'cbitpos' and 'reducedPhysBits' have
@@ -6566,7 +6566,7 @@ qemuProcessPrepareDomain(virQEMUDriver *driver,
      for (i = 0; i < vm->def->nshmems; i++)
          qemuDomainPrepareShmemChardev(vm->def->shmems[i]);
- if (vm->def->sev) {
+    if (vm->def->sec && vm->def->sec->sectype == 
VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
          VIR_DEBUG("Updating SEV platform info");
          if (qemuProcessUpdateSEVInfo(vm) < 0)
              return -1;
@@ -6602,12 +6602,13 @@ qemuProcessSEVCreateFile(virDomainObj *vm,
static int
-qemuProcessPrepareSEVGuestInput(virDomainObj *vm)
+qemuProcessPrepareSEVGuestInput(virDomainObj *vm,
+                                virDomainSecDef *sec)
  {
-    virDomainSEVDef *sev = vm->def->sev;
+    virDomainSEVDef *sev = sec->sev;
if (!sev)
-        return 0;
+        return -1;
VIR_DEBUG("Preparing SEV guest"); @@ -6625,6 +6626,28 @@ qemuProcessPrepareSEVGuestInput(virDomainObj *vm)
  }
+static int
+qemuProcessPrepareLaunchSecurityGuestInput(virDomainObj *vm)
+{
+    virDomainSecDef *sec = vm->def->sec;
+
+    if (!sec)
+        return 0;
+
+    switch ((virDomainLaunchSecurity) sec->sectype) {
+    case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+        return qemuProcessPrepareSEVGuestInput(vm, sec);
+    case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+        break;
+    case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+        virReportEnumRangeError(virDomainLaunchSecurity, sec->sectype);
+        return -1;
+    }
+
+    return 0;
+}
+
+
  static int
  qemuProcessPrepareHostStorage(virQEMUDriver *driver,
                                virDomainObj *vm,
@@ -6804,7 +6827,7 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
      if (qemuExtDevicesPrepareHost(driver, vm) < 0)
          return -1;
- if (qemuProcessPrepareSEVGuestInput(vm) < 0)
+    if (qemuProcessPrepareLaunchSecurityGuestInput(vm) < 0)
          return -1;
return 0;
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 141203f979..78582a7c2a 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1214,12 +1214,22 @@ qemuValidateDomainDef(const virDomainDef *def,
      if (qemuValidateDomainDefPanic(def, qemuCaps) < 0)
          return -1;
- if (def->sev &&
-        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("SEV launch security is not supported with "
-                         "this QEMU binary"));
-        return -1;
+    if (def->sec) {
+        switch ((virDomainLaunchSecurity) def->sec->sectype) {
+        case VIR_DOMAIN_LAUNCH_SECURITY_SEV:
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST)) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("SEV launch security is not supported with "
+                                 "this QEMU binary"));
+                return -1;
+            }
+            break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_NONE:
+            break;
+        case VIR_DOMAIN_LAUNCH_SECURITY_LAST:
+            virReportEnumRangeError(virDomainLaunchSecurity, 
def->sec->sectype);
+            return -1;
+        }
      }
if (def->naudios > 1 &&
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index e973964735..289b614b73 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1980,7 +1980,7 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
              rc = -1;
      }
- if (def->sev) {
+    if (def->sec && def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
          if (virSecurityDACRestoreSEVLabel(mgr, def) < 0)
              rc = -1;
      }
@@ -2187,7 +2187,7 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
              return -1;
      }
- if (def->sev) {
+    if (def->sec && def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
          if (virSecurityDACSetSEVLabel(mgr, def) < 0)
              return -1;
      }
diff --git 
a/tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err 
b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err
new file mode 100644
index 0000000000..63eaf64071
--- /dev/null
+++ 
b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.x86_64-2.12.0.err
@@ -0,0 +1 @@
+XML error: Failed to get launch security policy for launch security type SEV
diff --git a/tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml 
b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml
new file mode 100644
index 0000000000..5461b06c9d
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-sev-missing-policy.xml
@@ -0,0 +1,34 @@
+<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-1.0'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <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'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+  <launchSecurity type='sev'>
+    <dhCert>AQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAAAQAAAAAOAAA</dhCert>
+    <session>IHAVENOIDEABUTJUSTPROVIDINGASTRING</session>
+  </launchSecurity>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 25b0c81f21..594a01de45 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -3496,6 +3496,7 @@ mymain(void)
DO_TEST_CAPS_VER("launch-security-sev", "2.12.0");
      DO_TEST_CAPS_VER("launch-security-sev-missing-platform-info", "2.12.0");
+    DO_TEST_CAPS_VER_PARSE_ERROR("launch-security-sev-missing-policy", 
"2.12.0");
DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");
      DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");


Reply via email to