From e3048d6500ace943c8ce6ee52e00ee832615b6ab Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 3 Feb 2015 15:55:13 -0500 Subject: [PATCH 2/3] EFI/early: Implement /map to map EfiBootServicesData and Code Signed-off-by: Konrad Rzeszutek Wilk --- xen/arch/x86/efi/efi-boot.h | 12 +++++++++--- xen/common/efi/boot.c | 43 ++++++++++++++++++++++++++++++++++--------- xen/common/efi/efi.h | 2 +- xen/common/efi/runtime.c | 1 + 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index 0fbc4de..346f273 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -159,7 +159,8 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable, void *map, UINTN map_size, UINTN desc_size, - UINT32 desc_ver) + UINT32 desc_ver, + UINT32 map_bootservices) { struct e820entry *e; unsigned int i; @@ -177,9 +178,14 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable, default: type = E820_RESERVED; break; - case EfiConventionalMemory: case EfiBootServicesCode: case EfiBootServicesData: + if ( map_bootservices ) + { + type = E820_RESERVED; + break; + } + case EfiConventionalMemory: if ( !trampoline_phys && desc->PhysicalStart + len <= 0x100000 && len >= cfg.size && desc->PhysicalStart + len > cfg.addr ) cfg.addr = (desc->PhysicalStart + len - cfg.size) & PAGE_MASK; @@ -676,7 +682,7 @@ void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable setup_efi_pci(); efi_variables(); efi_set_gop_mode(gop, gop_mode); - efi_exit_boot(ImageHandle, SystemTable, 0); + efi_exit_boot(ImageHandle, SystemTable, 0, 0); } /* diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index 2389a1a..ec98914 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -86,7 +86,7 @@ static void efi_tables(void); static void setup_efi_pci(void); static void efi_variables(void); static void efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop_mode); -static void efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable, int exit_boot_services); +static void efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable, int exit_boot_services, int map_bs); static const EFI_BOOT_SERVICES *__initdata efi_bs; static EFI_HANDLE __initdata efi_ih; @@ -882,7 +882,7 @@ static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop efi_arch_video_init(gop, info_size, mode_info); } -static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable, int exit_boot_services) +static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable, int exit_boot_services, int map_bs) { EFI_STATUS status; UINTN map_key; @@ -902,7 +902,7 @@ static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *Syste PrintErrMesg(L"Cannot obtain memory map", status); efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size, - efi_mdesc_size, mdesc_ver); + efi_mdesc_size, mdesc_ver, map_bs); efi_arch_pre_exit_boot(); @@ -924,6 +924,7 @@ static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *Syste #endif efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START; efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START; + efi_map = map_bs; } static int __init efi_getnextvariable(bool_t query_only) @@ -1027,7 +1028,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) bool_t use_cfg_file; bool_t query_only = 0; bool_t exit_boot_services = 1; - + bool_t map_bs = 0; #ifndef CONFIG_ARM /* TODO - disabled until implemented on ARM */ efi_platform = 1; efi_loader = 1; @@ -1071,6 +1072,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) query_only = 1; else if ( wstrcmp(ptr + 1, L"noexit") == 0 ) exit_boot_services = 0; + else if ( wstrcmp(ptr + 1, L"map") == 0 ) + map_bs = 1; else if ( wstrncmp(ptr + 1, L"cfg=", 4) == 0 ) cfg_file_name = ptr + 5; else if ( i + 1 < argc && wstrcmp(ptr + 1, L"cfg") == 0 ) @@ -1082,6 +1085,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) PrintStr(L"-basevideo retain current video mode\r\n"); PrintStr(L"-cfg= specify configuration file\r\n"); PrintStr(L"-query GetNextVariableName up to five\r\n"); + PrintStr(L"-map map EfiBootServices Code and Data\r\n"); PrintStr(L"-noexit Don't call ExitBootServices\r\n"); PrintStr(L"-help, -? display this help\r\n"); blexit(NULL); @@ -1249,7 +1253,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) efi_set_gop_mode(gop, gop_mode); - efi_exit_boot(ImageHandle, SystemTable, exit_boot_services); + efi_exit_boot(ImageHandle, SystemTable, exit_boot_services, map_bs); efi_arch_post_exit_boot(); for( ; ; ); /* not reached */ @@ -1325,20 +1329,30 @@ void __init efi_init_memory(void) return; #endif - printk(XENLOG_INFO "EFI memory map:\n"); + printk(XENLOG_INFO "EFI memory map: %s\n", efi_map ? "(mapping BootServices)" : ""); for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size ) { EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i; u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT; unsigned long smfn, emfn; unsigned int prot = PAGE_HYPERVISOR; + unsigned int skip = 1; printk(XENLOG_INFO " %013" PRIx64 "-%013" PRIx64 " type=%u attr=%016" PRIx64 "\n", desc->PhysicalStart, desc->PhysicalStart + len - 1, desc->Type, desc->Attribute); - if ( !efi_rs_enable || !(desc->Attribute & EFI_MEMORY_RUNTIME) ) + if ( desc->Attribute & EFI_MEMORY_RUNTIME ) + skip = 0; + + if ( desc->Type == 4 && desc->Attribute != 0 && efi_map ) + skip = 0; + + if ( desc->Type == 3 && desc->Attribute != 0 && efi_map ) + skip = 0; + + if ( !efi_rs_enable || skip ) { printk(XENLOG_INFO " .. skipped!\n"); continue; @@ -1422,18 +1436,29 @@ void __init efi_init_memory(void) copy_mapping(0, max_page, ram_range_valid); + printk(XENLOG_INFO "Copying..\n"); /* Insert non-RAM runtime mappings inside the direct map. */ for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size ) { const EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i; - if ( (desc->Attribute & EFI_MEMORY_RUNTIME) && + if ( ((desc->Attribute & EFI_MEMORY_RUNTIME) || + ((desc->Type == 3 && desc->Attribute != 0 && efi_map ) || + (desc->Type == 4 && desc->Attribute != 0 && efi_map ))) && desc->VirtualStart != INVALID_VIRTUAL_ADDRESS && - desc->VirtualStart != desc->PhysicalStart ) + desc->VirtualStart != desc->PhysicalStart ) { + + printk(XENLOG_INFO " %013" PRIx64 "-%013" PRIx64 + " type=%u attr=%016" PRIx64 "\n", + PFN_DOWN(desc->PhysicalStart), + PFN_UP(desc->PhysicalStart + (desc->NumberOfPages << EFI_PAGE_SHIFT)), + desc->Type, desc->Attribute); + copy_mapping(PFN_DOWN(desc->PhysicalStart), PFN_UP(desc->PhysicalStart + (desc->NumberOfPages << EFI_PAGE_SHIFT)), rt_range_valid); + } } /* Insert non-RAM runtime mappings outside of the direct map. */ diff --git a/xen/common/efi/efi.h b/xen/common/efi/efi.h index c557104..6267020 100644 --- a/xen/common/efi/efi.h +++ b/xen/common/efi/efi.h @@ -20,7 +20,7 @@ struct efi_pci_rom { extern unsigned int efi_num_ct; extern const EFI_CONFIGURATION_TABLE *efi_ct; -extern unsigned int efi_version, efi_fw_revision; +extern unsigned int efi_version, efi_fw_revision, efi_map; extern const CHAR16 *efi_fw_vendor; extern const EFI_RUNTIME_SERVICES *efi_rs; diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c index 4ca25c2..e1709fd 100644 --- a/xen/common/efi/runtime.c +++ b/xen/common/efi/runtime.c @@ -27,6 +27,7 @@ const EFI_CONFIGURATION_TABLE *__read_mostly efi_ct; unsigned int __read_mostly efi_version; unsigned int __read_mostly efi_fw_revision; +unsigned int __read_mostly efi_map; const CHAR16 *__read_mostly efi_fw_vendor; const EFI_RUNTIME_SERVICES *__read_mostly efi_rs; -- 2.1.0