Signed-off-by: Tobin Feldman-Fitzthum <to...@linux.vnet.ibm.com>
---
target/i386/sev.c | 34 ++++++++++++++++++++++++++++++++--
target/i386/sev_i386.h | 16 ++++++++++++++++
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 774e47d9d1..4adc56d7e3 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -706,6 +706,8 @@ sev_guest_init(const char *id)
s->api_major = status.api_major;
s->api_minor = status.api_minor;
+ s->secret_gpa = 0;
+
trace_kvm_sev_init();
ret = sev_ioctl(s->sev_fd, KVM_SEV_INIT, NULL, &fw_error);
if (ret) {
@@ -731,6 +733,28 @@ err:
return NULL;
}
+static void
+sev_find_secret_gpa(uint8_t *ptr, uint64_t len)
+{
+ uint64_t offset;
+
+ SevROMSecretTable *secret_table;
+ QemuUUID secret_table_guid;
+
+ qemu_uuid_parse(SEV_ROM_SECRET_GUID,&secret_table_guid);
+ secret_table_guid = qemu_uuid_bswap(secret_table_guid);
+
+ offset = len - 0x1000;
+ while(offset > 0) {
+ secret_table = (SevROMSecretTable *)(ptr + offset);
+ if(qemu_uuid_is_equal(&secret_table_guid, (QemuUUID *) secret_table)){
+ sev_state->secret_gpa = (long unsigned int) secret_table->base;
+ break;
+ }
+ offset -= 0x1000;
+ }
+}
+
int
sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
{
@@ -738,6 +762,9 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
/* if SEV is in update state then encrypt the data else do nothing */
if (sev_check_state(SEV_STATE_LAUNCH_UPDATE)) {
+ if(!sev_state->secret_gpa) {
+ sev_find_secret_gpa(ptr, len);
+ }
return sev_launch_update_data(ptr, len);
}
@@ -776,8 +803,8 @@ int sev_inject_launch_secret(const char *packet_hdr,
/* secret can be inject only in this state */
if (!sev_check_state(SEV_STATE_LAUNCH_SECRET)) {
- error_report("Not in correct state. %x",sev_state->state);
- return 1;
+ error_report("Not in correct state. %x",sev_state->state);
+ return 1;
}
hdr = g_base64_decode(packet_hdr, &hdr_sz);
@@ -792,6 +819,9 @@ int sev_inject_launch_secret(const char *packet_hdr,
goto err;
}
+ if(sev_state->secret_gpa)
+ gpa = sev_state->secret_gpa;
+
hva = gpa2hva(gpa, data_sz);
if (!hva) {
goto err;
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index 8ada9d385d..b1f9ab93bb 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -19,6 +19,7 @@
#include "sysemu/kvm.h"
#include "sysemu/sev.h"
#include "qemu/error-report.h"
+#include "qemu/uuid.h"
#include "qapi/qapi-types-misc-target.h"
#define SEV_POLICY_NODBG 0x1
@@ -28,6 +29,8 @@
#define SEV_POLICY_DOMAIN 0x10
#define SEV_POLICY_SEV 0x20
+#define SEV_ROM_SECRET_GUID "adf956ad-e98c-484c-ae11-b51c7d336447"
+
#define TYPE_QSEV_GUEST_INFO "sev-guest"
#define QSEV_GUEST_INFO(obj) \
OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO)
@@ -42,6 +45,18 @@ extern SevCapability *sev_get_capabilities(void);
typedef struct QSevGuestInfo QSevGuestInfo;
typedef struct QSevGuestInfoClass QSevGuestInfoClass;
+typedef struct SevROMSecretTable SevROMSecretTable;
+
+/**
+ * If guest physical address for the launch secret is
+ * provided in the ROM, it should be in the following
+ * page-aligned structure.
+ */
+struct SevROMSecretTable {
+ QemuUUID guid;
+ unsigned int base;
+ unsigned int size;
+};
/**
* QSevGuestInfo:
@@ -78,6 +93,7 @@ struct SEVState {
uint32_t cbitpos;
uint32_t reduced_phys_bits;
uint32_t handle;
+ uint64_t secret_gpa;
int sev_fd;
SevState state;
gchar *measurement;