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