diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-12 13:26:49 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-12 13:26:49 -0700 |
commit | e6412f9833db23740ee848ab3d6e7af18dff82a6 (patch) | |
tree | c718a1ed9a631e01c226a25910a6939342a387b2 | |
parent | ed016af52ee3035b4799ebd7d53f9ae59d5782c4 (diff) | |
parent | 4d0a4388ccdd9482fef6b26f879d0f6099143f80 (diff) |
Merge tag 'efi-core-2020-10-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI changes from Ingo Molnar:
- Preliminary RISC-V enablement - the bulk of it will arrive via the
RISCV tree.
- Relax decompressed image placement rules for 32-bit ARM
- Add support for passing MOK certificate table contents via a config
table rather than a EFI variable.
- Add support for 18 bit DIMM row IDs in the CPER records.
- Work around broken Dell firmware that passes the entire Boot####
variable contents as the command line
- Add definition of the EFI_MEMORY_CPU_CRYPTO memory attribute so we
can identify it in the memory map listings.
- Don't abort the boot on arm64 if the EFI RNG protocol is available
but returns with an error
- Replace slashes with exclamation marks in efivarfs file names
- Split efi-pstore from the deprecated efivars sysfs code, so we can
disable the latter on !x86.
- Misc fixes, cleanups and updates.
* tag 'efi-core-2020-10-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits)
efi: mokvar: add missing include of asm/early_ioremap.h
efi: efivars: limit availability to X86 builds
efi: remove some false dependencies on CONFIG_EFI_VARS
efi: gsmi: fix false dependency on CONFIG_EFI_VARS
efi: efivars: un-export efivars_sysfs_init()
efi: pstore: move workqueue handling out of efivars
efi: pstore: disentangle from deprecated efivars module
efi: mokvar-table: fix some issues in new code
efi/arm64: libstub: Deal gracefully with EFI_RNG_PROTOCOL failure
efivarfs: Replace invalid slashes with exclamation marks in dentries.
efi: Delete deprecated parameter comments
efi/libstub: Fix missing-prototypes in string.c
efi: Add definition of EFI_MEMORY_CPU_CRYPTO and ability to report it
cper,edac,efi: Memory Error Record: bank group/address and chip id
edac,ghes,cper: Add Row Extension to Memory Error Record
efi/x86: Add a quirk to support command line arguments on Dell EFI firmware
efi/libstub: Add efi_warn and *_once logging helpers
integrity: Load certs from the EFI MOK config table
integrity: Move import of MokListRT certs to a separate routine
efi: Support for MOK variable config table
...
32 files changed, 871 insertions, 366 deletions
diff --git a/Documentation/arm/uefi.rst b/Documentation/arm/uefi.rst index f868330df6be..f732f957421f 100644 --- a/Documentation/arm/uefi.rst +++ b/Documentation/arm/uefi.rst @@ -23,7 +23,7 @@ makes it possible for the kernel to support additional features: For actually enabling [U]EFI support, enable: - CONFIG_EFI=y -- CONFIG_EFI_VARS=y or m +- CONFIG_EFIVAR_FS=y or m The implementation depends on receiving information about the UEFI environment in a Flattened Device Tree (FDT) - so is only available with CONFIG_OF. diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index 5dcf3c6011b7..3ee4f4381985 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -66,25 +66,24 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) #define MAX_UNCOMP_KERNEL_SIZE SZ_32M /* - * The kernel zImage should preferably be located between 32 MB and 128 MB - * from the base of DRAM. The min address leaves space for a maximal size - * uncompressed image, and the max address is due to how the zImage decompressor - * picks a destination address. + * phys-to-virt patching requires that the physical to virtual offset fits + * into the immediate field of an add/sub instruction, which comes down to the + * 24 least significant bits being zero, and so the offset should be a multiple + * of 16 MB. Since PAGE_OFFSET itself is a multiple of 16 MB, the physical + * base should be aligned to 16 MB as well. */ -#define ZIMAGE_OFFSET_LIMIT SZ_128M -#define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE +#define EFI_PHYS_ALIGN SZ_16M -/* on ARM, the FDT should be located in the first 128 MB of RAM */ -static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +/* on ARM, the FDT should be located in a lowmem region */ +static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) { - return dram_base + ZIMAGE_OFFSET_LIMIT; + return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; } /* on ARM, the initrd should be loaded in a lowmem region */ -static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, - unsigned long image_addr) +static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { - return dram_base + SZ_512M; + return round_down(image_addr, EFI_PHYS_ALIGN) + SZ_512M; } struct efi_arm_entry_state { diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index d4ab3f73e7a3..973b14415271 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -65,7 +65,7 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...); (SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN) /* on arm64, the FDT may be located anywhere in system RAM */ -static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +static inline unsigned long efi_get_max_fdt_addr(unsigned long image_addr) { return ULONG_MAX; } @@ -80,8 +80,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) * apply to other bootloaders, and are required for some kernel * configurations. */ -static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, - unsigned long image_addr) +static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1)); } diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 3511736fbc74..d41be0df72f8 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1077,6 +1077,7 @@ void __init setup_arch(char **cmdline_p) efi_fake_memmap(); efi_find_mirror(); efi_esrt_init(); + efi_mokvar_table_init(); /* * The EFI specification says that boot service code won't be diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index d37ebe6e70d7..8a26e705cb06 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -90,6 +90,9 @@ static const unsigned long * const efi_tables[] = { &efi.tpm_log, &efi.tpm_final_log, &efi_rng_seed, +#ifdef CONFIG_LOAD_UEFI_KEYS + &efi.mokvar_table, +#endif }; u64 efi_setup; /* efi setup_data physical address */ diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index dbbefd2798c5..a918ca93e4f7 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -372,8 +372,18 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) p += sprintf(p, "rank:%d ", mem_err->rank); if (mem_err->validation_bits & CPER_MEM_VALID_BANK) p += sprintf(p, "bank:%d ", mem_err->bank); - if (mem_err->validation_bits & CPER_MEM_VALID_ROW) - p += sprintf(p, "row:%d ", mem_err->row); + if (mem_err->validation_bits & CPER_MEM_VALID_BANK_GROUP) + p += sprintf(p, "bank_group:%d ", + mem_err->bank >> CPER_MEM_BANK_GROUP_SHIFT); + if (mem_err->validation_bits & CPER_MEM_VALID_BANK_ADDRESS) + p += sprintf(p, "bank_address:%d ", + mem_err->bank & CPER_MEM_BANK_ADDRESS_MASK); + if (mem_err->validation_bits & (CPER_MEM_VALID_ROW | CPER_MEM_VALID_ROW_EXT)) { + u32 row = mem_err->row; + + row |= cper_get_mem_extension(mem_err->validation_bits, mem_err->extended); + p += sprintf(p, "row:%d ", row); + } if (mem_err->validation_bits & CPER_MEM_VALID_COLUMN) p += sprintf(p, "col:%d ", mem_err->column); if (mem_err->validation_bits & CPER_MEM_VALID_BIT_POSITION) @@ -395,6 +405,9 @@ void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) strcpy(e->label, dimm->label); } } + if (mem_err->validation_bits & CPER_MEM_VALID_CHIP_ID) + p += sprintf(p, "chipID: %d ", + mem_err->extended >> CPER_MEM_CHIP_ID_SHIFT); if (p > e->location) *(p - 1) = '\0'; diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 3939699e62fe..da1887f72a51 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -4,20 +4,15 @@ menu "EFI (Extensible Firmware Interface) Support" config EFI_VARS tristate "EFI Variable Support via sysfs" - depends on EFI + depends on EFI && (X86 || IA64) default n help If you say Y here, you are able to get EFI (Extensible Firmware Interface) variable information via sysfs. You may read, write, create, and destroy EFI variables through this interface. - - Note that using this driver in concert with efibootmgr requires - at least test release version 0.5.0-test3 or later, which is - available from: - <http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz> - - Subsequent efibootmgr releases may be found at: - <http://github.com/vathpela/efibootmgr> + Note that this driver is only retained for compatibility with + legacy users: new users should use the efivarfs filesystem + instead. config EFI_ESRT bool @@ -26,7 +21,7 @@ config EFI_ESRT config EFI_VARS_PSTORE tristate "Register efivars backend for pstore" - depends on EFI_VARS && PSTORE + depends on PSTORE default y help Say Y here to enable use efivars as a backend to pstore. This @@ -137,7 +132,6 @@ config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER config EFI_BOOTLOADER_CONTROL tristate "EFI Bootloader Control" - depends on EFI_VARS default n help This module installs a reboot hook, such that if reboot() is @@ -281,7 +275,7 @@ config EFI_EARLYCON config EFI_CUSTOM_SSDT_OVERLAYS bool "Load custom ACPI SSDT overlay from an EFI variable" - depends on EFI_VARS && ACPI + depends on EFI && ACPI default ACPI_TABLE_UPGRADE help Allow loading of an ACPI SSDT overlay from an EFI variable specified diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 7a216984552b..e8da782280b6 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -28,11 +28,12 @@ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o +obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o fake_map-y += fake_mem.o fake_map-$(CONFIG_X86) += x86_fake_mem.o -arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o +arm-obj-$(CONFIG_EFI) := efi-init.o arm-runtime.o obj-$(CONFIG_ARM) += $(arm-obj-y) obj-$(CONFIG_ARM64) += $(arm-obj-y) obj-$(CONFIG_EFI_CAPSULE_LOADER) += capsule-loader.o diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index f564e15fbc7e..e15d484b6a5a 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -232,10 +232,20 @@ static int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg) n += scnprintf(msg + n, len - n, "rank: %d ", mem->rank); if (mem->validation_bits & CPER_MEM_VALID_BANK) n += scnprintf(msg + n, len - n, "bank: %d ", mem->bank); + if (mem->validation_bits & CPER_MEM_VALID_BANK_GROUP) + n += scnprintf(msg + n, len - n, "bank_group: %d ", + mem->bank >> CPER_MEM_BANK_GROUP_SHIFT); + if (mem->validation_bits & CPER_MEM_VALID_BANK_ADDRESS) + n += scnprintf(msg + n, len - n, "bank_address: %d ", + mem->bank & CPER_MEM_BANK_ADDRESS_MASK); if (mem->validation_bits & CPER_MEM_VALID_DEVICE) n += scnprintf(msg + n, len - n, "device: %d ", mem->device); - if (mem->validation_bits & CPER_MEM_VALID_ROW) - n += scnprintf(msg + n, len - n, "row: %d ", mem->row); + if (mem->validation_bits & (CPER_MEM_VALID_ROW | CPER_MEM_VALID_ROW_EXT)) { + u32 row = mem->row; + + row |= cper_get_mem_extension(mem->validation_bits, mem->extended); + n += scnprintf(msg + n, len - n, "row: %d ", row); + } if (mem->validation_bits & CPER_MEM_VALID_COLUMN) n += scnprintf(msg + n, len - n, "column: %d ", mem->column); if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION) @@ -250,6 +260,9 @@ static int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg) if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID) scnprintf(msg + n, len - n, "target_id: 0x%016llx ", mem->target_id); + if (mem->validation_bits & CPER_MEM_VALID_CHIP_ID) + scnprintf(msg + n, len - n, "chip_id: %d ", + mem->extended >> CPER_MEM_CHIP_ID_SHIFT); msg[n] = '\0'; return n; @@ -292,6 +305,7 @@ void cper_mem_err_pack(const struct cper_sec_mem_err *mem, cmem->requestor_id = mem->requestor_id; cmem->responder_id = mem->responder_id; cmem->target_id = mem->target_id; + cmem->extended = mem->extended; cmem->rank = mem->rank; cmem->mem_array_handle = mem->mem_array_handle; cmem->mem_dev_handle = mem->mem_dev_handle; diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/efi-init.c index 71c445d20258..f55a92ff12c0 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -236,6 +236,7 @@ void __init efi_init(void) reserve_regions(); efi_esrt_init(); + efi_mokvar_table_init(); memblock_reserve(data.phys_map & PAGE_MASK, PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c index feb7fe6f2da7..0ef086e43090 100644 --- a/drivers/firmware/efi/efi-pstore.c +++ b/drivers/firmware/efi/efi-pstore.c @@ -8,6 +8,8 @@ #define DUMP_NAME_LEN 66 +#define EFIVARS_DATA_SIZE_MAX 1024 + static bool efivars_pstore_disable = IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE); @@ -18,6 +20,9 @@ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644); EFI_VARIABLE_BOOTSERVICE_ACCESS | \ EFI_VARIABLE_RUNTIME_ACCESS) +static LIST_HEAD(efi_pstore_list); +static DECLARE_WORK(efivar_work, NULL); + static int efi_pstore_open(struct pstore_info *psi) { psi->data = NULL; @@ -126,7 +131,7 @@ static inline int __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry, if (entry->deleting) { list_del(&entry->list); efivar_entry_iter_end(); - efivar_unregister(entry); + kfree(entry); if (efivar_entry_iter_begin()) return -EINTR; } else if (turn_off_scanning) @@ -169,7 +174,7 @@ static int efi_pstore_sysfs_entry_iter(struct pstore_record *record) { struct efivar_entry **pos = (struct efivar_entry **)&record->psi->data; struct efivar_entry *entry, *n; - struct list_head *head = &efivar_sysfs_list; + struct list_head *head = &efi_pstore_list; int size = 0; int ret; @@ -263,8 +268,9 @@ static int efi_pstore_write(struct pstore_record *record) ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES, preemptible(), record->size, record->psi->buf); - if (record->reason == KMSG_DUMP_OOPS) - efivar_run_worker(); + if (record->reason == KMSG_DUMP_OOPS && try_module_get(THIS_MODULE)) + if (!schedule_work(&efivar_work)) + module_put(THIS_MODULE); return ret; }; @@ -314,12 +320,12 @@ static int efi_pstore_erase_name(const char *name) if (efivar_entry_iter_begin()) return -EINTR; - found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, + found = __efivar_entry_iter(efi_pstore_erase_func, &efi_pstore_list, efi_name, &entry); efivar_entry_iter_end(); if (found && !entry->scanning) - efivar_unregister(entry); + kfree(entry); return found ? 0 : -ENOENT; } @@ -354,14 +360,77 @@ static struct pstore_info efi_pstore_info = { .erase = efi_pstore_erase, }; +static int efi_pstore_callback(efi_char16_t *name, efi_guid_t vendor, + unsigned long name_size, void *data) +{ + struct efivar_entry *entry; + int ret; + + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return -ENOMEM; + + memcpy(entry->var.VariableName, name, name_size); + entry->var.VendorGuid = vendor; + + ret = efivar_entry_add(entry, &efi_pstore_list); + if (ret) + kfree(entry); + + return ret; +} + +static int efi_pstore_update_entry(efi_char16_t *name, efi_guid_t vendor, + unsigned long name_size, void *data) +{ + struct efivar_entry *entry = data; + + if (efivar_entry_find(name, vendor, &efi_pstore_list, false)) + return 0; + + memcpy(entry->var.VariableName, name, name_size); + memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t)); + + return 1; +} + +static void efi_pstore_update_entries(struct work_struct *work) +{ + struct efivar_entry *entry; + int err; + + /* Add new sysfs entries */ + while (1) { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return; + + err = efivar_init(efi_pstore_update_entry, entry, + false, &efi_pstore_list); + if (!err) + break; + + efivar_entry_add(entry, &efi_pstore_list); + } + + kfree(entry); + module_put(THIS_MODULE); +} + static __init int efivars_pstore_init(void) { + int ret; + if (!efivars_kobject() || !efivar_supports_writes()) return 0; if (efivars_pstore_disable) return 0; + ret = efivar_init(efi_pstore_callback, NULL, true, &efi_pstore_list); + if (ret) + return ret; + efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL); if (!efi_pstore_info.buf) return -ENOMEM; @@ -374,6 +443,8 @@ static __init int efivars_pstore_init(void) efi_pstore_info.bufsize = 0; } + INIT_WORK(&efivar_work, efi_pstore_update_entries); + return 0; } diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 3aa07c3b5136..5e5480a0a32d 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -43,6 +43,9 @@ struct efi __read_mostly efi = { .esrt = EFI_INVALID_TABLE_ADDR, .tpm_log = EFI_INVALID_TABLE_ADDR, .tpm_final_log = EFI_INVALID_TABLE_ADDR, +#ifdef CONFIG_LOAD_UEFI_KEYS + .mokvar_table = EFI_INVALID_TABLE_ADDR, +#endif }; EXPORT_SYMBOL(efi); @@ -519,6 +522,9 @@ static const efi_config_table_type_t common_tables[] __initconst = { #ifdef CONFIG_EFI_RCI2_TABLE {DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys }, #endif +#ifdef CONFIG_LOAD_UEFI_KEYS + {LINUX_EFI_MOK_VARIABLE_TABLE_GUID, &efi.mokvar_table, "MOKvar" }, +#endif {}, }; @@ -714,7 +720,7 @@ void __init efi_systab_report_header(const efi_table_hdr_t *systab_hdr, vendor); } -static __initdata char memory_type_name[][20] = { +static __initdata char memory_type_name[][13] = { "Reserved", "Loader Code", "Loader Data", @@ -722,14 +728,14 @@ static __initdata char memory_type_name[][20] = { "Boot Data", "Runtime Code", "Runtime Data", - "Conventional Memory", - "Unusable Memory", - "ACPI Reclaim Memory", - "ACPI Memory NVS", - "Memory Mapped I/O", - "MMIO Port Space", + "Conventional", + "Unusable", + "ACPI Reclaim", + "ACPI Mem NVS", + "MMIO", + "MMIO Port", "PAL Code", - "Persistent Memory", + "Persistent", }; char * __init efi_md_typeattr_format(char *buf, size_t size, @@ -756,26 +762,27 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | - EFI_MEMORY_NV | EFI_MEMORY_SP | + EFI_MEMORY_NV | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) snprintf(pos, size, "|attr=0x%016llx]", (unsigned long long)attr); else snprintf(pos, size, - "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", - attr & EFI_MEMORY_RUNTIME ? "RUN" : "", - attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", - attr & EFI_MEMORY_SP ? "SP" : "", - attr & EFI_MEMORY_NV ? "NV" : "", - attr & EFI_MEMORY_XP ? "XP" : "", - attr & EFI_MEMORY_RP ? "RP" : "", - attr & EFI_MEMORY_WP ? "WP" : "", - attr & EFI_MEMORY_RO ? "RO" : "", - attr & EFI_MEMORY_UCE ? "UCE" : "", - attr & EFI_MEMORY_WB ? "WB" : "", - attr & EFI_MEMORY_WT ? "WT" : "", - attr & EFI_MEMORY_WC ? "WC" : "", - attr & EFI_MEMORY_UC ? "UC" : ""); + "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + attr & EFI_MEMORY_RUNTIME ? "RUN" : "", + attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_CPU_CRYPTO ? "CC" : "", + attr & EFI_MEMORY_SP ? "SP" : "", + attr & EFI_MEMORY_NV ? "NV" : "", + attr & EFI_MEMORY_XP ? "XP" : "", + attr & EFI_MEMORY_RP ? "RP" : "", + attr & EFI_MEMORY_WP ? "WP" : "", + attr & EFI_MEMORY_RO ? "RO" : "", + attr & EFI_MEMORY_UCE ? "UCE" : "", + attr & EFI_MEMORY_WB ? "WB" : "", + attr & EFI_MEMORY_WT ? "WT" : "", + attr & EFI_MEMORY_WC ? "WC" : "", + attr & EFI_MEMORY_UC ? "UC" : ""); return buf; } diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index dcea137142b3..e6b16b3a17a8 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -22,10 +22,8 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>"); MODULE_DESCRIPTION("sysfs interface to EFI Variables"); MODULE_LICENSE("GPL"); MODULE_VERSION(EFIVARS_VERSION); -MODULE_ALIAS("platform:efivars"); -LIST_HEAD(efivar_sysfs_list); -EXPORT_SYMBOL_GPL(efivar_sysfs_list); +static LIST_HEAD(efivar_sysfs_list); static struct kset *efivars_kset; @@ -591,42 +589,6 @@ out_free: return error; } -static int efivar_update_sysfs_entry(efi_char16_t *name, efi_guid_t vendor, - unsigned long name_size, void *data) -{ - struct efivar_entry *entry = data; - - if (efivar_entry_find(name, vendor, &efivar_sysfs_list, false)) - return 0; - - memcpy(entry->var.VariableName, name, name_size); - memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t)); - - return 1; -} - -static void efivar_update_sysfs_entries(struct work_struct *work) -{ - struct efivar_entry *entry; - int err; - - /* Add new sysfs entries */ - while (1) { - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return; - - err = efivar_init(efivar_update_sysfs_entry, entry, - false, &efivar_sysfs_list); - if (!err) - break; - - efivar_create_sysfs_entry(entry); - } - - kfree(entry); -} - static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor, unsigned long name_size, void *data) { @@ -675,7 +637,7 @@ static void efivars_sysfs_exit(void) kset_unregister(efivars_kset); } -int efivars_sysfs_init(void) +static int efivars_sysfs_init(void) { struct kobject *parent_kobj = efivars_kobject(); int error = 0; @@ -701,11 +663,8 @@ int efivars_sysfs_init(void) return error; } - INIT_WORK(&efivar_work, efivar_update_sysfs_entries); - return 0; } -EXPORT_SYMBOL_GPL(efivars_sysfs_init); module_init(efivars_sysfs_init); module_exit(efivars_sysfs_exit); diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index d08e5d55838c..4b5b2403b3a0 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -113,162 +113,58 @@ void free_screen_info(struct screen_info *si) efi_bs_call(free_pool, si); } -static efi_status_t reserve_kernel_base(unsigned long dram_base, - unsigned long *reserve_addr, - unsigned long *reserve_size) -{ - efi_physical_addr_t alloc_addr; - efi_memory_desc_t *memory_map; - unsigned long nr_pages, map_size, desc_size, buff_size; - efi_status_t status; - unsigned long l; - - struct efi_boot_memmap map = { - .map = &memory_map, - .map_size = &map_size, - .desc_size = &desc_size, - .desc_ver = NULL, - .key_ptr = NULL, - .buff_size = &buff_size, - }; - - /* - * Reserve memory for the uncompressed kernel image. This is - * all that prevents any future allocations from conflicting - * with the kernel. Since we can't tell from the compressed - * image how much DRAM the kernel actually uses (due to BSS - * size uncertainty) we allocate the maximum possible size. - * Do this very early, as prints can cause memory allocations - * that may conflict with this. - */ - alloc_addr = dram_base + MAX_UNCOMP_KERNEL_SIZE; - nr_pages = MAX_UNCOMP_KERNEL_SIZE / EFI_PAGE_SIZE; - status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS, - EFI_BOOT_SERVICES_DATA, nr_pages, &alloc_addr); - if (status == EFI_SUCCESS) { - if (alloc_addr == dram_base) { - *reserve_addr = alloc_addr; - *reserve_size = MAX_UNCOMP_KERNEL_SIZE; - return EFI_SUCCESS; - } - /* - * If we end up here, the allocation succeeded but starts below - * dram_base. This can only occur if the real base of DRAM is - * not a multiple of 128 MB, in which case dram_base will have - * been rounded up. Since this implies that a part of the region - * was already occupied, we need to fall through to the code - * below to ensure that the existing allocations don't conflict. - * For this reason, we use EFI_BOOT_SERVICES_DATA above and not - * EFI_LOADER_DATA, which we wouldn't able to distinguish from - * allocations that we want to disallow. - */ - } - - /* - * If the allocation above failed, we may still be able to proceed: - * if the only allocations in the region are of types that will be - * released to the OS after ExitBootServices(), the decompressor can - * safely overwrite them. - */ - status = efi_get_memory_map(&map); - if (status != EFI_SUCCESS) { - efi_err("reserve_kernel_base(): Unable to retrieve memory map.\n"); - return status; - } - - for (l = 0; l < map_size; l += desc_size) { - efi_memory_desc_t *desc; - u64 start, end; - - desc = (void *)memory_map + l; - start = desc->phys_addr; - end = start + desc->num_pages * EFI_PAGE_SIZE; - - /* Skip if entry does not intersect with region */ - if (start >= dram_base + MAX_UNCOMP_KERNEL_SIZE || - end <= dram_base) - continue; - - switch (desc->type) { - case EFI_BOOT_SERVICES_CODE: - case EFI_BOOT_SERVICES_DATA: - /* Ignore types that are released to the OS anyway */ - continue; - - case EFI_CONVENTIONAL_MEMORY: - /* Skip soft reserved conventional memory */ - if (efi_soft_reserve_enabled() && - (desc->attribute & EFI_MEMORY_SP)) - continue; - - /* - * Reserve the intersection between this entry and the - * region. - */ - start = max(start, (u64)dram_base); - end = min(end, (u64)dram_base + MAX_UNCOMP_KERNEL_SIZE); - - status = efi_bs_call(allocate_pages, - EFI_ALLOCATE_ADDRESS, - EFI_LOADER_DATA, - (end - start) / EFI_PAGE_SIZE, - &start); - if (status != EFI_SUCCESS) { - efi_err("reserve_kernel_base(): alloc failed.\n"); - goto out; - } - break; - - case EFI_LOADER_CODE: - case EFI_LOADER_DATA: - /* - * These regions may be released and reallocated for - * another purpose (including EFI_RUNTIME_SERVICE_DATA) - * at any time during the execution of the OS loader, - * so we cannot consider them as safe. - */ - default: - /* - * Treat any other allocation in the region as unsafe */ - status = EFI_OUT_OF_RESOURCES; - goto out; - } - } - - status = EFI_SUCCESS; -out: - efi_bs_call(free_pool, memory_map); - return status; -} - efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, unsigned long *reserve_addr, unsigned long *reserve_size, - unsigned long dram_base, efi_loaded_image_t *image) |