diff mbox

[RFC,v4,14/20] sev: add LAUNCH_FINISH command

Message ID 148900641547.27090.18164660067628886320.stgit@brijesh-build-machine
State New
Headers show

Commit Message

Brijesh Singh March 8, 2017, 8:53 p.m. UTC
The command is used to finalize the SEV guest launch process.

The command returns a measurement value of the data encrypted through
the LAUNCH_UPDATE command. This measurement can be handed to the guest
owner to verify that the guest was launched into SEV-enabled mode.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 include/sysemu/sev.h |    1 +
 kvm-all.c            |    1 +
 sev.c                |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+)
diff mbox

Patch

diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index c614cc0..7632202 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -97,5 +97,6 @@  void *sev_guest_init(const char *keyid);
 void sev_set_debug_ops(void *handle, MemoryRegion *mr);
 int sev_create_launch_context(void *handle);
 int sev_encrypt_launch_buffer(void *handle, uint8_t *ptr, uint64_t len);
+int sev_release_launch_context(void *handle);
 #endif
 
diff --git a/kvm-all.c b/kvm-all.c
index 5e98534..92b4fbf 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1828,6 +1828,7 @@  static int kvm_init(MachineState *ms)
             kvm_state->memcrypt_debug_ops = sev_set_debug_ops;
             kvm_state->create_launch_context = sev_create_launch_context;
             kvm_state->encrypt_launch_data = sev_encrypt_launch_buffer;
+            kvm_state->release_launch_context = sev_release_launch_context;
             g_free(id);
         }
     }
diff --git a/sev.c b/sev.c
index b391012..d32391e 100644
--- a/sev.c
+++ b/sev.c
@@ -253,6 +253,72 @@  err:
     return ret;
 }
 
+static void
+print_hex_dump(const char *prefix_str, uint8_t *data, int len)
+{
+    int i;
+
+    DPRINTF("%s: ", prefix_str);
+    for (i = 0; i < len; i++) {
+        DPRINTF("%02hhx", *data++);
+    }
+    DPRINTF("\n");
+}
+
+static int
+sev_launch_finish(SEVState *s)
+{
+    uint8_t *data;
+    int error, ret;
+    struct kvm_sev_launch_measure *measure;
+
+    if (!s) {
+        return 1;
+    }
+
+    measure = g_malloc0(sizeof(*measure));
+    if (!measure) {
+        return 1;
+    }
+
+    /* query measurement blob length */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measure, &error);
+    if (!measure->length) {
+        fprintf(stderr, "Error: failed to get launch measurement length\n");
+        ret = 1;
+        goto err_1;
+    }
+
+    data = g_malloc0(measure->length);
+    if (!data) {
+        goto err_1;
+    }
+    measure->address = (unsigned long)data;
+    /* get measurement */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measure, &error);
+    if (ret) {
+        fprintf(stderr, "failed LAUNCH_MEASURE %d (%#x)\n", ret, error);
+        goto err_2;
+    }
+
+    print_hex_dump("SEV: MEASUREMENT", data, measure->length);
+
+    /* finalize the launch */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_FINISH, 0, &error);
+    if (ret) {
+        fprintf(stderr, "failed LAUNCH_FINISH %d (%#x)\n", ret, error);
+        goto err_2;
+    }
+
+    DPRINTF("SEV: LAUNCH_FINISH\n");
+err_2:
+    g_free(data);
+err_1:
+    g_free(measure);
+
+    return ret;
+}
+
 static int
 sev_mem_write(uint8_t *dst, const uint8_t *src, uint32_t len, MemTxAttrs attrs)
 {
@@ -334,6 +400,12 @@  sev_encrypt_launch_buffer(void *handle, uint8_t *ptr, uint64_t len)
     return sev_launch_update_data((SEVState *)handle, ptr, len);
 }
 
+int
+sev_release_launch_context(void *handle)
+{
+    return sev_launch_finish((SEVState *)handle);
+}
+
 bool
 sev_enabled(void)
 {