[PATCH 0/3] Add virDomainSetLaunchSecurityState API

V1 series based on initial RFC found here https://listman.redhat.com/archives/libvir-list/2021-November/msg00460.html This series is compile tested only. Functional testing will require reserving the test machine, configuring it, and writing some form of functional test :-). Is anyone aware of functional tests for the existing SEV-related APIs? Also, it has been a while since I added a new API, so not sure about the current state of the language bindings. Are there any non-automated tasks to expose the API in the various bindings? Jim Fehlig (3): libvirt: Introduce virDomainSetLaunchSecurityState public API remote: Add RPC support for the virDomainSetLaunchSecurityState API qemu: Implement the virDomainSetLaunchSecurityState API include/libvirt/libvirt-domain.h | 35 ++++++++++++++ src/driver-hypervisor.h | 7 +++ src/libvirt-domain.c | 52 +++++++++++++++++++++ src/libvirt_public.syms | 5 ++ 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 ++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 17 ++++++- src/remote_protocol-structs | 9 ++++ 12 files changed, 260 insertions(+), 1 deletion(-) -- 2.33.0

This API allows setting a launch secret within a guests's memory. The launch secret is created by the guest owner after retrieving and verifying the launch measurement with virDomainGetLaunchSecurityInfo. The API uses virTypedParameter for input, allowing it to be expanded to support other confidential computing technologies. In the case of SEV, a basic guest launch workflow is described in the SEV API spec in section "1.3.1 Launch" https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- include/libvirt/libvirt-domain.h | 35 +++++++++++++++++++++ src/driver-hypervisor.h | 7 +++++ src/libvirt-domain.c | 52 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ 4 files changed, 99 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 2f017c5b68..7af634cfb2 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -5086,11 +5086,46 @@ int virDomainSetLifecycleAction(virDomainPtr domain, */ # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT "sev-measurement" +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER: + * + * A macro used to represent the SEV launch secret header. The secret header + * is a base64-encoded VIR_TYPED_PARAM_STRING containing artifacts needed by + * the SEV firmware to recover the plain text of the launch secret. See + * section "6.6 LAUNCH_SECRET" in the SEV API specification for a detailed + * description of the secret header. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER "sev-secret-header" + +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET: + * + * A macro used to represent the SEV launch secret. The secret is a + * base64-encoded VIR_TYPED_PARAM_STRING containing an encrypted launch + * secret. The secret is created by the domain owner after the SEV launch + * measurement is retrieved and verified. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET "sev-secret" + +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS: + * + * A macro used to represent the physical address within the guest's memory + * where the secret will be set, as VIR_TYPED_PARAM_LLONG. If not specified, + * the address will be determined by the hypervisor. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS "sev-secret-set-address" + int virDomainGetLaunchSecurityInfo(virDomainPtr domain, virTypedParameterPtr *params, int *nparams, unsigned int flags); +int virDomainSetLaunchSecurityState(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags); + typedef enum { VIR_DOMAIN_GUEST_INFO_USERS = (1 << 0), /* return active users */ VIR_DOMAIN_GUEST_INFO_OS = (1 << 1), /* return OS information */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index d642af8a37..c83fb648a2 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1333,6 +1333,12 @@ typedef int int *nparams, unsigned int flags); +typedef int +(*virDrvDomainSetLaunchSecurityState)(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags); + typedef virDomainCheckpointPtr (*virDrvDomainCheckpointCreateXML)(virDomainPtr domain, const char *xmlDesc, @@ -1661,6 +1667,7 @@ struct _virHypervisorDriver { virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU; virDrvNodeGetSEVInfo nodeGetSEVInfo; virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo; + virDrvDomainSetLaunchSecurityState domainSetLaunchSecurityState; virDrvDomainCheckpointCreateXML domainCheckpointCreateXML; virDrvDomainCheckpointGetXMLDesc domainCheckpointGetXMLDesc; virDrvDomainListAllCheckpoints domainListAllCheckpoints; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index ce7cafde36..e62f0efa1a 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -12818,6 +12818,58 @@ int virDomainGetLaunchSecurityInfo(virDomainPtr domain, } +/** + * virDomainSetLaunchSecurityState: + * @domain: a domain object + * @params: pointer to launch security parameter objects + * @nparams: number of launch security parameters + * @flags: currently used, set to 0. + * + * Set a launch security secret in the guests's memory. The secret is created + * by the guest owner after retrieving and verifying the launch measurement + * with virDomainGetLaunchSecurityInfo. + * + * See VIR_DOMAIN_LAUNCH_SECURITY_* for a detailed description of accepted + * launch security parameters. + * + * Returns -1 in case of failure, 0 in case of success. + */ +int virDomainSetLaunchSecurityState(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virConnectPtr conn = domain->conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d flags=0x%x", + params, nparams, flags); + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + virCheckNonNullArgGoto(params, error); + virCheckPositiveArgGoto(nparams, error); + + if (virTypedParameterValidateSet(conn, params, nparams) < 0) + goto error; + + if (conn->driver->domainSetLaunchSecurityState) { + int ret; + ret = conn->driver->domainSetLaunchSecurityState(domain, params, + nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + + /** * virDomainAgentSetResponseTimeout: * @domain: a domain object diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 788a967df7..f93692c427 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -911,4 +911,9 @@ LIBVIRT_7.8.0 { virNetworkCreateXMLFlags; } LIBVIRT_7.7.0; +LIBVIRT_8.0.0 { + global: + virDomainSetLaunchSecurityState; +} LIBVIRT_7.8.0; + # .... define new API here using predicted next version number .... -- 2.33.0

On Tue, Nov 30, 2021 at 04:51:58PM -0700, Jim Fehlig wrote:
This API allows setting a launch secret within a guests's memory. The launch secret is created by the guest owner after retrieving and verifying the launch measurement with virDomainGetLaunchSecurityInfo.
The API uses virTypedParameter for input, allowing it to be expanded to support other confidential computing technologies. In the case of SEV, a basic guest launch workflow is described in the SEV API spec in section "1.3.1 Launch"
https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf
Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- include/libvirt/libvirt-domain.h | 35 +++++++++++++++++++++ src/driver-hypervisor.h | 7 +++++ src/libvirt-domain.c | 52 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ 4 files changed, 99 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 2f017c5b68..7af634cfb2 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -5086,11 +5086,46 @@ int virDomainSetLifecycleAction(virDomainPtr domain, */ # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT "sev-measurement"
+/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER: + * + * A macro used to represent the SEV launch secret header. The secret header + * is a base64-encoded VIR_TYPED_PARAM_STRING containing artifacts needed by + * the SEV firmware to recover the plain text of the launch secret. See + * section "6.6 LAUNCH_SECRET" in the SEV API specification for a detailed + * description of the secret header. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER "sev-secret-header" + +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET: + * + * A macro used to represent the SEV launch secret. The secret is a + * base64-encoded VIR_TYPED_PARAM_STRING containing an encrypted launch + * secret. The secret is created by the domain owner after the SEV launch + * measurement is retrieved and verified. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET "sev-secret" + +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS: + * + * A macro used to represent the physical address within the guest's memory + * where the secret will be set, as VIR_TYPED_PARAM_LLONG. If not specified, + * the address will be determined by the hypervisor. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS "sev-secret-set-address"
Should we be using ULLONG here, since it probably doesn't make sense for an address to be negative ?
+ int virDomainGetLaunchSecurityInfo(virDomainPtr domain, virTypedParameterPtr *params, int *nparams, unsigned int flags);
+int virDomainSetLaunchSecurityState(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags); +
+/** + * virDomainSetLaunchSecurityState: + * @domain: a domain object + * @params: pointer to launch security parameter objects + * @nparams: number of launch security parameters + * @flags: currently used, set to 0. + * + * Set a launch security secret in the guests's memory. The secret is created + * by the guest owner after retrieving and verifying the launch measurement + * with virDomainGetLaunchSecurityInfo. + * + * See VIR_DOMAIN_LAUNCH_SECURITY_* for a detailed description of accepted + * launch security parameters.
Should we note something about expected VM state/lifecycle When invoked, the VM must be running but with vCPUs paused. This can be achieved by passing VIR_DOMAIN_START_PAUSED to virDOmainCreate. If this method returns success, the vCPUs can be started with virDomainResume. On error the virtual machine should be destroy.
+ * + * Returns -1 in case of failure, 0 in case of success. + */ +int virDomainSetLaunchSecurityState(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virConnectPtr conn = domain->conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d flags=0x%x", + params, nparams, flags); + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + virResetLastError();
+ + virCheckDomainReturn(domain, -1); + virCheckNonNullArgGoto(params, error); + virCheckPositiveArgGoto(nparams, error);
Need a virCheckReadOnlyGoto too
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0) + goto error; + + if (conn->driver->domainSetLaunchSecurityState) { + int ret; + ret = conn->driver->domainSetLaunchSecurityState(domain, params, + nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +}
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 :|

On 12/3/21 08:06, Daniel P. Berrangé wrote:
On Tue, Nov 30, 2021 at 04:51:58PM -0700, Jim Fehlig wrote:
This API allows setting a launch secret within a guests's memory. The launch secret is created by the guest owner after retrieving and verifying the launch measurement with virDomainGetLaunchSecurityInfo.
The API uses virTypedParameter for input, allowing it to be expanded to support other confidential computing technologies. In the case of SEV, a basic guest launch workflow is described in the SEV API spec in section "1.3.1 Launch"
https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf
Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- include/libvirt/libvirt-domain.h | 35 +++++++++++++++++++++ src/driver-hypervisor.h | 7 +++++ src/libvirt-domain.c | 52 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ 4 files changed, 99 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 2f017c5b68..7af634cfb2 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -5086,11 +5086,46 @@ int virDomainSetLifecycleAction(virDomainPtr domain, */ # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT "sev-measurement"
+/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER: + * + * A macro used to represent the SEV launch secret header. The secret header + * is a base64-encoded VIR_TYPED_PARAM_STRING containing artifacts needed by + * the SEV firmware to recover the plain text of the launch secret. See + * section "6.6 LAUNCH_SECRET" in the SEV API specification for a detailed + * description of the secret header. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_HEADER "sev-secret-header" + +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET: + * + * A macro used to represent the SEV launch secret. The secret is a + * base64-encoded VIR_TYPED_PARAM_STRING containing an encrypted launch + * secret. The secret is created by the domain owner after the SEV launch + * measurement is retrieved and verified. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET "sev-secret" + +/** + * VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS: + * + * A macro used to represent the physical address within the guest's memory + * where the secret will be set, as VIR_TYPED_PARAM_LLONG. If not specified, + * the address will be determined by the hypervisor. + */ +# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS "sev-secret-set-address"
Should we be using ULLONG here, since it probably doesn't make sense for an address to be negative ?
Yes. I let a problem I was trying to solve in 3/3 leak out here. I'll describe the problem when responding to 3/3.
+ int virDomainGetLaunchSecurityInfo(virDomainPtr domain, virTypedParameterPtr *params, int *nparams, unsigned int flags);
+int virDomainSetLaunchSecurityState(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags); +
+/** + * virDomainSetLaunchSecurityState: + * @domain: a domain object + * @params: pointer to launch security parameter objects + * @nparams: number of launch security parameters + * @flags: currently used, set to 0. + * + * Set a launch security secret in the guests's memory. The secret is created + * by the guest owner after retrieving and verifying the launch measurement + * with virDomainGetLaunchSecurityInfo. + * + * See VIR_DOMAIN_LAUNCH_SECURITY_* for a detailed description of accepted + * launch security parameters.
Should we note something about expected VM state/lifecycle
When invoked, the VM must be running but with vCPUs paused. This can be achieved by passing VIR_DOMAIN_START_PAUSED to virDOmainCreate. If this method returns success, the vCPUs can be started with virDomainResume. On error the virtual machine should be destroy.
I'll include this and look at other doc improvements in V2. From libvirt perspective, I can document the entire workflow in the existing SEV kbase article, but will need to gain some hands on experience beforehand. That can be done independent of this series. Regards, Jim
+ * + * Returns -1 in case of failure, 0 in case of success. + */ +int virDomainSetLaunchSecurityState(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ + virConnectPtr conn = domain->conn; + + VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d flags=0x%x", + params, nparams, flags); + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + virResetLastError();
+ + virCheckDomainReturn(domain, -1); + virCheckNonNullArgGoto(params, error); + virCheckPositiveArgGoto(nparams, error);
Need a virCheckReadOnlyGoto too
+ if (virTypedParameterValidateSet(conn, params, nparams) < 0) + goto error; + + if (conn->driver->domainSetLaunchSecurityState) { + int ret; + ret = conn->driver->domainSetLaunchSecurityState(domain, params, + nparams, flags); + if (ret < 0) + goto error; + return ret; + } + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +}
Regards, Daniel

Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 17 ++++++++++++++++- src/remote_protocol-structs | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 235c406a5a..604239951c 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8574,6 +8574,7 @@ static virHypervisorDriver hypervisor_driver = { .domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */ .domainGetMessages = remoteDomainGetMessages, /* 7.1.0 */ .domainStartDirtyRateCalc = remoteDomainStartDirtyRateCalc, /* 7.2.0 */ + .domainSetLaunchSecurityState = remoteDomainSetLaunchSecurityState, /* 8.0.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 60010778ca..4f13cef662 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -272,6 +272,9 @@ const REMOTE_NODE_SEV_INFO_MAX = 64; /* Upper limit on number of launch security information entries */ const REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX = 64; +/* Upper limit on number of launch security state entries */ +const REMOTE_DOMAIN_LAUNCH_SECURITY_STATE_PARAMS_MAX = 64; + /* Upper limit on number of parameters describing a guest */ const REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX = 2048; @@ -3642,6 +3645,12 @@ struct remote_domain_get_launch_security_info_ret { remote_typed_param params<REMOTE_DOMAIN_LAUNCH_SECURITY_INFO_PARAMS_MAX>; }; +struct remote_domain_set_launch_security_state_args { + remote_nonnull_domain dom; + remote_typed_param params<REMOTE_DOMAIN_LAUNCH_SECURITY_STATE_PARAMS_MAX>; + unsigned int flags; +}; + /* nwfilter binding */ struct remote_nwfilter_binding_lookup_by_port_dev_args { @@ -6905,5 +6914,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_MEMORY_DEVICE_SIZE_CHANGE = 438 + REMOTE_PROC_DOMAIN_EVENT_MEMORY_DEVICE_SIZE_CHANGE = 438, + + /** + * @generate: both + * @acl: domain:write + */ + REMOTE_PROC_DOMAIN_SET_LAUNCH_SECURITY_STATE = 439 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index dbef4ace79..d88176781d 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3005,6 +3005,14 @@ struct remote_domain_get_launch_security_info_ret { remote_typed_param * params_val; } params; }; +struct remote_domain_set_launch_security_state_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_typed_param * params_val; + } params; + u_int flags; +}; struct remote_nwfilter_binding_lookup_by_port_dev_args { remote_nonnull_string name; }; @@ -3680,4 +3688,5 @@ enum remote_procedure { REMOTE_PROC_NODE_DEVICE_IS_ACTIVE = 436, REMOTE_PROC_NETWORK_CREATE_XML_FLAGS = 437, REMOTE_PROC_DOMAIN_EVENT_MEMORY_DEVICE_SIZE_CHANGE = 438, + REMOTE_PROC_DOMAIN_SET_LAUNCH_SECURITY_STATE = 439, }; -- 2.33.0

On Tue, Nov 30, 2021 at 04:51:59PM -0700, Jim Fehlig wrote:
Signed-off-by: Jim Fehlig <jfehlig@suse.com> --- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 17 ++++++++++++++++- src/remote_protocol-structs | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> 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 :|

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@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; + + 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, + 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 = ¶ms[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

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@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 = ¶ms[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 :|

On 12/3/21 08:10, Daniel P. Berrangé wrote:
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@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.
As Peter mentioned, 0 may be a valid injection address https://listman.redhat.com/archives/libvir-list/2021-November/msg00463.html The address in optional in the qemu API, in which case it is retrieved from ovmf IIUC. I used a signed variable here to distinguish between user not providing an address and providing one, including a valid value of 0.
+ + 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 = ¶ms[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)))
Heh, and I was supposed to handle that here :-). If injectaddr is -1, don't include the 'gpa' parameter to sev-inject-launch-secret. Will fix in V2, although alternative suggestions for handling the issue are welcomed. Regards, Jim
+ 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

On Fri, Dec 03, 2021 at 05:44:24PM -0700, Jim Fehlig wrote:
On 12/3/21 08:10, Daniel P. Berrangé wrote:
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@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.
As Peter mentioned, 0 may be a valid injection address
https://listman.redhat.com/archives/libvir-list/2021-November/msg00463.html
The address in optional in the qemu API, in which case it is retrieved from ovmf IIUC. I used a signed variable here to distinguish between user not providing an address and providing one, including a valid value of 0.
In terms of the API / RPC we can already distinguish the two scenarios. - If there is a parameter for the address with a value of 0, then it is an explicit address - If there is no parameter set at all, then we rely no the ovmf magic lookup. All we're missing is a way to distinguish the two scenarios when inside the QEMU driver. That's doable with just a 'bool hasSetaddr' parameter, which defaults to false, and gets set to true, if-and-only-if the VIR_DOMAIN_LAUNCH_SECURITY_SEV_SECRET_SET_ADDRESS param is present. 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 :|
participants (2)
-
Daniel P. Berrangé
-
Jim Fehlig