cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

efi-init.c (7685B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Extensible Firmware Interface
      4 *
      5 * Based on Extensible Firmware Interface Specification version 2.4
      6 *
      7 * Copyright (C) 2013 - 2015 Linaro Ltd.
      8 */
      9
     10#define pr_fmt(fmt)	"efi: " fmt
     11
     12#include <linux/efi.h>
     13#include <linux/fwnode.h>
     14#include <linux/init.h>
     15#include <linux/memblock.h>
     16#include <linux/mm_types.h>
     17#include <linux/of.h>
     18#include <linux/of_address.h>
     19#include <linux/of_fdt.h>
     20#include <linux/platform_device.h>
     21#include <linux/screen_info.h>
     22
     23#include <asm/efi.h>
     24
     25static int __init is_memory(efi_memory_desc_t *md)
     26{
     27	if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC))
     28		return 1;
     29	return 0;
     30}
     31
     32/*
     33 * Translate a EFI virtual address into a physical address: this is necessary,
     34 * as some data members of the EFI system table are virtually remapped after
     35 * SetVirtualAddressMap() has been called.
     36 */
     37static phys_addr_t __init efi_to_phys(unsigned long addr)
     38{
     39	efi_memory_desc_t *md;
     40
     41	for_each_efi_memory_desc(md) {
     42		if (!(md->attribute & EFI_MEMORY_RUNTIME))
     43			continue;
     44		if (md->virt_addr == 0)
     45			/* no virtual mapping has been installed by the stub */
     46			break;
     47		if (md->virt_addr <= addr &&
     48		    (addr - md->virt_addr) < (md->num_pages << EFI_PAGE_SHIFT))
     49			return md->phys_addr + addr - md->virt_addr;
     50	}
     51	return addr;
     52}
     53
     54static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR;
     55static __initdata unsigned long cpu_state_table = EFI_INVALID_TABLE_ADDR;
     56
     57static const efi_config_table_type_t arch_tables[] __initconst = {
     58	{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
     59	{LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table},
     60	{}
     61};
     62
     63static void __init init_screen_info(void)
     64{
     65	struct screen_info *si;
     66
     67	if (IS_ENABLED(CONFIG_ARM) &&
     68	    screen_info_table != EFI_INVALID_TABLE_ADDR) {
     69		si = early_memremap_ro(screen_info_table, sizeof(*si));
     70		if (!si) {
     71			pr_err("Could not map screen_info config table\n");
     72			return;
     73		}
     74		screen_info = *si;
     75		early_memunmap(si, sizeof(*si));
     76
     77		/* dummycon on ARM needs non-zero values for columns/lines */
     78		screen_info.orig_video_cols = 80;
     79		screen_info.orig_video_lines = 25;
     80	}
     81
     82	if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI &&
     83	    memblock_is_map_memory(screen_info.lfb_base))
     84		memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size);
     85}
     86
     87static int __init uefi_init(u64 efi_system_table)
     88{
     89	efi_config_table_t *config_tables;
     90	efi_system_table_t *systab;
     91	size_t table_size;
     92	int retval;
     93
     94	systab = early_memremap_ro(efi_system_table, sizeof(efi_system_table_t));
     95	if (systab == NULL) {
     96		pr_warn("Unable to map EFI system table.\n");
     97		return -ENOMEM;
     98	}
     99
    100	set_bit(EFI_BOOT, &efi.flags);
    101	if (IS_ENABLED(CONFIG_64BIT))
    102		set_bit(EFI_64BIT, &efi.flags);
    103
    104	retval = efi_systab_check_header(&systab->hdr, 2);
    105	if (retval)
    106		goto out;
    107
    108	efi.runtime = systab->runtime;
    109	efi.runtime_version = systab->hdr.revision;
    110
    111	efi_systab_report_header(&systab->hdr, efi_to_phys(systab->fw_vendor));
    112
    113	table_size = sizeof(efi_config_table_t) * systab->nr_tables;
    114	config_tables = early_memremap_ro(efi_to_phys(systab->tables),
    115					  table_size);
    116	if (config_tables == NULL) {
    117		pr_warn("Unable to map EFI config table array.\n");
    118		retval = -ENOMEM;
    119		goto out;
    120	}
    121	retval = efi_config_parse_tables(config_tables, systab->nr_tables,
    122					 IS_ENABLED(CONFIG_ARM) ? arch_tables
    123								: NULL);
    124
    125	early_memunmap(config_tables, table_size);
    126out:
    127	early_memunmap(systab, sizeof(efi_system_table_t));
    128	return retval;
    129}
    130
    131/*
    132 * Return true for regions that can be used as System RAM.
    133 */
    134static __init int is_usable_memory(efi_memory_desc_t *md)
    135{
    136	switch (md->type) {
    137	case EFI_LOADER_CODE:
    138	case EFI_LOADER_DATA:
    139	case EFI_ACPI_RECLAIM_MEMORY:
    140	case EFI_BOOT_SERVICES_CODE:
    141	case EFI_BOOT_SERVICES_DATA:
    142	case EFI_CONVENTIONAL_MEMORY:
    143	case EFI_PERSISTENT_MEMORY:
    144		/*
    145		 * Special purpose memory is 'soft reserved', which means it
    146		 * is set aside initially, but can be hotplugged back in or
    147		 * be assigned to the dax driver after boot.
    148		 */
    149		if (efi_soft_reserve_enabled() &&
    150		    (md->attribute & EFI_MEMORY_SP))
    151			return false;
    152
    153		/*
    154		 * According to the spec, these regions are no longer reserved
    155		 * after calling ExitBootServices(). However, we can only use
    156		 * them as System RAM if they can be mapped writeback cacheable.
    157		 */
    158		return (md->attribute & EFI_MEMORY_WB);
    159	default:
    160		break;
    161	}
    162	return false;
    163}
    164
    165static __init void reserve_regions(void)
    166{
    167	efi_memory_desc_t *md;
    168	u64 paddr, npages, size;
    169
    170	if (efi_enabled(EFI_DBG))
    171		pr_info("Processing EFI memory map:\n");
    172
    173	/*
    174	 * Discard memblocks discovered so far: if there are any at this
    175	 * point, they originate from memory nodes in the DT, and UEFI
    176	 * uses its own memory map instead.
    177	 */
    178	memblock_dump_all();
    179	memblock_remove(0, PHYS_ADDR_MAX);
    180
    181	for_each_efi_memory_desc(md) {
    182		paddr = md->phys_addr;
    183		npages = md->num_pages;
    184
    185		if (efi_enabled(EFI_DBG)) {
    186			char buf[64];
    187
    188			pr_info("  0x%012llx-0x%012llx %s\n",
    189				paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
    190				efi_md_typeattr_format(buf, sizeof(buf), md));
    191		}
    192
    193		memrange_efi_to_native(&paddr, &npages);
    194		size = npages << PAGE_SHIFT;
    195
    196		if (is_memory(md)) {
    197			early_init_dt_add_memory_arch(paddr, size);
    198
    199			if (!is_usable_memory(md))
    200				memblock_mark_nomap(paddr, size);
    201
    202			/* keep ACPI reclaim memory intact for kexec etc. */
    203			if (md->type == EFI_ACPI_RECLAIM_MEMORY)
    204				memblock_reserve(paddr, size);
    205		}
    206	}
    207}
    208
    209void __init efi_init(void)
    210{
    211	struct efi_memory_map_data data;
    212	u64 efi_system_table;
    213
    214	/* Grab UEFI information placed in FDT by stub */
    215	efi_system_table = efi_get_fdt_params(&data);
    216	if (!efi_system_table)
    217		return;
    218
    219	if (efi_memmap_init_early(&data) < 0) {
    220		/*
    221		* If we are booting via UEFI, the UEFI memory map is the only
    222		* description of memory we have, so there is little point in
    223		* proceeding if we cannot access it.
    224		*/
    225		panic("Unable to map EFI memory map.\n");
    226	}
    227
    228	WARN(efi.memmap.desc_version != 1,
    229	     "Unexpected EFI_MEMORY_DESCRIPTOR version %ld",
    230	      efi.memmap.desc_version);
    231
    232	if (uefi_init(efi_system_table) < 0) {
    233		efi_memmap_unmap();
    234		return;
    235	}
    236
    237	reserve_regions();
    238	/*
    239	 * For memblock manipulation, the cap should come after the memblock_add().
    240	 * And now, memblock is fully populated, it is time to do capping.
    241	 */
    242	early_init_dt_check_for_usable_mem_range();
    243	efi_esrt_init();
    244	efi_mokvar_table_init();
    245
    246	memblock_reserve(data.phys_map & PAGE_MASK,
    247			 PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
    248
    249	init_screen_info();
    250
    251#ifdef CONFIG_ARM
    252	/* ARM does not permit early mappings to persist across paging_init() */
    253	efi_memmap_unmap();
    254
    255	if (cpu_state_table != EFI_INVALID_TABLE_ADDR) {
    256		struct efi_arm_entry_state *state;
    257		bool dump_state = true;
    258
    259		state = early_memremap_ro(cpu_state_table,
    260					  sizeof(struct efi_arm_entry_state));
    261		if (state == NULL) {
    262			pr_warn("Unable to map CPU entry state table.\n");
    263			return;
    264		}
    265
    266		if ((state->sctlr_before_ebs & 1) == 0)
    267			pr_warn(FW_BUG "EFI stub was entered with MMU and Dcache disabled, please fix your firmware!\n");
    268		else if ((state->sctlr_after_ebs & 1) == 0)
    269			pr_warn(FW_BUG "ExitBootServices() returned with MMU and Dcache disabled, please fix your firmware!\n");
    270		else
    271			dump_state = false;
    272
    273		if (dump_state || efi_enabled(EFI_DBG)) {
    274			pr_info("CPSR at EFI stub entry        : 0x%08x\n", state->cpsr_before_ebs);
    275			pr_info("SCTLR at EFI stub entry       : 0x%08x\n", state->sctlr_before_ebs);
    276			pr_info("CPSR after ExitBootServices() : 0x%08x\n", state->cpsr_after_ebs);
    277			pr_info("SCTLR after ExitBootServices(): 0x%08x\n", state->sctlr_after_ebs);
    278		}
    279		early_memunmap(state, sizeof(struct efi_arm_entry_state));
    280	}
    281#endif
    282}