[RFC PATCH 1/7] qemu: provide support to query the TDX capabilities

Pavel Hrdina phrdina at redhat.com
Fri Jun 18 12:40:55 UTC 2021


On Fri, Jun 18, 2021 at 04:50:46PM +0800, Zhenzhong Duan wrote:
> QEMU provides support for launching an encrypted VMs on Intel x86
> platform using Trust Domain Extension (TDX) feature. This patch adds
> support to query the TDX capabilities from the QEMU.
> 
> Currently there is no elements in TDX capabilities except a placeholder.
> 
> Signed-off-by: Chenyi Qiang <chenyi.qiang at intel.com>
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan at intel.com>
> ---
>  src/conf/domain_capabilities.c |  8 +++++
>  src/conf/domain_capabilities.h | 10 +++++++
>  src/libvirt_private.syms       |  1 +
>  src/qemu/qemu_capabilities.c   | 30 +++++++++++++++++++
>  src/qemu/qemu_capabilities.h   |  1 +
>  src/qemu/qemu_monitor.c        |  8 +++++
>  src/qemu/qemu_monitor.h        |  3 ++
>  src/qemu/qemu_monitor_json.c   | 53 ++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_monitor_json.h   |  3 ++
>  9 files changed, 117 insertions(+)
> 
> diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
> index cb90ae0176..31577095e9 100644
> --- a/src/conf/domain_capabilities.c
> +++ b/src/conf/domain_capabilities.c
> @@ -76,6 +76,14 @@ virSEVCapabilitiesFree(virSEVCapability *cap)
>      g_free(cap);
>  }
>  
> +void
> +virTDXCapabilitiesFree(virTDXCapability *cap)
> +{
> +    if (!cap)
> +        return;
> +
> +    VIR_FREE(cap);
> +}
>  
>  static void
>  virDomainCapsDispose(void *obj)
> diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
> index b6433b20c9..e099788da9 100644
> --- a/src/conf/domain_capabilities.h
> +++ b/src/conf/domain_capabilities.h
> @@ -173,6 +173,12 @@ struct _virSEVCapability {
>      unsigned int reduced_phys_bits;
>  };
>  
> +typedef struct _virTDXCapability virTDXCapability;
> +struct _virTDXCapability {
> +    /* no elements for Intel TDX for now, just put a placeholder */
> +    uint64_t placeholder;
> +};
> +

There is no need to add unused code into libvirt especially if the
impact is only internal and it is not exposed to users. It can be added
in the future if needed. Because this patch series doesn't add any TDX
specific capability into this structure please drop all related code
to this placeholder.

Pavel

>  typedef enum {
>      VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0,
>      VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO,
> @@ -254,3 +260,7 @@ void
>  virSEVCapabilitiesFree(virSEVCapability *capabilities);
>  
>  G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree);
> +
> +void virTDXCapabilitiesFree(virTDXCapability *capabilities);
> +
> +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virTDXCapability, virTDXCapabilitiesFree);
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 2efa787664..8cbb60b577 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -218,6 +218,7 @@ virDomainCapsEnumSet;
>  virDomainCapsFormat;
>  virDomainCapsNew;
>  virSEVCapabilitiesFree;
> +virTDXCapabilitiesFree;
>  
>  
>  # conf/domain_conf.h
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 059d6badf2..a143e453f4 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -636,6 +636,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
>                /* 405 */
>                "confidential-guest-support",
>                "query-display-options",
> +              "tdx-guest",
>      );
>  
>  
> @@ -716,6 +717,8 @@ struct _virQEMUCaps {
>  
>      virSEVCapability *sevCapabilities;
>  
> +    virTDXCapability *tdxCapabilities;
> +
>      /* Capabilities which may differ depending on the accelerator. */
>      virQEMUCapsAccel kvm;
>      virQEMUCapsAccel tcg;
> @@ -1354,6 +1357,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
>      { "input-linux", QEMU_CAPS_INPUT_LINUX },
>      { "virtio-gpu-gl-pci", QEMU_CAPS_VIRTIO_GPU_GL_PCI },
>      { "virtio-vga-gl", QEMU_CAPS_VIRTIO_VGA_GL },
> +    { "tdx-guest", QEMU_CAPS_TDX_GUEST},
>  };
>  
>  
> @@ -2027,6 +2031,7 @@ void virQEMUCapsDispose(void *obj)
>      g_free(qemuCaps->gicCapabilities);
>  
>      virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
> +    virTDXCapabilitiesFree(qemuCaps->tdxCapabilities);
>  
>      virQEMUCapsAccelClear(&qemuCaps->kvm);
>      virQEMUCapsAccelClear(&qemuCaps->tcg);
> @@ -3354,6 +3359,29 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
>      return 0;
>  }
>  
> +static int
> +virQEMUCapsProbeQMPTDXCapabilities(virQEMUCaps *qemuCaps,
> +                                   qemuMonitor *mon)
> +{
> +    int rc = -1;
> +    virTDXCapability *caps = NULL;
> +
> +    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDX_GUEST))
> +        return 0;
> +
> +    if ((rc = qemuMonitorGetTDXCapabilities(mon, &caps)) < 0)
> +        return -1;
> +
> +    /* TDX isn't actually supported */
> +    if (rc == 0) {
> +        virQEMUCapsClear(qemuCaps, QEMU_CAPS_TDX_GUEST);
> +        return 0;
> +    }
> +
> +    virTDXCapabilitiesFree(qemuCaps->tdxCapabilities);
> +    qemuCaps->tdxCapabilities = caps;
> +    return 0;
> +}
>  
>  /*
>   * Filter for features which should never be passed to QEMU. Either because
> @@ -5316,6 +5344,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps,
>          return -1;
>      if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0)
>          return -1;
> +    if (virQEMUCapsProbeQMPTDXCapabilities(qemuCaps, mon) < 0)
> +        return -1;
>  
>      virQEMUCapsInitProcessCaps(qemuCaps);
>  
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index b2878312ac..a51bd9a256 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -616,6 +616,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
>      /* 405 */
>      QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT, /* -machine confidential-guest-support */
>      QEMU_CAPS_QUERY_DISPLAY_OPTIONS, /* 'query-display-options' qmp command present */
> +    QEMU_CAPS_TDX_GUEST, /* -object tdx-guest,... */
>  
>      QEMU_CAPS_LAST /* this must always be the last item */
>  } virQEMUCapsFlags;
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index 8f35b4240f..f2a3badeec 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -3946,6 +3946,14 @@ qemuMonitorNBDServerStart(qemuMonitor *mon,
>      return qemuMonitorJSONNBDServerStart(mon, server, tls_alias);
>  }
>  
> +int
> +qemuMonitorGetTDXCapabilities(qemuMonitor *mon,
> +                             virTDXCapability **capabilities)
> +{
> +    QEMU_CHECK_MONITOR(mon);
> +
> +    return qemuMonitorJSONGetTDXCapabilities(mon, capabilities);
> +}
>  
>  int
>  qemuMonitorNBDServerAdd(qemuMonitor *mon,
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 6a25def78b..48c18c5220 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -859,6 +859,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon,
>  int qemuMonitorGetSEVCapabilities(qemuMonitor *mon,
>                                    virSEVCapability **capabilities);
>  
> +int qemuMonitorGetTDXCapabilities(qemuMonitor *mon,
> +                                  virTDXCapability **capabilities);
> +
>  typedef enum {
>    QEMU_MONITOR_MIGRATE_BACKGROUND       = 1 << 0,
>    QEMU_MONITOR_MIGRATE_NON_SHARED_DISK  = 1 << 1, /* migration with non-shared storage with full disk copy */
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 223777739d..c58152e86f 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -7028,6 +7028,59 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon,
>      return ret;
>  }
>  
> +/**
> + * qemuMonitorJSONGetTDXCapabilities:
> + * @mon: qemu monitor object
> + * @capabilities: pointer to pointer to a TDX capability structure to be filled
> + *
> + * Returns -1 on error, 0 if TDX is not supported, and 1 if TDX is supported on
> + * the platform.
> + */
> +int
> +qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon,
> +                                  virTDXCapability **capabilities)
> +{
> +    int ret = -1;
> +    virJSONValue *cmd;
> +    virJSONValue *reply = NULL;
> +    g_autoptr(virTDXCapability) capability = NULL;
> +
> +    *capabilities = NULL;
> +
> +    if (!(cmd = qemuMonitorJSONMakeCommand("query-tdx-capabilities",
> +                                           NULL)))
> +        return -1;
> +
> +    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
> +        goto cleanup;
> +
> +    /* QEMU has only compiled-in support of TDX */
> +    if (qemuMonitorJSONHasError(reply, "GenericError")) {
> +        ret = 0;
> +        goto cleanup;
> +    }
> +
> +    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
> +        goto cleanup;
> +
> +    if (!virJSONValueObjectGetObject(reply, "return")) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("query-tdx-capabilities reply was missing return"));
> +        return -1;
> +    }
> +
> +    capability = g_new0(virTDXCapability, 1);
> +
> +    *capabilities = g_steal_pointer(&capability);
> +
> +    ret = 1;
> + cleanup:
> +    virJSONValueFree(cmd);
> +    virJSONValueFree(reply);
> +
> +    return ret;
> +}
> +
>  static virJSONValue *
>  qemuMonitorJSONBuildInetSocketAddress(const char *host,
>                                        const char *port)
> diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
> index 01a3ba25f1..3fe6a34c4c 100644
> --- a/src/qemu/qemu_monitor_json.h
> +++ b/src/qemu/qemu_monitor_json.h
> @@ -157,6 +157,9 @@ int qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon,
>  int qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon,
>                                        virSEVCapability **capabilities);
>  
> +int qemuMonitorJSONGetTDXCapabilities(qemuMonitor *mon,
> +                                      virTDXCapability **capabilities);
> +
>  int qemuMonitorJSONMigrate(qemuMonitor *mon,
>                             unsigned int flags,
>                             const char *uri);
> -- 
> 2.25.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210618/ba86a0d9/attachment-0001.sig>


More information about the libvir-list mailing list