QEMU >= 2.12 provides 'sev-guest' object which is used to launch encrypted
VMs on AMD platform using SEV feature. The various inputs required to
launch SEV guest is provided through the tag. A typical
SEV guest launch command line looks like this:
# $QEMU ...\
-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 ...\
-machine memory-encryption=sev0 \
Signed-off-by: Brijesh Singh
---
src/qemu/qemu_command.c | 41
src/qemu/qemu_process.c | 62 +
tests/qemuxml2argvdata/launch-security-sev.args | 29
tests/qemuxml2argvdata/launch-security-sev.xml | 37 +++
tests/qemuxml2argvtest.c| 4 ++
5 files changed, 173 insertions(+)
create mode 100644 tests/qemuxml2argvdata/launch-security-sev.args
create mode 100644 tests/qemuxml2argvdata/launch-security-sev.xml
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cb397c75586a..63941e10ad83 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7203,6 +7203,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
virQEMUCapsGet(qemuCaps, QEMU_CAPS_LOADPARM))
qemuAppendLoadparmMachineParm(, def);
+if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST) && def->sev)
+virBufferAddLit(, ",memory-encryption=sev0");
+
virCommandAddArgBuffer(cmd, );
ret = 0;
@@ -9566,6 +9569,41 @@ qemuBuildTPMCommandLine(virCommandPtr cmd,
return 0;
}
+static int
+qemuBuildSevCommandLine(virDomainObjPtr vm, virCommandPtr cmd,
+virDomainSevDefPtr sev)
+{
+virBuffer obj = VIR_BUFFER_INITIALIZER;
+qemuDomainObjPrivatePtr priv = vm->privateData;
+char *path = NULL;
+
+if (!sev)
+return 0;
+
+VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d",
+ sev->policy, sev->cbitpos, sev->reduced_phys_bits);
+
+virBufferAsprintf(, "sev-guest,id=sev0,cbitpos=%d", sev->cbitpos);
+virBufferAsprintf(, ",reduced-phys-bits=%d", sev->reduced_phys_bits);
+virBufferAsprintf(, ",policy=0x%x", sev->policy);
+
+if (sev->dh_cert) {
+if (virAsprintf(, "%s/dh_cert.base64", priv->libDir) < 0)
+return -1;
+virBufferAsprintf(, ",dh-cert-file=%s", path);
+VIR_FREE(path);
+}
+
+if (sev->session) {
+if (virAsprintf(, "%s/session.base64", priv->libDir) < 0)
+return -1;
+virBufferAsprintf(, ",session-file=%s", path);
+VIR_FREE(path);
+}
+
+virCommandAddArgList(cmd, "-object", virBufferContentAndReset(), NULL);
+return 0;
+}
static int
qemuBuildVMCoreInfoCommandLine(virCommandPtr cmd,
@@ -10097,6 +10135,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildVMCoreInfoCommandLine(cmd, def, qemuCaps) < 0)
goto error;
+if (qemuBuildSevCommandLine(vm, cmd, def->sev) < 0)
+goto error;
+
if (snapshot)
virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ac2049b95df5..3cf818aee034 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5919,6 +5919,65 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
}
+static int
+qemuBuildSevCreateFile(const char *configDir,
+ const char *name,
+ const char *data)
+{
+char *configFile;
+
+if (!(configFile = virFileBuildPath(configDir, name, ".base64")))
+return -1;
+
+if (virFileRewriteStr(configFile, S_IRUSR | S_IWUSR, data) < 0) {
+virReportSystemError(errno, _("failed to write data to config '%s'"),
+ configFile);
+goto error;
+}
+
+VIR_FREE(configFile);
+return 0;
+
+ error:
+VIR_FREE(configFile);
+return -1;
+}
+
+
+static int
+qemuProcessPrepareSevGuestInput(virDomainObjPtr vm)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virDomainDefPtr def = vm->def;
+virQEMUCapsPtr qemuCaps = priv->qemuCaps;
+virDomainSevDefPtr sev = def->sev;
+
+if (!sev)
+return 0;
+
+VIR_DEBUG("Prepare SEV guest");
+
+if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST)) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+_("Domain %s asked for 'sev' launch but this "
+ "QEMU does not support SEV feature"), vm->def->name);
+return -1;
+}
+
+if (sev->dh_cert) {
+if (qemuBuildSevCreateFile(priv->libDir, "dh_cert", sev->dh_cert) < 0)
+return -1;
+}
+
+if (sev->session) {
+if (qemuBuildSevCreateFile(priv->libDir, "session", sev->session) < 0)
+return -1;
+}
+
+return 0;
+}
+
+
static int
qemuProcessPrepareHostStorage(virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -6043,6 +6102,9 @@ qemuProcessPrepareHost(virQEMUDriverPtr driver,