From 4c87a1868835d05f1cadae7b8ad6a7c95d9d9c0e Mon Sep 17 00:00:00 2001 From: Ross Philipson Date: Tue, 14 Mar 2017 15:40:33 -0400 Subject: Initial commit of EFI TBOOT work from internal project. Signed-off-by: Ross Philipson --- xen/xen-efi-tboot-launch.patch | 284 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 xen/xen-efi-tboot-launch.patch (limited to 'xen/xen-efi-tboot-launch.patch') 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 -- cgit v1.2.3