Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ac385d8 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'efi-urgent' of...

Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi

 into x86/urgent

Pull EFI fixes from Matt Fleming:

  * Fix early boot regression affecting x86 EFI boot stub when loading
    initrds above 4GB - Yinghai Lu

  * Relocate GOT entries in the x86 EFI boot stub now that we have
    symbols with global visibility - Matt Fleming

  * fdt memory reservation fix for arm64 - Mark Salter

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents cc99535e 0ceac9e0
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -149,7 +149,6 @@ void __init arm64_memblock_init(void)
		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
#endif

	if (!efi_enabled(EFI_MEMMAP))
	early_init_fdt_scan_reserved_mem();

	/* 4GB maximum for 32-bit only capable devices */
+11 −7
Original line number Diff line number Diff line
@@ -1032,7 +1032,6 @@ struct boot_params *make_boot_params(struct efi_config *c)
	int i;
	unsigned long ramdisk_addr;
	unsigned long ramdisk_size;
	unsigned long initrd_addr_max;

	efi_early = c;
	sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
@@ -1095,15 +1094,20 @@ struct boot_params *make_boot_params(struct efi_config *c)

	memset(sdt, 0, sizeof(*sdt));

	if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G)
		initrd_addr_max = -1UL;
	else
		initrd_addr_max = hdr->initrd_addr_max;
	status = handle_cmdline_files(sys_table, image,
				      (char *)(unsigned long)hdr->cmd_line_ptr,
				      "initrd=", hdr->initrd_addr_max,
				      &ramdisk_addr, &ramdisk_size);

	if (status != EFI_SUCCESS &&
	    hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) {
		efi_printk(sys_table, "Trying to load files to higher address\n");
		status = handle_cmdline_files(sys_table, image,
				      (char *)(unsigned long)hdr->cmd_line_ptr,
				      "initrd=", initrd_addr_max,
				      "initrd=", -1UL,
				      &ramdisk_addr, &ramdisk_size);
	}

	if (status != EFI_SUCCESS)
		goto fail2;
	hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
+40 −14
Original line number Diff line number Diff line
@@ -30,6 +30,33 @@
#include <asm/boot.h>
#include <asm/asm-offsets.h>

/*
 * Adjust our own GOT
 *
 * The relocation base must be in %ebx
 *
 * It is safe to call this macro more than once, because in some of the
 * code paths multiple invocations are inevitable, e.g. via the efi*
 * entry points.
 *
 * Relocation is only performed the first time.
 */
.macro FIXUP_GOT
	cmpb	$1, got_fixed(%ebx)
	je	2f

	leal	_got(%ebx), %edx
	leal	_egot(%ebx), %ecx
1:
	cmpl	%ecx, %edx
	jae	2f
	addl	%ebx, (%edx)
	addl	$4, %edx
	jmp	1b
2:
	movb	$1, got_fixed(%ebx)
.endm

	__HEAD
ENTRY(startup_32)
#ifdef CONFIG_EFI_STUB
@@ -56,6 +83,9 @@ ENTRY(efi_pe_entry)
	add	%esi, 88(%eax)
	pushl	%eax

	movl	%esi, %ebx
	FIXUP_GOT

	call	make_boot_params
	cmpl	$0, %eax
	je	fail
@@ -81,6 +111,10 @@ ENTRY(efi32_stub_entry)
	leal	efi32_config(%esi), %eax
	add	%esi, 88(%eax)
	pushl	%eax

	movl	%esi, %ebx
	FIXUP_GOT

2:
	call	efi_main
	cmpl	$0, %eax
@@ -190,19 +224,7 @@ relocated:
	shrl	$2, %ecx
	rep	stosl

/*
 * Adjust our own GOT
 */
	leal	_got(%ebx), %edx
	leal	_egot(%ebx), %ecx
1:
	cmpl	%ecx, %edx
	jae	2f
	addl	%ebx, (%edx)
	addl	$4, %edx
	jmp	1b
2:

	FIXUP_GOT
/*
 * Do the decompression, and jump to the new kernel..
 */
@@ -225,8 +247,12 @@ relocated:
	xorl	%ebx, %ebx
	jmp	*%eax

#ifdef CONFIG_EFI_STUB
	.data
/* Have we relocated the GOT? */
got_fixed:
	.byte 0

#ifdef CONFIG_EFI_STUB
efi32_config:
	.fill 11,8,0
	.long efi_call_phys
+41 −15
Original line number Diff line number Diff line
@@ -32,6 +32,33 @@
#include <asm/processor-flags.h>
#include <asm/asm-offsets.h>

/*
 * Adjust our own GOT
 *
 * The relocation base must be in %rbx
 *
 * It is safe to call this macro more than once, because in some of the
 * code paths multiple invocations are inevitable, e.g. via the efi*
 * entry points.
 *
 * Relocation is only performed the first time.
 */
.macro FIXUP_GOT
	cmpb	$1, got_fixed(%rip)
	je	2f

	leaq	_got(%rip), %rdx
	leaq	_egot(%rip), %rcx
1:
	cmpq	%rcx, %rdx
	jae	2f
	addq	%rbx, (%rdx)
	addq	$8, %rdx
	jmp	1b
2:
	movb	$1, got_fixed(%rip)
.endm

	__HEAD
	.code32
ENTRY(startup_32)
@@ -252,10 +279,13 @@ ENTRY(efi_pe_entry)
	subq	$1b, %rbp

	/*
	 * Relocate efi_config->call().
	 * Relocate efi_config->call() and the GOT entries.
	 */
	addq	%rbp, efi64_config+88(%rip)

	movq	%rbp, %rbx
	FIXUP_GOT

	movq	%rax, %rdi
	call	make_boot_params
	cmpq	$0,%rax
@@ -271,10 +301,13 @@ handover_entry:
	subq	$1b, %rbp

	/*
	 * Relocate efi_config->call().
	 * Relocate efi_config->call() and the GOT entries.
	 */
	movq	efi_config(%rip), %rax
	addq	%rbp, 88(%rax)

	movq	%rbp, %rbx
	FIXUP_GOT
2:
	movq	efi_config(%rip), %rdi
	call	efi_main
@@ -385,18 +418,7 @@ relocated:
	shrq	$3, %rcx
	rep	stosq

/*
 * Adjust our own GOT
 */
	leaq	_got(%rip), %rdx
	leaq	_egot(%rip), %rcx
1:
	cmpq	%rcx, %rdx
	jae	2f
	addq	%rbx, (%rdx)
	addq	$8, %rdx
	jmp	1b
2:
	FIXUP_GOT

/*
 * Do the decompression, and jump to the new kernel..
@@ -437,6 +459,10 @@ gdt:
	.quad   0x0000000000000000	/* TS continued */
gdt_end:

/* Have we relocated the GOT? */
got_fixed:
	.byte	0

#ifdef CONFIG_EFI_STUB
efi_config:
	.quad	0
+9 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
			unsigned long map_size, unsigned long desc_size,
			u32 desc_ver)
{
	int node, prev;
	int node, prev, num_rsv;
	int status;
	u32 fdt_val32;
	u64 fdt_val64;
@@ -73,6 +73,14 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
		prev = node;
	}

	/*
	 * Delete all memory reserve map entries. When booting via UEFI,
	 * kernel will use the UEFI memory map to find reserved regions.
	 */
	num_rsv = fdt_num_mem_rsv(fdt);
	while (num_rsv-- > 0)
		fdt_del_mem_rsv(fdt, num_rsv);

	node = fdt_subnode_offset(fdt, 0, "chosen");
	if (node < 0) {
		node = fdt_add_subnode(fdt, 0, "chosen");