Probe for QEMU's QMP TPM support by querying the lists of
supported TPM models (query-tpm-models) and backend types
(query-tpm-types). 

The setting of the capability flags following the strings
returned from the commands above is only provided in the
patch where domain_conf.c gets TPM support due to dependencies
on functions only introduced there. 

Signed-off-by: Stefan Berger <stef...@linux.vnet.ibm.com>

---
 src/qemu/qemu_capabilities.c |    3 +
 src/qemu/qemu_capabilities.h |    3 +
 src/qemu/qemu_monitor.c      |   44 +++++++++++++++++++++
 src/qemu/qemu_monitor.h      |    6 ++
 src/qemu/qemu_monitor_json.c |   90 +++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |    8 +++
 6 files changed, 154 insertions(+)

Index: libvirt/src/qemu/qemu_capabilities.c
===================================================================
--- libvirt.orig/src/qemu/qemu_capabilities.c
+++ libvirt/src/qemu/qemu_capabilities.c
@@ -212,6 +212,9 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAS
               "rng-egd",
               "virtio-ccw",
               "dtb",
+              "tpm-passthrough",
+
+              "tpm-tis", /* 135 */
     );
 
 struct _virQEMUCaps {
Index: libvirt/src/qemu/qemu_capabilities.h
===================================================================
--- libvirt.orig/src/qemu/qemu_capabilities.h
+++ libvirt/src/qemu/qemu_capabilities.h
@@ -173,6 +173,8 @@ enum virQEMUCapsFlags {
     QEMU_CAPS_OBJECT_RNG_EGD     = 131, /* EGD protocol daemon for rng */
     QEMU_CAPS_VIRTIO_CCW         = 132, /* -device virtio-*-ccw */
     QEMU_CAPS_DTB                = 133, /* -dtb file */
+    QEMU_CAPS_DEVICE_TPM_PASSTHROUGH = 134, /* -tpmdev passthrough */
+    QEMU_CAPS_DEVICE_TPM_TIS     = 135, /* -device tpm_tis */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
@@ -254,4 +256,5 @@ int virQEMUCapsParseDeviceStr(virQEMUCap
 VIR_ENUM_DECL(virQEMUCaps);
 
 bool virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps);
+
 #endif /* __QEMU_CAPABILITIES_H__*/
Index: libvirt/src/qemu/qemu_monitor.c
===================================================================
--- libvirt.orig/src/qemu/qemu_monitor.c
+++ libvirt/src/qemu/qemu_monitor.c
@@ -3522,3 +3522,47 @@ int qemuMonitorNBDServerStop(qemuMonitor
 
     return qemuMonitorJSONNBDServerStop(mon);
 }
+
+
+int qemuMonitorGetTPMModels(qemuMonitorPtr mon,
+                            char ***tpmmodels)
+{
+    VIR_DEBUG("mon=%p tpmmodels=%p",
+              mon, tpmmodels);
+
+    if (!mon) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("monitor must not be NULL"));
+        return -1;
+    }
+
+    if (!mon->json) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("JSON monitor is required"));
+        return -1;
+    }
+
+    return qemuMonitorJSONGetTPMModels(mon, tpmmodels);
+}
+
+
+int qemuMonitorGetTPMTypes(qemuMonitorPtr mon,
+                           char ***tpmtypes)
+{
+    VIR_DEBUG("mon=%p tpmtypes=%p",
+              mon, tpmtypes);
+
+    if (!mon) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("monitor must not be NULL"));
+        return -1;
+    }
+
+    if (!mon->json) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("JSON monitor is required"));
+        return -1;
+    }
+
+    return qemuMonitorJSONGetTPMTypes(mon, tpmtypes);
+}
Index: libvirt/src/qemu/qemu_monitor.h
===================================================================
--- libvirt.orig/src/qemu/qemu_monitor.h
+++ libvirt/src/qemu/qemu_monitor.h
@@ -683,6 +683,12 @@ int qemuMonitorNBDServerAdd(qemuMonitorP
                             const char *deviceID,
                             bool writable);
 int qemuMonitorNBDServerStop(qemuMonitorPtr);
+int qemuMonitorGetTPMModels(qemuMonitorPtr mon,
+                            char ***tpmmodels);
+
+int qemuMonitorGetTPMTypes(qemuMonitorPtr mon,
+                           char ***tpmtypes);
+
 /**
  * When running two dd process and using <> redirection, we need a
  * shell that will not truncate files.  These two strings serve that
Index: libvirt/src/qemu/qemu_monitor_json.c
===================================================================
--- libvirt.orig/src/qemu/qemu_monitor_json.c
+++ libvirt/src/qemu/qemu_monitor_json.c
@@ -41,6 +41,7 @@
 #include "datatypes.h"
 #include "virerror.h"
 #include "virjson.h"
+#include "virstring.h"
 
 #ifdef WITH_DTRACE_PROBES
 # include "libvirt_qemu_probes.h"
@@ -4693,3 +4694,92 @@ qemuMonitorJSONNBDServerStop(qemuMonitor
     virJSONValueFree(reply);
     return ret;
 }
+
+
+static int
+qemuMonitorJSONGetStringArray(qemuMonitorPtr mon, const char *qmpCmd,
+                              char ***array)
+{
+    int ret;
+    virJSONValuePtr cmd;
+    virJSONValuePtr reply = NULL;
+    virJSONValuePtr data;
+    char **list = NULL;
+    int n = 0;
+    size_t i;
+
+    *array = NULL;
+
+    if (!(cmd = qemuMonitorJSONMakeCommand(qmpCmd, NULL)))
+        return -1;
+
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+    if (ret == 0)
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+
+    if (ret < 0)
+        goto cleanup;
+
+    ret = -1;
+
+    if (!(data = virJSONValueObjectGet(reply, "return"))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("%s reply was missing return data"),
+                       qmpCmd);
+        goto cleanup;
+    }
+
+    if ((n = virJSONValueArraySize(data)) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("%s reply data was not an array"),
+                       qmpCmd);
+        goto cleanup;
+    }
+
+    /* null-terminated list */
+    if (VIR_ALLOC_N(list, n + 1) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    for (i = 0 ; i < n ; i++) {
+        virJSONValuePtr child = virJSONValueArrayGet(data, i);
+        const char *tmp;
+
+        if (!(tmp = virJSONValueGetString(child))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("%s array element does not contain data"),
+                           qmpCmd);
+            goto cleanup;
+        }
+
+        if (!(list[i] = strdup(tmp))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+
+    ret = n;
+    *array = list;
+
+cleanup:
+    if (ret < 0)
+        virStringFreeList(list);
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+int qemuMonitorJSONGetTPMModels(qemuMonitorPtr mon,
+                                char ***tpmmodels)
+{
+    return qemuMonitorJSONGetStringArray(mon, "query-tpm-models", tpmmodels);
+}
+
+
+int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon,
+                               char ***tpmtypes)
+{
+    return qemuMonitorJSONGetStringArray(mon, "query-tpm-types", tpmtypes);
+}
Index: libvirt/src/qemu/qemu_monitor_json.h
===================================================================
--- libvirt.orig/src/qemu/qemu_monitor_json.h
+++ libvirt/src/qemu/qemu_monitor_json.h
@@ -341,4 +341,12 @@ int qemuMonitorJSONNBDServerAdd(qemuMoni
                                 const char *deviceID,
                                 bool writable);
 int qemuMonitorJSONNBDServerStop(qemuMonitorPtr mon);
+int qemuMonitorJSONGetTPMModels(qemuMonitorPtr mon,
+                                char ***tpmmodels)
+    ATTRIBUTE_NONNULL(2);
+
+int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon,
+                               char ***tpmtypes)
+    ATTRIBUTE_NONNULL(2);
+
 #endif /* QEMU_MONITOR_JSON_H */

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

Reply via email to