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

[libvirt] [PATCH v5 10/11] TPM support for QEMU command line



For TPM passthrough device support create command line parameters like:

-tpmdev passthrough,id=tpm-tpm0,path=/dev/tpm0,cancel-path=/sys/class/misc/tpm0/device/cancel -device tpm-tis,tpmdev=tpm-tpm0,id=tpm0

Signed-off-by: Stefan Berger <stefanb linux vnet ibm com>
Reviewed-by: Corey Bryant <coreyb linux vnet ibm com>
Tested-by: Corey Bryant <coreyb linux vnet ibm com>

---
 src/qemu/qemu_command.c |  104 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

Index: libvirt/src/qemu/qemu_command.c
===================================================================
--- libvirt.orig/src/qemu/qemu_command.c
+++ libvirt/src/qemu/qemu_command.c
@@ -46,6 +46,7 @@
 #include "base64.h"
 #include "device_conf.h"
 #include "virstoragefile.h"
+#include "virtpm.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -799,6 +800,10 @@ qemuAssignDeviceAliases(virDomainDefPtr
         if (virAsprintf(&def->rng->info.alias, "rng%d", 0) < 0)
             goto no_memory;
     }
+    if (def->tpm) {
+        if (virAsprintf(&def->tpm->info.alias, "tpm%d", 0) < 0)
+            goto no_memory;
+    }
 
     return 0;
 
@@ -4825,6 +4830,89 @@ cleanup:
 }
 
 
+static char *qemuBuildTPMBackendStr(const virDomainDefPtr def,
+                                    virQEMUCapsPtr qemuCaps,
+                                    const char *emulator)
+{
+    const virDomainTPMDefPtr tpm = def->tpm;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    const char *type = virDomainTPMBackendTypeToString(tpm->type);
+    const char *cancel_path;
+
+    virBufferAsprintf(&buf, "%s,id=tpm-%s", type, tpm->info.alias);
+
+    switch (tpm->type) {
+    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH))
+            goto no_support;
+
+        virBufferAddLit(&buf, ",path=");
+        virBufferEscape(&buf, ',', ",", "%s",
+                        tpm->data.passthrough.source.data.file.path);
+
+        if (!(cancel_path = virTPMFindCancelPath()))
+            goto error;
+
+        virBufferAddLit(&buf, ",cancel-path=");
+        virBufferEscape(&buf, ',', ",", "%s", cancel_path);
+        VIR_FREE(cancel_path);
+
+        break;
+    case VIR_DOMAIN_TPM_TYPE_LAST:
+        goto error;
+    }
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+ no_support:
+    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                   _("The QEMU executable %s does not support TPM "
+                     "backend type %s"),
+                   emulator, type);
+
+ error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
+
+static char *qemuBuildTPMDevStr(const virDomainDefPtr def,
+                                virQEMUCapsPtr qemuCaps,
+                                const char *emulator)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    const virDomainTPMDefPtr tpm = def->tpm;
+    const char *model = virDomainTPMModelTypeToString(tpm->model);
+
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_TIS)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("The QEMU executable %s does not support TPM "
+                       "model %s"),
+                       emulator, model);
+        goto error;
+    }
+
+    virBufferAsprintf(&buf, "%s,tpmdev=tpm-%s,id=%s",
+                      model, tpm->info.alias, tpm->info.alias);
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+ error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
+
 static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -7135,6 +7223,22 @@ qemuBuildCommandLine(virConnectPtr conn,
         }
     }
 
+    if (def->tpm) {
+        char *optstr;
+
+        if (!(optstr = qemuBuildTPMBackendStr(def, qemuCaps, emulator)))
+            goto error;
+
+        virCommandAddArgList(cmd, "-tpmdev", optstr, NULL);
+        VIR_FREE(optstr);
+
+        if (!(optstr = qemuBuildTPMDevStr(def, qemuCaps, emulator)))
+            goto error;
+
+        virCommandAddArgList(cmd, "-device", optstr, NULL);
+        VIR_FREE(optstr);
+    }
+
     for (i = 0 ; i < def->ninputs ; i++) {
         virDomainInputDefPtr input = def->inputs[i];
 


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