[v5,18/23] sev: emit the SEV_MEASUREMENT event

Message ID 20171206200346.116537-19-brijesh.singh@amd.com
State New
Headers show
Series
  • x86: Secure Encrypted Virtualization (AMD)
Related show

Commit Message

Brijesh Singh Dec. 6, 2017, 8:03 p.m.
During machine creation we encrypted the guest bios image, the
LAUNCH_MEASURE command can be used to retrieve the measurement of
the encrypted memory region. Emit the SEV_MEASUREMENT event so that
libvirt can grab the measurement value as soon as we are done with
creating the encrypted machine.

Cc: Daniel P. Berrange <berrange@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 accel/kvm/sev.c      | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/sev.h |  1 +
 2 files changed, 59 insertions(+)

Patch

diff --git a/accel/kvm/sev.c b/accel/kvm/sev.c
index 83fc950bd3ac..c0eea371fa06 100644
--- a/accel/kvm/sev.c
+++ b/accel/kvm/sev.c
@@ -18,6 +18,7 @@ 
 #include "sysemu/kvm.h"
 #include "sysemu/sev.h"
 #include "sysemu/sysemu.h"
+#include "qapi-event.h"
 
 #define DEFAULT_GUEST_POLICY    0x1 /* disable debug */
 #define DEFAULT_SEV_DEVICE      "/dev/sev"
@@ -32,6 +33,7 @@ 
 #endif
 
 static int sev_fd;
+static SEVState *sev_state;
 
 #define SEV_FW_MAX_ERROR      0x17
 
@@ -399,6 +401,59 @@  err:
     return ret;
 }
 
+static void
+sev_launch_get_measure(Notifier *notifier, void *unused)
+{
+    int ret, error;
+    guchar *data;
+    SEVState *s = sev_state;
+    struct kvm_sev_launch_measure *measurement;
+
+    measurement = g_malloc0(sizeof(*measurement));
+    if (!measurement) {
+        return;
+    }
+
+    /* query the measurement blob length */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measurement, &error);
+    if (!measurement->len) {
+        error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
+                     __func__, ret, error, fw_error_to_str(errno));
+        goto free_measurement;
+    }
+
+    s->cur_state = SEV_STATE_SECRET;
+
+    data = g_malloc(measurement->len);
+    if (s->measurement) {
+        goto free_data;
+    }
+
+    measurement->uaddr = (unsigned long)data;
+
+    /* get the measurement blob */
+    ret = sev_ioctl(KVM_SEV_LAUNCH_MEASURE, measurement, &error);
+    if (ret) {
+        error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
+                     __func__, ret, error, fw_error_to_str(errno));
+        goto free_data;
+    }
+
+    s->measurement = g_base64_encode(data, measurement->len);
+
+    DPRINTF("SEV: MEASUREMENT: %s\n", s->measurement);
+    qapi_event_send_sev_measurement(s->measurement, &error_abort);
+
+free_data:
+    g_free(data);
+free_measurement:
+    g_free(measurement);
+}
+
+static Notifier sev_machine_done_notify = {
+    .notify = sev_launch_get_measure,
+};
+
 void *
 sev_guest_init(const char *id)
 {
@@ -441,6 +496,9 @@  sev_guest_init(const char *id)
     }
 
     ram_block_notifier_add(&sev_ram_notifier);
+    qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
+
+    sev_state = s;
 
     return s;
 err:
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index b1ea3f805290..3af945935b60 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -64,6 +64,7 @@  enum {
 struct SEVState {
     QSevGuestInfo *sev_info;
     int cur_state;
+    gchar *measurement;
 };
 
 typedef struct SEVState SEVState;