aboutsummaryrefslogtreecommitdiff
path: root/target/i386/sev.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/i386/sev.c')
-rw-r--r--target/i386/sev.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 2d14879166..0132beaf24 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -516,6 +516,68 @@ sev_launch_update_data(uint8_t *addr, uint64_t len)
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;
+
+ if (!sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
+ return;
+ }
+
+ measurement = g_new0(struct kvm_sev_launch_measure, 1);
+
+ /* query the measurement blob length */
+ ret = sev_ioctl(sev_state->sev_fd, 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;
+ }
+
+ data = g_new0(guchar, measurement->len);
+ measurement->uaddr = (unsigned long)data;
+
+ /* get the measurement blob */
+ ret = sev_ioctl(sev_state->sev_fd, 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;
+ }
+
+ sev_set_guest_state(SEV_STATE_LAUNCH_SECRET);
+
+ /* encode the measurement value and emit the event */
+ s->measurement = g_base64_encode(data, measurement->len);
+ trace_kvm_sev_launch_measurement(s->measurement);
+
+free_data:
+ g_free(data);
+free_measurement:
+ g_free(measurement);
+}
+
+char *
+sev_get_launch_measurement(void)
+{
+ if (sev_state &&
+ sev_state->state >= SEV_STATE_LAUNCH_SECRET) {
+ return g_strdup(sev_state->measurement);
+ }
+
+ return NULL;
+}
+
+static Notifier sev_machine_done_notify = {
+ .notify = sev_launch_get_measure,
+};
+
void *
sev_guest_init(const char *id)
{
@@ -593,6 +655,7 @@ sev_guest_init(const char *id)
}
ram_block_notifier_add(&sev_ram_notifier);
+ qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
return s;
err: