Commit bc53f67d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'efi-urgent-2020-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI fixes from Ingo Molnar:

 - Fix build regression on v4.8 and older

 - Robustness fix for TPM log parsing code

 - kobject refcount fix for the ESRT parsing code

 - Two efivarfs fixes to make it behave more like an ordinary file
   system

 - Style fixup for zero length arrays

 - Fix a regression in path separator handling in the initrd loader

 - Fix a missing prototype warning

 - Add some kerneldoc headers for newly introduced stub routines

 - Allow support for SSDT overrides via EFI variables to be disabled

 - Report CPU mode and MMU state upon entry for 32-bit ARM

 - Use the correct stack pointer alignment when entering from mixed mode

* tag 'efi-urgent-2020-06-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/libstub: arm: Print CPU boot mode and MMU state at boot
  efi/libstub: arm: Omit arch specific config table matching array on arm64
  efi/x86: Setup stack correctly for efi_pe_entry
  efi: Make it possible to disable efivar_ssdt entirely
  efi/libstub: Descriptions for stub helper functions
  efi/libstub: Fix path separator regression
  efi/libstub: Fix missing-prototype warning for skip_spaces()
  efi: Replace zero-length array and use struct_size() helper
  efivarfs: Don't return -EINTR when rate-limiting reads
  efivarfs: Update inode modification time for successful writes
  efi/esrt: Fix reference count leak in esre_create_sysfs_entry.
  efi/tpm: Verify event log header before parsing
  efi/x86: Fix build with gcc 4
parents 91a9a90d 2a55280a
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -87,4 +87,11 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
	return dram_base + SZ_512M;
}

struct efi_arm_entry_state {
	u32	cpsr_before_ebs;
	u32	sctlr_before_ebs;
	u32	cpsr_after_ebs;
	u32	sctlr_after_ebs;
};

#endif /* _ASM_ARM_EFI_H */
+10 −1
Original line number Diff line number Diff line
@@ -213,7 +213,6 @@ SYM_FUNC_START(startup_32)
	 * We place all of the values on our mini stack so lret can
	 * used to perform that far jump.
	 */
	pushl	$__KERNEL_CS
	leal	startup_64(%ebp), %eax
#ifdef CONFIG_EFI_MIXED
	movl	efi32_boot_args(%ebp), %edi
@@ -224,11 +223,20 @@ SYM_FUNC_START(startup_32)
	movl	efi32_boot_args+8(%ebp), %edx	// saved bootparams pointer
	cmpl	$0, %edx
	jnz	1f
	/*
	 * efi_pe_entry uses MS calling convention, which requires 32 bytes of
	 * shadow space on the stack even if all arguments are passed in
	 * registers. We also need an additional 8 bytes for the space that
	 * would be occupied by the return address, and this also results in
	 * the correct stack alignment for entry.
	 */
	subl	$40, %esp
	leal	efi_pe_entry(%ebp), %eax
	movl	%edi, %ecx			// MS calling convention
	movl	%esi, %edx
1:
#endif
	pushl	$__KERNEL_CS
	pushl	%eax

	/* Enter paged protected Mode, activating Long Mode */
@@ -784,6 +792,7 @@ SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0)

SYM_DATA_START_LOCAL(boot_stack)
	.fill BOOT_STACK_SIZE, 1, 0
	.balign 16
SYM_DATA_END_LABEL(boot_stack, SYM_L_LOCAL, boot_stack_end)

/*
+11 −0
Original line number Diff line number Diff line
@@ -278,3 +278,14 @@ config EFI_EARLYCON
	depends on SERIAL_EARLYCON && !ARM && !IA64
	select FONT_SUPPORT
	select ARCH_USE_MEMREMAP_PROT

config EFI_CUSTOM_SSDT_OVERLAYS
	bool "Load custom ACPI SSDT overlay from an EFI variable"
	depends on EFI_VARS && ACPI
	default ACPI_TABLE_UPGRADE
	help
	  Allow loading of an ACPI SSDT overlay from an EFI variable specified
	  by a kernel command line option.

	  See Documentation/admin-guide/acpi/ssdt-overlays.rst for more
	  information.
+36 −4
Original line number Diff line number Diff line
@@ -52,9 +52,11 @@ static phys_addr_t __init efi_to_phys(unsigned long addr)
}

static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR;
static __initdata unsigned long cpu_state_table = EFI_INVALID_TABLE_ADDR;

static const efi_config_table_type_t arch_tables[] __initconst = {
	{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
	{LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table},
	{}
};

@@ -62,7 +64,8 @@ static void __init init_screen_info(void)
{
	struct screen_info *si;

	if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
	if (IS_ENABLED(CONFIG_ARM) &&
	    screen_info_table != EFI_INVALID_TABLE_ADDR) {
		si = early_memremap_ro(screen_info_table, sizeof(*si));
		if (!si) {
			pr_err("Could not map screen_info config table\n");
@@ -116,7 +119,8 @@ static int __init uefi_init(u64 efi_system_table)
		goto out;
	}
	retval = efi_config_parse_tables(config_tables, systab->nr_tables,
					 arch_tables);
					 IS_ENABLED(CONFIG_ARM) ? arch_tables
								: NULL);

	early_memunmap(config_tables, table_size);
out:
@@ -238,9 +242,37 @@ void __init efi_init(void)

	init_screen_info();

#ifdef CONFIG_ARM
	/* ARM does not permit early mappings to persist across paging_init() */
	if (IS_ENABLED(CONFIG_ARM))
	efi_memmap_unmap();

	if (cpu_state_table != EFI_INVALID_TABLE_ADDR) {
		struct efi_arm_entry_state *state;
		bool dump_state = true;

		state = early_memremap_ro(cpu_state_table,
					  sizeof(struct efi_arm_entry_state));
		if (state == NULL) {
			pr_warn("Unable to map CPU entry state table.\n");
			return;
		}

		if ((state->sctlr_before_ebs & 1) == 0)
			pr_warn(FW_BUG "EFI stub was entered with MMU and Dcache disabled, please fix your firmware!\n");
		else if ((state->sctlr_after_ebs & 1) == 0)
			pr_warn(FW_BUG "ExitBootServices() returned with MMU and Dcache disabled, please fix your firmware!\n");
		else
			dump_state = false;

		if (dump_state || efi_enabled(EFI_DBG)) {
			pr_info("CPSR at EFI stub entry        : 0x%08x\n", state->cpsr_before_ebs);
			pr_info("SCTLR at EFI stub entry       : 0x%08x\n", state->sctlr_before_ebs);
			pr_info("CPSR after ExitBootServices() : 0x%08x\n", state->cpsr_after_ebs);
			pr_info("SCTLR after ExitBootServices(): 0x%08x\n", state->sctlr_after_ebs);
		}
		early_memunmap(state, sizeof(struct efi_arm_entry_state));
	}
#endif
}

static bool efifb_overlaps_pci_range(const struct of_pci_range *range)
+3 −2
Original line number Diff line number Diff line
@@ -189,7 +189,7 @@ static void generic_ops_unregister(void)
	efivars_unregister(&generic_efivars);
}

#if IS_ENABLED(CONFIG_ACPI)
#ifdef CONFIG_EFI_CUSTOM_SSDT_OVERLAYS
#define EFIVAR_SSDT_NAME_MAX	16
static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
static int __init efivar_ssdt_setup(char *str)
@@ -622,7 +622,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
			rsv = (void *)(p + prsv % PAGE_SIZE);

			/* reserve the entry itself */
			memblock_reserve(prsv, EFI_MEMRESERVE_SIZE(rsv->size));
			memblock_reserve(prsv,
					 struct_size(rsv, entry, rsv->size));

			for (i = 0; i < atomic_read(&rsv->count); i++) {
				memblock_reserve(rsv->entry[i].base,
Loading