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

arm-runtime.c (3874B)


      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, 2014 Linaro Ltd.
      8 */
      9
     10#include <linux/dmi.h>
     11#include <linux/efi.h>
     12#include <linux/io.h>
     13#include <linux/memblock.h>
     14#include <linux/mm_types.h>
     15#include <linux/preempt.h>
     16#include <linux/rbtree.h>
     17#include <linux/rwsem.h>
     18#include <linux/sched.h>
     19#include <linux/slab.h>
     20#include <linux/spinlock.h>
     21#include <linux/pgtable.h>
     22
     23#include <asm/cacheflush.h>
     24#include <asm/efi.h>
     25#include <asm/mmu.h>
     26#include <asm/pgalloc.h>
     27
     28#if defined(CONFIG_PTDUMP_DEBUGFS) && defined(CONFIG_ARM64)
     29#include <asm/ptdump.h>
     30
     31static struct ptdump_info efi_ptdump_info = {
     32	.mm		= &efi_mm,
     33	.markers	= (struct addr_marker[]){
     34		{ 0,				"UEFI runtime start" },
     35		{ DEFAULT_MAP_WINDOW_64,	"UEFI runtime end" },
     36		{ -1,				NULL }
     37	},
     38	.base_addr	= 0,
     39};
     40
     41static int __init ptdump_init(void)
     42{
     43	if (efi_enabled(EFI_RUNTIME_SERVICES))
     44		ptdump_debugfs_register(&efi_ptdump_info, "efi_page_tables");
     45
     46	return 0;
     47}
     48device_initcall(ptdump_init);
     49
     50#endif
     51
     52static bool __init efi_virtmap_init(void)
     53{
     54	efi_memory_desc_t *md;
     55
     56	efi_mm.pgd = pgd_alloc(&efi_mm);
     57	mm_init_cpumask(&efi_mm);
     58	init_new_context(NULL, &efi_mm);
     59
     60	for_each_efi_memory_desc(md) {
     61		phys_addr_t phys = md->phys_addr;
     62		int ret;
     63
     64		if (!(md->attribute & EFI_MEMORY_RUNTIME))
     65			continue;
     66		if (md->virt_addr == 0)
     67			return false;
     68
     69		ret = efi_create_mapping(&efi_mm, md);
     70		if (ret) {
     71			pr_warn("  EFI remap %pa: failed to create mapping (%d)\n",
     72				&phys, ret);
     73			return false;
     74		}
     75	}
     76
     77	if (efi_memattr_apply_permissions(&efi_mm, efi_set_mapping_permissions))
     78		return false;
     79
     80	return true;
     81}
     82
     83/*
     84 * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
     85 * non-early mapping of the UEFI system table and virtual mappings for all
     86 * EFI_MEMORY_RUNTIME regions.
     87 */
     88static int __init arm_enable_runtime_services(void)
     89{
     90	u64 mapsize;
     91
     92	if (!efi_enabled(EFI_BOOT)) {
     93		pr_info("EFI services will not be available.\n");
     94		return 0;
     95	}
     96
     97	efi_memmap_unmap();
     98
     99	mapsize = efi.memmap.desc_size * efi.memmap.nr_map;
    100
    101	if (efi_memmap_init_late(efi.memmap.phys_map, mapsize)) {
    102		pr_err("Failed to remap EFI memory map\n");
    103		return 0;
    104	}
    105
    106	if (efi_soft_reserve_enabled()) {
    107		efi_memory_desc_t *md;
    108
    109		for_each_efi_memory_desc(md) {
    110			int md_size = md->num_pages << EFI_PAGE_SHIFT;
    111			struct resource *res;
    112
    113			if (!(md->attribute & EFI_MEMORY_SP))
    114				continue;
    115
    116			res = kzalloc(sizeof(*res), GFP_KERNEL);
    117			if (WARN_ON(!res))
    118				break;
    119
    120			res->start	= md->phys_addr;
    121			res->end	= md->phys_addr + md_size - 1;
    122			res->name	= "Soft Reserved";
    123			res->flags	= IORESOURCE_MEM;
    124			res->desc	= IORES_DESC_SOFT_RESERVED;
    125
    126			insert_resource(&iomem_resource, res);
    127		}
    128	}
    129
    130	if (efi_runtime_disabled()) {
    131		pr_info("EFI runtime services will be disabled.\n");
    132		return 0;
    133	}
    134
    135	if (efi_enabled(EFI_RUNTIME_SERVICES)) {
    136		pr_info("EFI runtime services access via paravirt.\n");
    137		return 0;
    138	}
    139
    140	pr_info("Remapping and enabling EFI services.\n");
    141
    142	if (!efi_virtmap_init()) {
    143		pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n");
    144		return -ENOMEM;
    145	}
    146
    147	/* Set up runtime services function pointers */
    148	efi_native_runtime_setup();
    149	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
    150
    151	return 0;
    152}
    153early_initcall(arm_enable_runtime_services);
    154
    155void efi_virtmap_load(void)
    156{
    157	preempt_disable();
    158	efi_set_pgd(&efi_mm);
    159}
    160
    161void efi_virtmap_unload(void)
    162{
    163	efi_set_pgd(current->active_mm);
    164	preempt_enable();
    165}
    166
    167
    168static int __init arm_dmi_init(void)
    169{
    170	/*
    171	 * On arm64/ARM, DMI depends on UEFI, and dmi_setup() needs to
    172	 * be called early because dmi_id_init(), which is an arch_initcall
    173	 * itself, depends on dmi_scan_machine() having been called already.
    174	 */
    175	dmi_setup();
    176	return 0;
    177}
    178core_initcall(arm_dmi_init);