arm64/efi: efistub: jump to 'stext' directly, not through the header
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 8 Oct 2014 14:11:27 +0000 (16:11 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 5 Nov 2014 08:02:59 +0000 (09:02 +0100)
After the EFI stub has done its business, it jumps into the kernel by
branching to offset #0 of the loaded Image, which is where it expects
to find the header containing a 'branch to stext' instruction.

However, the UEFI spec 2.1.1 states the following regarding PE/COFF
image loading:
"A UEFI image is loaded into memory through the LoadImage() Boot
Service. This service loads an image with a PE32+ format into memory.
This PE32+ loader is required to load all sections of the PE32+ image
into memory."

In other words, it is /not/ required to load parts of the image that are
not covered by a PE/COFF section, so it may not have loaded the header
at the expected offset, as it is not covered by any PE/COFF section.

So instead, jump to 'stext' directly, which is at the base of the
PE/COFF .text section, by supplying a symbol 'stext_offset' to
efi-entry.o which contains the relative offset of stext into the Image.
Also replace other open coded calculations of the same value with a
reference to 'stext_offset'

Acked-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Roy Franz <roy.franz@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
arch/arm64/kernel/efi-entry.S
arch/arm64/kernel/head.S

index 619b1dd7bcdea70e184daacbfb5dd7797c8460c0..a0016d3a17dafa6070cf669d61fa034c17cad106 100644 (file)
@@ -61,7 +61,8 @@ ENTRY(efi_stub_entry)
         */
        mov     x20, x0         // DTB address
        ldr     x0, [sp, #16]   // relocated _text address
-       mov     x21, x0
+       ldr     x21, =stext_offset
+       add     x21, x0, x21
 
        /*
         * Flush dcache covering current runtime addresses
index 0a6e4f924df87fa2a595b2774ac752f119d4e7e5..8c06c9d269d2290d94837253e8e55ab569da199d 100644 (file)
@@ -132,6 +132,8 @@ efi_head:
 #endif
 
 #ifdef CONFIG_EFI
+       .globl  stext_offset
+       .set    stext_offset, stext - efi_head
        .align 3
 pe_header:
        .ascii  "PE"
@@ -155,7 +157,7 @@ optional_header:
        .long   0                               // SizeOfInitializedData
        .long   0                               // SizeOfUninitializedData
        .long   efi_stub_entry - efi_head       // AddressOfEntryPoint
-       .long   stext - efi_head                // BaseOfCode
+       .long   stext_offset                    // BaseOfCode
 
 extra_header_fields:
        .quad   0                               // ImageBase
@@ -172,7 +174,7 @@ extra_header_fields:
        .long   _end - efi_head                 // SizeOfImage
 
        // Everything before the kernel image is considered part of the header
-       .long   stext - efi_head                // SizeOfHeaders
+       .long   stext_offset                    // SizeOfHeaders
        .long   0                               // CheckSum
        .short  0xa                             // Subsystem (EFI application)
        .short  0                               // DllCharacteristics
@@ -217,9 +219,9 @@ section_table:
        .byte   0
        .byte   0                       // end of 0 padding of section name
        .long   _end - stext            // VirtualSize
-       .long   stext - efi_head        // VirtualAddress
+       .long   stext_offset            // VirtualAddress
        .long   _edata - stext          // SizeOfRawData
-       .long   stext - efi_head        // PointerToRawData
+       .long   stext_offset            // PointerToRawData
 
        .long   0               // PointerToRelocations (0 for executables)
        .long   0               // PointerToLineNumbers (0 for executables)