summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-13 14:31:47 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-13 14:31:47 -0800
commitfc4c9f450493daef1c996c9d4b3c647ec3121509 (patch)
tree99078a5d34ba783b9b43092fe2c275784c7cab98 /drivers
parent717e6eb49bdd98357d14c90d60a3409196b33cfc (diff)
parente8dfdf3162eb549d064b8c10b1564f7e8ee82591 (diff)
downloadlinux-fc4c9f450493daef1c996c9d4b3c647ec3121509.tar.gz
linux-fc4c9f450493daef1c996c9d4b3c647ec3121509.tar.bz2
linux-fc4c9f450493daef1c996c9d4b3c647ec3121509.zip
Merge tag 'efi-next-for-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI updates from Ard Biesheuvel: "Another fairly sizable pull request, by EFI subsystem standards. Most of the work was done by me, some of it in collaboration with the distro and bootloader folks (GRUB, systemd-boot), where the main focus has been on removing pointless per-arch differences in the way EFI boots a Linux kernel. - Refactor the zboot code so that it incorporates all the EFI stub logic, rather than calling the decompressed kernel as a EFI app. - Add support for initrd= command line option to x86 mixed mode. - Allow initrd= to be used with arbitrary EFI accessible file systems instead of just the one the kernel itself was loaded from. - Move some x86-only handling and manipulation of the EFI memory map into arch/x86, as it is not used anywhere else. - More flexible handling of any random seeds provided by the boot environment (i.e., systemd-boot) so that it becomes available much earlier during the boot. - Allow improved arch-agnostic EFI support in loaders, by setting a uniform baseline of supported features, and adding a generic magic number to the DOS/PE header. This should allow loaders such as GRUB or systemd-boot to reduce the amount of arch-specific handling substantially. - (arm64) Run EFI runtime services from a dedicated stack, and use it to recover from synchronous exceptions that might occur in the firmware code. - (arm64) Ensure that we don't allocate memory outside of the 48-bit addressable physical range. - Make EFI pstore record size configurable - Add support for decoding CXL specific CPER records" * tag 'efi-next-for-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: (43 commits) arm64: efi: Recover from synchronous exceptions occurring in firmware arm64: efi: Execute runtime services from a dedicated stack arm64: efi: Limit allocations to 48-bit addressable physical region efi: Put Linux specific magic number in the DOS header efi: libstub: Always enable initrd command line loader and bump version efi: stub: use random seed from EFI variable efi: vars: prohibit reading random seed variables efi: random: combine bootloader provided RNG seed with RNG protocol output efi/cper, cxl: Decode CXL Error Log efi/cper, cxl: Decode CXL Protocol Error Section efi: libstub: fix efi_load_initrd_dev_path() kernel-doc comment efi: x86: Move EFI runtime map sysfs code to arch/x86 efi: runtime-maps: Clarify purpose and enable by default for kexec efi: pstore: Add module parameter for setting the record size efi: xen: Set EFI_PARAVIRT for Xen dom0 boot on all architectures efi: memmap: Move manipulation routines into x86 arch tree efi: memmap: Move EFI fake memmap support into x86 arch tree efi: libstub: Undeprecate the command line initrd loader efi: libstub: Add mixed mode support to command line initrd loader efi: libstub: Permit mixed mode return types other than efi_status_t ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firmware/efi/Kconfig45
-rw-r--r--drivers/firmware/efi/Makefile7
-rw-r--r--drivers/firmware/efi/cper.c9
-rw-r--r--drivers/firmware/efi/cper_cxl.c179
-rw-r--r--drivers/firmware/efi/cper_cxl.h66
-rw-r--r--drivers/firmware/efi/efi-init.c21
-rw-r--r--drivers/firmware/efi/efi-pstore.c23
-rw-r--r--drivers/firmware/efi/efi.c14
-rw-r--r--drivers/firmware/efi/fake_mem.c124
-rw-r--r--drivers/firmware/efi/fake_mem.h10
-rw-r--r--drivers/firmware/efi/fdtparams.c4
-rw-r--r--drivers/firmware/efi/libstub/Makefile34
-rw-r--r--drivers/firmware/efi/libstub/Makefile.zboot22
-rw-r--r--drivers/firmware/efi/libstub/alignedmem.c7
-rw-r--r--drivers/firmware/efi/libstub/arm32-stub.c37
-rw-r--r--drivers/firmware/efi/libstub/arm64-entry.S67
-rw-r--r--drivers/firmware/efi/libstub/arm64-stub.c75
-rw-r--r--drivers/firmware/efi/libstub/arm64.c76
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-entry.c65
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-helper.c150
-rw-r--r--drivers/firmware/efi/libstub/efi-stub.c140
-rw-r--r--drivers/firmware/efi/libstub/efistub.h143
-rw-r--r--drivers/firmware/efi/libstub/file.c122
-rw-r--r--drivers/firmware/efi/libstub/intrinsics.c18
-rw-r--r--drivers/firmware/efi/libstub/loongarch-stub.c89
-rw-r--r--drivers/firmware/efi/libstub/loongarch.c80
-rw-r--r--drivers/firmware/efi/libstub/mem.c5
-rw-r--r--drivers/firmware/efi/libstub/printk.c154
-rw-r--r--drivers/firmware/efi/libstub/random.c96
-rw-r--r--drivers/firmware/efi/libstub/randomalloc.c7
-rw-r--r--drivers/firmware/efi/libstub/riscv-stub.c96
-rw-r--r--drivers/firmware/efi/libstub/riscv.c98
-rw-r--r--drivers/firmware/efi/libstub/screen_info.c56
-rw-r--r--drivers/firmware/efi/libstub/string.c95
-rw-r--r--drivers/firmware/efi/libstub/zboot-header.S5
-rw-r--r--drivers/firmware/efi/libstub/zboot.c307
-rw-r--r--drivers/firmware/efi/memmap.c243
-rw-r--r--drivers/firmware/efi/runtime-map.c193
-rw-r--r--drivers/firmware/efi/runtime-wrappers.c1
-rw-r--r--drivers/firmware/efi/x86_fake_mem.c75
40 files changed, 1494 insertions, 1564 deletions
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 6787ed8dfacf..043ca31c114e 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -26,39 +26,6 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
backend for pstore by default. This setting can be overridden
using the efivars module's pstore_disable parameter.
-config EFI_RUNTIME_MAP
- bool "Export efi runtime maps to sysfs"
- depends on X86 && EFI && KEXEC_CORE
- default y
- help
- Export efi runtime memory maps to /sys/firmware/efi/runtime-map.
- That memory map is used for example by kexec to set up efi virtual
- mapping the 2nd kernel, but can also be used for debugging purposes.
-
- See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
-
-config EFI_FAKE_MEMMAP
- bool "Enable EFI fake memory map"
- depends on EFI && X86
- default n
- help
- Saying Y here will enable "efi_fake_mem" boot option.
- By specifying this parameter, you can add arbitrary attribute
- to specific memory range by updating original (firmware provided)
- EFI memmap.
- This is useful for debugging of EFI memmap related feature.
- e.g. Address Range Mirroring feature.
-
-config EFI_MAX_FAKE_MEM
- int "maximum allowable number of ranges in efi_fake_mem boot option"
- depends on EFI_FAKE_MEMMAP
- range 1 128
- default 8
- help
- Maximum allowable number of ranges in efi_fake_mem boot option.
- Ranges can be set up to this value using comma-separated list.
- The default value is 8.
-
config EFI_SOFT_RESERVE
bool "Reserve EFI Specific Purpose Memory"
depends on EFI && EFI_STUB && ACPI_HMAT
@@ -139,18 +106,6 @@ config EFI_ARMSTUB_DTB_LOADER
functionality for bootloaders that do not have such support
this option is necessary.
-config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
- bool "Enable the command line initrd loader" if !X86
- depends on EFI_STUB && (EFI_GENERIC_STUB || X86)
- default y if X86
- depends on !RISCV && !LOONGARCH
- help
- Select this config option to add support for the initrd= command
- line parameter, allowing an initrd that resides on the same volume
- as the kernel image to be loaded into memory.
-
- This method is deprecated.
-
config EFI_BOOTLOADER_CONTROL
tristate "EFI Bootloader Control"
select UCS2_STRING
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 8d151e332584..b51f2a4c821e 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -19,11 +19,9 @@ endif
obj-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdtparams.o
obj-$(CONFIG_EFI_ESRT) += esrt.o
obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
-obj-$(CONFIG_UEFI_CPER) += cper.o
-obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o
+obj-$(CONFIG_UEFI_CPER) += cper.o cper_cxl.o
obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o
subdir-$(CONFIG_EFI_STUB) += libstub
-obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_map.o
obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
obj-$(CONFIG_EFI_TEST) += test/
obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
@@ -32,9 +30,6 @@ 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
-
obj-$(CONFIG_SYSFB) += sysfb_efi.o
arm-obj-$(CONFIG_EFI) := efi-init.o arm-runtime.o
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 053eae13f409..35c37f667781 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -24,6 +24,7 @@
#include <linux/bcd.h>
#include <acpi/ghes.h>
#include <ras/ras_event.h>
+#include "cper_cxl.h"
/*
* CPER record ID need to be unique even after reboot, because record
@@ -598,6 +599,14 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
cper_print_fw_err(newpfx, gdata, fw_err);
else
goto err_section_too_small;
+ } else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
+ struct cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
+
+ printk("%ssection_type: CXL Protocol Error\n", newpfx);
+ if (gdata->error_data_length >= sizeof(*prot_err))
+ cper_print_prot_err(newpfx, prot_err);
+ else
+ goto err_section_too_small;
} else {
const void *err = acpi_hest_get_payload(gdata);
diff --git a/drivers/firmware/efi/cper_cxl.c b/drivers/firmware/efi/cper_cxl.c
new file mode 100644
index 000000000000..53e435c4f310
--- /dev/null
+++ b/drivers/firmware/efi/cper_cxl.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UEFI Common Platform Error Record (CPER) support for CXL Section.
+ *
+ * Copyright (C) 2022 Advanced Micro Devices, Inc.
+ *
+ * Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
+ */
+
+#include <linux/cper.h>
+#include "cper_cxl.h"
+#include <linux/cxl_err.h>
+
+#define PROT_ERR_VALID_AGENT_TYPE BIT_ULL(0)
+#define PROT_ERR_VALID_AGENT_ADDRESS BIT_ULL(1)
+#define PROT_ERR_VALID_DEVICE_ID BIT_ULL(2)
+#define PROT_ERR_VALID_SERIAL_NUMBER BIT_ULL(3)
+#define PROT_ERR_VALID_CAPABILITY BIT_ULL(4)
+#define PROT_ERR_VALID_DVSEC BIT_ULL(5)
+#define PROT_ERR_VALID_ERROR_LOG BIT_ULL(6)
+
+static const char * const prot_err_agent_type_strs[] = {
+ "Restricted CXL Device",
+ "Restricted CXL Host Downstream Port",
+ "CXL Device",
+ "CXL Logical Device",
+ "CXL Fabric Manager managed Logical Device",
+ "CXL Root Port",
+ "CXL Downstream Switch Port",
+ "CXL Upstream Switch Port",
+};
+
+/*
+ * The layout of the enumeration and the values matches CXL Agent Type
+ * field in the UEFI 2.10 Section N.2.13,
+ */
+enum {
+ RCD, /* Restricted CXL Device */
+ RCH_DP, /* Restricted CXL Host Downstream Port */
+ DEVICE, /* CXL Device */
+ LD, /* CXL Logical Device */
+ FMLD, /* CXL Fabric Manager managed Logical Device */
+ RP, /* CXL Root Port */
+ DSP, /* CXL Downstream Switch Port */
+ USP, /* CXL Upstream Switch Port */
+};
+
+void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err)
+{
+ if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_TYPE)
+ pr_info("%s agent_type: %d, %s\n", pfx, prot_err->agent_type,
+ prot_err->agent_type < ARRAY_SIZE(prot_err_agent_type_strs)
+ ? prot_err_agent_type_strs[prot_err->agent_type]
+ : "unknown");
+
+ if (prot_err->valid_bits & PROT_ERR_VALID_AGENT_ADDRESS) {
+ switch (prot_err->agent_type) {
+ /*
+ * According to UEFI 2.10 Section N.2.13, the term CXL Device
+ * is used to refer to Restricted CXL Device, CXL Device, CXL
+ * Logical Device or a CXL Fabric Manager Managed Logical
+ * Device.
+ */
+ case RCD:
+ case DEVICE:
+ case LD:
+ case FMLD:
+ case RP:
+ case DSP:
+ case USP:
+ pr_info("%s agent_address: %04x:%02x:%02x.%x\n",
+ pfx, prot_err->agent_addr.segment,
+ prot_err->agent_addr.bus,
+ prot_err->agent_addr.device,
+ prot_err->agent_addr.function);
+ break;
+ case RCH_DP:
+ pr_info("%s rcrb_base_address: 0x%016llx\n", pfx,
+ prot_err->agent_addr.rcrb_base_addr);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (prot_err->valid_bits & PROT_ERR_VALID_DEVICE_ID) {
+ const __u8 *class_code;
+
+ switch (prot_err->agent_type) {
+ case RCD:
+ case DEVICE:
+ case LD:
+ case FMLD:
+ case RP:
+ case DSP:
+ case USP:
+ pr_info("%s slot: %d\n", pfx,
+ prot_err->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
+ pr_info("%s vendor_id: 0x%04x, device_id: 0x%04x\n",
+ pfx, prot_err->device_id.vendor_id,
+ prot_err->device_id.device_id);
+ pr_info("%s sub_vendor_id: 0x%04x, sub_device_id: 0x%04x\n",
+ pfx, prot_err->device_id.subsystem_vendor_id,
+ prot_err->device_id.subsystem_id);
+ class_code = prot_err->device_id.class_code;
+ pr_info("%s class_code: %02x%02x\n", pfx,
+ class_code[1], class_code[0]);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (prot_err->valid_bits & PROT_ERR_VALID_SERIAL_NUMBER) {
+ switch (prot_err->agent_type) {
+ case RCD:
+ case DEVICE:
+ case LD:
+ case FMLD:
+ pr_info("%s lower_dw: 0x%08x, upper_dw: 0x%08x\n", pfx,
+ prot_err->dev_serial_num.lower_dw,
+ prot_err->dev_serial_num.upper_dw);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (prot_err->valid_bits & PROT_ERR_VALID_CAPABILITY) {
+ switch (prot_err->agent_type) {
+ case RCD:
+ case DEVICE:
+ case LD:
+ case FMLD:
+ case RP:
+ case DSP:
+ case USP:
+ print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4,
+ prot_err->capability,
+ sizeof(prot_err->capability), 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (prot_err->valid_bits & PROT_ERR_VALID_DVSEC) {
+ pr_info("%s DVSEC length: 0x%04x\n", pfx, prot_err->dvsec_len);
+
+ pr_info("%s CXL DVSEC:\n", pfx);
+ print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, (prot_err + 1),
+ prot_err->dvsec_len, 0);
+ }
+
+ if (prot_err->valid_bits & PROT_ERR_VALID_ERROR_LOG) {
+ size_t size = sizeof(*prot_err) + prot_err->dvsec_len;
+ struct cxl_ras_capability_regs *cxl_ras;
+
+ pr_info("%s Error log length: 0x%04x\n", pfx, prot_err->err_len);
+
+ pr_info("%s CXL Error Log:\n", pfx);
+ cxl_ras = (struct cxl_ras_capability_regs *)((long)prot_err + size);
+ pr_info("%s cxl_ras_uncor_status: 0x%08x", pfx,
+ cxl_ras->uncor_status);
+ pr_info("%s cxl_ras_uncor_mask: 0x%08x\n", pfx,
+ cxl_ras->uncor_mask);
+ pr_info("%s cxl_ras_uncor_severity: 0x%08x\n", pfx,
+ cxl_ras->uncor_severity);
+ pr_info("%s cxl_ras_cor_status: 0x%08x", pfx,
+ cxl_ras->cor_status);
+ pr_info("%s cxl_ras_cor_mask: 0x%08x\n", pfx,
+ cxl_ras->cor_mask);
+ pr_info("%s cap_control: 0x%08x\n", pfx,
+ cxl_ras->cap_control);
+ pr_info("%s Header Log Registers:\n", pfx);
+ print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, cxl_ras->header_log,
+ sizeof(cxl_ras->header_log), 0);
+ }
+}
diff --git a/drivers/firmware/efi/cper_cxl.h b/drivers/firmware/efi/cper_cxl.h
new file mode 100644
index 000000000000..86bfcf7909ec
--- /dev/null
+++ b/drivers/firmware/efi/cper_cxl.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * UEFI Common Platform Error Record (CPER) support for CXL Section.
+ *
+ * Copyright (C) 2022 Advanced Micro Devices, Inc.
+ *
+ * Author: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com>
+ */
+
+#ifndef LINUX_CPER_CXL_H
+#define LINUX_CPER_CXL_H
+
+/* CXL Protocol Error Section */
+#define CPER_SEC_CXL_PROT_ERR \
+ GUID_INIT(0x80B9EFB4, 0x52B5, 0x4DE3, 0xA7, 0x77, 0x68, 0x78, \
+ 0x4B, 0x77, 0x10, 0x48)
+
+#pragma pack(1)
+
+/* Compute Express Link Protocol Error Section, UEFI v2.10 sec N.2.13 */
+struct cper_sec_prot_err {
+ u64 valid_bits;
+ u8 agent_type;
+ u8 reserved[7];
+
+ /*
+ * Except for RCH Downstream Port, all the remaining CXL Agent
+ * types are uniquely identified by the PCIe compatible SBDF number.
+ */
+ union {
+ u64 rcrb_base_addr;
+ struct {
+ u8 function;
+ u8 device;
+ u8 bus;
+ u16 segment;
+ u8 reserved_1[3];
+ };
+ } agent_addr;
+
+ struct {
+ u16 vendor_id;
+ u16 device_id;
+ u16 subsystem_vendor_id;
+ u16 subsystem_id;
+ u8 class_code[2];
+ u16 slot;
+ u8 reserved_1[4];
+ } device_id;
+
+ struct {
+ u32 lower_dw;
+ u32 upper_dw;
+ } dev_serial_num;
+
+ u8 capability[60];
+ u16 dvsec_len;
+ u16 err_len;
+ u8 reserved_2[4];
+};
+
+#pragma pack()
+
+void cper_print_prot_err(const char *pfx, const struct cper_sec_prot_err *prot_err);
+
+#endif //__CPER_CXL_
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 2fd770b499a3..1639159493e3 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -22,6 +22,8 @@
#include <asm/efi.h>
+unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
+
static int __init is_memory(efi_memory_desc_t *md)
{
if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC))
@@ -55,9 +57,22 @@ extern __weak const efi_config_table_type_t efi_arch_tables[];
static void __init init_screen_info(void)
{
- if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI &&
- memblock_is_map_memory(screen_info.lfb_base))
- memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size);
+ struct screen_info *si;
+
+ if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
+ si = early_memremap(screen_info_table, sizeof(*si));
+ if (!si) {
+ pr_err("Could not map screen_info config table\n");
+ return;
+ }
+ screen_info = *si;
+ memset(si, 0, sizeof(*si));
+ early_memunmap(si, sizeof(*si));
+
+ if (memblock_is_map_memory(screen_info.lfb_base))
+ memblock_mark_nomap(screen_info.lfb_base,
+ screen_info.lfb_size);
+ }
}
static int __init uefi_init(u64 efi_system_table)
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 97a9e84840a0..e7b9ec6f8a86 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -10,7 +10,9 @@ MODULE_IMPORT_NS(EFIVAR);
#define DUMP_NAME_LEN 66
-#define EFIVARS_DATA_SIZE_MAX 1024
+static unsigned int record_size = 1024;
+module_param(record_size, uint, 0444);
+MODULE_PARM_DESC(record_size, "size of each pstore UEFI var (in bytes, min/default=1024)");
static bool efivars_pstore_disable =
IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
@@ -30,7 +32,7 @@ static int efi_pstore_open(struct pstore_info *psi)
if (err)
return err;
- psi->data = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL);
+ psi->data = kzalloc(record_size, GFP_KERNEL);
if (!psi->data)
return -ENOMEM;
@@ -52,7 +54,7 @@ static inline u64 generic_id(u64 timestamp, unsigned int part, int count)
static int efi_pstore_read_func(struct pstore_record *record,
efi_char16_t *varname)
{
- unsigned long wlen, size = EFIVARS_DATA_SIZE_MAX;
+ unsigned long wlen, size = record_size;
char name[DUMP_NAME_LEN], data_type;
efi_status_t status;
int cnt;
@@ -133,7 +135,7 @@ static ssize_t efi_pstore_read(struct pstore_record *record)
efi_status_t status;
for (;;) {
- varname_size = EFIVARS_DATA_SIZE_MAX;
+ varname_size = 1024;
/*
* If this is the first read() call in the pstore enumeration,
@@ -224,11 +226,20 @@ static __init int efivars_pstore_init(void)
if (efivars_pstore_disable)
return 0;
- efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+ /*
+ * Notice that 1024 is the minimum here to prevent issues with
+ * decompression algorithms that were spotted during tests;
+ * even in the case of not using compression, smaller values would
+ * just pollute more the pstore FS with many small collected files.
+ */
+ if (record_size < 1024)
+ record_size = 1024;
+
+ efi_pstore_info.buf = kmalloc(record_size, GFP_KERNEL);
if (!efi_pstore_info.buf)
return -ENOMEM;
- efi_pstore_info.bufsize = 1024;
+ efi_pstore_info.bufsize = record_size;
if (pstore_register(&efi_pstore_info)) {
kfree(efi_pstore_info.buf);
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 16dae588f0e3..31a4090c66b3 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -58,6 +58,8 @@ static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
+extern unsigned long screen_info_table;
+
struct mm_struct efi_mm = {
.mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
.mm_users = ATOMIC_INIT(2),
@@ -412,10 +414,6 @@ static int __init efisubsys_init(void)
goto err_unregister;
}
- error = efi_runtime_map_init(efi_kobj);
- if (error)
- goto err_remove_group;
-
/* and the standard mountpoint for efivarfs */
error = sysfs_create_mount_point(efi_kobj, "efivars");
if (error) {
@@ -442,6 +440,7 @@ err_unregister:
generic_ops_unregister();
err_put:
kobject_put(efi_kobj);
+ efi_kobj = NULL;
destroy_workqueue(efi_rts_wq);
return error;
}
@@ -566,6 +565,9 @@ static const efi_config_table_type_t common_tables[] __initconst = {
#ifdef CONFIG_EFI_COCO_SECRET
{LINUX_EFI_COCO_SECRET_AREA_GUID, &efi.coco_secret, "CocoSecret" },
#endif
+#ifdef CONFIG_EFI_GENERIC_STUB
+ {LINUX_EFI_SCREEN_INFO_TABLE_GUID, &screen_info_table },
+#endif
{},
};
@@ -630,7 +632,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
seed = early_memremap(efi_rng_seed, sizeof(*seed));
if (seed != NULL) {
- size = min(seed->size, EFI_RANDOM_SEED_SIZE);
+ size = min_t(u32, seed->size, SZ_1K); // sanity check
early_memunmap(seed, sizeof(*seed));
} else {
pr_err("Could not map UEFI random seed!\n");
@@ -639,8 +641,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
seed = early_memremap(efi_rng_seed,
sizeof(*seed) + size);
if (seed != NULL) {
- pr_notice("seeding entropy pool\n");
add_bootloader_randomness(seed->bits, size);
+ memzero_explicit(seed->bits, size);
early_memunmap(seed, sizeof(*seed) + size);
} else {
pr_err("Could not map UEFI random seed!\n");
diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c
deleted file mode 100644
index 6e0f34a38171..000000000000
--- a/drivers/firmware/efi/fake_mem.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * fake_mem.c
- *
- * Copyright (C) 2015 FUJITSU LIMITED
- * Author: Taku Izumi <izumi.taku@jp.fujitsu.com>
- *
- * This code introduces new boot option named "efi_fake_mem"
- * By specifying this parameter, you can add arbitrary attribute to
- * specific memory range by updating original (firmware provided) EFI
- * memmap.
- */
-
-#include <linux/kernel.h>
-#include <linux/efi.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/types.h>
-#include <linux/sort.h>
-#include "fake_mem.h"
-
-struct efi_mem_range efi_fake_mems[EFI_MAX_FAKEMEM];
-int nr_fake_mem;
-
-static int __init cmp_fake_mem(const void *x1, const void *x2)
-{
- const struct efi_mem_range *m1 = x1;
- const struct efi_mem_range *m2 = x2;
-
- if (m1->range.start < m2->range.start)
- return -1;
- if (m1->range.start > m2->range.start)
- return 1;
- return 0;
-}
-
-static void __init efi_fake_range(struct efi_mem_range *efi_range)
-{
- struct efi_memory_map_data data = { 0 };
- int new_nr_map = efi.memmap.nr_map;
- efi_memory_desc_t *md;
- void *new_memmap;
-
- /* count up the number of EFI memory descriptor */
- for_each_efi_memory_desc(md)
- new_nr_map += efi_memmap_split_count(md, &efi_range->range);
-
- /* allocate memory for new EFI memmap */
- if (efi_memmap_alloc(new_nr_map, &data) != 0)
- return;
-
- /* create new EFI memmap */
- new_memmap = early_memremap(data.phys_map, data.size);
- if (!new_memmap) {
- __efi_memmap_free(data.phys_map, data.size, data.flags);
- return;
- }
-
- efi_memmap_insert(&efi.memmap, new_memmap, efi_range);
-
- /* swap into new EFI memmap */
- early_memunmap(new_memmap, data.size);
-
- efi_memmap_install(&data);
-}
-
-void __init efi_fake_memmap(void)
-{
- int i;
-
- if (!efi_enabled(EFI_MEMMAP) || !nr_fake_mem)
- return;
-
- for (i = 0; i < nr_fake_mem; i++)
- efi_fake_range(&efi_fake_mems[i]);
-
- /* print new EFI memmap */
- efi_print_memmap();
-}
-
-static int __init setup_fake_mem(char *p)
-{
- u64 start = 0, mem_size = 0, attribute = 0;
- int i;
-
- if (!p)
- return -EINVAL;
-
- while (*p != '\0') {
- mem_size = memparse(p, &p);
- if (*p == '@')
- start = memparse(p+1, &p);
- else
- break;
-
- if (*p == ':')
- attribute = simple_strtoull(p+1, &p, 0);
- else
- break;
-
- if (nr_fake_mem >= EFI_MAX_FAKEMEM)
- break;
-
- efi_fake_mems[nr_fake_mem].range.start = start;
- efi_fake_mems[nr_fake_mem].range.end = start + mem_size - 1;
- efi_fake_mems[nr_fake_mem].attribute = attribute;
- nr_fake_mem++;
-
- if (*p == ',')
- p++;
- }
-
- sort(efi_fake_mems, nr_fake_mem, sizeof(struct efi_mem_range),
- cmp_fake_mem, NULL);
-
- for (i = 0; i < nr_fake_mem; i++)
- pr_info("efi_fake_mem: add attr=0x%016llx to [mem 0x%016llx-0x%016llx]",
- efi_fake_mems[i].attribute, efi_fake_mems[i].range.start,
- efi_fake_mems[i].range.end);
-
- return *p == '\0' ? 0 : -EINVAL;
-}
-
-early_param("efi_fake_mem", setup_fake_mem);
diff --git a/drivers/firmware/efi/fake_mem.h b/drivers/firmware/efi/fake_mem.h
deleted file mode 100644
index d52791af4b18..000000000000
--- a/drivers/firmware/efi/fake_mem.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __EFI_FAKE_MEM_H__
-#define __EFI_FAKE_MEM_H__
-#include <asm/efi.h>
-
-#define EFI_MAX_FAKEMEM CONFIG_EFI_MAX_FAKE_MEM
-
-extern struct efi_mem_range efi_fake_mems[EFI_MA