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.
Signed-off-by: Boris Fiuczynski <fiuczy@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");
--
2.30.2
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 <danielhb413@gmail.com>
>
> Signed-off-by: Boris Fiuczynski <fiuczy@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");
>
© 2016 - 2026 Red Hat, Inc.