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

Commit 3151b942 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 EFI boot regression introduced during the merge window where the
   firmware was reading random values from the stack because we were
   passing a pointer to the wrong object type.

 * Kernel corruption has been reported when booting with the EFI boot
   stub which was tracked down to setting a bogus value for
   bp->hdr.code32_start, resulting in corruption during relocation.

 * Olivier Martin reported that the wrong file handles were being passed
   to efi_file_(read|close), which works for x86 by luck due to the way
   that the FAT driver is implemented, but doesn't work on ARM."

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents f704a7d7 47514c99
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
	efi_file_info_t *info;
	efi_status_t status;
	efi_guid_t info_guid = EFI_FILE_INFO_ID;
	u32 info_sz;
	u64 info_sz;

	status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
				 EFI_FILE_MODE_READ, (u64)0);
@@ -167,31 +167,31 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh,
}

static inline efi_status_t
efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr)
efi_file_read(void *handle, unsigned long *size, void *addr)
{
	unsigned long func;

	if (efi_early->is64) {
		efi_file_handle_64_t *fh = __fh;
		efi_file_handle_64_t *fh = handle;

		func = (unsigned long)fh->read;
		return efi_early->call(func, handle, size, addr);
	} else {
		efi_file_handle_32_t *fh = __fh;
		efi_file_handle_32_t *fh = handle;

		func = (unsigned long)fh->read;
		return efi_early->call(func, handle, size, addr);
	}
}

static inline efi_status_t efi_file_close(void *__fh, void *handle)
static inline efi_status_t efi_file_close(void *handle)
{
	if (efi_early->is64) {
		efi_file_handle_64_t *fh = __fh;
		efi_file_handle_64_t *fh = handle;

		return efi_early->call((unsigned long)fh->close, handle);
	} else {
		efi_file_handle_32_t *fh = __fh;
		efi_file_handle_32_t *fh = handle;

		return efi_early->call((unsigned long)fh->close, handle);
	}
@@ -1016,6 +1016,9 @@ void setup_graphics(struct boot_params *boot_params)
 * Because the x86 boot code expects to be passed a boot_params we
 * need to create one ourselves (usually the bootloader would create
 * one for us).
 *
 * The caller is responsible for filling out ->code32_start in the
 * returned boot_params.
 */
struct boot_params *make_boot_params(struct efi_config *c)
{
@@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c)
	hdr->vid_mode = 0xffff;
	hdr->boot_flag = 0xAA55;

	hdr->code32_start = (__u64)(unsigned long)image->image_base;

	hdr->type_of_loader = 0x21;

	/* Convert unicode cmdline to ascii */
+2 −6
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ ENTRY(efi_pe_entry)
	call	make_boot_params
	cmpl	$0, %eax
	je	fail
	movl	%esi, BP_code32_start(%eax)
	popl	%ecx
	pushl	%eax
	pushl	%ecx
@@ -90,12 +91,7 @@ fail:
	hlt
	jmp	fail
2:
	call	3f
3:
	popl	%eax
	subl	$3b, %eax
	subl	BP_pref_address(%esi), %eax
	add	BP_code32_start(%esi), %eax
	movl	BP_code32_start(%esi), %eax
	leal	preferred_addr(%eax), %eax
	jmp	*%eax

+3 −6
Original line number Diff line number Diff line
@@ -261,6 +261,8 @@ ENTRY(efi_pe_entry)
	cmpq	$0,%rax
	je	fail
	mov	%rax, %rsi
	leaq	startup_32(%rip), %rax
	movl	%eax, BP_code32_start(%rsi)
	jmp	2f		/* Skip the relocation */

handover_entry:
@@ -284,12 +286,7 @@ fail:
	hlt
	jmp	fail
2:
	call	3f
3:
	popq	%rax
	subq	$3b, %rax
	subq	BP_pref_address(%rsi), %rax
	add	BP_code32_start(%esi), %eax
	movl	BP_code32_start(%esi), %eax
	leaq	preferred_addr(%rax), %rax
	jmp	*%rax

+3 −3
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
				else
					chunksize = size;

				status = efi_file_read(fh, files[j].handle,
				status = efi_file_read(files[j].handle,
						       &chunksize,
						       (void *)addr);
				if (status != EFI_SUCCESS) {
@@ -408,7 +408,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
				size -= chunksize;
			}

			efi_file_close(fh, files[j].handle);
			efi_file_close(files[j].handle);
		}

	}
@@ -425,7 +425,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,

close_handles:
	for (k = j; k < i; k++)
		efi_file_close(fh, files[k].handle);
		efi_file_close(files[k].handle);
free_files:
	efi_call_early(free_pool, files);
fail: