18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci#define pr_fmt(fmt) "efi: " fmt 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/init.h> 58c2ecf20Sopenharmony_ci#include <linux/kernel.h> 68c2ecf20Sopenharmony_ci#include <linux/string.h> 78c2ecf20Sopenharmony_ci#include <linux/time.h> 88c2ecf20Sopenharmony_ci#include <linux/types.h> 98c2ecf20Sopenharmony_ci#include <linux/efi.h> 108c2ecf20Sopenharmony_ci#include <linux/slab.h> 118c2ecf20Sopenharmony_ci#include <linux/memblock.h> 128c2ecf20Sopenharmony_ci#include <linux/acpi.h> 138c2ecf20Sopenharmony_ci#include <linux/dmi.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <asm/e820/api.h> 168c2ecf20Sopenharmony_ci#include <asm/efi.h> 178c2ecf20Sopenharmony_ci#include <asm/uv/uv.h> 188c2ecf20Sopenharmony_ci#include <asm/cpu_device_id.h> 198c2ecf20Sopenharmony_ci#include <asm/realmode.h> 208c2ecf20Sopenharmony_ci#include <asm/reboot.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define EFI_MIN_RESERVE 5120 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define EFI_DUMMY_GUID \ 258c2ecf20Sopenharmony_ci EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define QUARK_CSH_SIGNATURE 0x5f435348 /* _CSH */ 288c2ecf20Sopenharmony_ci#define QUARK_SECURITY_HEADER_SIZE 0x400 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Header prepended to the standard EFI capsule on Quark systems the are based 328c2ecf20Sopenharmony_ci * on Intel firmware BSP. 338c2ecf20Sopenharmony_ci * @csh_signature: Unique identifier to sanity check signed module 348c2ecf20Sopenharmony_ci * presence ("_CSH"). 358c2ecf20Sopenharmony_ci * @version: Current version of CSH used. Should be one for Quark A0. 368c2ecf20Sopenharmony_ci * @modulesize: Size of the entire module including the module header 378c2ecf20Sopenharmony_ci * and payload. 388c2ecf20Sopenharmony_ci * @security_version_number_index: Index of SVN to use for validation of signed 398c2ecf20Sopenharmony_ci * module. 408c2ecf20Sopenharmony_ci * @security_version_number: Used to prevent against roll back of modules. 418c2ecf20Sopenharmony_ci * @rsvd_module_id: Currently unused for Clanton (Quark). 428c2ecf20Sopenharmony_ci * @rsvd_module_vendor: Vendor Identifier. For Intel products value is 438c2ecf20Sopenharmony_ci * 0x00008086. 448c2ecf20Sopenharmony_ci * @rsvd_date: BCD representation of build date as yyyymmdd, where 458c2ecf20Sopenharmony_ci * yyyy=4 digit year, mm=1-12, dd=1-31. 468c2ecf20Sopenharmony_ci * @headersize: Total length of the header including including any 478c2ecf20Sopenharmony_ci * padding optionally added by the signing tool. 488c2ecf20Sopenharmony_ci * @hash_algo: What Hash is used in the module signing. 498c2ecf20Sopenharmony_ci * @cryp_algo: What Crypto is used in the module signing. 508c2ecf20Sopenharmony_ci * @keysize: Total length of the key data including including any 518c2ecf20Sopenharmony_ci * padding optionally added by the signing tool. 528c2ecf20Sopenharmony_ci * @signaturesize: Total length of the signature including including any 538c2ecf20Sopenharmony_ci * padding optionally added by the signing tool. 548c2ecf20Sopenharmony_ci * @rsvd_next_header: 32-bit pointer to the next Secure Boot Module in the 558c2ecf20Sopenharmony_ci * chain, if there is a next header. 568c2ecf20Sopenharmony_ci * @rsvd: Reserved, padding structure to required size. 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * See also QuartSecurityHeader_t in 598c2ecf20Sopenharmony_ci * Quark_EDKII_v1.2.1.1/QuarkPlatformPkg/Include/QuarkBootRom.h 608c2ecf20Sopenharmony_ci * from https://downloadcenter.intel.com/download/23197/Intel-Quark-SoC-X1000-Board-Support-Package-BSP 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_cistruct quark_security_header { 638c2ecf20Sopenharmony_ci u32 csh_signature; 648c2ecf20Sopenharmony_ci u32 version; 658c2ecf20Sopenharmony_ci u32 modulesize; 668c2ecf20Sopenharmony_ci u32 security_version_number_index; 678c2ecf20Sopenharmony_ci u32 security_version_number; 688c2ecf20Sopenharmony_ci u32 rsvd_module_id; 698c2ecf20Sopenharmony_ci u32 rsvd_module_vendor; 708c2ecf20Sopenharmony_ci u32 rsvd_date; 718c2ecf20Sopenharmony_ci u32 headersize; 728c2ecf20Sopenharmony_ci u32 hash_algo; 738c2ecf20Sopenharmony_ci u32 cryp_algo; 748c2ecf20Sopenharmony_ci u32 keysize; 758c2ecf20Sopenharmony_ci u32 signaturesize; 768c2ecf20Sopenharmony_ci u32 rsvd_next_header; 778c2ecf20Sopenharmony_ci u32 rsvd[2]; 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic const efi_char16_t efi_dummy_name[] = L"DUMMY"; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic bool efi_no_storage_paranoia; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/* 858c2ecf20Sopenharmony_ci * Some firmware implementations refuse to boot if there's insufficient 868c2ecf20Sopenharmony_ci * space in the variable store. The implementation of garbage collection 878c2ecf20Sopenharmony_ci * in some FW versions causes stale (deleted) variables to take up space 888c2ecf20Sopenharmony_ci * longer than intended and space is only freed once the store becomes 898c2ecf20Sopenharmony_ci * almost completely full. 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * Enabling this option disables the space checks in 928c2ecf20Sopenharmony_ci * efi_query_variable_store() and forces garbage collection. 938c2ecf20Sopenharmony_ci * 948c2ecf20Sopenharmony_ci * Only enable this option if deleting EFI variables does not free up 958c2ecf20Sopenharmony_ci * space in your variable store, e.g. if despite deleting variables 968c2ecf20Sopenharmony_ci * you're unable to create new ones. 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_cistatic int __init setup_storage_paranoia(char *arg) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci efi_no_storage_paranoia = true; 1018c2ecf20Sopenharmony_ci return 0; 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ciearly_param("efi_no_storage_paranoia", setup_storage_paranoia); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* 1068c2ecf20Sopenharmony_ci * Deleting the dummy variable which kicks off garbage collection 1078c2ecf20Sopenharmony_ci*/ 1088c2ecf20Sopenharmony_civoid efi_delete_dummy_variable(void) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci efi.set_variable_nonblocking((efi_char16_t *)efi_dummy_name, 1118c2ecf20Sopenharmony_ci &EFI_DUMMY_GUID, 1128c2ecf20Sopenharmony_ci EFI_VARIABLE_NON_VOLATILE | 1138c2ecf20Sopenharmony_ci EFI_VARIABLE_BOOTSERVICE_ACCESS | 1148c2ecf20Sopenharmony_ci EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); 1158c2ecf20Sopenharmony_ci} 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/* 1188c2ecf20Sopenharmony_ci * In the nonblocking case we do not attempt to perform garbage 1198c2ecf20Sopenharmony_ci * collection if we do not have enough free space. Rather, we do the 1208c2ecf20Sopenharmony_ci * bare minimum check and give up immediately if the available space 1218c2ecf20Sopenharmony_ci * is below EFI_MIN_RESERVE. 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * This function is intended to be small and simple because it is 1248c2ecf20Sopenharmony_ci * invoked from crash handler paths. 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_cistatic efi_status_t 1278c2ecf20Sopenharmony_ciquery_variable_store_nonblocking(u32 attributes, unsigned long size) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci efi_status_t status; 1308c2ecf20Sopenharmony_ci u64 storage_size, remaining_size, max_size; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci status = efi.query_variable_info_nonblocking(attributes, &storage_size, 1338c2ecf20Sopenharmony_ci &remaining_size, 1348c2ecf20Sopenharmony_ci &max_size); 1358c2ecf20Sopenharmony_ci if (status != EFI_SUCCESS) 1368c2ecf20Sopenharmony_ci return status; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci if (remaining_size - size < EFI_MIN_RESERVE) 1398c2ecf20Sopenharmony_ci return EFI_OUT_OF_RESOURCES; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci return EFI_SUCCESS; 1428c2ecf20Sopenharmony_ci} 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci/* 1458c2ecf20Sopenharmony_ci * Some firmware implementations refuse to boot if there's insufficient space 1468c2ecf20Sopenharmony_ci * in the variable store. Ensure that we never use more than a safe limit. 1478c2ecf20Sopenharmony_ci * 1488c2ecf20Sopenharmony_ci * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable 1498c2ecf20Sopenharmony_ci * store. 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_ciefi_status_t efi_query_variable_store(u32 attributes, unsigned long size, 1528c2ecf20Sopenharmony_ci bool nonblocking) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci efi_status_t status; 1558c2ecf20Sopenharmony_ci u64 storage_size, remaining_size, max_size; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) 1588c2ecf20Sopenharmony_ci return 0; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if (nonblocking) 1618c2ecf20Sopenharmony_ci return query_variable_store_nonblocking(attributes, size); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci status = efi.query_variable_info(attributes, &storage_size, 1648c2ecf20Sopenharmony_ci &remaining_size, &max_size); 1658c2ecf20Sopenharmony_ci if (status != EFI_SUCCESS) 1668c2ecf20Sopenharmony_ci return status; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci /* 1698c2ecf20Sopenharmony_ci * We account for that by refusing the write if permitting it would 1708c2ecf20Sopenharmony_ci * reduce the available space to under 5KB. This figure was provided by 1718c2ecf20Sopenharmony_ci * Samsung, so should be safe. 1728c2ecf20Sopenharmony_ci */ 1738c2ecf20Sopenharmony_ci if ((remaining_size - size < EFI_MIN_RESERVE) && 1748c2ecf20Sopenharmony_ci !efi_no_storage_paranoia) { 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* 1778c2ecf20Sopenharmony_ci * Triggering garbage collection may require that the firmware 1788c2ecf20Sopenharmony_ci * generate a real EFI_OUT_OF_RESOURCES error. We can force 1798c2ecf20Sopenharmony_ci * that by attempting to use more space than is available. 1808c2ecf20Sopenharmony_ci */ 1818c2ecf20Sopenharmony_ci unsigned long dummy_size = remaining_size + 1024; 1828c2ecf20Sopenharmony_ci void *dummy = kzalloc(dummy_size, GFP_KERNEL); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci if (!dummy) 1858c2ecf20Sopenharmony_ci return EFI_OUT_OF_RESOURCES; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci status = efi.set_variable((efi_char16_t *)efi_dummy_name, 1888c2ecf20Sopenharmony_ci &EFI_DUMMY_GUID, 1898c2ecf20Sopenharmony_ci EFI_VARIABLE_NON_VOLATILE | 1908c2ecf20Sopenharmony_ci EFI_VARIABLE_BOOTSERVICE_ACCESS | 1918c2ecf20Sopenharmony_ci EFI_VARIABLE_RUNTIME_ACCESS, 1928c2ecf20Sopenharmony_ci dummy_size, dummy); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci if (status == EFI_SUCCESS) { 1958c2ecf20Sopenharmony_ci /* 1968c2ecf20Sopenharmony_ci * This should have failed, so if it didn't make sure 1978c2ecf20Sopenharmony_ci * that we delete it... 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ci efi_delete_dummy_variable(); 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci kfree(dummy); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* 2058c2ecf20Sopenharmony_ci * The runtime code may now have triggered a garbage collection 2068c2ecf20Sopenharmony_ci * run, so check the variable info again 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ci status = efi.query_variable_info(attributes, &storage_size, 2098c2ecf20Sopenharmony_ci &remaining_size, &max_size); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci if (status != EFI_SUCCESS) 2128c2ecf20Sopenharmony_ci return status; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci /* 2158c2ecf20Sopenharmony_ci * There still isn't enough room, so return an error 2168c2ecf20Sopenharmony_ci */ 2178c2ecf20Sopenharmony_ci if (remaining_size - size < EFI_MIN_RESERVE) 2188c2ecf20Sopenharmony_ci return EFI_OUT_OF_RESOURCES; 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci return EFI_SUCCESS; 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(efi_query_variable_store); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci/* 2268c2ecf20Sopenharmony_ci * The UEFI specification makes it clear that the operating system is 2278c2ecf20Sopenharmony_ci * free to do whatever it wants with boot services code after 2288c2ecf20Sopenharmony_ci * ExitBootServices() has been called. Ignoring this recommendation a 2298c2ecf20Sopenharmony_ci * significant bunch of EFI implementations continue calling into boot 2308c2ecf20Sopenharmony_ci * services code (SetVirtualAddressMap). In order to work around such 2318c2ecf20Sopenharmony_ci * buggy implementations we reserve boot services region during EFI 2328c2ecf20Sopenharmony_ci * init and make sure it stays executable. Then, after 2338c2ecf20Sopenharmony_ci * SetVirtualAddressMap(), it is discarded. 2348c2ecf20Sopenharmony_ci * 2358c2ecf20Sopenharmony_ci * However, some boot services regions contain data that is required 2368c2ecf20Sopenharmony_ci * by drivers, so we need to track which memory ranges can never be 2378c2ecf20Sopenharmony_ci * freed. This is done by tagging those regions with the 2388c2ecf20Sopenharmony_ci * EFI_MEMORY_RUNTIME attribute. 2398c2ecf20Sopenharmony_ci * 2408c2ecf20Sopenharmony_ci * Any driver that wants to mark a region as reserved must use 2418c2ecf20Sopenharmony_ci * efi_mem_reserve() which will insert a new EFI memory descriptor 2428c2ecf20Sopenharmony_ci * into efi.memmap (splitting existing regions if necessary) and tag 2438c2ecf20Sopenharmony_ci * it with EFI_MEMORY_RUNTIME. 2448c2ecf20Sopenharmony_ci */ 2458c2ecf20Sopenharmony_civoid __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci struct efi_memory_map_data data = { 0 }; 2488c2ecf20Sopenharmony_ci struct efi_mem_range mr; 2498c2ecf20Sopenharmony_ci efi_memory_desc_t md; 2508c2ecf20Sopenharmony_ci int num_entries; 2518c2ecf20Sopenharmony_ci void *new; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci if (efi_mem_desc_lookup(addr, &md) || 2548c2ecf20Sopenharmony_ci md.type != EFI_BOOT_SERVICES_DATA) { 2558c2ecf20Sopenharmony_ci pr_err("Failed to lookup EFI memory descriptor for %pa\n", &addr); 2568c2ecf20Sopenharmony_ci return; 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci if (addr + size > md.phys_addr + (md.num_pages << EFI_PAGE_SHIFT)) { 2608c2ecf20Sopenharmony_ci pr_err("Region spans EFI memory descriptors, %pa\n", &addr); 2618c2ecf20Sopenharmony_ci return; 2628c2ecf20Sopenharmony_ci } 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci size += addr % EFI_PAGE_SIZE; 2658c2ecf20Sopenharmony_ci size = round_up(size, EFI_PAGE_SIZE); 2668c2ecf20Sopenharmony_ci addr = round_down(addr, EFI_PAGE_SIZE); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci mr.range.start = addr; 2698c2ecf20Sopenharmony_ci mr.range.end = addr + size - 1; 2708c2ecf20Sopenharmony_ci mr.attribute = md.attribute | EFI_MEMORY_RUNTIME; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci num_entries = efi_memmap_split_count(&md, &mr.range); 2738c2ecf20Sopenharmony_ci num_entries += efi.memmap.nr_map; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci if (efi_memmap_alloc(num_entries, &data) != 0) { 2768c2ecf20Sopenharmony_ci pr_err("Could not allocate boot services memmap\n"); 2778c2ecf20Sopenharmony_ci return; 2788c2ecf20Sopenharmony_ci } 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci new = early_memremap_prot(data.phys_map, data.size, 2818c2ecf20Sopenharmony_ci pgprot_val(pgprot_encrypted(FIXMAP_PAGE_NORMAL))); 2828c2ecf20Sopenharmony_ci if (!new) { 2838c2ecf20Sopenharmony_ci pr_err("Failed to map new boot services memmap\n"); 2848c2ecf20Sopenharmony_ci return; 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci efi_memmap_insert(&efi.memmap, new, &mr); 2888c2ecf20Sopenharmony_ci early_memunmap(new, data.size); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci efi_memmap_install(&data); 2918c2ecf20Sopenharmony_ci e820__range_update(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED); 2928c2ecf20Sopenharmony_ci e820__update_table(e820_table); 2938c2ecf20Sopenharmony_ci} 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci/* 2968c2ecf20Sopenharmony_ci * Helper function for efi_reserve_boot_services() to figure out if we 2978c2ecf20Sopenharmony_ci * can free regions in efi_free_boot_services(). 2988c2ecf20Sopenharmony_ci * 2998c2ecf20Sopenharmony_ci * Use this function to ensure we do not free regions owned by somebody 3008c2ecf20Sopenharmony_ci * else. We must only reserve (and then free) regions: 3018c2ecf20Sopenharmony_ci * 3028c2ecf20Sopenharmony_ci * - Not within any part of the kernel 3038c2ecf20Sopenharmony_ci * - Not the BIOS reserved area (E820_TYPE_RESERVED, E820_TYPE_NVS, etc) 3048c2ecf20Sopenharmony_ci */ 3058c2ecf20Sopenharmony_cistatic __init bool can_free_region(u64 start, u64 size) 3068c2ecf20Sopenharmony_ci{ 3078c2ecf20Sopenharmony_ci if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end)) 3088c2ecf20Sopenharmony_ci return false; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci if (!e820__mapped_all(start, start+size, E820_TYPE_RAM)) 3118c2ecf20Sopenharmony_ci return false; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci return true; 3148c2ecf20Sopenharmony_ci} 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_civoid __init efi_reserve_boot_services(void) 3178c2ecf20Sopenharmony_ci{ 3188c2ecf20Sopenharmony_ci efi_memory_desc_t *md; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci if (!efi_enabled(EFI_MEMMAP)) 3218c2ecf20Sopenharmony_ci return; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci for_each_efi_memory_desc(md) { 3248c2ecf20Sopenharmony_ci u64 start = md->phys_addr; 3258c2ecf20Sopenharmony_ci u64 size = md->num_pages << EFI_PAGE_SHIFT; 3268c2ecf20Sopenharmony_ci bool already_reserved; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci if (md->type != EFI_BOOT_SERVICES_CODE && 3298c2ecf20Sopenharmony_ci md->type != EFI_BOOT_SERVICES_DATA) 3308c2ecf20Sopenharmony_ci continue; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci already_reserved = memblock_is_region_reserved(start, size); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci /* 3358c2ecf20Sopenharmony_ci * Because the following memblock_reserve() is paired 3368c2ecf20Sopenharmony_ci * with memblock_free_late() for this region in 3378c2ecf20Sopenharmony_ci * efi_free_boot_services(), we must be extremely 3388c2ecf20Sopenharmony_ci * careful not to reserve, and subsequently free, 3398c2ecf20Sopenharmony_ci * critical regions of memory (like the kernel image) or 3408c2ecf20Sopenharmony_ci * those regions that somebody else has already 3418c2ecf20Sopenharmony_ci * reserved. 3428c2ecf20Sopenharmony_ci * 3438c2ecf20Sopenharmony_ci * A good example of a critical region that must not be 3448c2ecf20Sopenharmony_ci * freed is page zero (first 4Kb of memory), which may 3458c2ecf20Sopenharmony_ci * contain boot services code/data but is marked 3468c2ecf20Sopenharmony_ci * E820_TYPE_RESERVED by trim_bios_range(). 3478c2ecf20Sopenharmony_ci */ 3488c2ecf20Sopenharmony_ci if (!already_reserved) { 3498c2ecf20Sopenharmony_ci memblock_reserve(start, size); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci /* 3528c2ecf20Sopenharmony_ci * If we are the first to reserve the region, no 3538c2ecf20Sopenharmony_ci * one else cares about it. We own it and can 3548c2ecf20Sopenharmony_ci * free it later. 3558c2ecf20Sopenharmony_ci */ 3568c2ecf20Sopenharmony_ci if (can_free_region(start, size)) 3578c2ecf20Sopenharmony_ci continue; 3588c2ecf20Sopenharmony_ci } 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci /* 3618c2ecf20Sopenharmony_ci * We don't own the region. We must not free it. 3628c2ecf20Sopenharmony_ci * 3638c2ecf20Sopenharmony_ci * Setting this bit for a boot services region really 3648c2ecf20Sopenharmony_ci * doesn't make sense as far as the firmware is 3658c2ecf20Sopenharmony_ci * concerned, but it does provide us with a way to tag 3668c2ecf20Sopenharmony_ci * those regions that must not be paired with 3678c2ecf20Sopenharmony_ci * memblock_free_late(). 3688c2ecf20Sopenharmony_ci */ 3698c2ecf20Sopenharmony_ci md->attribute |= EFI_MEMORY_RUNTIME; 3708c2ecf20Sopenharmony_ci } 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci/* 3748c2ecf20Sopenharmony_ci * Apart from having VA mappings for EFI boot services code/data regions, 3758c2ecf20Sopenharmony_ci * (duplicate) 1:1 mappings were also created as a quirk for buggy firmware. So, 3768c2ecf20Sopenharmony_ci * unmap both 1:1 and VA mappings. 3778c2ecf20Sopenharmony_ci */ 3788c2ecf20Sopenharmony_cistatic void __init efi_unmap_pages(efi_memory_desc_t *md) 3798c2ecf20Sopenharmony_ci{ 3808c2ecf20Sopenharmony_ci pgd_t *pgd = efi_mm.pgd; 3818c2ecf20Sopenharmony_ci u64 pa = md->phys_addr; 3828c2ecf20Sopenharmony_ci u64 va = md->virt_addr; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci /* 3858c2ecf20Sopenharmony_ci * EFI mixed mode has all RAM mapped to access arguments while making 3868c2ecf20Sopenharmony_ci * EFI runtime calls, hence don't unmap EFI boot services code/data 3878c2ecf20Sopenharmony_ci * regions. 3888c2ecf20Sopenharmony_ci */ 3898c2ecf20Sopenharmony_ci if (efi_is_mixed()) 3908c2ecf20Sopenharmony_ci return; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci if (kernel_unmap_pages_in_pgd(pgd, pa, md->num_pages)) 3938c2ecf20Sopenharmony_ci pr_err("Failed to unmap 1:1 mapping for 0x%llx\n", pa); 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci if (kernel_unmap_pages_in_pgd(pgd, va, md->num_pages)) 3968c2ecf20Sopenharmony_ci pr_err("Failed to unmap VA mapping for 0x%llx\n", va); 3978c2ecf20Sopenharmony_ci} 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_civoid __init efi_free_boot_services(void) 4008c2ecf20Sopenharmony_ci{ 4018c2ecf20Sopenharmony_ci struct efi_memory_map_data data = { 0 }; 4028c2ecf20Sopenharmony_ci efi_memory_desc_t *md; 4038c2ecf20Sopenharmony_ci int num_entries = 0; 4048c2ecf20Sopenharmony_ci void *new, *new_md; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci /* Keep all regions for /sys/kernel/debug/efi */ 4078c2ecf20Sopenharmony_ci if (efi_enabled(EFI_DBG)) 4088c2ecf20Sopenharmony_ci return; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci for_each_efi_memory_desc(md) { 4118c2ecf20Sopenharmony_ci unsigned long long start = md->phys_addr; 4128c2ecf20Sopenharmony_ci unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; 4138c2ecf20Sopenharmony_ci size_t rm_size; 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci if (md->type != EFI_BOOT_SERVICES_CODE && 4168c2ecf20Sopenharmony_ci md->type != EFI_BOOT_SERVICES_DATA) { 4178c2ecf20Sopenharmony_ci num_entries++; 4188c2ecf20Sopenharmony_ci continue; 4198c2ecf20Sopenharmony_ci } 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci /* Do not free, someone else owns it: */ 4228c2ecf20Sopenharmony_ci if (md->attribute & EFI_MEMORY_RUNTIME) { 4238c2ecf20Sopenharmony_ci num_entries++; 4248c2ecf20Sopenharmony_ci continue; 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci /* 4288c2ecf20Sopenharmony_ci * Before calling set_virtual_address_map(), EFI boot services 4298c2ecf20Sopenharmony_ci * code/data regions were mapped as a quirk for buggy firmware. 4308c2ecf20Sopenharmony_ci * Unmap them from efi_pgd before freeing them up. 4318c2ecf20Sopenharmony_ci */ 4328c2ecf20Sopenharmony_ci efi_unmap_pages(md); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci /* 4358c2ecf20Sopenharmony_ci * Nasty quirk: if all sub-1MB memory is used for boot 4368c2ecf20Sopenharmony_ci * services, we can get here without having allocated the 4378c2ecf20Sopenharmony_ci * real mode trampoline. It's too late to hand boot services 4388c2ecf20Sopenharmony_ci * memory back to the memblock allocator, so instead 4398c2ecf20Sopenharmony_ci * try to manually allocate the trampoline if needed. 4408c2ecf20Sopenharmony_ci * 4418c2ecf20Sopenharmony_ci * I've seen this on a Dell XPS 13 9350 with firmware 4428c2ecf20Sopenharmony_ci * 1.4.4 with SGX enabled booting Linux via Fedora 24's 4438c2ecf20Sopenharmony_ci * grub2-efi on a hard disk. (And no, I don't know why 4448c2ecf20Sopenharmony_ci * this happened, but Linux should still try to boot rather 4458c2ecf20Sopenharmony_ci * panicing early.) 4468c2ecf20Sopenharmony_ci */ 4478c2ecf20Sopenharmony_ci rm_size = real_mode_size_needed(); 4488c2ecf20Sopenharmony_ci if (rm_size && (start + rm_size) < (1<<20) && size >= rm_size) { 4498c2ecf20Sopenharmony_ci set_real_mode_mem(start); 4508c2ecf20Sopenharmony_ci start += rm_size; 4518c2ecf20Sopenharmony_ci size -= rm_size; 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci memblock_free_late(start, size); 4558c2ecf20Sopenharmony_ci } 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci if (!num_entries) 4588c2ecf20Sopenharmony_ci return; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci if (efi_memmap_alloc(num_entries, &data) != 0) { 4618c2ecf20Sopenharmony_ci pr_err("Failed to allocate new EFI memmap\n"); 4628c2ecf20Sopenharmony_ci return; 4638c2ecf20Sopenharmony_ci } 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci new = memremap(data.phys_map, data.size, MEMREMAP_WB); 4668c2ecf20Sopenharmony_ci if (!new) { 4678c2ecf20Sopenharmony_ci pr_err("Failed to map new EFI memmap\n"); 4688c2ecf20Sopenharmony_ci return; 4698c2ecf20Sopenharmony_ci } 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci /* 4728c2ecf20Sopenharmony_ci * Build a new EFI memmap that excludes any boot services 4738c2ecf20Sopenharmony_ci * regions that are not tagged EFI_MEMORY_RUNTIME, since those 4748c2ecf20Sopenharmony_ci * regions have now been freed. 4758c2ecf20Sopenharmony_ci */ 4768c2ecf20Sopenharmony_ci new_md = new; 4778c2ecf20Sopenharmony_ci for_each_efi_memory_desc(md) { 4788c2ecf20Sopenharmony_ci if (!(md->attribute & EFI_MEMORY_RUNTIME) && 4798c2ecf20Sopenharmony_ci (md->type == EFI_BOOT_SERVICES_CODE || 4808c2ecf20Sopenharmony_ci md->type == EFI_BOOT_SERVICES_DATA)) 4818c2ecf20Sopenharmony_ci continue; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci memcpy(new_md, md, efi.memmap.desc_size); 4848c2ecf20Sopenharmony_ci new_md += efi.memmap.desc_size; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci memunmap(new); 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci if (efi_memmap_install(&data) != 0) { 4908c2ecf20Sopenharmony_ci pr_err("Could not install new EFI memmap\n"); 4918c2ecf20Sopenharmony_ci return; 4928c2ecf20Sopenharmony_ci } 4938c2ecf20Sopenharmony_ci} 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci/* 4968c2ecf20Sopenharmony_ci * A number of config table entries get remapped to virtual addresses 4978c2ecf20Sopenharmony_ci * after entering EFI virtual mode. However, the kexec kernel requires 4988c2ecf20Sopenharmony_ci * their physical addresses therefore we pass them via setup_data and 4998c2ecf20Sopenharmony_ci * correct those entries to their respective physical addresses here. 5008c2ecf20Sopenharmony_ci * 5018c2ecf20Sopenharmony_ci * Currently only handles smbios which is necessary for some firmware 5028c2ecf20Sopenharmony_ci * implementation. 5038c2ecf20Sopenharmony_ci */ 5048c2ecf20Sopenharmony_ciint __init efi_reuse_config(u64 tables, int nr_tables) 5058c2ecf20Sopenharmony_ci{ 5068c2ecf20Sopenharmony_ci int i, sz, ret = 0; 5078c2ecf20Sopenharmony_ci void *p, *tablep; 5088c2ecf20Sopenharmony_ci struct efi_setup_data *data; 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci if (nr_tables == 0) 5118c2ecf20Sopenharmony_ci return 0; 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci if (!efi_setup) 5148c2ecf20Sopenharmony_ci return 0; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci if (!efi_enabled(EFI_64BIT)) 5178c2ecf20Sopenharmony_ci return 0; 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci data = early_memremap(efi_setup, sizeof(*data)); 5208c2ecf20Sopenharmony_ci if (!data) { 5218c2ecf20Sopenharmony_ci ret = -ENOMEM; 5228c2ecf20Sopenharmony_ci goto out; 5238c2ecf20Sopenharmony_ci } 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci if (!data->smbios) 5268c2ecf20Sopenharmony_ci goto out_memremap; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci sz = sizeof(efi_config_table_64_t); 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci p = tablep = early_memremap(tables, nr_tables * sz); 5318c2ecf20Sopenharmony_ci if (!p) { 5328c2ecf20Sopenharmony_ci pr_err("Could not map Configuration table!\n"); 5338c2ecf20Sopenharmony_ci ret = -ENOMEM; 5348c2ecf20Sopenharmony_ci goto out_memremap; 5358c2ecf20Sopenharmony_ci } 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci for (i = 0; i < nr_tables; i++) { 5388c2ecf20Sopenharmony_ci efi_guid_t guid; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci guid = ((efi_config_table_64_t *)p)->guid; 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) 5438c2ecf20Sopenharmony_ci ((efi_config_table_64_t *)p)->table = data->smbios; 5448c2ecf20Sopenharmony_ci p += sz; 5458c2ecf20Sopenharmony_ci } 5468c2ecf20Sopenharmony_ci early_memunmap(tablep, nr_tables * sz); 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ciout_memremap: 5498c2ecf20Sopenharmony_ci early_memunmap(data, sizeof(*data)); 5508c2ecf20Sopenharmony_ciout: 5518c2ecf20Sopenharmony_ci return ret; 5528c2ecf20Sopenharmony_ci} 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_civoid __init efi_apply_memmap_quirks(void) 5558c2ecf20Sopenharmony_ci{ 5568c2ecf20Sopenharmony_ci /* 5578c2ecf20Sopenharmony_ci * Once setup is done earlier, unmap the EFI memory map on mismatched 5588c2ecf20Sopenharmony_ci * firmware/kernel architectures since there is no support for runtime 5598c2ecf20Sopenharmony_ci * services. 5608c2ecf20Sopenharmony_ci */ 5618c2ecf20Sopenharmony_ci if (!efi_runtime_supported()) { 5628c2ecf20Sopenharmony_ci pr_info("Setup done, disabling due to 32/64-bit mismatch\n"); 5638c2ecf20Sopenharmony_ci efi_memmap_unmap(); 5648c2ecf20Sopenharmony_ci } 5658c2ecf20Sopenharmony_ci} 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci/* 5688c2ecf20Sopenharmony_ci * For most modern platforms the preferred method of powering off is via 5698c2ecf20Sopenharmony_ci * ACPI. However, there are some that are known to require the use of 5708c2ecf20Sopenharmony_ci * EFI runtime services and for which ACPI does not work at all. 5718c2ecf20Sopenharmony_ci * 5728c2ecf20Sopenharmony_ci * Using EFI is a last resort, to be used only if no other option 5738c2ecf20Sopenharmony_ci * exists. 5748c2ecf20Sopenharmony_ci */ 5758c2ecf20Sopenharmony_cibool efi_reboot_required(void) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci if (!acpi_gbl_reduced_hardware) 5788c2ecf20Sopenharmony_ci return false; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci efi_reboot_quirk_mode = EFI_RESET_WARM; 5818c2ecf20Sopenharmony_ci return true; 5828c2ecf20Sopenharmony_ci} 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_cibool efi_poweroff_required(void) 5858c2ecf20Sopenharmony_ci{ 5868c2ecf20Sopenharmony_ci return acpi_gbl_reduced_hardware || acpi_no_s5; 5878c2ecf20Sopenharmony_ci} 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci#ifdef CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_cistatic int qrk_capsule_setup_info(struct capsule_info *cap_info, void **pkbuff, 5928c2ecf20Sopenharmony_ci size_t hdr_bytes) 5938c2ecf20Sopenharmony_ci{ 5948c2ecf20Sopenharmony_ci struct quark_security_header *csh = *pkbuff; 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci /* Only process data block that is larger than the security header */ 5978c2ecf20Sopenharmony_ci if (hdr_bytes < sizeof(struct quark_security_header)) 5988c2ecf20Sopenharmony_ci return 0; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci if (csh->csh_signature != QUARK_CSH_SIGNATURE || 6018c2ecf20Sopenharmony_ci csh->headersize != QUARK_SECURITY_HEADER_SIZE) 6028c2ecf20Sopenharmony_ci return 1; 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci /* Only process data block if EFI header is included */ 6058c2ecf20Sopenharmony_ci if (hdr_bytes < QUARK_SECURITY_HEADER_SIZE + 6068c2ecf20Sopenharmony_ci sizeof(efi_capsule_header_t)) 6078c2ecf20Sopenharmony_ci return 0; 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_ci pr_debug("Quark security header detected\n"); 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci if (csh->rsvd_next_header != 0) { 6128c2ecf20Sopenharmony_ci pr_err("multiple Quark security headers not supported\n"); 6138c2ecf20Sopenharmony_ci return -EINVAL; 6148c2ecf20Sopenharmony_ci } 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci *pkbuff += csh->headersize; 6178c2ecf20Sopenharmony_ci cap_info->total_size = csh->headersize; 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci /* 6208c2ecf20Sopenharmony_ci * Update the first page pointer to skip over the CSH header. 6218c2ecf20Sopenharmony_ci */ 6228c2ecf20Sopenharmony_ci cap_info->phys[0] += csh->headersize; 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci /* 6258c2ecf20Sopenharmony_ci * cap_info->capsule should point at a virtual mapping of the entire 6268c2ecf20Sopenharmony_ci * capsule, starting at the capsule header. Our image has the Quark 6278c2ecf20Sopenharmony_ci * security header prepended, so we cannot rely on the default vmap() 6288c2ecf20Sopenharmony_ci * mapping created by the generic capsule code. 6298c2ecf20Sopenharmony_ci * Given that the Quark firmware does not appear to care about the 6308c2ecf20Sopenharmony_ci * virtual mapping, let's just point cap_info->capsule at our copy 6318c2ecf20Sopenharmony_ci * of the capsule header. 6328c2ecf20Sopenharmony_ci */ 6338c2ecf20Sopenharmony_ci cap_info->capsule = &cap_info->header; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci return 1; 6368c2ecf20Sopenharmony_ci} 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_cistatic const struct x86_cpu_id efi_capsule_quirk_ids[] = { 6398c2ecf20Sopenharmony_ci X86_MATCH_VENDOR_FAM_MODEL(INTEL, 5, INTEL_FAM5_QUARK_X1000, 6408c2ecf20Sopenharmony_ci &qrk_capsule_setup_info), 6418c2ecf20Sopenharmony_ci { } 6428c2ecf20Sopenharmony_ci}; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ciint efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, 6458c2ecf20Sopenharmony_ci size_t hdr_bytes) 6468c2ecf20Sopenharmony_ci{ 6478c2ecf20Sopenharmony_ci int (*quirk_handler)(struct capsule_info *, void **, size_t); 6488c2ecf20Sopenharmony_ci const struct x86_cpu_id *id; 6498c2ecf20Sopenharmony_ci int ret; 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci if (hdr_bytes < sizeof(efi_capsule_header_t)) 6528c2ecf20Sopenharmony_ci return 0; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci cap_info->total_size = 0; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci id = x86_match_cpu(efi_capsule_quirk_ids); 6578c2ecf20Sopenharmony_ci if (id) { 6588c2ecf20Sopenharmony_ci /* 6598c2ecf20Sopenharmony_ci * The quirk handler is supposed to return 6608c2ecf20Sopenharmony_ci * - a value > 0 if the setup should continue, after advancing 6618c2ecf20Sopenharmony_ci * kbuff as needed 6628c2ecf20Sopenharmony_ci * - 0 if not enough hdr_bytes are available yet 6638c2ecf20Sopenharmony_ci * - a negative error code otherwise 6648c2ecf20Sopenharmony_ci */ 6658c2ecf20Sopenharmony_ci quirk_handler = (typeof(quirk_handler))id->driver_data; 6668c2ecf20Sopenharmony_ci ret = quirk_handler(cap_info, &kbuff, hdr_bytes); 6678c2ecf20Sopenharmony_ci if (ret <= 0) 6688c2ecf20Sopenharmony_ci return ret; 6698c2ecf20Sopenharmony_ci } 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci memcpy(&cap_info->header, kbuff, sizeof(cap_info->header)); 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci cap_info->total_size += cap_info->header.imagesize; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci return __efi_capsule_setup_info(cap_info); 6768c2ecf20Sopenharmony_ci} 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci#endif 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci/* 6818c2ecf20Sopenharmony_ci * If any access by any efi runtime service causes a page fault, then, 6828c2ecf20Sopenharmony_ci * 1. If it's efi_reset_system(), reboot through BIOS. 6838c2ecf20Sopenharmony_ci * 2. If any other efi runtime service, then 6848c2ecf20Sopenharmony_ci * a. Return error status to the efi caller process. 6858c2ecf20Sopenharmony_ci * b. Disable EFI Runtime Services forever and 6868c2ecf20Sopenharmony_ci * c. Freeze efi_rts_wq and schedule new process. 6878c2ecf20Sopenharmony_ci * 6888c2ecf20Sopenharmony_ci * @return: Returns, if the page fault is not handled. This function 6898c2ecf20Sopenharmony_ci * will never return if the page fault is handled successfully. 6908c2ecf20Sopenharmony_ci */ 6918c2ecf20Sopenharmony_civoid efi_recover_from_page_fault(unsigned long phys_addr) 6928c2ecf20Sopenharmony_ci{ 6938c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_X86_64)) 6948c2ecf20Sopenharmony_ci return; 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci /* 6978c2ecf20Sopenharmony_ci * Make sure that an efi runtime service caused the page fault. 6988c2ecf20Sopenharmony_ci */ 6998c2ecf20Sopenharmony_ci if (efi_rts_work.efi_rts_id == EFI_NONE) 7008c2ecf20Sopenharmony_ci return; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci /* 7038c2ecf20Sopenharmony_ci * Address range 0x0000 - 0x0fff is always mapped in the efi_pgd, so 7048c2ecf20Sopenharmony_ci * page faulting on these addresses isn't expected. 7058c2ecf20Sopenharmony_ci */ 7068c2ecf20Sopenharmony_ci if (phys_addr <= 0x0fff) 7078c2ecf20Sopenharmony_ci return; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci /* 7108c2ecf20Sopenharmony_ci * Print stack trace as it might be useful to know which EFI Runtime 7118c2ecf20Sopenharmony_ci * Service is buggy. 7128c2ecf20Sopenharmony_ci */ 7138c2ecf20Sopenharmony_ci WARN(1, FW_BUG "Page fault caused by firmware at PA: 0x%lx\n", 7148c2ecf20Sopenharmony_ci phys_addr); 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci /* 7178c2ecf20Sopenharmony_ci * Buggy efi_reset_system() is handled differently from other EFI 7188c2ecf20Sopenharmony_ci * Runtime Services as it doesn't use efi_rts_wq. Although, 7198c2ecf20Sopenharmony_ci * native_machine_emergency_restart() says that machine_real_restart() 7208c2ecf20Sopenharmony_ci * could fail, it's better not to compilcate this fault handler 7218c2ecf20Sopenharmony_ci * because this case occurs *very* rarely and hence could be improved 7228c2ecf20Sopenharmony_ci * on a need by basis. 7238c2ecf20Sopenharmony_ci */ 7248c2ecf20Sopenharmony_ci if (efi_rts_work.efi_rts_id == EFI_RESET_SYSTEM) { 7258c2ecf20Sopenharmony_ci pr_info("efi_reset_system() buggy! Reboot through BIOS\n"); 7268c2ecf20Sopenharmony_ci machine_real_restart(MRR_BIOS); 7278c2ecf20Sopenharmony_ci return; 7288c2ecf20Sopenharmony_ci } 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci /* 7318c2ecf20Sopenharmony_ci * Before calling EFI Runtime Service, the kernel has switched the 7328c2ecf20Sopenharmony_ci * calling process to efi_mm. Hence, switch back to task_mm. 7338c2ecf20Sopenharmony_ci */ 7348c2ecf20Sopenharmony_ci arch_efi_call_virt_teardown(); 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci /* Signal error status to the efi caller process */ 7378c2ecf20Sopenharmony_ci efi_rts_work.status = EFI_ABORTED; 7388c2ecf20Sopenharmony_ci complete(&efi_rts_work.efi_rts_comp); 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); 7418c2ecf20Sopenharmony_ci pr_info("Froze efi_rts_wq and disabled EFI Runtime Services\n"); 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci /* 7448c2ecf20Sopenharmony_ci * Call schedule() in an infinite loop, so that any spurious wake ups 7458c2ecf20Sopenharmony_ci * will never run efi_rts_wq again. 7468c2ecf20Sopenharmony_ci */ 7478c2ecf20Sopenharmony_ci for (;;) { 7488c2ecf20Sopenharmony_ci set_current_state(TASK_IDLE); 7498c2ecf20Sopenharmony_ci schedule(); 7508c2ecf20Sopenharmony_ci } 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci return; 7538c2ecf20Sopenharmony_ci} 754