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.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 93c4d60b82..1546606811 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -29,6 +29,8 @@
#include "trace.h"
#include "migration/blocker.h"
#include "qom/object.h"
+#include "exec/address-spaces.h"
+#include "monitor/monitor.h"
#define TYPE_SEV_GUEST "sev-guest"
OBJECT_DECLARE_SIMPLE_TYPE(SevGuestState, SEV_GUEST)
@@ -785,6 +787,69 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
return 0;
}
+int sev_inject_launch_secret(const char *packet_hdr, const char *secret,
+ uint64_t gpa, Error **errp)
+{
+ struct kvm_sev_launch_secret input;
+ g_autofree guchar *data = NULL, *hdr = NULL;
+ int error, ret = 1;
+ void *hva;
+ gsize hdr_sz = 0, data_sz = 0;
+ MemoryRegion *mr = NULL;
+
+ if (!sev_guest) {
+ error_setg(errp, "SEV: SEV not enabled.");
+ return 1;
+ }
+
+ /* secret can be injected only in this state */
+ if (!sev_check_state(sev_guest, SEV_STATE_LAUNCH_SECRET)) {
+ error_setg(errp, "SEV: Not in correct state. (LSECRET) %x",
+ sev_guest->state);
+ return 1;
+ }
+
+ hdr = g_base64_decode(packet_hdr, &hdr_sz);
+ if (!hdr || !hdr_sz) {
+ error_setg(errp, "SEV: Failed to decode sequence header");
+ return 1;
+ }
+
+ data = g_base64_decode(secret, &data_sz);
+ if (!data || !data_sz) {
+ error_setg(errp, "SEV: Failed to decode data");
+ return 1;
+ }
+
+ hva = gpa2hva(&mr, gpa, data_sz, errp);
+ if (!hva) {
+ error_prepend(errp, "SEV: Failed to calculate guest address: ");
+ return 1;
+ }
+
+ input.hdr_uaddr = (uint64_t)(unsigned long)hdr;
+ input.hdr_len = hdr_sz;
+
+ input.trans_uaddr = (uint64_t)(unsigned long)data;
+ input.trans_len = data_sz;
+
+ input.guest_uaddr = (uint64_t)(unsigned long)hva;
+ input.guest_len = data_sz;
+
+ trace_kvm_sev_launch_secret(gpa, input.guest_uaddr,
+ input.trans_uaddr, input.trans_len);
+
+ ret = sev_ioctl(sev_guest->sev_fd, KVM_SEV_LAUNCH_SECRET,
+ &input, &error);
+ if (ret) {
+ error_setg(errp, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
+ ret, error, fw_error_to_str(error));
+ return ret;
+ }
+
+ return 0;
+}
+
static void
sev_register_types(void)
{