summaryrefslogtreecommitdiffstats
path: root/xen/xen-efi-tboot-launch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'xen/xen-efi-tboot-launch.patch')
-rw-r--r--xen/xen-efi-tboot-launch.patch284
1 files changed, 284 insertions, 0 deletions
diff --git a/xen/xen-efi-tboot-launch.patch b/xen/xen-efi-tboot-launch.patch
new file mode 100644
index 0000000..9fb99c1
--- /dev/null
+++ b/xen/xen-efi-tboot-launch.patch
@@ -0,0 +1,284 @@
+Index: xen-4.7.1/xen/arch/x86/efi/efi-tboot.h
+===================================================================
+--- /dev/null
++++ xen-4.7.1/xen/arch/x86/efi/efi-tboot.h
+@@ -0,0 +1,35 @@
++#ifndef __EFITBOOT_H__
++#define __EFITBOOT_H__
++
++/* Shared RT variable between TBOOT and Xen */
++#define EFI_TBOOT_XEN_GUID \
++ { 0xf112e6cb, 0xce01, 0x4573, {0xa0, 0x52, 0xfb, 0xdb, 0x6c, 0xc0, 0xc7, 0xcb} }
++
++#define EFI_TBOOT_XEN_REV 1
++#define EFI_TBOOT_XEN_NAME L"TbootXenVar"
++
++static EFI_GUID __initdata TbootXenGuid = EFI_TBOOT_XEN_GUID;
++
++typedef void (*post_launch_t)(void *ets);
++
++typedef struct __packed efi_xen_tboot_data {
++ void *kernel;
++ uint64_t kernel_size;
++ void *ramdisk;
++ uint64_t ramdisk_size;
++ void *memory_map;
++ uint64_t memory_map_size;
++ uint64_t memory_desc_size;
++ uint64_t post_launch_cb;
++} efi_xen_tboot_data_t;
++
++typedef void (*begin_launch_t)(struct efi_xen_tboot_data *xtd);
++
++typedef struct __packed efi_tboot_xen_var {
++ uint64_t revision;
++ const char *xen_config;
++ uint64_t xen_config_size;
++ uint64_t begin_launch_cb;
++} efi_tboot_xen_var_t;
++
++#endif /* __EFITBOOT_H__ */
+Index: xen-4.7.1/xen/common/efi/boot.c
+===================================================================
+--- xen-4.7.1.orig/xen/common/efi/boot.c
++++ xen-4.7.1/xen/common/efi/boot.c
+@@ -79,6 +79,7 @@ static size_t wstrlen(const CHAR16 * s);
+ static int set_color(u32 mask, int bpp, u8 *pos, u8 *sz);
+ static bool_t match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
+
++static const EFI_SYSTEM_TABLE *__initdata efi_st;
+ static const EFI_BOOT_SERVICES *__initdata efi_bs;
+ static UINT32 __initdata efi_bs_revision;
+ static EFI_HANDLE __initdata efi_ih;
+@@ -98,6 +99,14 @@ static CHAR16 __initdata newline[] = L"\
+ #define PrintStr(s) StdOut->OutputString(StdOut, s)
+ #define PrintErr(s) StdErr->OutputString(StdErr, s)
+
++/* TBOOT specific definitions */
++#include "efi-tboot.h"
++
++static struct efi_tboot_xen_var __initdata txv;
++static struct efi_xen_tboot_data __initdata xtd;
++static void* __initdata xtd_memmap;
++extern void *g_efi_tboot_shared;
++
+ /*
+ * Include architecture specific implementation here, which references the
+ * static globals defined above.
+@@ -580,6 +589,7 @@ static char *__init get_value(const stru
+ static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+ {
+ efi_ih = ImageHandle;
++ efi_st = SystemTable;
+ efi_bs = SystemTable->BootServices;
+ efi_bs_revision = efi_bs->Hdr.Revision;
+ efi_rs = SystemTable->RuntimeServices;
+@@ -839,6 +849,95 @@ static void __init efi_variables(void)
+ }
+ }
+
++#if 0
++static void __init efi_debug_pause(void)
++{
++ EFI_STATUS status;
++ EFI_INPUT_KEY key;
++
++ PrintStr(L"Pause...");
++ efi_st->ConIn->Reset(efi_st->ConIn, FALSE);
++ while ((status = efi_st->ConIn->ReadKeyStroke(efi_st->ConIn, &key)) == EFI_NOT_READY);
++}
++#endif
++
++static void __init efi_xen_tboot_variable(void)
++{
++ EFI_STATUS status;
++ UINTN size = 0;
++
++ status = efi_rs->GetVariable(EFI_TBOOT_XEN_NAME,
++ &TbootXenGuid,
++ NULL,
++ &size,
++ NULL);
++
++ /* No TBOOT/Xen variable */
++ if ( EFI_ERROR(status) && status != EFI_BUFFER_TOO_SMALL )
++ return;
++
++ if (size != sizeof(struct efi_tboot_xen_var)) {
++ PrintStr(L"Warning: TBOOT/Xen shared variable, wrong size: ");
++ DisplayUint(size, 0);
++ PrintStr(newline);
++ return;
++ }
++
++ status = efi_rs->GetVariable(EFI_TBOOT_XEN_NAME,
++ &TbootXenGuid,
++ NULL,
++ &size,
++ &txv);
++ if ( EFI_ERROR(status) )
++ blexit(L"Unable to get TBOOT-Xen runtime variable");
++}
++
++static bool_t __init tboot_present(void)
++{
++ return (txv.revision == EFI_TBOOT_XEN_REV);
++}
++
++static void __init tboot_get_config(struct file *file)
++{
++ EFI_STATUS status;
++
++ file->addr = min(1UL << (32 + PAGE_SHIFT),
++ HYPERVISOR_VIRT_END - DIRECTMAP_VIRT_START);
++ status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
++ PFN_UP(txv.xen_config_size), &file->addr);
++ if ( EFI_ERROR(status) )
++ blexit(L"Unable to allocate memory for TBOOT provided config");
++
++ memcpy(file->ptr, txv.xen_config, txv.xen_config_size);
++ file->size = txv.xen_config_size;
++}
++
++static void __init tboot_post_launch(void *ets)
++{
++ g_efi_tboot_shared = ets;
++
++ efi_arch_post_exit_boot();
++ for( ; ; ); /* not reached */
++}
++
++static void __init tboot_begin_launch(void)
++{
++ xtd.kernel = kernel.ptr;
++ xtd.kernel_size = kernel.size;
++ xtd.ramdisk = ramdisk.ptr;
++ xtd.ramdisk_size = ramdisk.size;
++ xtd.memory_map = xtd_memmap;
++ xtd.memory_map_size = efi_memmap_size;
++ xtd.memory_desc_size = efi_mdesc_size;
++ xtd.post_launch_cb = (uint64_t)tboot_post_launch;
++
++ __asm__ __volatile__ (
++ "call *%%rax\n\t"
++ :
++ : "a" (txv.begin_launch_cb), "c" (&xtd));
++ /* no return */
++}
++
+ static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop_mode)
+ {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
+@@ -893,6 +992,9 @@ static void __init efi_exit_boot(EFI_HAN
+ if ( EFI_ERROR(status) )
+ PrintErrMesg(L"Cannot exit boot services", status);
+
++ /* Save unadjusted memmap pointer for Xen/TBOOT data */
++ xtd_memmap = efi_memmap;
++
+ /* Adjust pointers into EFI. */
+ efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START;
+ #ifdef USE_SET_VIRTUAL_ADDRESS_MAP
+@@ -924,7 +1026,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
+ static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
+ EFI_LOADED_IMAGE *loaded_image;
+ EFI_STATUS status;
+- unsigned int i, argc;
++ unsigned int i, argc = 0;
+ CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
+ UINTN gop_mode = ~0;
+ EFI_SHIM_LOCK_PROTOCOL *shim_lock;
+@@ -945,7 +1047,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
+
+ efi_arch_load_addr_check(loaded_image);
+
+- if ( use_cfg_file )
++ if ( use_cfg_file && !tboot_present() )
+ {
+ argc = get_argv(0, NULL, loaded_image->LoadOptions,
+ loaded_image->LoadOptionsSize, NULL);
+@@ -1004,6 +1106,9 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
+
+ efi_arch_relocate_image(0);
+
++ /* Find the Xen/TBOOT RT variable if booted through TBOOT */
++ efi_xen_tboot_variable();
++
+ if ( use_cfg_file )
+ {
+ EFI_FILE_HANDLE dir_handle;
+@@ -1021,7 +1126,9 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
+ dir_handle = get_parent_handle(loaded_image, &file_name);
+
+ /* Read and parse the config file. */
+- if ( !cfg_file_name )
++ if ( tboot_present() )
++ tboot_get_config(&cfg);
++ else if ( !cfg_file_name )
+ {
+ CHAR16 *tail;
+
+@@ -1055,6 +1162,9 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
+ name.s = get_value(&cfg, "global", "chain");
+ if ( !name.s )
+ break;
++ /* Chain loaded configs not OK in TBOOT land */
++ if ( tboot_present() )
++ break;
+ efi_bs->FreePages(cfg.addr, PFN_UP(cfg.size));
+ cfg.addr = 0;
+ if ( !read_file(dir_handle, s2w(&name), &cfg, NULL) )
+@@ -1147,6 +1257,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SY
+
+ efi_exit_boot(ImageHandle, SystemTable);
+
++ /* Do the measured launch, end up back here if it fails. */
++ if ( tboot_present() )
++ tboot_begin_launch();
++
+ efi_arch_post_exit_boot();
+ for( ; ; ); /* not reached */
+ }
+Index: xen-4.7.1/xen/arch/x86/tboot.c
+===================================================================
+--- xen-4.7.1.orig/xen/arch/x86/tboot.c
++++ xen-4.7.1/xen/arch/x86/tboot.c
+@@ -18,6 +18,9 @@
+ static unsigned long __initdata opt_tboot_pa;
+ integer_param("tboot", opt_tboot_pa);
+
++/* Global pointer to shared data passed by EFI boot code. */
++void *g_efi_tboot_shared;
++
+ /* Global pointer to shared data; NULL means no measured launch. */
+ tboot_shared_t *g_tboot_shared;
+
+Index: xen-4.7.1/xen/include/asm-x86/tboot.h
+===================================================================
+--- xen-4.7.1.orig/xen/include/asm-x86/tboot.h
++++ xen-4.7.1/xen/include/asm-x86/tboot.h
+@@ -78,6 +78,13 @@ typedef struct __packed {
+ uint64_t kernel_s3_resume_vector;
+ } tboot_acpi_sleep_info_t;
+
++#define TB_RESMEM_BLOCKS 128
++
++typedef struct __packed {
++ uint64_t addr;
++ uint64_t length;
++} reserve_map_t;
++
+ typedef struct __packed {
+ /* version 3+ fields: */
+ uuid_t uuid; /* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */
+@@ -102,6 +109,10 @@ typedef struct __packed {
+ uint32_t flags;
+ uint64_t ap_wake_addr; /* phys addr of kernel/VMM SIPI vector */
+ uint32_t ap_wake_trigger; /* kernel/VMM writes APIC ID to wake AP */
++ /* version 7+ fields */
++ /* reserve mem blocks to adjust dom0 E820 */
++ uint64_t reserve_map_count;
++ reserve_map_t reserve_map[TB_RESMEM_BLOCKS];
+ } tboot_shared_t;
+
+ #define TB_SHUTDOWN_REBOOT 0