Commit e9765680 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into efi/core



Pull EFI updates for v5.7 from Ard Biesheuvel:

This time, the set of changes for the EFI subsystem is much larger than
usual. The main reasons are:

 - Get things cleaned up before EFI support for RISC-V arrives, which will
   increase the size of the validation matrix, and therefore the threshold to
   making drastic changes,

 - After years of defunct maintainership, the GRUB project has finally started
   to consider changes from the distros regarding UEFI boot, some of which are
   highly specific to the way x86 does UEFI secure boot and measured boot,
   based on knowledge of both shim internals and the layout of bootparams and
   the x86 setup header. Having this maintenance burden on other architectures
   (which don't need shim in the first place) is hard to justify, so instead,
   we are introducing a generic Linux/UEFI boot protocol.

Summary of changes:

 - Boot time GDT handling changes (Arvind)

 - Simplify handling of EFI properties table on arm64

 - Generic EFI stub cleanups, to improve command line handling, file I/O,
   memory allocation, etc.

 - Introduce a generic initrd loading method based on calling back into
   the firmware, instead of relying on the x86 EFI handover protocol or
   device tree.

 - Introduce a mixed mode boot method that does not rely on the x86 EFI
   handover protocol either, and could potentially be adopted by other
   architectures (if another one ever surfaces where one execution mode
   is a superset of another)

 - Clean up the contents of struct efi, and move out everything that
   doesn't need to be stored there.

 - Incorporate support for UEFI spec v2.8A changes that permit firmware
   implementations to return EFI_UNSUPPORTED from UEFI runtime services at
   OS runtime, and expose a mask of which ones are supported or unsupported
   via a configuration table.

 - Various documentation updates and minor code cleanups (Heinrich)

 - Partial fix for the lack of by-VA cache maintenance in the decompressor
   on 32-bit ARM. Note that these patches were deliberately put at the
   beginning so they can be used as a stable branch that will be shared with
   a PR containing the complete fix, which I will send to the ARM tree.

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents c5f86891 dc235d62
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -490,15 +490,11 @@ Protocol: 2.00+
		kernel) to not write early messages that require
		accessing the display hardware directly.

  Bit 6 (write): KEEP_SEGMENTS
  Bit 6 (obsolete): KEEP_SEGMENTS

	Protocol: 2.07+

	- If 0, reload the segment registers in the 32bit entry point.
	- If 1, do not reload the segment registers in the 32bit entry point.

		Assume that %cs %ds %ss %es are all set to flat segments with
		a base of 0 (or the equivalent for their environment).
        - This flag is obsolete.

  Bit 7 (write): CAN_USE_HEAP

+3 −3
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ optional_header:
		.long	__pecoff_code_size		@ SizeOfCode
		.long	__pecoff_data_size		@ SizeOfInitializedData
		.long	0				@ SizeOfUninitializedData
		.long	efi_stub_entry - start		@ AddressOfEntryPoint
		.long	efi_entry - start		@ AddressOfEntryPoint
		.long	start_offset			@ BaseOfCode
		.long	__pecoff_data_start - start	@ BaseOfData

@@ -70,8 +70,8 @@ extra_header_fields:
		.long	SZ_512				@ FileAlignment
		.short	0				@ MajorOsVersion
		.short	0				@ MinorOsVersion
		.short	0				@ MajorImageVersion
		.short	0				@ MinorImageVersion
		.short	LINUX_EFISTUB_MAJOR_VERSION	@ MajorImageVersion
		.short	LINUX_EFISTUB_MINOR_VERSION	@ MinorImageVersion
		.short	0				@ MajorSubsystemVersion
		.short	0				@ MinorSubsystemVersion
		.long	0				@ Win32VersionValue
+25 −35
Original line number Diff line number Diff line
@@ -1437,30 +1437,28 @@ __enter_kernel:
reloc_code_end:

#ifdef CONFIG_EFI_STUB
		.align	2
_start:		.long	start - .

ENTRY(efi_stub_entry)
		@ allocate space on stack for passing current zImage address
		@ and for the EFI stub to return of new entry point of
		@ zImage, as EFI stub may copy the kernel. Pointer address
		@ is passed in r2. r0 and r1 are passed through from the
		@ EFI firmware to efi_entry
		adr	ip, _start
		ldr	r3, [ip]
		add	r3, r3, ip
		stmfd	sp!, {r3, lr}
		mov	r2, sp			@ pass zImage address in r2
		bl	efi_entry

		@ Check for error return from EFI stub. r0 has FDT address
		@ or error code.
		cmn	r0, #1
		beq	efi_load_fail

		@ Preserve return value of efi_entry() in r4
		mov	r4, r0
ENTRY(efi_enter_kernel)
		mov	r7, r0				@ preserve image base
		mov	r4, r1				@ preserve DT pointer

		mov	r0, r4				@ DT start
		add	r1, r4, r2			@ DT end
		bl	cache_clean_flush

		mov	r0, r7				@ relocated zImage
		ldr	r1, =_edata			@ size of zImage
		add	r1, r1, r0			@ end of zImage
		bl	cache_clean_flush

		@ The PE/COFF loader might not have cleaned the code we are
		@ running beyond the PoU, and so calling cache_off below from
		@ inside the PE/COFF loader allocated region is unsafe. Let's
		@ assume our own zImage relocation code did a better job, and
		@ jump into its version of this routine before proceeding.
		ldr	r1, .Ljmp
		sub	r1, r7, r1
		mov	pc, r1				@ no mode switch
0:
		bl	cache_off

		@ Set parameters for booting zImage according to boot protocol
@@ -1469,18 +1467,10 @@ ENTRY(efi_stub_entry)
		mov	r0, #0
		mov	r1, #0xFFFFFFFF
		mov	r2, r4

		@ Branch to (possibly) relocated zImage that is in [sp]
		ldr	lr, [sp]
		ldr	ip, =start_offset
		add	lr, lr, ip
		mov	pc, lr				@ no mode switch

efi_load_fail:
		@ Return EFI_LOAD_ERROR to EFI firmware on error.
		ldr	r0, =0x80000001
		ldmfd	sp!, {ip, pc}
ENDPROC(efi_stub_entry)
		b	__efi_start
ENDPROC(efi_enter_kernel)
		.align	2
.Ljmp:		.long	start - 0b
#endif

		.align
+0 −10
Original line number Diff line number Diff line
@@ -57,13 +57,6 @@ efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);

/* arch specific definitions used by the stub code */

/*
 * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from
 * start of kernel and may not cross a 2MiB boundary. We set alignment to
 * 2MiB so we know it won't cross a 2MiB boundary.
 */
#define EFI_FDT_ALIGN	SZ_2M   /* used by allocate_new_fdt_and_exit_boot() */

/*
 * In some configurations (e.g. VMAP_STACK && 64K pages), stacks built into the
 * kernel need greater alignment than we require the segments to be padded to.
@@ -107,9 +100,6 @@ static inline void free_screen_info(struct screen_info *si)
{
}

/* redeclare as 'hidden' so the compiler will generate relative references */
extern struct screen_info screen_info __attribute__((__visibility__("hidden")));

static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt)
{
}
+17 −69
Original line number Diff line number Diff line
@@ -10,81 +10,35 @@

#include <asm/assembler.h>

#define EFI_LOAD_ERROR 0x8000000000000001

	__INIT

	/*
	 * We arrive here from the EFI boot manager with:
	 *
	 *    * CPU in little-endian mode
	 *    * MMU on with identity-mapped RAM
	 *    * Icache and Dcache on
	 *
	 * We will most likely be running from some place other than where
	 * we want to be. The kernel image wants to be placed at TEXT_OFFSET
	 * from start of RAM.
	 */
ENTRY(entry)
	/*
	 * Create a stack frame to save FP/LR with extra space
	 * for image_addr variable passed to efi_entry().
	 */
	stp	x29, x30, [sp, #-32]!
	mov	x29, sp

	/*
	 * Call efi_entry to do the real work.
	 * x0 and x1 are already set up by firmware. Current runtime
	 * address of image is calculated and passed via *image_addr.
	 *
	 * unsigned long efi_entry(void *handle,
	 *                         efi_system_table_t *sys_table,
	 *                         unsigned long *image_addr) ;
	 */
	adr_l	x8, _text
	add	x2, sp, 16
	str	x8, [x2]
	bl	efi_entry
	cmn	x0, #1
	b.eq	efi_load_fail

ENTRY(efi_enter_kernel)
	/*
	 * efi_entry() will have copied the kernel image if necessary and we
	 * return here with device tree address in x0 and the kernel entry
	 * point stored at *image_addr. Save those values in registers which
	 * are callee preserved.
	 */
	mov	x20, x0		// DTB address
	ldr	x0, [sp, #16]	// relocated _text address
	ldr	w21, =stext_offset
	add	x21, x0, x21

	/*
	 * Calculate size of the kernel Image (same for original and copy).
	 * end up here with device tree address in x1 and the kernel entry
	 * point stored in x0. Save those values in registers which are
	 * callee preserved.
	 */
	adr_l	x1, _text
	adr_l	x2, _edata
	sub	x1, x2, x1
	mov	x19, x0			// relocated Image address
	mov	x20, x1			// DTB address

	/*
	 * Flush the copied Image to the PoC, and ensure it is not shadowed by
	 * stale icache entries from before relocation.
	 */
	ldr	w1, =kernel_size
	bl	__flush_dcache_area
	ic	ialluis
	dsb	sy

	/*
	 * Ensure that the rest of this function (in the original Image) is
	 * visible when the caches are disabled. The I-cache can't have stale
	 * entries for the VA range of the current image, so no maintenance is
	 * necessary.
	 * Jump across, into the copy of the image that we just cleaned
	 * to the PoC, so that we can safely disable the MMU and caches.
	 */
	adr	x0, entry
	adr	x1, entry_end
	sub	x1, x1, x0
	bl	__flush_dcache_area

	ldr	w0, .Ljmp
	sub	x0, x19, w0, sxtw
	br	x0
0:
	/* Turn off Dcache and MMU */
	mrs	x0, CurrentEL
	cmp	x0, #CurrentEL_EL2
@@ -109,12 +63,6 @@ ENTRY(entry)
	mov	x1, xzr
	mov	x2, xzr
	mov	x3, xzr
	br	x21

efi_load_fail:
	mov	x0, #EFI_LOAD_ERROR
	ldp	x29, x30, [sp], #32
	ret

entry_end:
ENDPROC(entry)
	b	stext
ENDPROC(efi_enter_kernel)
.Ljmp:	.long	_text - 0b
Loading