Skip to content

Commit

Permalink
Merge branch 'efi-core-for-linus' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/tip/tip

Pull EFI updates from Ingo Molnar:
 "The EFI changes in this cycle are much larger than usual, for two
  (positive) reasons:

   - The GRUB project is showing signs of life again, resulting in the
     introduction of the generic Linux/UEFI boot protocol, instead of
     x86 specific hacks which are increasingly difficult to maintain.
     There's hope that all future extensions will now go through that
     boot protocol.

   - Preparatory work for RISC-V EFI support.

  The main changes are:

   - Boot time GDT handling changes

   - 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.

   - Partial fix for the lack of by-VA cache maintenance in the
     decompressor on 32-bit ARM.

   - Changes to load device firmware from EFI boot service memory
     regions

   - Various documentation updates and minor code cleanups and fixes"

* 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (114 commits)
  efi/libstub/arm: Fix spurious message that an initrd was loaded
  efi/libstub/arm64: Avoid image_base value from efi_loaded_image
  partitions/efi: Fix partition name parsing in GUID partition entry
  efi/x86: Fix cast of image argument
  efi/libstub/x86: Use ULONG_MAX as upper bound for all allocations
  efi: Fix a mistype in comments mentioning efivar_entry_iter_begin()
  efi/libstub: Avoid linking libstub/lib-ksyms.o into vmlinux
  efi/x86: Preserve %ebx correctly in efi_set_virtual_address_map()
  efi/x86: Ignore the memory attributes table on i386
  efi/x86: Don't relocate the kernel unless necessary
  efi/x86: Remove extra headroom for setup block
  efi/x86: Add kernel preferred address to PE header
  efi/x86: Decompress at start of PE image load address
  x86/boot/compressed/32: Save the output address instead of recalculating it
  efi/libstub/x86: Deal with exit() boot service returning
  x86/boot: Use unsigned comparison for addresses
  efi/x86: Avoid using code32_start
  efi/x86: Make efi32_pe_entry() more readable
  efi/x86: Respect 32-bit ABI in efi32_pe_entry()
  efi/x86: Annotate the LOADED_IMAGE_PROTOCOL_GUID with SYM_DATA
  ...
  • Loading branch information
torvalds committed Mar 30, 2020
2 parents 7c4fa15 + 594e576 commit a776c27
Show file tree
Hide file tree
Showing 73 changed files with 2,933 additions and 2,685 deletions.
11 changes: 11 additions & 0 deletions Documentation/driver-api/firmware/efi/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.. SPDX-License-Identifier: GPL-2.0
============
UEFI Support
============

UEFI stub library functions
===========================

.. kernel-doc:: drivers/firmware/efi/libstub/mem.c
:internal:
1 change: 1 addition & 0 deletions Documentation/driver-api/firmware/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Linux Firmware API

introduction
core
efi/index
request_firmware
other_interfaces

Expand Down
8 changes: 2 additions & 6 deletions Documentation/x86/boot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 0 additions & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -6363,7 +6363,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
S: Maintained
F: Documentation/admin-guide/efi-stub.rst
F: arch/*/kernel/efi.c
F: arch/x86/boot/compressed/eboot.[ch]
F: arch/*/include/asm/efi.h
F: arch/x86/platform/efi/
F: drivers/firmware/efi/
Expand Down
6 changes: 3 additions & 3 deletions arch/arm/boot/compressed/efi-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down
58 changes: 23 additions & 35 deletions arch/arm/boot/compressed/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -1437,29 +1437,25 @@ __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 unless
@ we explicitly clean it to the PoC.
adr r0, call_cache_fn @ region of code we will
adr r1, 0f @ run with MMU off
bl cache_clean_flush
bl cache_off

Expand All @@ -1469,18 +1465,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)
add r7, r7, #(__efi_start - start)
mov pc, r7 @ no mode switch
ENDPROC(efi_enter_kernel)
0:
#endif

.align
Expand Down
10 changes: 0 additions & 10 deletions arch/arm64/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
{
}
Expand Down
90 changes: 19 additions & 71 deletions arch/arm64/kernel/efi-entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

SYM_CODE_START(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
ldr w2, =stext_offset
add x19, x0, x2 // relocated Image entrypoint
mov x20, x1 // DTB address

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

/*
* 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.
* Clean the remainder of this routine 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

adr x0, 0f
ldr w1, 3f
bl __clean_dcache_area_poc
0:
/* Turn off Dcache and MMU */
mrs x0, CurrentEL
cmp x0, #CurrentEL_EL2
Expand All @@ -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)
br x19
SYM_CODE_END(efi_enter_kernel)
3: .long . - 0b
6 changes: 3 additions & 3 deletions arch/arm64/kernel/efi-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ optional_header:
.long __initdata_begin - efi_header_end // SizeOfCode
.long __pecoff_data_size // SizeOfInitializedData
.long 0 // SizeOfUninitializedData
.long __efistub_entry - _head // AddressOfEntryPoint
.long __efistub_efi_entry - _head // AddressOfEntryPoint
.long efi_header_end - _head // BaseOfCode

extra_header_fields:
Expand All @@ -36,8 +36,8 @@ extra_header_fields:
.long PECOFF_FILE_ALIGNMENT // FileAlignment
.short 0 // MajorOperatingSystemVersion
.short 0 // MinorOperatingSystemVersion
.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
Expand Down
7 changes: 5 additions & 2 deletions arch/arm64/kernel/image-vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

#ifdef CONFIG_EFI

__efistub_stext_offset = stext - _text;
__efistub_kernel_size = _edata - _text;
__efistub_stext_offset = stext - _text;


/*
* The EFI stub has its own symbol namespace prefixed by __efistub_, to
Expand All @@ -33,7 +35,7 @@ __efistub_strnlen = __pi_strnlen;
__efistub_strcmp = __pi_strcmp;
__efistub_strncmp = __pi_strncmp;
__efistub_strrchr = __pi_strrchr;
__efistub___flush_dcache_area = __pi___flush_dcache_area;
__efistub___clean_dcache_area_poc = __pi___clean_dcache_area_poc;

#ifdef CONFIG_KASAN
__efistub___memcpy = __pi_memcpy;
Expand All @@ -45,6 +47,7 @@ __efistub__text = _text;
__efistub__end = _end;
__efistub__edata = _edata;
__efistub_screen_info = screen_info;
__efistub__ctype = _ctype;

#endif

Expand Down
Loading

0 comments on commit a776c27

Please sign in to comment.