diff options
Diffstat (limited to 'target/i386/sev.c')
-rw-r--r-- | target/i386/sev.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/target/i386/sev.c b/target/i386/sev.c index 11c9a3cc21..dc0e53019b 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -341,6 +341,12 @@ sev_enabled(void) return !!sev_guest; } +bool +sev_es_enabled(void) +{ + return false; +} + uint64_t sev_get_me_mask(void) { @@ -561,6 +567,20 @@ sev_launch_update_data(SevGuestState *sev, uint8_t *addr, uint64_t len) return ret; } +static int +sev_launch_update_vmsa(SevGuestState *sev) +{ + int ret, fw_error; + + ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL, &fw_error); + if (ret) { + error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); + } + + return ret; +} + static void sev_launch_get_measure(Notifier *notifier, void *unused) { @@ -573,6 +593,14 @@ sev_launch_get_measure(Notifier *notifier, void *unused) return; } + if (sev_es_enabled()) { + /* measure all the VM save areas before getting launch_measure */ + ret = sev_launch_update_vmsa(sev); + if (ret) { + exit(1); + } + } + measurement = g_new0(struct kvm_sev_launch_measure, 1); /* query the measurement blob length */ @@ -667,7 +695,7 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) SevGuestState *sev = (SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST); char *devname; - int ret, fw_error; + int ret, fw_error, cmd; uint32_t ebx; uint32_t host_cbitpos; struct sev_user_data_status status = {}; @@ -724,8 +752,20 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) sev->api_major = status.api_major; sev->api_minor = status.api_minor; + if (sev_es_enabled()) { + if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) { + error_report("%s: guest policy requires SEV-ES, but " + "host SEV-ES support unavailable", + __func__); + goto err; + } + cmd = KVM_SEV_ES_INIT; + } else { + cmd = KVM_SEV_INIT; + } + trace_kvm_sev_init(); - ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, &fw_error); + ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); if (ret) { error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); |