Re: [PATCH v2 1/1] Expose available AMD SEV models in domain capabilities

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

 



On 2/20/24 07:31, Takashi Kajinami wrote:
> This introduces the new "model" field in sev elements, returned by
> domain capabilities API, so that client can ensure SEV-ES is available
> in this hypervisor.
> 
> Signed-off-by: Takashi Kajinami <kajinamit@xxxxxxxxxxxxxxx>
> ---
>  docs/formatdomaincaps.rst      |  5 ++
>  src/conf/domain_capabilities.c |  2 +
>  src/conf/domain_capabilities.h |  1 +
>  src/conf/domain_conf.c         |  7 +++
>  src/conf/domain_conf.h         |  8 ++++
>  src/qemu/qemu_capabilities.c   | 84 +++++++++++++++++++++++++---------
>  6 files changed, 85 insertions(+), 22 deletions(-)
> 
> diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
> index ef752a0f3a..78a6f8736f 100644
> --- a/docs/formatdomaincaps.rst
> +++ b/docs/formatdomaincaps.rst
> @@ -753,6 +753,11 @@ in domain XML <formatdomain.html#launch-security>`__
>  ``maxESGuests``
>     The maximum number of SEV-ES guests that can be launched on the host. This
>     value may be configurable in the firmware for some hosts.
> +``cpu0Id``
> +   ID of CPU0, which is used to get the signed Chip Endorsement Key (CEK) of
> +   the CPU of AMD system from AMD's Key Distribution Service (KDS).
> +``model``
> +   Available SEV models.
>  
>  SGX capabilities
>  ^^^^^^^^^^^^^^^^
> diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
> index 68eb3c9797..26d9b0a21c 100644
> --- a/src/conf/domain_capabilities.c
> +++ b/src/conf/domain_capabilities.c
> @@ -654,6 +654,8 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf,
>      if (sev->cpu0_id != NULL)
>          virBufferAsprintf(buf, "<cpu0Id>%s</cpu0Id>\n", sev->cpu0_id);
>  
> +    ENUM_PROCESS(sev, model, virDomainSevModelTypeToString);
> +
>      virBufferAdjustIndent(buf, -2);
>      virBufferAddLit(buf, "</sev>\n");
>  }
> diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
> index fadc30cdd7..1a84ea6101 100644
> --- a/src/conf/domain_capabilities.h
> +++ b/src/conf/domain_capabilities.h
> @@ -213,6 +213,7 @@ struct _virSEVCapability {
>      unsigned int reduced_phys_bits;
>      unsigned int max_guests;
>      unsigned int max_es_guests;
> +    virDomainCapsEnum model;
>  };
>  
>  typedef struct _virSGXSection virSGXSection;
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 3597959e33..cf0077d584 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1509,6 +1509,13 @@ VIR_ENUM_IMPL(virDomainLaunchSecurity,
>                "s390-pv",
>  );
>  
> +VIR_ENUM_IMPL(virDomainSevModel,
> +              VIR_DOMAIN_SEV_MODEL_LAST,
> +              "",
> +              "sev",
> +              "sev-es",
> +);
> +
>  typedef enum {
>      VIR_DOMAIN_NET_VHOSTUSER_MODE_NONE,
>      VIR_DOMAIN_NET_VHOSTUSER_MODE_CLIENT,
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index c7e5005b3b..a06fde1032 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2854,6 +2854,13 @@ typedef enum {
>      VIR_DOMAIN_LAUNCH_SECURITY_LAST,
>  } virDomainLaunchSecurity;
>  
> +typedef enum {
> +    VIR_DOMAIN_SEV_MODEL_NONE,
> +    VIR_DOMAIN_SEV_MODEL_SEV,
> +    VIR_DOMAIN_SEV_MODEL_SEV_ES,

There's SEV SNP now too.

> +
> +    VIR_DOMAIN_SEV_MODEL_LAST,
> +} virDomainSevModel;
>  
>  struct _virDomainSEVDef {
>      char *dh_cert;
> @@ -4237,6 +4244,7 @@ VIR_ENUM_DECL(virDomainCryptoType);
>  VIR_ENUM_DECL(virDomainCryptoBackend);
>  VIR_ENUM_DECL(virDomainShmemModel);
>  VIR_ENUM_DECL(virDomainShmemRole);
> +VIR_ENUM_DECL(virDomainSevModel);
>  VIR_ENUM_DECL(virDomainLaunchSecurity);
>  /* from libvirt.h */
>  VIR_ENUM_DECL(virDomainState);
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index e383d85920..d264c3128c 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -1881,6 +1881,7 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
>      tmp->reduced_phys_bits = src->reduced_phys_bits;
>      tmp->max_guests = src->max_guests;
>      tmp->max_es_guests = src->max_es_guests;
> +    tmp->model = src->model;
>  
>      *dst = g_steal_pointer(&tmp);
>  }
> @@ -3402,6 +3403,62 @@ virQEMUCapsGetSEVMaxGuests(virSEVCapability *caps)
>      }
>  }
>  
> +
> +/*
> + * Check whether AMD Secure Encrypted Virtualization (x86) is enabled
> + */
> +static bool
> +virQEMUCapsKVMSupportsSecureGuestSEV(void)
> +{
> +    g_autofree char *modValue = NULL;
> +
> +    if (virFileReadValueString(&modValue, "/sys/module/kvm_amd/parameters/sev") < 0)
> +        return false;
> +
> +    if (modValue[0] != '1' && modValue[0] != 'Y' && modValue[0] != 'y')
> +        return false;
> +
> +    if (virFileExists(QEMU_DEV_SEV))
> +        return true;
> +
> +    return false;
> +}
> +
> +
> +/*
> + * Check whether AMD Secure Encrypted Virtualization-Encrypted State (x86) is enabled
> + */
> +static bool
> +virQEMUCapsKVMSupportsSecureGuestSEVES(void)
> +{
> +    g_autofree char *modValue = NULL;
> +
> +    if (virFileReadValueString(&modValue, "/sys/module/kvm_amd/parameters/sev_es") < 0)
> +        return false;
> +
> +    if (modValue[0] != '1' && modValue[0] != 'Y' && modValue[0] != 'y')
> +        return false;
> +
> +    if (virFileExists(QEMU_DEV_SEV))
> +        return true;
> +
> +    return false;
> +}

These two functions differ only in the path they query. Now, I'm not
sure the kernel module can have "Y" without /dev/sev existing.
Anyway, I think one of these function should be turned into

static bool
func(const char *path)
{
  virFileReadValueString(&modValue, path);
  if (modValue[0] != 'y' ...)
    return false;
  return true;
}

and then ...


> +
> +
> +static void
> +virQEMUCapsGetSEVModel(virSEVCapability *caps)
> +{
> +    caps->model.report = true;

.. here we can have a static array of tuples:

const char *params[VIR_DOMAIN_SEV_MODEL_LAST] = {
  [VIR_DOMAIN_SEV_MODEL_SEV] = "/sys/module/kvm_amd/parameters/sev",
  [VIR_DOMAIN_SEV_MODEL_SEV_ES] = "/sys/module/kvm_amd/parameters/sev_es",
};
size_t i;

caps->model.report = true;

for (i = 0; i < VIR_DOMAIN_SEV_MODEL_LAST; i++) {
  if (virQEMUCapsKVMSupportsSecureGuestSEVES(params[i]))
    VIR_DOMAIN_CAPS_ENUM_SET(caps->model, i);
}

Or something among those lines.

Michal



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux