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