@@ -1679,6 +1679,8 @@ static int kvm_init(MachineState *ms)
if (!kvm_state->memcrypt_handle) {
goto err;
}
+
+ kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
}
ret = kvm_arch_init(ms, s);
@@ -15,6 +15,11 @@
#include "qemu-common.h"
#include "sysemu/sev.h"
+int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
+{
+ return 1;
+}
+
void *sev_guest_init(const char *id)
{
return NULL;
@@ -100,6 +100,13 @@ fw_error_to_str(int code)
return sev_fw_errlist[code];
}
+static bool
+sev_check_state(SevState state)
+{
+ assert(sev_state);
+ return sev_state->state == state ? true : false;
+}
+
static void
sev_set_guest_state(SevState new_state)
{
@@ -480,6 +487,29 @@ sev_launch_start(SEVState *s)
return 0;
}
+static int
+sev_launch_update_data(uint8_t *addr, uint64_t len)
+{
+ int ret, fw_error;
+ struct kvm_sev_launch_update_data update;
+
+ if (!addr || !len) {
+ return 1;
+ }
+
+ update.uaddr = (__u64)addr;
+ update.len = len;
+ trace_kvm_sev_launch_update_data(addr, len);
+ ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
+ &update, &fw_error);
+ if (ret) {
+ error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
+ __func__, ret, fw_error, fw_error_to_str(fw_error));
+ }
+
+ return ret;
+}
+
void *
sev_guest_init(const char *id)
{
@@ -568,6 +598,19 @@ err:
return NULL;
}
+int
+sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
+{
+ assert(handle);
+
+ /* if SEV is in update state then encrypt the data else do nothing */
+ if (sev_check_state(SEV_STATE_LUPDATE)) {
+ return sev_launch_update_data(ptr, len);
+ }
+
+ return 0;
+}
+
static void
sev_register_types(void)
{
@@ -12,3 +12,4 @@ kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%lu"
kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu"
kvm_sev_change_state(const char *old, const char *new) "%s -> %s"
kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
+kvm_sev_launch_update_data(void *addr, uint64_t len) "addr %p len 0x%" PRIu64
The KVM_SEV_LAUNCH_UPDATE_DATA command is used to encrypt a guest memory region using the VM Encryption Key created using LAUNCH_START. Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> --- accel/kvm/kvm-all.c | 2 ++ stubs/sev.c | 5 +++++ target/i386/sev.c | 43 +++++++++++++++++++++++++++++++++++++++++++ target/i386/trace-events | 1 + 4 files changed, 51 insertions(+)