[RFC PATCH 3/3] qemu: Implement the virDomainInjectLaunchSecret API

Jim Fehlig jfehlig at suse.com
Wed Nov 17 02:23:54 UTC 2021


Inject a launch secret in domain memory using the sev-inject-launch-secret
QMP API. Only supported for SEV-enabed domains.

Signed-off-by: Jim Fehlig <jfehlig at suse.com>
---
 src/qemu/qemu_driver.c       | 53 ++++++++++++++++++++++++++++++++++++
 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, 110 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d954635dde..58e3f08afe 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20104,6 +20104,58 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
     return ret;
 }
 
+
+static int
+qemuDomainInjectLaunchSecret(virDomainPtr domain,
+                             const char *secrethdr,
+                             const char *secret,
+                             unsigned long long injectaddr,
+                             unsigned int flags)
+{
+    virQEMUDriver *driver = domain->conn->privateData;
+    virDomainObj *vm;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    if (!(vm = qemuDomainObjFromDomain(domain)))
+        goto cleanup;
+
+    if (virDomainInjectLaunchSecretEnsureACL(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",
+                       _("injecting a launch secret is only supported in SEV-enabled domains"));
+        goto cleanup;
+    }
+
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+        goto cleanup;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
+        goto endjob;
+
+    if (qemuMonitorInjectLaunchSecret(QEMU_DOMAIN_PRIVATE(vm)->mon,
+                                      secrethdr, secret, injectaddr) < 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 |
@@ -20981,6 +21033,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainAuthorizedSSHKeysSet = qemuDomainAuthorizedSSHKeysSet, /* 6.10.0 */
     .domainGetMessages = qemuDomainGetMessages, /* 7.1.0 */
     .domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 7.2.0 */
+    .domainInjectLaunchSecret = qemuDomainInjectLaunchSecret, /* 7.10.0 */
 };
 
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 810dac209d..c64469a03b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4383,6 +4383,18 @@ qemuMonitorGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+int
+qemuMonitorInjectLaunchSecret(qemuMonitor *mon,
+                              const char *secrethdr,
+                              const char *secret,
+                              unsigned long long injectaddr)
+{
+    QEMU_CHECK_MONITOR(mon);
+
+    return qemuMonitorJSONInjectLaunchSecret(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 0dd7b1c4e2..2dec2b57bb 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1445,6 +1445,12 @@ int qemuMonitorBlockdevMediumInsert(qemuMonitor *mon,
 char *
 qemuMonitorGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorInjectLaunchSecret(qemuMonitor *mon,
+                              const char *secrethdr,
+                              const char *secret,
+                              unsigned 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 4669b9135d..69aef078ec 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8124,6 +8124,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
+qemuMonitorJSONInjectLaunchSecret(qemuMonitor *mon,
+                                  const char *secrethdr,
+                                  const char *secret,
+                                  unsigned 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..95758cdc6e 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 qemuMonitorJSONInjectLaunchSecret(qemuMonitor *mon,
+                                      const char *secrethdr,
+                                      const char *secret,
+                                      unsigned long long injectaddr);
+
 int qemuMonitorJSONGetVersion(qemuMonitor *mon,
                               int *major,
                               int *minor,
-- 
2.33.0





More information about the libvir-list mailing list