From: Arvind Sankar <nivedita@alum.mit.edu>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: linux-efi@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 0/5] Minimize the need to move the kernel in the EFI stub
Date: Tue, 3 Mar 2020 17:12:00 -0500 [thread overview]
Message-ID: <20200303221205.4048668-1-nivedita@alum.mit.edu> (raw)
In-Reply-To: <20200301230537.2247550-1-nivedita@alum.mit.edu>
This series adds the ability to use the entire PE image space for
decompression, provides the preferred address to the PE loader via the
header, and finally restricts efi_relocate_kernel to cases where we
really need it rather than whenever we were loaded at something other
than preferred address.
Based on tip:efi/core + the cleanup series [1]
[1] https://lore.kernel.org/linux-efi/20200301230436.2246909-1-nivedita@alum.mit.edu/
Changes from v1
- clarify a few comments
- cleanups to code formatting
Arvind Sankar (5):
x86/boot/compressed/32: Save the output address instead of
recalculating it
efi/x86: Decompress at start of PE image load address
efi/x86: Add kernel preferred address to PE header
efi/x86: Remove extra headroom for setup block
efi/x86: Don't relocate the kernel unless necessary
arch/x86/boot/compressed/head_32.S | 42 +++++++++++++++-------
arch/x86/boot/compressed/head_64.S | 42 ++++++++++++++++++++--
arch/x86/boot/header.S | 6 ++--
arch/x86/boot/tools/build.c | 44 ++++++++++++++++-------
drivers/firmware/efi/libstub/x86-stub.c | 48 ++++++++++++++++++++++---
5 files changed, 147 insertions(+), 35 deletions(-)
Range-diff against v1:
1: 0cdb6bf27a24 ! 1: 2ecbf60b9ecd x86/boot/compressed/32: Save the output address instead of recalculating it
@@ Metadata
## Commit message ##
x86/boot/compressed/32: Save the output address instead of recalculating it
- In preparation for being able to decompress starting at a different
- address than startup_32, save the calculated output address instead of
- recalculating it later.
+ In preparation for being able to decompress into a buffer starting at a
+ different address than startup_32, save the calculated output address
+ instead of recalculating it later.
We now keep track of three addresses:
%edx: startup_32 as we were loaded by bootloader
2: d4df840752ac ! 2: e2bdbe6cb692 efi/x86: Decompress at start of PE image load address
@@ arch/x86/boot/compressed/head_64.S: SYM_FUNC_START(efi32_pe_entry)
movl -4(%ebp), %esi // loaded_image
movl LI32_image_base(%esi), %esi // loaded_image->image_base
movl %ebx, %ebp // startup_32 for efi32_pe_stub_entry
++ /*
++ * We need to set the image_offset variable here since startup_32 will
++ * use it before we get to the 64-bit efi_pe_entry in C code.
++ */
+ subl %esi, %ebx
+ movl %ebx, image_offset(%ebp) // save image_offset
jmp efi32_pe_stub_entry
@@ drivers/firmware/efi/libstub/x86-stub.c: unsigned long efi_main(efi_handle_t han
efi_printk("efi_relocate_kernel() failed!\n");
goto fail;
}
++ /*
++ * Now that we've copied the kernel elsewhere, we no longer
++ * have a setup block before startup_32, so reset image_offset
++ * to zero in case it was set earlier.
++ */
+ image_offset = 0;
}
3: 4bae68f25b90 ! 3: ea840f78f138 efi/x86: Add kernel preferred address to PE header
@@ arch/x86/boot/header.S: optional_header:
extra_header_fields:
+ # PE specification requires ImageBase to be 64k-aligned
-+ .set ImageBase, (LOAD_PHYSICAL_ADDR+0xffff) & ~0xffff
++ .set image_base, (LOAD_PHYSICAL_ADDR + 0xffff) & ~0xffff
#ifdef CONFIG_X86_32
- .long 0 # ImageBase
-+ .long ImageBase # ImageBase
++ .long image_base # ImageBase
#else
- .quad 0 # ImageBase
-+ .quad ImageBase # ImageBase
++ .quad image_base # ImageBase
#endif
.long 0x20 # SectionAlignment
.long 0x20 # FileAlignment
4: 2330a25c6b0f ! 4: c25a9b507d6d efi/x86: Remove extra headroom for setup block
@@ Commit message
account for setup block") added headroom to the PE image to account for
the setup block, which wasn't used for the decompression buffer.
- Now that we decompress from the start of the image, this is no longer
- required.
+ Now that the decompression buffer is located at the start of the image,
+ and includes the setup block, this is no longer required.
Add a check to make sure that the head section of the compressed kernel
won't overwrite itself while relocating. This is only for
5: 2081f91cbe75 ! 5: d3dc3af1c7b8 efi/x86: Don't relocate the kernel unless necessary
@@ arch/x86/boot/tools/build.c: static void update_pecoff_text(unsigned int text_st
* Size of code: Subtract the size of the first sector (512 bytes)
## drivers/firmware/efi/libstub/x86-stub.c ##
+@@
+
+ #include "efistub.h"
+
++/* Maximum physical address for 64-bit kernel with 4-level paging */
++#define MAXMEM_X86_64_4LEVEL (1ull << 46)
++
+ static efi_system_table_t *sys_table;
+ extern const bool efi_is64;
+ extern u32 image_offset;
@@ drivers/firmware/efi/libstub/x86-stub.c: unsigned long efi_main(efi_handle_t handle,
struct boot_params *boot_params)
{
@@ drivers/firmware/efi/libstub/x86-stub.c: unsigned long efi_main(efi_handle_t han
- * address, relocate it.
+ * If the kernel isn't already loaded at a suitable address,
+ * relocate it.
++ *
+ * It must be loaded above LOAD_PHYSICAL_ADDR.
-+ * The maximum address for 64-bit is 1 << 46 for 4-level paging.
++ *
++ * The maximum address for 64-bit is 1 << 46 for 4-level paging. This
++ * is defined as the macro MAXMEM, but unfortunately that is not a
++ * compile-time constant if 5-level paging is configured, so we instead
++ * define our own macro for use here.
++ *
+ * For 32-bit, the maximum address is complicated to figure out, for
+ * now use KERNEL_IMAGE_SIZE, which will be 512MiB, the same as what
+ * KASLR uses.
++ *
+ * Also relocate it if image_offset is zero, i.e. we weren't loaded by
+ * LoadImage, but we are not aligned correctly.
*/
- if (bzimage_addr - image_offset != hdr->pref_address) {
++
+ buffer_start = ALIGN(bzimage_addr - image_offset,
+ hdr->kernel_alignment);
+ buffer_end = buffer_start + hdr->init_size;
+
-+ if (buffer_start < LOAD_PHYSICAL_ADDR
-+ || IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE
-+ || IS_ENABLED(CONFIG_X86_64) && buffer_end > 1ull << 46
-+ || image_offset == 0 && !IS_ALIGNED(bzimage_addr,
-+ hdr->kernel_alignment)) {
++ if ((buffer_start < LOAD_PHYSICAL_ADDR) ||
++ (IS_ENABLED(CONFIG_X86_32) && buffer_end > KERNEL_IMAGE_SIZE) ||
++ (IS_ENABLED(CONFIG_X86_64) && buffer_end > MAXMEM_X86_64_4LEVEL) ||
++ (image_offset == 0 && !IS_ALIGNED(bzimage_addr,
++ hdr->kernel_alignment))) {
status = efi_relocate_kernel(&bzimage_addr,
hdr->init_size, hdr->init_size,
hdr->pref_address,
--
2.24.1
next prev parent reply other threads:[~2020-03-03 22:12 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-01 23:05 [PATCH 0/5] Minimize the need to move the kernel in the EFI stub Arvind Sankar
2020-03-01 23:05 ` [PATCH 1/5] x86/boot/compressed/32: Save the output address instead of recalculating it Arvind Sankar
2020-03-03 19:10 ` Ard Biesheuvel
2020-03-01 23:05 ` [PATCH 2/5] efi/x86: Decompress at start of PE image load address Arvind Sankar
2020-03-03 6:28 ` Mika Penttilä
2020-03-03 13:45 ` Arvind Sankar
2020-03-03 19:08 ` Ard Biesheuvel
2020-03-01 23:05 ` [PATCH 3/5] efi/x86: Add kernel preferred address to PE header Arvind Sankar
2020-03-03 19:11 ` Ard Biesheuvel
2020-03-01 23:05 ` [PATCH 4/5] efi/x86: Remove extra headroom for setup block Arvind Sankar
2020-03-02 4:21 ` Mika Penttilä
2020-03-03 4:14 ` Arvind Sankar
2020-03-01 23:05 ` [PATCH 5/5] efi/x86: Don't relocate the kernel unless necessary Arvind Sankar
2020-03-03 19:15 ` Ard Biesheuvel
2020-03-03 22:12 ` Arvind Sankar [this message]
2020-03-03 22:12 ` [PATCH v2 1/5] x86/boot/compressed/32: Save the output address instead of recalculating it Arvind Sankar
2020-03-03 22:12 ` [PATCH v2 2/5] efi/x86: Decompress at start of PE image load address Arvind Sankar
2020-03-03 22:12 ` [PATCH v2 3/5] efi/x86: Add kernel preferred address to PE header Arvind Sankar
2020-03-03 22:12 ` [PATCH v2 4/5] efi/x86: Remove extra headroom for setup block Arvind Sankar
2020-05-11 17:01 ` Mike Lothian
2020-05-11 18:36 ` Arvind Sankar
2020-05-11 21:13 ` Ard Biesheuvel
2020-05-11 22:53 ` Arvind Sankar
2020-05-11 22:58 ` [PATCH] x86/boot: Mark global variables as static Arvind Sankar
2020-05-11 23:12 ` Mike Lothian
2020-05-12 11:05 ` Ard Biesheuvel
2020-03-03 22:12 ` [PATCH v2 5/5] efi/x86: Don't relocate the kernel unless necessary Arvind Sankar
2020-03-03 23:08 ` Ard Biesheuvel
2020-03-03 23:34 ` Arvind Sankar
2020-03-04 7:30 ` Ard Biesheuvel
2020-03-03 22:26 ` [PATCH v2 0/5] Minimize the need to move the kernel in the EFI stub Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200303221205.4048668-1-nivedita@alum.mit.edu \
--to=nivedita@alum.mit.edu \
--cc=ardb@kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).