root/drivers/firmware/efi/arm-runtime.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ptdump_init
  2. efi_virtmap_init
  3. arm_enable_runtime_services
  4. efi_virtmap_load
  5. efi_virtmap_unload
  6. arm_dmi_init

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

/* [<][>][^][v][top][bottom][index][help] */