2019-02-02 10:41:15 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2014-04-15 22:47:52 -04:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org>
|
|
|
|
*
|
|
|
|
* This file implements the EFI boot stub for the arm64 kernel.
|
|
|
|
* Adapted from ARM version by Mark Salter <msalter@redhat.com>
|
|
|
|
*/
|
2017-08-18 20:49:36 +01:00
|
|
|
|
|
|
|
|
2014-04-15 22:47:52 -04:00
|
|
|
#include <linux/efi.h>
|
2014-07-02 14:54:41 +02:00
|
|
|
#include <asm/efi.h>
|
2017-07-14 15:54:36 +01:00
|
|
|
#include <asm/memory.h>
|
2020-02-10 17:02:32 +01:00
|
|
|
#include <asm/sections.h>
|
2014-04-15 22:47:52 -04:00
|
|
|
|
2016-01-26 14:48:29 +01:00
|
|
|
#include "efistub.h"
|
|
|
|
|
2019-12-24 16:10:19 +01:00
|
|
|
efi_status_t handle_kernel_image(unsigned long *image_addr,
|
2016-02-17 12:35:57 +00:00
|
|
|
unsigned long *image_size,
|
|
|
|
unsigned long *reserve_addr,
|
|
|
|
unsigned long *reserve_size,
|
2022-03-19 18:35:53 +01:00
|
|
|
efi_loaded_image_t *image,
|
|
|
|
efi_handle_t image_handle)
|
2014-04-15 22:47:52 -04:00
|
|
|
{
|
2023-01-11 11:22:36 +01:00
|
|
|
unsigned long kernel_size, kernel_codesize, kernel_memsize;
|
2015-10-29 15:07:25 +01:00
|
|
|
|
efi/libstub: Use relocated version of kernel's struct screen_info
In some cases, we expose the kernel's struct screen_info to the EFI stub
directly, so it gets populated before even entering the kernel. This
means the early console is available as soon as the early param parsing
happens, which is nice. It also means we need two different ways to pass
this information, as this trick only works if the EFI stub is baked into
the core kernel image, which is not always the case.
Huacai reports that the preparatory refactoring that was needed to
implement this alternative method for zboot resulted in a non-functional
efifb earlycon for other cases as well, due to the reordering of the
kernel image relocation with the population of the screen_info struct,
and the latter now takes place after copying the image to its new
location, which means we copy the old, uninitialized state.
So let's ensure that the same-image version of alloc_screen_info()
produces the correct screen_info pointer, by taking the displacement of
the loaded image into account.
Reported-by: Huacai Chen <chenhuacai@loongson.cn>
Tested-by: Huacai Chen <chenhuacai@loongson.cn>
Link: https://lore.kernel.org/linux-efi/20230310021749.921041-1-chenhuacai@loongson.cn/
Fixes: 42c8ea3dca094ab8 ("efi: libstub: Factor out EFI stub entrypoint into separate file")
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2023-03-22 01:11:18 +01:00
|
|
|
if (image->image_base != _text) {
|
2020-04-30 14:28:35 -04:00
|
|
|
efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n");
|
efi/libstub: Use relocated version of kernel's struct screen_info
In some cases, we expose the kernel's struct screen_info to the EFI stub
directly, so it gets populated before even entering the kernel. This
means the early console is available as soon as the early param parsing
happens, which is nice. It also means we need two different ways to pass
this information, as this trick only works if the EFI stub is baked into
the core kernel image, which is not always the case.
Huacai reports that the preparatory refactoring that was needed to
implement this alternative method for zboot resulted in a non-functional
efifb earlycon for other cases as well, due to the reordering of the
kernel image relocation with the population of the screen_info struct,
and the latter now takes place after copying the image to its new
location, which means we copy the old, uninitialized state.
So let's ensure that the same-image version of alloc_screen_info()
produces the correct screen_info pointer, by taking the displacement of
the loaded image into account.
Reported-by: Huacai Chen <chenhuacai@loongson.cn>
Tested-by: Huacai Chen <chenhuacai@loongson.cn>
Link: https://lore.kernel.org/linux-efi/20230310021749.921041-1-chenhuacai@loongson.cn/
Fixes: 42c8ea3dca094ab8 ("efi: libstub: Factor out EFI stub entrypoint into separate file")
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2023-03-22 01:11:18 +01:00
|
|
|
image->image_base = _text;
|
|
|
|
}
|
2014-04-15 22:47:52 -04:00
|
|
|
|
2022-01-19 18:14:27 +02:00
|
|
|
if (!IS_ALIGNED((u64)_text, SEGMENT_ALIGN))
|
|
|
|
efi_err("FIRMWARE BUG: kernel image not aligned on %dk boundary\n",
|
|
|
|
SEGMENT_ALIGN >> 10);
|
2021-07-26 16:31:44 +02:00
|
|
|
|
2014-04-15 22:47:52 -04:00
|
|
|
kernel_size = _edata - _text;
|
2023-01-11 11:22:36 +01:00
|
|
|
kernel_codesize = __inittext_end - _text;
|
2016-01-26 14:48:29 +01:00
|
|
|
kernel_memsize = kernel_size + (_end - _edata);
|
2020-08-25 15:54:40 +02:00
|
|
|
*reserve_size = kernel_memsize;
|
2023-07-22 14:38:48 +02:00
|
|
|
*image_addr = (unsigned long)_text;
|
2016-01-26 14:48:29 +01:00
|
|
|
|
2024-07-10 12:22:46 +02:00
|
|
|
return efi_kaslr_relocate_kernel(image_addr, reserve_addr, reserve_size,
|
|
|
|
kernel_size, kernel_codesize, kernel_memsize,
|
|
|
|
efi_kaslr_get_phys_seed(image_handle));
|
2023-01-11 11:22:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
asmlinkage void primary_entry(void);
|
|
|
|
|
|
|
|
unsigned long primary_entry_offset(void)
|
|
|
|
{
|
2022-10-17 16:06:39 +02:00
|
|
|
/*
|
2023-01-11 11:22:36 +01:00
|
|
|
* When built as part of the kernel, the EFI stub cannot branch to the
|
|
|
|
* kernel proper via the image header, as the PE/COFF header is
|
|
|
|
* strictly not part of the in-memory presentation of the image, only
|
|
|
|
* of the file representation. So instead, we need to jump to the
|
|
|
|
* actual entrypoint in the .text region of the image.
|
2022-10-17 16:06:39 +02:00
|
|
|
*/
|
2023-01-11 11:22:36 +01:00
|
|
|
return (char *)primary_entry - _text;
|
2014-04-15 22:47:52 -04:00
|
|
|
}
|
2023-07-22 14:38:48 +02:00
|
|
|
|
|
|
|
void efi_icache_sync(unsigned long start, unsigned long end)
|
|
|
|
{
|
|
|
|
caches_clean_inval_pou(start, end);
|
|
|
|
}
|