Re: [libvirt] [PATCH v6 5/9] qemu: add support to launch SEV guest

2018-05-28 Thread Erik Skultety
On Wed, May 23, 2018 at 04:18:30PM -0500, Brijesh Singh wrote:
> QEMU >= 2.12 provides 'sev-guest' object which is used to launch encrypted
>

Unnecessary new line here...

> 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 
> ---

Reviewed-by: Erik Skultety 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v6 5/9] qemu: add support to launch SEV guest

2018-05-23 Thread Brijesh Singh
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,