LCOV - code coverage report
Current view: top level - drivers/firmware/efi - efi.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 11 391 2.8 %
Date: 2022-03-28 16:04:14 Functions: 4 31 12.9 %
Branches: 5 237 2.1 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * efi.c - EFI subsystem
       4                 :            :  *
       5                 :            :  * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
       6                 :            :  * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
       7                 :            :  * Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
       8                 :            :  *
       9                 :            :  * This code registers /sys/firmware/efi{,/efivars} when EFI is supported,
      10                 :            :  * allowing the efivarfs to be mounted or the efivars module to be loaded.
      11                 :            :  * The existance of /sys/firmware/efi may also be used by userspace to
      12                 :            :  * determine that the system supports EFI.
      13                 :            :  */
      14                 :            : 
      15                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      16                 :            : 
      17                 :            : #include <linux/kobject.h>
      18                 :            : #include <linux/module.h>
      19                 :            : #include <linux/init.h>
      20                 :            : #include <linux/device.h>
      21                 :            : #include <linux/efi.h>
      22                 :            : #include <linux/of.h>
      23                 :            : #include <linux/of_fdt.h>
      24                 :            : #include <linux/io.h>
      25                 :            : #include <linux/kexec.h>
      26                 :            : #include <linux/platform_device.h>
      27                 :            : #include <linux/random.h>
      28                 :            : #include <linux/reboot.h>
      29                 :            : #include <linux/slab.h>
      30                 :            : #include <linux/acpi.h>
      31                 :            : #include <linux/ucs2_string.h>
      32                 :            : #include <linux/memblock.h>
      33                 :            : #include <linux/security.h>
      34                 :            : 
      35                 :            : #include <asm/early_ioremap.h>
      36                 :            : 
      37                 :            : struct efi __read_mostly efi = {
      38                 :            :         .mps                    = EFI_INVALID_TABLE_ADDR,
      39                 :            :         .acpi                   = EFI_INVALID_TABLE_ADDR,
      40                 :            :         .acpi20                 = EFI_INVALID_TABLE_ADDR,
      41                 :            :         .smbios                 = EFI_INVALID_TABLE_ADDR,
      42                 :            :         .smbios3                = EFI_INVALID_TABLE_ADDR,
      43                 :            :         .boot_info              = EFI_INVALID_TABLE_ADDR,
      44                 :            :         .hcdp                   = EFI_INVALID_TABLE_ADDR,
      45                 :            :         .uga                    = EFI_INVALID_TABLE_ADDR,
      46                 :            :         .fw_vendor              = EFI_INVALID_TABLE_ADDR,
      47                 :            :         .runtime                = EFI_INVALID_TABLE_ADDR,
      48                 :            :         .config_table           = EFI_INVALID_TABLE_ADDR,
      49                 :            :         .esrt                   = EFI_INVALID_TABLE_ADDR,
      50                 :            :         .properties_table       = EFI_INVALID_TABLE_ADDR,
      51                 :            :         .mem_attr_table         = EFI_INVALID_TABLE_ADDR,
      52                 :            :         .rng_seed               = EFI_INVALID_TABLE_ADDR,
      53                 :            :         .tpm_log                = EFI_INVALID_TABLE_ADDR,
      54                 :            :         .tpm_final_log          = EFI_INVALID_TABLE_ADDR,
      55                 :            :         .mem_reserve            = EFI_INVALID_TABLE_ADDR,
      56                 :            : };
      57                 :            : EXPORT_SYMBOL(efi);
      58                 :            : 
      59                 :            : struct mm_struct efi_mm = {
      60                 :            :         .mm_rb                  = RB_ROOT,
      61                 :            :         .mm_users               = ATOMIC_INIT(2),
      62                 :            :         .mm_count               = ATOMIC_INIT(1),
      63                 :            :         .mmap_sem               = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
      64                 :            :         .page_table_lock        = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
      65                 :            :         .mmlist                 = LIST_HEAD_INIT(efi_mm.mmlist),
      66                 :            :         .cpu_bitmap             = { [BITS_TO_LONGS(NR_CPUS)] = 0},
      67                 :            : };
      68                 :            : 
      69                 :            : struct workqueue_struct *efi_rts_wq;
      70                 :            : 
      71                 :            : static bool disable_runtime;
      72                 :          0 : static int __init setup_noefi(char *arg)
      73                 :            : {
      74                 :          0 :         disable_runtime = true;
      75                 :          0 :         return 0;
      76                 :            : }
      77                 :            : early_param("noefi", setup_noefi);
      78                 :            : 
      79                 :          0 : bool efi_runtime_disabled(void)
      80                 :            : {
      81                 :          0 :         return disable_runtime;
      82                 :            : }
      83                 :            : 
      84                 :          0 : bool __pure __efi_soft_reserve_enabled(void)
      85                 :            : {
      86                 :          0 :         return !efi_enabled(EFI_MEM_NO_SOFT_RESERVE);
      87                 :            : }
      88                 :            : 
      89                 :          0 : static int __init parse_efi_cmdline(char *str)
      90                 :            : {
      91         [ #  # ]:          0 :         if (!str) {
      92                 :          0 :                 pr_warn("need at least one option\n");
      93                 :          0 :                 return -EINVAL;
      94                 :            :         }
      95                 :            : 
      96         [ #  # ]:          0 :         if (parse_option_str(str, "debug"))
      97                 :          0 :                 set_bit(EFI_DBG, &efi.flags);
      98                 :            : 
      99         [ #  # ]:          0 :         if (parse_option_str(str, "noruntime"))
     100                 :          0 :                 disable_runtime = true;
     101                 :            : 
     102         [ #  # ]:          0 :         if (parse_option_str(str, "nosoftreserve"))
     103                 :          0 :                 set_bit(EFI_MEM_NO_SOFT_RESERVE, &efi.flags);
     104                 :            : 
     105                 :            :         return 0;
     106                 :            : }
     107                 :            : early_param("efi", parse_efi_cmdline);
     108                 :            : 
     109                 :            : struct kobject *efi_kobj;
     110                 :            : 
     111                 :            : /*
     112                 :            :  * Let's not leave out systab information that snuck into
     113                 :            :  * the efivars driver
     114                 :            :  * Note, do not add more fields in systab sysfs file as it breaks sysfs
     115                 :            :  * one value per file rule!
     116                 :            :  */
     117                 :          0 : static ssize_t systab_show(struct kobject *kobj,
     118                 :            :                            struct kobj_attribute *attr, char *buf)
     119                 :            : {
     120                 :          0 :         char *str = buf;
     121                 :            : 
     122         [ #  # ]:          0 :         if (!kobj || !buf)
     123                 :            :                 return -EINVAL;
     124                 :            : 
     125         [ #  # ]:          0 :         if (efi.mps != EFI_INVALID_TABLE_ADDR)
     126                 :          0 :                 str += sprintf(str, "MPS=0x%lx\n", efi.mps);
     127         [ #  # ]:          0 :         if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
     128                 :          0 :                 str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20);
     129         [ #  # ]:          0 :         if (efi.acpi != EFI_INVALID_TABLE_ADDR)
     130                 :          0 :                 str += sprintf(str, "ACPI=0x%lx\n", efi.acpi);
     131                 :            :         /*
     132                 :            :          * If both SMBIOS and SMBIOS3 entry points are implemented, the
     133                 :            :          * SMBIOS3 entry point shall be preferred, so we list it first to
     134                 :            :          * let applications stop parsing after the first match.
     135                 :            :          */
     136         [ #  # ]:          0 :         if (efi.smbios3 != EFI_INVALID_TABLE_ADDR)
     137                 :          0 :                 str += sprintf(str, "SMBIOS3=0x%lx\n", efi.smbios3);
     138         [ #  # ]:          0 :         if (efi.smbios != EFI_INVALID_TABLE_ADDR)
     139                 :          0 :                 str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
     140         [ #  # ]:          0 :         if (efi.hcdp != EFI_INVALID_TABLE_ADDR)
     141                 :          0 :                 str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp);
     142         [ #  # ]:          0 :         if (efi.boot_info != EFI_INVALID_TABLE_ADDR)
     143                 :          0 :                 str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info);
     144         [ #  # ]:          0 :         if (efi.uga != EFI_INVALID_TABLE_ADDR)
     145                 :          0 :                 str += sprintf(str, "UGA=0x%lx\n", efi.uga);
     146                 :            : 
     147                 :          0 :         return str - buf;
     148                 :            : }
     149                 :            : 
     150                 :            : static struct kobj_attribute efi_attr_systab = __ATTR_RO_MODE(systab, 0400);
     151                 :            : 
     152                 :            : #define EFI_FIELD(var) efi.var
     153                 :            : 
     154                 :            : #define EFI_ATTR_SHOW(name) \
     155                 :            : static ssize_t name##_show(struct kobject *kobj, \
     156                 :            :                                 struct kobj_attribute *attr, char *buf) \
     157                 :            : { \
     158                 :            :         return sprintf(buf, "0x%lx\n", EFI_FIELD(name)); \
     159                 :            : }
     160                 :            : 
     161                 :          0 : EFI_ATTR_SHOW(fw_vendor);
     162                 :          0 : EFI_ATTR_SHOW(runtime);
     163                 :          0 : EFI_ATTR_SHOW(config_table);
     164                 :            : 
     165                 :          0 : static ssize_t fw_platform_size_show(struct kobject *kobj,
     166                 :            :                                      struct kobj_attribute *attr, char *buf)
     167                 :            : {
     168         [ #  # ]:          0 :         return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
     169                 :            : }
     170                 :            : 
     171                 :            : static struct kobj_attribute efi_attr_fw_vendor = __ATTR_RO(fw_vendor);
     172                 :            : static struct kobj_attribute efi_attr_runtime = __ATTR_RO(runtime);
     173                 :            : static struct kobj_attribute efi_attr_config_table = __ATTR_RO(config_table);
     174                 :            : static struct kobj_attribute efi_attr_fw_platform_size =
     175                 :            :         __ATTR_RO(fw_platform_size);
     176                 :            : 
     177                 :            : static struct attribute *efi_subsys_attrs[] = {
     178                 :            :         &efi_attr_systab.attr,
     179                 :            :         &efi_attr_fw_vendor.attr,
     180                 :            :         &efi_attr_runtime.attr,
     181                 :            :         &efi_attr_config_table.attr,
     182                 :            :         &efi_attr_fw_platform_size.attr,
     183                 :            :         NULL,
     184                 :            : };
     185                 :            : 
     186                 :          0 : static umode_t efi_attr_is_visible(struct kobject *kobj,
     187                 :            :                                    struct attribute *attr, int n)
     188                 :            : {
     189         [ #  # ]:          0 :         if (attr == &efi_attr_fw_vendor.attr) {
     190         [ #  # ]:          0 :                 if (efi_enabled(EFI_PARAVIRT) ||
     191         [ #  # ]:          0 :                                 efi.fw_vendor == EFI_INVALID_TABLE_ADDR)
     192                 :            :                         return 0;
     193         [ #  # ]:          0 :         } else if (attr == &efi_attr_runtime.attr) {
     194         [ #  # ]:          0 :                 if (efi.runtime == EFI_INVALID_TABLE_ADDR)
     195                 :            :                         return 0;
     196         [ #  # ]:          0 :         } else if (attr == &efi_attr_config_table.attr) {
     197         [ #  # ]:          0 :                 if (efi.config_table == EFI_INVALID_TABLE_ADDR)
     198                 :            :                         return 0;
     199                 :            :         }
     200                 :            : 
     201                 :          0 :         return attr->mode;
     202                 :            : }
     203                 :            : 
     204                 :            : static const struct attribute_group efi_subsys_attr_group = {
     205                 :            :         .attrs = efi_subsys_attrs,
     206                 :            :         .is_visible = efi_attr_is_visible,
     207                 :            : };
     208                 :            : 
     209                 :            : static struct efivars generic_efivars;
     210                 :            : static struct efivar_operations generic_ops;
     211                 :            : 
     212                 :          0 : static int generic_ops_register(void)
     213                 :            : {
     214                 :          0 :         generic_ops.get_variable = efi.get_variable;
     215                 :          0 :         generic_ops.set_variable = efi.set_variable;
     216                 :          0 :         generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
     217                 :          0 :         generic_ops.get_next_variable = efi.get_next_variable;
     218                 :          0 :         generic_ops.query_variable_store = efi_query_variable_store;
     219                 :            : 
     220                 :          0 :         return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
     221                 :            : }
     222                 :            : 
     223                 :          0 : static void generic_ops_unregister(void)
     224                 :            : {
     225                 :          0 :         efivars_unregister(&generic_efivars);
     226                 :          0 : }
     227                 :            : 
     228                 :            : #if IS_ENABLED(CONFIG_ACPI)
     229                 :            : #define EFIVAR_SSDT_NAME_MAX    16
     230                 :            : static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
     231                 :          0 : static int __init efivar_ssdt_setup(char *str)
     232                 :            : {
     233                 :          0 :         int ret = security_locked_down(LOCKDOWN_ACPI_TABLES);
     234                 :            : 
     235         [ #  # ]:          0 :         if (ret)
     236                 :            :                 return ret;
     237                 :            : 
     238         [ #  # ]:          0 :         if (strlen(str) < sizeof(efivar_ssdt))
     239                 :          0 :                 memcpy(efivar_ssdt, str, strlen(str));
     240                 :            :         else
     241                 :          0 :                 pr_warn("efivar_ssdt: name too long: %s\n", str);
     242                 :            :         return 0;
     243                 :            : }
     244                 :            : __setup("efivar_ssdt=", efivar_ssdt_setup);
     245                 :            : 
     246                 :          0 : static __init int efivar_ssdt_iter(efi_char16_t *name, efi_guid_t vendor,
     247                 :            :                                    unsigned long name_size, void *data)
     248                 :            : {
     249                 :          0 :         struct efivar_entry *entry;
     250                 :          0 :         struct list_head *list = data;
     251                 :          0 :         char utf8_name[EFIVAR_SSDT_NAME_MAX];
     252                 :          0 :         int limit = min_t(unsigned long, EFIVAR_SSDT_NAME_MAX, name_size);
     253                 :            : 
     254                 :          0 :         ucs2_as_utf8(utf8_name, name, limit - 1);
     255         [ #  # ]:          0 :         if (strncmp(utf8_name, efivar_ssdt, limit) != 0)
     256                 :            :                 return 0;
     257                 :            : 
     258                 :          0 :         entry = kmalloc(sizeof(*entry), GFP_KERNEL);
     259         [ #  # ]:          0 :         if (!entry)
     260                 :            :                 return 0;
     261                 :            : 
     262                 :          0 :         memcpy(entry->var.VariableName, name, name_size);
     263                 :          0 :         memcpy(&entry->var.VendorGuid, &vendor, sizeof(efi_guid_t));
     264                 :            : 
     265                 :          0 :         efivar_entry_add(entry, list);
     266                 :            : 
     267                 :          0 :         return 0;
     268                 :            : }
     269                 :            : 
     270                 :          0 : static __init int efivar_ssdt_load(void)
     271                 :            : {
     272                 :          0 :         LIST_HEAD(entries);
     273                 :          0 :         struct efivar_entry *entry, *aux;
     274                 :          0 :         unsigned long size;
     275                 :          0 :         void *data;
     276                 :          0 :         int ret;
     277                 :            : 
     278         [ #  # ]:          0 :         if (!efivar_ssdt[0])
     279                 :            :                 return 0;
     280                 :            : 
     281                 :          0 :         ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries);
     282                 :            : 
     283         [ #  # ]:          0 :         list_for_each_entry_safe(entry, aux, &entries, list) {
     284                 :          0 :                 pr_info("loading SSDT from variable %s-%pUl\n", efivar_ssdt,
     285                 :            :                         &entry->var.VendorGuid);
     286                 :            : 
     287                 :          0 :                 list_del(&entry->list);
     288                 :            : 
     289                 :          0 :                 ret = efivar_entry_size(entry, &size);
     290         [ #  # ]:          0 :                 if (ret) {
     291                 :          0 :                         pr_err("failed to get var size\n");
     292                 :          0 :                         goto free_entry;
     293                 :            :                 }
     294                 :            : 
     295         [ #  # ]:          0 :                 data = kmalloc(size, GFP_KERNEL);
     296         [ #  # ]:          0 :                 if (!data) {
     297                 :          0 :                         ret = -ENOMEM;
     298                 :          0 :                         goto free_entry;
     299                 :            :                 }
     300                 :            : 
     301                 :          0 :                 ret = efivar_entry_get(entry, NULL, &size, data);
     302         [ #  # ]:          0 :                 if (ret) {
     303                 :          0 :                         pr_err("failed to get var data\n");
     304                 :          0 :                         goto free_data;
     305                 :            :                 }
     306                 :            : 
     307                 :          0 :                 ret = acpi_load_table(data, NULL);
     308         [ #  # ]:          0 :                 if (ret) {
     309                 :          0 :                         pr_err("failed to load table: %d\n", ret);
     310                 :          0 :                         goto free_data;
     311                 :            :                 }
     312                 :            : 
     313                 :          0 :                 goto free_entry;
     314                 :            : 
     315                 :          0 : free_data:
     316                 :          0 :                 kfree(data);
     317                 :            : 
     318                 :          0 : free_entry:
     319                 :          0 :                 kfree(entry);
     320                 :            :         }
     321                 :            : 
     322                 :            :         return ret;
     323                 :            : }
     324                 :            : #else
     325                 :            : static inline int efivar_ssdt_load(void) { return 0; }
     326                 :            : #endif
     327                 :            : 
     328                 :            : /*
     329                 :            :  * We register the efi subsystem with the firmware subsystem and the
     330                 :            :  * efivars subsystem with the efi subsystem, if the system was booted with
     331                 :            :  * EFI.
     332                 :            :  */
     333                 :         13 : static int __init efisubsys_init(void)
     334                 :            : {
     335                 :         13 :         int error;
     336                 :            : 
     337         [ -  + ]:         13 :         if (!efi_enabled(EFI_BOOT))
     338                 :            :                 return 0;
     339                 :            : 
     340                 :            :         /*
     341                 :            :          * Since we process only one efi_runtime_service() at a time, an
     342                 :            :          * ordered workqueue (which creates only one execution context)
     343                 :            :          * should suffice all our needs.
     344                 :            :          */
     345                 :          0 :         efi_rts_wq = alloc_ordered_workqueue("efi_rts_wq", 0);
     346         [ #  # ]:          0 :         if (!efi_rts_wq) {
     347                 :          0 :                 pr_err("Creating efi_rts_wq failed, EFI runtime services disabled.\n");
     348                 :          0 :                 clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
     349                 :          0 :                 return 0;
     350                 :            :         }
     351                 :            : 
     352                 :            :         /* We register the efi directory at /sys/firmware/efi */
     353                 :          0 :         efi_kobj = kobject_create_and_add("efi", firmware_kobj);
     354         [ #  # ]:          0 :         if (!efi_kobj) {
     355                 :          0 :                 pr_err("efi: Firmware registration failed.\n");
     356                 :          0 :                 return -ENOMEM;
     357                 :            :         }
     358                 :            : 
     359                 :          0 :         error = generic_ops_register();
     360         [ #  # ]:          0 :         if (error)
     361                 :          0 :                 goto err_put;
     362                 :            : 
     363         [ #  # ]:          0 :         if (efi_enabled(EFI_RUNTIME_SERVICES))
     364                 :          0 :                 efivar_ssdt_load();
     365                 :            : 
     366                 :          0 :         error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
     367         [ #  # ]:          0 :         if (error) {
     368                 :          0 :                 pr_err("efi: Sysfs attribute export failed with error %d.\n",
     369                 :            :                        error);
     370                 :          0 :                 goto err_unregister;
     371                 :            :         }
     372                 :            : 
     373                 :          0 :         error = efi_runtime_map_init(efi_kobj);
     374         [ #  # ]:          0 :         if (error)
     375                 :          0 :                 goto err_remove_group;
     376                 :            : 
     377                 :            :         /* and the standard mountpoint for efivarfs */
     378                 :          0 :         error = sysfs_create_mount_point(efi_kobj, "efivars");
     379         [ #  # ]:          0 :         if (error) {
     380                 :          0 :                 pr_err("efivars: Subsystem registration failed.\n");
     381                 :          0 :                 goto err_remove_group;
     382                 :            :         }
     383                 :            : 
     384                 :            :         return 0;
     385                 :            : 
     386                 :          0 : err_remove_group:
     387                 :          0 :         sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
     388                 :          0 : err_unregister:
     389                 :          0 :         generic_ops_unregister();
     390                 :          0 : err_put:
     391                 :          0 :         kobject_put(efi_kobj);
     392                 :          0 :         return error;
     393                 :            : }
     394                 :            : 
     395                 :            : subsys_initcall(efisubsys_init);
     396                 :            : 
     397                 :            : /*
     398                 :            :  * Find the efi memory descriptor for a given physical address.  Given a
     399                 :            :  * physical address, determine if it exists within an EFI Memory Map entry,
     400                 :            :  * and if so, populate the supplied memory descriptor with the appropriate
     401                 :            :  * data.
     402                 :            :  */
     403                 :          0 : int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md)
     404                 :            : {
     405                 :          0 :         efi_memory_desc_t *md;
     406                 :            : 
     407         [ #  # ]:          0 :         if (!efi_enabled(EFI_MEMMAP)) {
     408         [ #  # ]:          0 :                 pr_err_once("EFI_MEMMAP is not enabled.\n");
     409                 :          0 :                 return -EINVAL;
     410                 :            :         }
     411                 :            : 
     412         [ #  # ]:          0 :         if (!out_md) {
     413         [ #  # ]:          0 :                 pr_err_once("out_md is null.\n");
     414                 :          0 :                 return -EINVAL;
     415                 :            :         }
     416                 :            : 
     417   [ #  #  #  # ]:          0 :         for_each_efi_memory_desc(md) {
     418                 :          0 :                 u64 size;
     419                 :          0 :                 u64 end;
     420                 :            : 
     421                 :          0 :                 size = md->num_pages << EFI_PAGE_SHIFT;
     422                 :          0 :                 end = md->phys_addr + size;
     423   [ #  #  #  # ]:          0 :                 if (phys_addr >= md->phys_addr && phys_addr < end) {
     424                 :          0 :                         memcpy(out_md, md, sizeof(*out_md));
     425                 :          0 :                         return 0;
     426                 :            :                 }
     427                 :            :         }
     428                 :            :         return -ENOENT;
     429                 :            : }
     430                 :            : 
     431                 :            : /*
     432                 :            :  * Calculate the highest address of an efi memory descriptor.
     433                 :            :  */
     434                 :          0 : u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
     435                 :            : {
     436                 :          0 :         u64 size = md->num_pages << EFI_PAGE_SHIFT;
     437                 :          0 :         u64 end = md->phys_addr + size;
     438                 :          0 :         return end;
     439                 :            : }
     440                 :            : 
     441                 :          0 : void __init __weak efi_arch_mem_reserve(phys_addr_t addr, u64 size) {}
     442                 :            : 
     443                 :            : /**
     444                 :            :  * efi_mem_reserve - Reserve an EFI memory region
     445                 :            :  * @addr: Physical address to reserve
     446                 :            :  * @size: Size of reservation
     447                 :            :  *
     448                 :            :  * Mark a region as reserved from general kernel allocation and
     449                 :            :  * prevent it being released by efi_free_boot_services().
     450                 :            :  *
     451                 :            :  * This function should be called drivers once they've parsed EFI
     452                 :            :  * configuration tables to figure out where their data lives, e.g.
     453                 :            :  * efi_esrt_init().
     454                 :            :  */
     455                 :          0 : void __init efi_mem_reserve(phys_addr_t addr, u64 size)
     456                 :            : {
     457         [ #  # ]:          0 :         if (!memblock_is_region_reserved(addr, size))
     458                 :          0 :                 memblock_reserve(addr, size);
     459                 :            : 
     460                 :            :         /*
     461                 :            :          * Some architectures (x86) reserve all boot services ranges
     462                 :            :          * until efi_free_boot_services() because of buggy firmware
     463                 :            :          * implementations. This means the above memblock_reserve() is
     464                 :            :          * superfluous on x86 and instead what it needs to do is
     465                 :            :          * ensure the @start, @size is not freed.
     466                 :            :          */
     467                 :          0 :         efi_arch_mem_reserve(addr, size);
     468                 :          0 : }
     469                 :            : 
     470                 :            : static __initdata efi_config_table_type_t common_tables[] = {
     471                 :            :         {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
     472                 :            :         {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
     473                 :            :         {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
     474                 :            :         {MPS_TABLE_GUID, "MPS", &efi.mps},
     475                 :            :         {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
     476                 :            :         {SMBIOS3_TABLE_GUID, "SMBIOS 3.0", &efi.smbios3},
     477                 :            :         {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
     478                 :            :         {EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
     479                 :            :         {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
     480                 :            :         {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
     481                 :            :         {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed},
     482                 :            :         {LINUX_EFI_TPM_EVENT_LOG_GUID, "TPMEventLog", &efi.tpm_log},
     483                 :            :         {LINUX_EFI_TPM_FINAL_LOG_GUID, "TPMFinalLog", &efi.tpm_final_log},
     484                 :            :         {LINUX_EFI_MEMRESERVE_TABLE_GUID, "MEMRESERVE", &efi.mem_reserve},
     485                 :            : #ifdef CONFIG_EFI_RCI2_TABLE
     486                 :            :         {DELLEMC_EFI_RCI2_TABLE_GUID, NULL, &rci2_table_phys},
     487                 :            : #endif
     488                 :            :         {NULL_GUID, NULL, NULL},
     489                 :            : };
     490                 :            : 
     491                 :            : static __init int match_config_table(efi_guid_t *guid,
     492                 :            :                                      unsigned long table,
     493                 :            :                                      efi_config_table_type_t *table_types)
     494                 :            : {
     495                 :            :         int i;
     496                 :            : 
     497                 :            :         if (table_types) {
     498                 :            :                 for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
     499                 :            :                         if (!efi_guidcmp(*guid, table_types[i].guid)) {
     500                 :            :                                 *(table_types[i].ptr) = table;
     501                 :            :                                 if (table_types[i].name)
     502                 :            :                                         pr_cont(" %s=0x%lx ",
     503                 :            :                                                 table_types[i].name, table);
     504                 :            :                                 return 1;
     505                 :            :                         }
     506                 :            :                 }
     507                 :            :         }
     508                 :            : 
     509                 :            :         return 0;
     510                 :            : }
     511                 :            : 
     512                 :          0 : int __init efi_config_parse_tables(void *config_tables, int count, int sz,
     513                 :            :                                    efi_config_table_type_t *arch_tables)
     514                 :            : {
     515                 :          0 :         void *tablep;
     516                 :          0 :         int i;
     517                 :            : 
     518                 :          0 :         tablep = config_tables;
     519                 :          0 :         pr_info("");
     520         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     521                 :          0 :                 efi_guid_t guid;
     522                 :          0 :                 unsigned long table;
     523                 :            : 
     524         [ #  # ]:          0 :                 if (efi_enabled(EFI_64BIT)) {
     525                 :          0 :                         u64 table64;
     526                 :          0 :                         guid = ((efi_config_table_64_t *)tablep)->guid;
     527                 :          0 :                         table64 = ((efi_config_table_64_t *)tablep)->table;
     528                 :          0 :                         table = table64;
     529                 :            : #ifndef CONFIG_64BIT
     530                 :            :                         if (table64 >> 32) {
     531                 :            :                                 pr_cont("\n");
     532                 :            :                                 pr_err("Table located above 4GB, disabling EFI.\n");
     533                 :            :                                 return -EINVAL;
     534                 :            :                         }
     535                 :            : #endif
     536                 :            :                 } else {
     537                 :          0 :                         guid = ((efi_config_table_32_t *)tablep)->guid;
     538                 :          0 :                         table = ((efi_config_table_32_t *)tablep)->table;
     539                 :            :                 }
     540                 :            : 
     541         [ #  # ]:          0 :                 if (!match_config_table(&guid, table, common_tables))
     542                 :          0 :                         match_config_table(&guid, table, arch_tables);
     543                 :            : 
     544                 :          0 :                 tablep += sz;
     545                 :            :         }
     546                 :          0 :         pr_cont("\n");
     547                 :          0 :         set_bit(EFI_CONFIG_TABLES, &efi.flags);
     548                 :            : 
     549         [ #  # ]:          0 :         if (efi.rng_seed != EFI_INVALID_TABLE_ADDR) {
     550                 :          0 :                 struct linux_efi_random_seed *seed;
     551                 :          0 :                 u32 size = 0;
     552                 :            : 
     553                 :          0 :                 seed = early_memremap(efi.rng_seed, sizeof(*seed));
     554         [ #  # ]:          0 :                 if (seed != NULL) {
     555                 :          0 :                         size = READ_ONCE(seed->size);
     556                 :          0 :                         early_memunmap(seed, sizeof(*seed));
     557                 :            :                 } else {
     558                 :          0 :                         pr_err("Could not map UEFI random seed!\n");
     559                 :            :                 }
     560         [ #  # ]:          0 :                 if (size > 0) {
     561                 :          0 :                         seed = early_memremap(efi.rng_seed,
     562                 :            :                                               sizeof(*seed) + size);
     563         [ #  # ]:          0 :                         if (seed != NULL) {
     564                 :          0 :                                 pr_notice("seeding entropy pool\n");
     565                 :          0 :                                 add_bootloader_randomness(seed->bits, size);
     566                 :          0 :                                 early_memunmap(seed, sizeof(*seed) + size);
     567                 :            :                         } else {
     568                 :          0 :                                 pr_err("Could not map UEFI random seed!\n");
     569                 :            :                         }
     570                 :            :                 }
     571                 :            :         }
     572                 :            : 
     573         [ #  # ]:          0 :         if (efi_enabled(EFI_MEMMAP))
     574                 :          0 :                 efi_memattr_init();
     575                 :            : 
     576                 :          0 :         efi_tpm_eventlog_init();
     577                 :            : 
     578                 :            :         /* Parse the EFI Properties table if it exists */
     579         [ #  # ]:          0 :         if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
     580                 :          0 :                 efi_properties_table_t *tbl;
     581                 :            : 
     582                 :          0 :                 tbl = early_memremap(efi.properties_table, sizeof(*tbl));
     583         [ #  # ]:          0 :                 if (tbl == NULL) {
     584                 :          0 :                         pr_err("Could not map Properties table!\n");
     585                 :          0 :                         return -ENOMEM;
     586                 :            :                 }
     587                 :            : 
     588         [ #  # ]:          0 :                 if (tbl->memory_protection_attribute &
     589                 :            :                     EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA)
     590                 :          0 :                         set_bit(EFI_NX_PE_DATA, &efi.flags);
     591                 :            : 
     592                 :          0 :                 early_memunmap(tbl, sizeof(*tbl));
     593                 :            :         }
     594                 :            : 
     595         [ #  # ]:          0 :         if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
     596                 :            :                 unsigned long prsv = efi.mem_reserve;
     597                 :            : 
     598         [ #  # ]:          0 :                 while (prsv) {
     599                 :          0 :                         struct linux_efi_memreserve *rsv;
     600                 :          0 :                         u8 *p;
     601                 :          0 :                         int i;
     602                 :            : 
     603                 :            :                         /*
     604                 :            :                          * Just map a full page: that is what we will get
     605                 :            :                          * anyway, and it permits us to map the entire entry
     606                 :            :                          * before knowing its size.
     607                 :            :                          */
     608                 :          0 :                         p = early_memremap(ALIGN_DOWN(prsv, PAGE_SIZE),
     609                 :            :                                            PAGE_SIZE);
     610         [ #  # ]:          0 :                         if (p == NULL) {
     611                 :          0 :                                 pr_err("Could not map UEFI memreserve entry!\n");
     612                 :          0 :                                 return -ENOMEM;
     613                 :            :                         }
     614                 :            : 
     615                 :          0 :                         rsv = (void *)(p + prsv % PAGE_SIZE);
     616                 :            : 
     617                 :            :                         /* reserve the entry itself */
     618                 :          0 :                         memblock_reserve(prsv, EFI_MEMRESERVE_SIZE(rsv->size));
     619                 :            : 
     620         [ #  # ]:          0 :                         for (i = 0; i < atomic_read(&rsv->count); i++) {
     621                 :          0 :                                 memblock_reserve(rsv->entry[i].base,
     622                 :            :                                                  rsv->entry[i].size);
     623                 :            :                         }
     624                 :            : 
     625                 :          0 :                         prsv = rsv->next;
     626                 :          0 :                         early_memunmap(p, PAGE_SIZE);
     627                 :            :                 }
     628                 :            :         }
     629                 :            : 
     630                 :            :         return 0;
     631                 :            : }
     632                 :            : 
     633                 :          0 : int __init efi_config_init(efi_config_table_type_t *arch_tables)
     634                 :            : {
     635                 :          0 :         void *config_tables;
     636                 :          0 :         int sz, ret;
     637                 :            : 
     638         [ #  # ]:          0 :         if (efi.systab->nr_tables == 0)
     639                 :            :                 return 0;
     640                 :            : 
     641         [ #  # ]:          0 :         if (efi_enabled(EFI_64BIT))
     642                 :            :                 sz = sizeof(efi_config_table_64_t);
     643                 :            :         else
     644                 :          0 :                 sz = sizeof(efi_config_table_32_t);
     645                 :            : 
     646                 :            :         /*
     647                 :            :          * Let's see what config tables the firmware passed to us.
     648                 :            :          */
     649                 :          0 :         config_tables = early_memremap(efi.systab->tables,
     650                 :          0 :                                        efi.systab->nr_tables * sz);
     651         [ #  # ]:          0 :         if (config_tables == NULL) {
     652                 :          0 :                 pr_err("Could not map Configuration table!\n");
     653                 :          0 :                 return -ENOMEM;
     654                 :            :         }
     655                 :            : 
     656                 :          0 :         ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
     657                 :            :                                       arch_tables);
     658                 :            : 
     659                 :          0 :         early_memunmap(config_tables, efi.systab->nr_tables * sz);
     660                 :          0 :         return ret;
     661                 :            : }
     662                 :            : 
     663                 :            : #ifdef CONFIG_EFI_VARS_MODULE
     664                 :            : static int __init efi_load_efivars(void)
     665                 :            : {
     666                 :            :         struct platform_device *pdev;
     667                 :            : 
     668                 :            :         if (!efi_enabled(EFI_RUNTIME_SERVICES))
     669                 :            :                 return 0;
     670                 :            : 
     671                 :            :         pdev = platform_device_register_simple("efivars", 0, NULL, 0);
     672                 :            :         return PTR_ERR_OR_ZERO(pdev);
     673                 :            : }
     674                 :            : device_initcall(efi_load_efivars);
     675                 :            : #endif
     676                 :            : 
     677                 :            : #ifdef CONFIG_EFI_PARAMS_FROM_FDT
     678                 :            : 
     679                 :            : #define UEFI_PARAM(name, prop, field)                      \
     680                 :            :         {                                                  \
     681                 :            :                 { name },                                  \
     682                 :            :                 { prop },                                  \
     683                 :            :                 offsetof(struct efi_fdt_params, field),    \
     684                 :            :                 sizeof_field(struct efi_fdt_params, field) \
     685                 :            :         }
     686                 :            : 
     687                 :            : struct params {
     688                 :            :         const char name[32];
     689                 :            :         const char propname[32];
     690                 :            :         int offset;
     691                 :            :         int size;
     692                 :            : };
     693                 :            : 
     694                 :            : static __initdata struct params fdt_params[] = {
     695                 :            :         UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
     696                 :            :         UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
     697                 :            :         UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
     698                 :            :         UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
     699                 :            :         UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
     700                 :            : };
     701                 :            : 
     702                 :            : static __initdata struct params xen_fdt_params[] = {
     703                 :            :         UEFI_PARAM("System Table", "xen,uefi-system-table", system_table),
     704                 :            :         UEFI_PARAM("MemMap Address", "xen,uefi-mmap-start", mmap),
     705                 :            :         UEFI_PARAM("MemMap Size", "xen,uefi-mmap-size", mmap_size),
     706                 :            :         UEFI_PARAM("MemMap Desc. Size", "xen,uefi-mmap-desc-size", desc_size),
     707                 :            :         UEFI_PARAM("MemMap Desc. Version", "xen,uefi-mmap-desc-ver", desc_ver)
     708                 :            : };
     709                 :            : 
     710                 :            : #define EFI_FDT_PARAMS_SIZE     ARRAY_SIZE(fdt_params)
     711                 :            : 
     712                 :            : static __initdata struct {
     713                 :            :         const char *uname;
     714                 :            :         const char *subnode;
     715                 :            :         struct params *params;
     716                 :            : } dt_params[] = {
     717                 :            :         { "hypervisor", "uefi", xen_fdt_params },
     718                 :            :         { "chosen", NULL, fdt_params },
     719                 :            : };
     720                 :            : 
     721                 :            : struct param_info {
     722                 :            :         int found;
     723                 :            :         void *params;
     724                 :            :         const char *missing;
     725                 :            : };
     726                 :            : 
     727                 :            : static int __init __find_uefi_params(unsigned long node,
     728                 :            :                                      struct param_info *info,
     729                 :            :                                      struct params *params)
     730                 :            : {
     731                 :            :         const void *prop;
     732                 :            :         void *dest;
     733                 :            :         u64 val;
     734                 :            :         int i, len;
     735                 :            : 
     736                 :            :         for (i = 0; i < EFI_FDT_PARAMS_SIZE; i++) {
     737                 :            :                 prop = of_get_flat_dt_prop(node, params[i].propname, &len);
     738                 :            :                 if (!prop) {
     739                 :            :                         info->missing = params[i].name;
     740                 :            :                         return 0;
     741                 :            :                 }
     742                 :            : 
     743                 :            :                 dest = info->params + params[i].offset;
     744                 :            :                 info->found++;
     745                 :            : 
     746                 :            :                 val = of_read_number(prop, len / sizeof(u32));
     747                 :            : 
     748                 :            :                 if (params[i].size == sizeof(u32))
     749                 :            :                         *(u32 *)dest = val;
     750                 :            :                 else
     751                 :            :                         *(u64 *)dest = val;
     752                 :            : 
     753                 :            :                 if (efi_enabled(EFI_DBG))
     754                 :            :                         pr_info("  %s: 0x%0*llx\n", params[i].name,
     755                 :            :                                 params[i].size * 2, val);
     756                 :            :         }
     757                 :            : 
     758                 :            :         return 1;
     759                 :            : }
     760                 :            : 
     761                 :            : static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
     762                 :            :                                        int depth, void *data)
     763                 :            : {
     764                 :            :         struct param_info *info = data;
     765                 :            :         int i;
     766                 :            : 
     767                 :            :         for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
     768                 :            :                 const char *subnode = dt_params[i].subnode;
     769                 :            : 
     770                 :            :                 if (depth != 1 || strcmp(uname, dt_params[i].uname) != 0) {
     771                 :            :                         info->missing = dt_params[i].params[0].name;
     772                 :            :                         continue;
     773                 :            :                 }
     774                 :            : 
     775                 :            :                 if (subnode) {
     776                 :            :                         int err = of_get_flat_dt_subnode_by_name(node, subnode);
     777                 :            : 
     778                 :            :                         if (err < 0)
     779                 :            :                                 return 0;
     780                 :            : 
     781                 :            :                         node = err;
     782                 :            :                 }
     783                 :            : 
     784                 :            :                 return __find_uefi_params(node, info, dt_params[i].params);
     785                 :            :         }
     786                 :            : 
     787                 :            :         return 0;
     788                 :            : }
     789                 :            : 
     790                 :            : int __init efi_get_fdt_params(struct efi_fdt_params *params)
     791                 :            : {
     792                 :            :         struct param_info info;
     793                 :            :         int ret;
     794                 :            : 
     795                 :            :         pr_info("Getting EFI parameters from FDT:\n");
     796                 :            : 
     797                 :            :         info.found = 0;
     798                 :            :         info.params = params;
     799                 :            : 
     800                 :            :         ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
     801                 :            :         if (!info.found)
     802                 :            :                 pr_info("UEFI not found.\n");
     803                 :            :         else if (!ret)
     804                 :            :                 pr_err("Can't find '%s' in device tree!\n",
     805                 :            :                        info.missing);
     806                 :            : 
     807                 :            :         return ret;
     808                 :            : }
     809                 :            : #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
     810                 :            : 
     811                 :            : static __initdata char memory_type_name[][20] = {
     812                 :            :         "Reserved",
     813                 :            :         "Loader Code",
     814                 :            :         "Loader Data",
     815                 :            :         "Boot Code",
     816                 :            :         "Boot Data",
     817                 :            :         "Runtime Code",
     818                 :            :         "Runtime Data",
     819                 :            :         "Conventional Memory",
     820                 :            :         "Unusable Memory",
     821                 :            :         "ACPI Reclaim Memory",
     822                 :            :         "ACPI Memory NVS",
     823                 :            :         "Memory Mapped I/O",
     824                 :            :         "MMIO Port Space",
     825                 :            :         "PAL Code",
     826                 :            :         "Persistent Memory",
     827                 :            : };
     828                 :            : 
     829                 :          0 : char * __init efi_md_typeattr_format(char *buf, size_t size,
     830                 :            :                                      const efi_memory_desc_t *md)
     831                 :            : {
     832                 :          0 :         char *pos;
     833                 :          0 :         int type_len;
     834                 :          0 :         u64 attr;
     835                 :            : 
     836                 :          0 :         pos = buf;
     837         [ #  # ]:          0 :         if (md->type >= ARRAY_SIZE(memory_type_name))
     838                 :          0 :                 type_len = snprintf(pos, size, "[type=%u", md->type);
     839                 :            :         else
     840                 :          0 :                 type_len = snprintf(pos, size, "[%-*s",
     841                 :            :                                     (int)(sizeof(memory_type_name[0]) - 1),
     842                 :          0 :                                     memory_type_name[md->type]);
     843         [ #  # ]:          0 :         if (type_len >= size)
     844                 :            :                 return buf;
     845                 :            : 
     846                 :          0 :         pos += type_len;
     847                 :          0 :         size -= type_len;
     848                 :            : 
     849                 :          0 :         attr = md->attribute;
     850         [ #  # ]:          0 :         if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
     851                 :            :                      EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO |
     852                 :            :                      EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP |
     853                 :            :                      EFI_MEMORY_NV | EFI_MEMORY_SP |
     854                 :            :                      EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE))
     855                 :          0 :                 snprintf(pos, size, "|attr=0x%016llx]",
     856                 :            :                          (unsigned long long)attr);
     857                 :            :         else
     858                 :          0 :                 snprintf(pos, size,
     859                 :            :                          "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
     860         [ #  # ]:          0 :                          attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
     861         [ #  # ]:          0 :                          attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "",
     862         [ #  # ]:          0 :                          attr & EFI_MEMORY_SP      ? "SP"  : "",
     863         [ #  # ]:          0 :                          attr & EFI_MEMORY_NV      ? "NV"  : "",
     864         [ #  # ]:          0 :                          attr & EFI_MEMORY_XP      ? "XP"  : "",
     865         [ #  # ]:          0 :                          attr & EFI_MEMORY_RP      ? "RP"  : "",
     866         [ #  # ]:          0 :                          attr & EFI_MEMORY_WP      ? "WP"  : "",
     867         [ #  # ]:          0 :                          attr & EFI_MEMORY_RO      ? "RO"  : "",
     868         [ #  # ]:          0 :                          attr & EFI_MEMORY_UCE     ? "UCE" : "",
     869         [ #  # ]:          0 :                          attr & EFI_MEMORY_WB      ? "WB"  : "",
     870         [ #  # ]:          0 :                          attr & EFI_MEMORY_WT      ? "WT"  : "",
     871         [ #  # ]:          0 :                          attr & EFI_MEMORY_WC      ? "WC"  : "",
     872         [ #  # ]:          0 :                          attr & EFI_MEMORY_UC      ? "UC"  : "");
     873                 :            :         return buf;
     874                 :            : }
     875                 :            : 
     876                 :            : /*
     877                 :            :  * IA64 has a funky EFI memory map that doesn't work the same way as
     878                 :            :  * other architectures.
     879                 :            :  */
     880                 :            : #ifndef CONFIG_IA64
     881                 :            : /*
     882                 :            :  * efi_mem_attributes - lookup memmap attributes for physical address
     883                 :            :  * @phys_addr: the physical address to lookup
     884                 :            :  *
     885                 :            :  * Search in the EFI memory map for the region covering
     886                 :            :  * @phys_addr. Returns the EFI memory attributes if the region
     887                 :            :  * was found in the memory map, 0 otherwise.
     888                 :            :  */
     889                 :          0 : u64 efi_mem_attributes(unsigned long phys_addr)
     890                 :            : {
     891                 :          0 :         efi_memory_desc_t *md;
     892                 :            : 
     893         [ #  # ]:          0 :         if (!efi_enabled(EFI_MEMMAP))
     894                 :            :                 return 0;
     895                 :            : 
     896   [ #  #  #  # ]:          0 :         for_each_efi_memory_desc(md) {
     897         [ #  # ]:          0 :                 if ((md->phys_addr <= phys_addr) &&
     898                 :          0 :                     (phys_addr < (md->phys_addr +
     899         [ #  # ]:          0 :                     (md->num_pages << EFI_PAGE_SHIFT))))
     900                 :          0 :                         return md->attribute;
     901                 :            :         }
     902                 :            :         return 0;
     903                 :            : }
     904                 :            : 
     905                 :            : /*
     906                 :            :  * efi_mem_type - lookup memmap type for physical address
     907                 :            :  * @phys_addr: the physical address to lookup
     908                 :            :  *
     909                 :            :  * Search in the EFI memory map for the region covering @phys_addr.
     910                 :            :  * Returns the EFI memory type if the region was found in the memory
     911                 :            :  * map, -EINVAL otherwise.
     912                 :            :  */
     913                 :          0 : int efi_mem_type(unsigned long phys_addr)
     914                 :            : {
     915                 :          0 :         const efi_memory_desc_t *md;
     916                 :            : 
     917         [ #  # ]:          0 :         if (!efi_enabled(EFI_MEMMAP))
     918                 :            :                 return -ENOTSUPP;
     919                 :            : 
     920   [ #  #  #  # ]:          0 :         for_each_efi_memory_desc(md) {
     921         [ #  # ]:          0 :                 if ((md->phys_addr <= phys_addr) &&
     922                 :          0 :                     (phys_addr < (md->phys_addr +
     923         [ #  # ]:          0 :                                   (md->num_pages << EFI_PAGE_SHIFT))))
     924                 :          0 :                         return md->type;
     925                 :            :         }
     926                 :            :         return -EINVAL;
     927                 :            : }
     928                 :            : #endif
     929                 :            : 
     930                 :          0 : int efi_status_to_err(efi_status_t status)
     931                 :            : {
     932                 :          0 :         int err;
     933                 :            : 
     934   [ #  #  #  #  :          0 :         switch (status) {
             #  #  #  #  
                      # ]
     935                 :            :         case EFI_SUCCESS:
     936                 :            :                 err = 0;
     937                 :            :                 break;
     938                 :          0 :         case EFI_INVALID_PARAMETER:
     939                 :          0 :                 err = -EINVAL;
     940                 :          0 :                 break;
     941                 :          0 :         case EFI_OUT_OF_RESOURCES:
     942                 :          0 :                 err = -ENOSPC;
     943                 :          0 :                 break;
     944                 :          0 :         case EFI_DEVICE_ERROR:
     945                 :          0 :                 err = -EIO;
     946                 :          0 :                 break;
     947                 :          0 :         case EFI_WRITE_PROTECTED:
     948                 :          0 :                 err = -EROFS;
     949                 :          0 :                 break;
     950                 :          0 :         case EFI_SECURITY_VIOLATION:
     951                 :          0 :                 err = -EACCES;
     952                 :          0 :                 break;
     953                 :          0 :         case EFI_NOT_FOUND:
     954                 :          0 :                 err = -ENOENT;
     955                 :          0 :                 break;
     956                 :          0 :         case EFI_ABORTED:
     957                 :          0 :                 err = -EINTR;
     958                 :          0 :                 break;
     959                 :          0 :         default:
     960                 :          0 :                 err = -EINVAL;
     961                 :            :         }
     962                 :            : 
     963                 :          0 :         return err;
     964                 :            : }
     965                 :            : 
     966                 :            : static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
     967                 :            : static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
     968                 :            : 
     969                 :         13 : static int __init efi_memreserve_map_root(void)
     970                 :            : {
     971         [ -  + ]:         13 :         if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
     972                 :            :                 return -ENODEV;
     973                 :            : 
     974                 :          0 :         efi_memreserve_root = memremap(efi.mem_reserve,
     975                 :            :                                        sizeof(*efi_memreserve_root),
     976                 :            :                                        MEMREMAP_WB);
     977   [ #  #  #  # ]:          0 :         if (WARN_ON_ONCE(!efi_memreserve_root))
     978                 :          0 :                 return -ENOMEM;
     979                 :            :         return 0;
     980                 :            : }
     981                 :            : 
     982                 :          0 : static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size)
     983                 :            : {
     984                 :          0 :         struct resource *res, *parent;
     985                 :            : 
     986                 :          0 :         res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
     987         [ #  # ]:          0 :         if (!res)
     988                 :            :                 return -ENOMEM;
     989                 :            : 
     990                 :          0 :         res->name    = "reserved";
     991                 :          0 :         res->flags   = IORESOURCE_MEM;
     992                 :          0 :         res->start   = addr;
     993                 :          0 :         res->end     = addr + size - 1;
     994                 :            : 
     995                 :            :         /* we expect a conflict with a 'System RAM' region */
     996                 :          0 :         parent = request_resource_conflict(&iomem_resource, res);
     997         [ #  # ]:          0 :         return parent ? request_resource(parent, res) : 0;
     998                 :            : }
     999                 :            : 
    1000                 :          0 : int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
    1001                 :            : {
    1002                 :          0 :         struct linux_efi_memreserve *rsv;
    1003                 :          0 :         unsigned long prsv;
    1004                 :          0 :         int rc, index;
    1005                 :            : 
    1006         [ #  # ]:          0 :         if (efi_memreserve_root == (void *)ULONG_MAX)
    1007                 :            :                 return -ENODEV;
    1008                 :            : 
    1009         [ #  # ]:          0 :         if (!efi_memreserve_root) {
    1010                 :          0 :                 rc = efi_memreserve_map_root();
    1011         [ #  # ]:          0 :                 if (rc)
    1012                 :            :                         return rc;
    1013                 :            :         }
    1014                 :            : 
    1015                 :            :         /* first try to find a slot in an existing linked list entry */
    1016         [ #  # ]:          0 :         for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) {
    1017                 :          0 :                 rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
    1018                 :          0 :                 index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size);
    1019         [ #  # ]:          0 :                 if (index < rsv->size) {
    1020                 :          0 :                         rsv->entry[index].base = addr;
    1021                 :          0 :                         rsv->entry[index].size = size;
    1022                 :            : 
    1023                 :          0 :                         memunmap(rsv);
    1024                 :          0 :                         return efi_mem_reserve_iomem(addr, size);
    1025                 :            :                 }
    1026                 :          0 :                 memunmap(rsv);
    1027                 :            :         }
    1028                 :            : 
    1029                 :            :         /* no slot found - allocate a new linked list entry */
    1030                 :          0 :         rsv = (struct linux_efi_memreserve *)__get_free_page(GFP_ATOMIC);
    1031         [ #  # ]:          0 :         if (!rsv)
    1032                 :            :                 return -ENOMEM;
    1033                 :            : 
    1034         [ #  # ]:          0 :         rc = efi_mem_reserve_iomem(__pa(rsv), SZ_4K);
    1035         [ #  # ]:          0 :         if (rc) {
    1036                 :          0 :                 free_page((unsigned long)rsv);
    1037                 :          0 :                 return rc;
    1038                 :            :         }
    1039                 :            : 
    1040                 :            :         /*
    1041                 :            :          * The memremap() call above assumes that a linux_efi_memreserve entry
    1042                 :            :          * never crosses a page boundary, so let's ensure that this remains true
    1043                 :            :          * even when kexec'ing a 4k pages kernel from a >4k pages kernel, by
    1044                 :            :          * using SZ_4K explicitly in the size calculation below.
    1045                 :            :          */
    1046                 :          0 :         rsv->size = EFI_MEMRESERVE_COUNT(SZ_4K);
    1047                 :          0 :         atomic_set(&rsv->count, 1);
    1048                 :          0 :         rsv->entry[0].base = addr;
    1049                 :          0 :         rsv->entry[0].size = size;
    1050                 :            : 
    1051                 :          0 :         spin_lock(&efi_mem_reserve_persistent_lock);
    1052                 :          0 :         rsv->next = efi_memreserve_root->next;
    1053         [ #  # ]:          0 :         efi_memreserve_root->next = __pa(rsv);
    1054                 :          0 :         spin_unlock(&efi_mem_reserve_persistent_lock);
    1055                 :            : 
    1056                 :          0 :         return efi_mem_reserve_iomem(addr, size);
    1057                 :            : }
    1058                 :            : 
    1059                 :         13 : static int __init efi_memreserve_root_init(void)
    1060                 :            : {
    1061         [ +  - ]:         13 :         if (efi_memreserve_root)
    1062                 :            :                 return 0;
    1063         [ +  - ]:         13 :         if (efi_memreserve_map_root())
    1064                 :         13 :                 efi_memreserve_root = (void *)ULONG_MAX;
    1065                 :            :         return 0;
    1066                 :            : }
    1067                 :            : early_initcall(efi_memreserve_root_init);
    1068                 :            : 
    1069                 :            : #ifdef CONFIG_KEXEC
    1070                 :          0 : static int update_efi_random_seed(struct notifier_block *nb,
    1071                 :            :                                   unsigned long code, void *unused)
    1072                 :            : {
    1073                 :          0 :         struct linux_efi_random_seed *seed;
    1074                 :          0 :         u32 size = 0;
    1075                 :            : 
    1076         [ #  # ]:          0 :         if (!kexec_in_progress)
    1077                 :            :                 return NOTIFY_DONE;
    1078                 :            : 
    1079                 :          0 :         seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB);
    1080         [ #  # ]:          0 :         if (seed != NULL) {
    1081                 :          0 :                 size = min(seed->size, EFI_RANDOM_SEED_SIZE);
    1082                 :          0 :                 memunmap(seed);
    1083                 :            :         } else {
    1084                 :          0 :                 pr_err("Could not map UEFI random seed!\n");
    1085                 :            :         }
    1086         [ #  # ]:          0 :         if (size > 0) {
    1087                 :          0 :                 seed = memremap(efi.rng_seed, sizeof(*seed) + size,
    1088                 :            :                                 MEMREMAP_WB);
    1089         [ #  # ]:          0 :                 if (seed != NULL) {
    1090                 :          0 :                         seed->size = size;
    1091                 :          0 :                         get_random_bytes(seed->bits, seed->size);
    1092                 :          0 :                         memunmap(seed);
    1093                 :            :                 } else {
    1094                 :          0 :                         pr_err("Could not map UEFI random seed!\n");
    1095                 :            :                 }
    1096                 :            :         }
    1097                 :            :         return NOTIFY_DONE;
    1098                 :            : }
    1099                 :            : 
    1100                 :            : static struct notifier_block efi_random_seed_nb = {
    1101                 :            :         .notifier_call = update_efi_random_seed,
    1102                 :            : };
    1103                 :            : 
    1104                 :         13 : static int register_update_efi_random_seed(void)
    1105                 :            : {
    1106         [ -  + ]:         13 :         if (efi.rng_seed == EFI_INVALID_TABLE_ADDR)
    1107                 :            :                 return 0;
    1108                 :          0 :         return register_reboot_notifier(&efi_random_seed_nb);
    1109                 :            : }
    1110                 :            : late_initcall(register_update_efi_random_seed);
    1111                 :            : #endif

Generated by: LCOV version 1.14