@@ -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:
@@ -64,6 +64,7 @@ enum {
struct SEVState {
QSevGuestInfo *sev_info;
int cur_state;
+ gchar *measurement;
};
typedef struct SEVState SEVState;
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(+)