[PATCH 3/3] qemu: Implement the virDomainSetLaunchSecurityState API

Daniel P. Berrangé berrange at redhat.com
Fri Dec 3 15:10:29 UTC 2021


On Tue, Nov 30, 2021 at 04:52:00PM -0700, Jim Fehlig wrote:
> Set a launch secret in guest memory using the sev-inject-launch-secret
> QMP API. Only supported for SEV-enabled guests.
> 
> Signed-off-by: Jim Fehlig <jfehlig at suse.com>
> ---
>  src/qemu/qemu_driver.c       | 78 ++++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_monitor.c      | 12 ++++++
>  src/qemu/qemu_monitor.h      |  6 +++
>  src/qemu/qemu_monitor_json.c | 34 ++++++++++++++++
>  src/qemu/qemu_monitor_json.h |  5 +++
>  5 files changed, 135 insertions(+)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 4e680bc0a7..b6ee41b29e 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -20056,6 +20056,83 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
>      return ret;
>  }
>  
> +
> +static int
> +qemuDomainSetLaunchSecurityState(virDomainPtr domain,
> +                                 virTypedParameterPtr params,
> +                                 int nparams,
> +                                 unsigned int flags)
> +{
> +    virQEMUDriver *driver = domain->conn->privateData;
> +    virDomainObj *vm;
> +    int ret = -1;
> +    size_t i;
> +    g_autofree char *secrethdr = NULL;
> +    g_autofree char *secret = NULL;
> +    long long setaddr = -1;

unsigned, but would need to defaut to 0 then i guess.

> +
> +    virCheckFlags(0, -1);
> +    if (virTypedParamsValidate(params, nparams,
> +                               VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER,
> +                               VIR_TYPED_PARAM_STRING,
> +                               VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET,
> +                               VIR_TYPED_PARAM_STRING,
> +                               VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS,
> +                               VIR_TYPED_PARAM_LLONG,

UULONG

> +                               NULL) < 0)
> +        return -1;
> +
> +    if (!(vm = qemuDomainObjFromDomain(domain)))
> +        goto cleanup;
> +
> +    if (virDomainSetLaunchSecurityStateEnsureACL(domain->conn, vm->def) < 0)
> +        goto cleanup;
> +
> +    /* Currently only SEV is supported */
> +    if (!vm->def->sec ||
> +        vm->def->sec->sectype != VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
> +        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> +                       _("setting a launch secret is only supported in SEV-enabled domains"));
> +        goto cleanup;
> +    }
> +
> +    for (i = 0; i < nparams; i++) {
> +        virTypedParameterPtr param = &params[i];
> +
> +        if (STREQ(param->field, VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER))
> +            secrethdr = g_strdup(param->value.s);
> +        else if (STREQ(param->field, VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET))
> +            secret = g_strdup(param->value.s);
> +        else if (STREQ(param->field, VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS))
> +            setaddr =  param->value.l;
> +    }
> +
> +    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
> +        goto cleanup;
> +
> +    if (virDomainObjCheckActive(vm) < 0)
> +        goto endjob;
> +
> +    qemuDomainObjEnterMonitor(driver, vm);
> +
> +    if (qemuMonitorSetLaunchSecurityState(QEMU_DOMAIN_PRIVATE(vm)->mon,
> +                                          secrethdr, secret, setaddr) < 0)
> +        goto endjob;
> +
> +    if (qemuDomainObjExitMonitor(driver, vm) < 0)
> +        goto endjob;
> +
> +    ret = 0;
> +
> + endjob:
> +    qemuDomainObjEndJob(driver, vm);
> +
> + cleanup:
> +    virDomainObjEndAPI(&vm);
> +    return ret;
> +}
> +
> +
>  static const unsigned int qemuDomainGetGuestInfoSupportedTypes =
>      VIR_DOMAIN_GUEST_INFO_USERS |
>      VIR_DOMAIN_GUEST_INFO_OS |
> @@ -20930,6 +21007,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
>      .domainAuthorizedSSHKeysSet = qemuDomainAuthorizedSSHKeysSet, /* 6.10.0 */
>      .domainGetMessages = qemuDomainGetMessages, /* 7.1.0 */
>      .domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 7.2.0 */
> +    .domainSetLaunchSecurityState = qemuDomainSetLaunchSecurityState, /* 8.0.0 */
>  };
>  
>  
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index 26b59801b8..7f31a53231 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -4372,6 +4372,18 @@ qemuMonitorGetSEVMeasurement(qemuMonitor *mon)
>  }
>  
>  
> +int
> +qemuMonitorSetLaunchSecurityState(qemuMonitor *mon,
> +                                  const char *secrethdr,
> +                                  const char *secret,
> +                                  long long injectaddr)
> +{
> +    QEMU_CHECK_MONITOR(mon);
> +
> +    return qemuMonitorJSONSetLaunchSecurityState(mon, secrethdr, secret, injectaddr);
> +}
> +
> +
>  int
>  qemuMonitorGetPRManagerInfo(qemuMonitor *mon,
>                              GHashTable **retinfo)
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 99ecebc648..c485e403fd 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -1444,6 +1444,12 @@ int qemuMonitorBlockdevMediumInsert(qemuMonitor *mon,
>  char *
>  qemuMonitorGetSEVMeasurement(qemuMonitor *mon);
>  
> +int
> +qemuMonitorSetLaunchSecurityState(qemuMonitor *mon,
> +                                  const char *secrethdr,
> +                                  const char *secret,
> +                                  long long injectaddr);
> +
>  typedef struct _qemuMonitorPRManagerInfo qemuMonitorPRManagerInfo;
>  struct _qemuMonitorPRManagerInfo {
>      bool connected;
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 56f0b22b2a..35aea34b5f 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -8174,6 +8174,40 @@ qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon)
>  }
>  
>  
> +/**
> + * The function is used to inject a launch secret in an SEV guest.
> + *
> + * Example JSON:
> + *
> + * { "execute" : "sev-inject-launch-secret",
> + *   "data": { "packet-header": "str", "secret": "str", "gpa": "uint64" } }
> + */
> +int
> +qemuMonitorJSONSetLaunchSecurityState(qemuMonitor *mon,
> +                                      const char *secrethdr,
> +                                      const char *secret,
> +                                      long long injectaddr)
> +{
> +    g_autoptr(virJSONValue) cmd = NULL;
> +    g_autoptr(virJSONValue) reply = NULL;
> +
> +    if (!(cmd = qemuMonitorJSONMakeCommand("sev-inject-launch-secret",
> +                                           "s:packet-header", secrethdr,
> +                                           "s:secret", secret,
> +                                           "U:gpa", injectaddr,
> +                                           NULL)))
> +        return -1;
> +
> +    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
> +        return -1;
> +
> +    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
> +        return -1;
> +
> +    return 0;
> +}
> +
> +
>  /*
>   * Example return data
>   *
> diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
> index f7fb13f56c..4d2d73c661 100644
> --- a/src/qemu/qemu_monitor_json.h
> +++ b/src/qemu/qemu_monitor_json.h
> @@ -368,6 +368,11 @@ int qemuMonitorJSONSystemWakeup(qemuMonitor *mon);
>  
>  char *qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon);
>  
> +int qemuMonitorJSONSetLaunchSecurityState(qemuMonitor *mon,
> +                                          const char *secrethdr,
> +                                          const char *secret,
> +                                          long long injectaddr);
> +
>  int qemuMonitorJSONGetVersion(qemuMonitor *mon,
>                                int *major,
>                                int *minor,
> -- 
> 2.33.0
> 
> 

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list