@@ -91,6 +91,31 @@ bool amd_sev_es_enabled(void)
return sev_es_enabled;
}
+efi_status_t setup_amd_sev_es(void)
+{
+ struct descriptor_table_ptr idtr;
+ idt_entry_t *idt;
+
+ if (!amd_sev_es_enabled()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ /*
+ * Copy UEFI's #VC IDT entry, so KVM-Unit-Tests can reuse it and does
+ * not have to re-implement a #VC handler.
+ *
+ * TODO: Reusing UEFI #VC handler is a temporary workaround to simplify
+ * the boot up process, the long-term solution is to implement a #VC
+ * handler in KVM-Unit-Tests and load it, so that KVM-Unit-Tests does
+ * not depend on specific UEFI #VC handler implementation.
+ */
+ sidt(&idtr);
+ idt = (idt_entry_t *)idtr.base;
+ boot_idt[SEV_ES_VC_HANDLER_VECTOR] = idt[SEV_ES_VC_HANDLER_VECTOR];
+
+ return EFI_SUCCESS;
+}
+
static void copy_gdt_entry(gdt_entry_t *dst, gdt_entry_t *src, unsigned segment)
{
unsigned index;
@@ -39,7 +39,14 @@
bool amd_sev_enabled(void);
efi_status_t setup_amd_sev(void);
+/*
+ * AMD Programmer's Manual Volume 2
+ * - Section "#VC Exception"
+ */
+#define SEV_ES_VC_HANDLER_VECTOR 29
+
bool amd_sev_es_enabled(void);
+efi_status_t setup_amd_sev_es(void);
void copy_uefi_segments(void);
unsigned long long get_amd_sev_c_bit_mask(void);
@@ -227,6 +227,18 @@ efi_status_t setup_efi_pre_boot(unsigned long *mapkey, efi_bootinfo_t *efi_booti
}
}
+ status = setup_amd_sev_es();
+ if (status != EFI_SUCCESS) {
+ switch (status) {
+ case EFI_UNSUPPORTED:
+ /* Continue if AMD SEV-ES is not supported */
+ break;
+ default:
+ printf("Set up AMD SEV-ES failed\n");
+ return status;
+ }
+ }
+
return EFI_SUCCESS;
}
AMD SEV-ES introduces a new #VC exception that handles the communication between guest and host. UEFI already implements a #VC handler so there is no need to re-implement it in KVM-Unit-Tests. To reuse this #VC handler, this commit reads UEFI's IDT, copy the #VC IDT entry into KVM-Unit-Tests' IDT. Reusing UEFI #VC handler is a temporary workaround, and the long-term solution is to implement a #VC handler in KVM-Unit-Tests so it does not depend on specific UEFI's #VC handler. However, we still believe that the current approach is good as an intermediate solution, because it unlocks a lot of testing and we do not expect that testing to be inherently tied to the UEFI's #VC handler. In this commit, load_idt() can work and now guest crashes in setup_page_table(), which will be fixed by follow-up commits. Signed-off-by: Zixuan Wang <zixuanwang@google.com> --- lib/x86/amd_sev.c | 25 +++++++++++++++++++++++++ lib/x86/amd_sev.h | 7 +++++++ lib/x86/setup.c | 12 ++++++++++++ 3 files changed, 44 insertions(+)