* 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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJUDqq/AAoJEC84WcCNIz1VgzEP/1Ax+XnXQjIRMGcR7gHolcan
 lzBzDL3afEp28LcWevmDZ9Bp4VRFjCRecg1gdI64HJhn+b7Ay1iPX/hUaIqfgPfb
 ptY8uAomNAwDyxC7z0S13GNiZZxPKB6eHnoV8t2Hi3uM8oUnkca/WTXHOyXs+gJG
 4fQZtXWn/T8j7vAXuHGSbdH1pF4HYf2vX9i0c7iWVIcKyl+Oe5xGMcql4BqPJnAz
 6hN9etyRMWF37CHZjD1pH0YHhRMJ6uuqUFvUQZt2q+OPUzgYVPv1Es6984r5q2CI
 HHQK2RSfHifYhNuLHuQo+8hOzz41pTriUrrDLDYk9SXDaJM4nHF6n2AXvra320P3
 Xa0TR87+DxOdCM+1s1LeLl/9wMrwz1tgx8m9St16yISnRcGkkJrWYeV9z4PXYsi5
 Qe1uGFS4eVWMAGVuaQgOP/olLAOxr1Vxwrnci+mg4Zh5LgohDZ4FBqbDdMeP3GIF
 vuI+yNnH9jxqmKZXD7wKtxVmS5s3vB3bH0+H8fFCMdBfUWqcM2CA0QJjSCsYGgkB
 mv5jaccRBk8WlI4KrDDuJ2BzM5prg59XTsO0m8oaloCk8b2OEvOte3XsF1DAkYh+
 DnMbESfyDJxc6OFzq6pzAFeY5JUbSgWe0AwnyDJ3Woo9qCCpSkQHImllohRuXVgO
 BruJYYr5r55mjhyDWzJk
 =DjZA
 -----END PGP SIGNATURE-----

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: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2014-09-09 16:56:12 +02:00
commit 5ac385d835
5 changed files with 102 additions and 39 deletions

View File

@ -149,8 +149,7 @@ 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();
early_init_fdt_scan_reserved_mem();
/* 4GB maximum for 32-bit only capable devices */
if (IS_ENABLED(CONFIG_ZONE_DMA))

View File

@ -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=", initrd_addr_max,
"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=", -1UL,
&ramdisk_addr, &ramdisk_size);
}
if (status != EFI_SUCCESS)
goto fail2;
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;

View File

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

View File

@ -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,19 +418,8 @@ 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

View File

@ -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");