2019-02-02 17:41:15 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2015-09-24 11:17:54 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013 Linaro Ltd; <roy.franz@linaro.org>
|
|
|
|
*/
|
|
|
|
#include <linux/efi.h>
|
|
|
|
#include <asm/efi.h>
|
|
|
|
|
2017-04-05 00:09:09 +08:00
|
|
|
#include "efistub.h"
|
|
|
|
|
efi/libstub: arm: Print CPU boot mode and MMU state at boot
On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
(or both), even though the EFI spec does not actually support this.
While booting at HYP mode is something we might tolerate, fiddling
with the caches is a more serious issue, as disabling the caches is
tricky to do safely from C code, and running without the Dcache makes
it impossible to support unaligned memory accesses, which is another
explicit requirement imposed by the EFI spec.
So take note of the CPU mode and MMU state in the EFI stub diagnostic
output so that we can easily diagnose any issues that may arise from
this. E.g.,
EFI stub: Entering in SVC mode with MMU enabled
Also, capture the CPSR and SCTLR system register values at EFI stub
entry, and after ExitBootServices() returns, and check whether the
MMU and Dcache were disabled at any point. If this is the case, a
diagnostic message like the following will be emitted:
efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, please fix your firmware!
efi: CPSR at EFI stub entry : 0x600001d3
efi: SCTLR at EFI stub entry : 0x00c51838
efi: CPSR after ExitBootServices() : 0x600001d3
efi: SCTLR after ExitBootServices(): 0x00c50838
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
2020-06-07 21:41:35 +08:00
|
|
|
static efi_guid_t cpu_state_guid = LINUX_EFI_ARM_CPU_STATE_TABLE_GUID;
|
|
|
|
|
|
|
|
struct efi_arm_entry_state *efi_entry_state;
|
|
|
|
|
|
|
|
static void get_cpu_state(u32 *cpsr, u32 *sctlr)
|
|
|
|
{
|
|
|
|
asm("mrs %0, cpsr" : "=r"(*cpsr));
|
|
|
|
if ((*cpsr & MODE_MASK) == HYP_MODE)
|
|
|
|
asm("mrc p15, 4, %0, c1, c0, 0" : "=r"(*sctlr));
|
|
|
|
else
|
|
|
|
asm("mrc p15, 0, %0, c1, c0, 0" : "=r"(*sctlr));
|
|
|
|
}
|
|
|
|
|
2019-12-24 23:10:19 +08:00
|
|
|
efi_status_t check_platform_features(void)
|
2016-02-17 20:36:01 +08:00
|
|
|
{
|
efi/libstub: arm: Print CPU boot mode and MMU state at boot
On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
(or both), even though the EFI spec does not actually support this.
While booting at HYP mode is something we might tolerate, fiddling
with the caches is a more serious issue, as disabling the caches is
tricky to do safely from C code, and running without the Dcache makes
it impossible to support unaligned memory accesses, which is another
explicit requirement imposed by the EFI spec.
So take note of the CPU mode and MMU state in the EFI stub diagnostic
output so that we can easily diagnose any issues that may arise from
this. E.g.,
EFI stub: Entering in SVC mode with MMU enabled
Also, capture the CPSR and SCTLR system register values at EFI stub
entry, and after ExitBootServices() returns, and check whether the
MMU and Dcache were disabled at any point. If this is the case, a
diagnostic message like the following will be emitted:
efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, please fix your firmware!
efi: CPSR at EFI stub entry : 0x600001d3
efi: SCTLR at EFI stub entry : 0x00c51838
efi: CPSR after ExitBootServices() : 0x600001d3
efi: SCTLR after ExitBootServices(): 0x00c50838
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
2020-06-07 21:41:35 +08:00
|
|
|
efi_status_t status;
|
|
|
|
u32 cpsr, sctlr;
|
2016-02-17 20:36:01 +08:00
|
|
|
int block;
|
|
|
|
|
efi/libstub: arm: Print CPU boot mode and MMU state at boot
On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
(or both), even though the EFI spec does not actually support this.
While booting at HYP mode is something we might tolerate, fiddling
with the caches is a more serious issue, as disabling the caches is
tricky to do safely from C code, and running without the Dcache makes
it impossible to support unaligned memory accesses, which is another
explicit requirement imposed by the EFI spec.
So take note of the CPU mode and MMU state in the EFI stub diagnostic
output so that we can easily diagnose any issues that may arise from
this. E.g.,
EFI stub: Entering in SVC mode with MMU enabled
Also, capture the CPSR and SCTLR system register values at EFI stub
entry, and after ExitBootServices() returns, and check whether the
MMU and Dcache were disabled at any point. If this is the case, a
diagnostic message like the following will be emitted:
efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, please fix your firmware!
efi: CPSR at EFI stub entry : 0x600001d3
efi: SCTLR at EFI stub entry : 0x00c51838
efi: CPSR after ExitBootServices() : 0x600001d3
efi: SCTLR after ExitBootServices(): 0x00c50838
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
2020-06-07 21:41:35 +08:00
|
|
|
get_cpu_state(&cpsr, &sctlr);
|
|
|
|
|
|
|
|
efi_info("Entering in %s mode with MMU %sabled\n",
|
|
|
|
((cpsr & MODE_MASK) == HYP_MODE) ? "HYP" : "SVC",
|
|
|
|
(sctlr & 1) ? "en" : "dis");
|
|
|
|
|
|
|
|
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
|
|
|
|
sizeof(*efi_entry_state),
|
|
|
|
(void **)&efi_entry_state);
|
|
|
|
if (status != EFI_SUCCESS) {
|
|
|
|
efi_err("allocate_pool() failed\n");
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
efi_entry_state->cpsr_before_ebs = cpsr;
|
|
|
|
efi_entry_state->sctlr_before_ebs = sctlr;
|
|
|
|
|
|
|
|
status = efi_bs_call(install_configuration_table, &cpu_state_guid,
|
|
|
|
efi_entry_state);
|
|
|
|
if (status != EFI_SUCCESS) {
|
|
|
|
efi_err("install_configuration_table() failed\n");
|
|
|
|
goto free_state;
|
|
|
|
}
|
|
|
|
|
2016-02-17 20:36:01 +08:00
|
|
|
/* non-LPAE kernels can run anywhere */
|
|
|
|
if (!IS_ENABLED(CONFIG_ARM_LPAE))
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
|
|
|
/* LPAE kernels need compatible hardware */
|
|
|
|
block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
|
|
|
|
if (block < 5) {
|
2020-05-01 02:28:35 +08:00
|
|
|
efi_err("This LPAE kernel is not supported by your CPU\n");
|
efi/libstub: arm: Print CPU boot mode and MMU state at boot
On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
(or both), even though the EFI spec does not actually support this.
While booting at HYP mode is something we might tolerate, fiddling
with the caches is a more serious issue, as disabling the caches is
tricky to do safely from C code, and running without the Dcache makes
it impossible to support unaligned memory accesses, which is another
explicit requirement imposed by the EFI spec.
So take note of the CPU mode and MMU state in the EFI stub diagnostic
output so that we can easily diagnose any issues that may arise from
this. E.g.,
EFI stub: Entering in SVC mode with MMU enabled
Also, capture the CPSR and SCTLR system register values at EFI stub
entry, and after ExitBootServices() returns, and check whether the
MMU and Dcache were disabled at any point. If this is the case, a
diagnostic message like the following will be emitted:
efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, please fix your firmware!
efi: CPSR at EFI stub entry : 0x600001d3
efi: SCTLR at EFI stub entry : 0x00c51838
efi: CPSR after ExitBootServices() : 0x600001d3
efi: SCTLR after ExitBootServices(): 0x00c50838
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
2020-06-07 21:41:35 +08:00
|
|
|
status = EFI_UNSUPPORTED;
|
|
|
|
goto drop_table;
|
2016-02-17 20:36:01 +08:00
|
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
efi/libstub: arm: Print CPU boot mode and MMU state at boot
On 32-bit ARM, we may boot at HYP mode, or with the MMU and caches off
(or both), even though the EFI spec does not actually support this.
While booting at HYP mode is something we might tolerate, fiddling
with the caches is a more serious issue, as disabling the caches is
tricky to do safely from C code, and running without the Dcache makes
it impossible to support unaligned memory accesses, which is another
explicit requirement imposed by the EFI spec.
So take note of the CPU mode and MMU state in the EFI stub diagnostic
output so that we can easily diagnose any issues that may arise from
this. E.g.,
EFI stub: Entering in SVC mode with MMU enabled
Also, capture the CPSR and SCTLR system register values at EFI stub
entry, and after ExitBootServices() returns, and check whether the
MMU and Dcache were disabled at any point. If this is the case, a
diagnostic message like the following will be emitted:
efi: [Firmware Bug]: EFI stub was entered with MMU and Dcache disabled, please fix your firmware!
efi: CPSR at EFI stub entry : 0x600001d3
efi: SCTLR at EFI stub entry : 0x00c51838
efi: CPSR after ExitBootServices() : 0x600001d3
efi: SCTLR after ExitBootServices(): 0x00c50838
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
2020-06-07 21:41:35 +08:00
|
|
|
|
|
|
|
drop_table:
|
|
|
|
efi_bs_call(install_configuration_table, &cpu_state_guid, NULL);
|
|
|
|
free_state:
|
|
|
|
efi_bs_call(free_pool, efi_entry_state);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
void efi_handle_post_ebs_state(void)
|
|
|
|
{
|
|
|
|
get_cpu_state(&efi_entry_state->cpsr_after_ebs,
|
|
|
|
&efi_entry_state->sctlr_after_ebs);
|
2016-02-17 20:36:01 +08:00
|
|
|
}
|
|
|
|
|
2016-04-26 04:06:53 +08:00
|
|
|
static efi_guid_t screen_info_guid = LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID;
|
|
|
|
|
2019-12-24 23:10:19 +08:00
|
|
|
struct screen_info *alloc_screen_info(void)
|
2016-04-26 04:06:53 +08:00
|
|
|
{
|
|
|
|
struct screen_info *si;
|
|
|
|
efi_status_t status;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unlike on arm64, where we can directly fill out the screen_info
|
|
|
|
* structure from the stub, we need to allocate a buffer to hold
|
|
|
|
* its contents while we hand over to the kernel proper from the
|
|
|
|
* decompressor.
|
|
|
|
*/
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
|
|
|
|
sizeof(*si), (void **)&si);
|
2016-04-26 04:06:53 +08:00
|
|
|
|
|
|
|
if (status != EFI_SUCCESS)
|
|
|
|
return NULL;
|
|
|
|
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
status = efi_bs_call(install_configuration_table,
|
|
|
|
&screen_info_guid, si);
|
2016-04-26 04:06:53 +08:00
|
|
|
if (status == EFI_SUCCESS)
|
|
|
|
return si;
|
|
|
|
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
efi_bs_call(free_pool, si);
|
2016-04-26 04:06:53 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-12-24 23:10:19 +08:00
|
|
|
void free_screen_info(struct screen_info *si)
|
2016-04-26 04:06:53 +08:00
|
|
|
{
|
|
|
|
if (!si)
|
|
|
|
return;
|
|
|
|
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
efi_bs_call(install_configuration_table, &screen_info_guid, NULL);
|
|
|
|
efi_bs_call(free_pool, si);
|
2016-04-26 04:06:53 +08:00
|
|
|
}
|
|
|
|
|
2019-12-24 23:10:19 +08:00
|
|
|
static efi_status_t reserve_kernel_base(unsigned long dram_base,
|
2017-04-05 00:02:44 +08:00
|
|
|
unsigned long *reserve_addr,
|
|
|
|
unsigned long *reserve_size)
|
|
|
|
{
|
|
|
|
efi_physical_addr_t alloc_addr;
|
|
|
|
efi_memory_desc_t *memory_map;
|
|
|
|
unsigned long nr_pages, map_size, desc_size, buff_size;
|
|
|
|
efi_status_t status;
|
|
|
|
unsigned long l;
|
|
|
|
|
|
|
|
struct efi_boot_memmap map = {
|
|
|
|
.map = &memory_map,
|
|
|
|
.map_size = &map_size,
|
|
|
|
.desc_size = &desc_size,
|
|
|
|
.desc_ver = NULL,
|
|
|
|
.key_ptr = NULL,
|
|
|
|
.buff_size = &buff_size,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reserve memory for the uncompressed kernel image. This is
|
|
|
|
* all that prevents any future allocations from conflicting
|
|
|
|
* with the kernel. Since we can't tell from the compressed
|
|
|
|
* image how much DRAM the kernel actually uses (due to BSS
|
|
|
|
* size uncertainty) we allocate the maximum possible size.
|
|
|
|
* Do this very early, as prints can cause memory allocations
|
|
|
|
* that may conflict with this.
|
|
|
|
*/
|
|
|
|
alloc_addr = dram_base + MAX_UNCOMP_KERNEL_SIZE;
|
|
|
|
nr_pages = MAX_UNCOMP_KERNEL_SIZE / EFI_PAGE_SIZE;
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
|
|
|
|
EFI_BOOT_SERVICES_DATA, nr_pages, &alloc_addr);
|
2017-04-05 00:02:44 +08:00
|
|
|
if (status == EFI_SUCCESS) {
|
|
|
|
if (alloc_addr == dram_base) {
|
|
|
|
*reserve_addr = alloc_addr;
|
|
|
|
*reserve_size = MAX_UNCOMP_KERNEL_SIZE;
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* If we end up here, the allocation succeeded but starts below
|
|
|
|
* dram_base. This can only occur if the real base of DRAM is
|
|
|
|
* not a multiple of 128 MB, in which case dram_base will have
|
|
|
|
* been rounded up. Since this implies that a part of the region
|
|
|
|
* was already occupied, we need to fall through to the code
|
|
|
|
* below to ensure that the existing allocations don't conflict.
|
|
|
|
* For this reason, we use EFI_BOOT_SERVICES_DATA above and not
|
|
|
|
* EFI_LOADER_DATA, which we wouldn't able to distinguish from
|
|
|
|
* allocations that we want to disallow.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the allocation above failed, we may still be able to proceed:
|
|
|
|
* if the only allocations in the region are of types that will be
|
|
|
|
* released to the OS after ExitBootServices(), the decompressor can
|
|
|
|
* safely overwrite them.
|
|
|
|
*/
|
2019-12-24 23:10:19 +08:00
|
|
|
status = efi_get_memory_map(&map);
|
2017-04-05 00:02:44 +08:00
|
|
|
if (status != EFI_SUCCESS) {
|
2020-05-01 02:28:35 +08:00
|
|
|
efi_err("reserve_kernel_base(): Unable to retrieve memory map.\n");
|
2017-04-05 00:02:44 +08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = 0; l < map_size; l += desc_size) {
|
|
|
|
efi_memory_desc_t *desc;
|
|
|
|
u64 start, end;
|
|
|
|
|
|
|
|
desc = (void *)memory_map + l;
|
|
|
|
start = desc->phys_addr;
|
|
|
|
end = start + desc->num_pages * EFI_PAGE_SIZE;
|
|
|
|
|
|
|
|
/* Skip if entry does not intersect with region */
|
|
|
|
if (start >= dram_base + MAX_UNCOMP_KERNEL_SIZE ||
|
|
|
|
end <= dram_base)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
switch (desc->type) {
|
|
|
|
case EFI_BOOT_SERVICES_CODE:
|
|
|
|
case EFI_BOOT_SERVICES_DATA:
|
|
|
|
/* Ignore types that are released to the OS anyway */
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case EFI_CONVENTIONAL_MEMORY:
|
2019-11-07 09:43:21 +08:00
|
|
|
/* Skip soft reserved conventional memory */
|
|
|
|
if (efi_soft_reserve_enabled() &&
|
|
|
|
(desc->attribute & EFI_MEMORY_SP))
|
|
|
|
continue;
|
|
|
|
|
2017-04-05 00:02:44 +08:00
|
|
|
/*
|
|
|
|
* Reserve the intersection between this entry and the
|
|
|
|
* region.
|
|
|
|
*/
|
|
|
|
start = max(start, (u64)dram_base);
|
|
|
|
end = min(end, (u64)dram_base + MAX_UNCOMP_KERNEL_SIZE);
|
|
|
|
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
status = efi_bs_call(allocate_pages,
|
|
|
|
EFI_ALLOCATE_ADDRESS,
|
|
|
|
EFI_LOADER_DATA,
|
|
|
|
(end - start) / EFI_PAGE_SIZE,
|
|
|
|
&start);
|
2017-04-05 00:02:44 +08:00
|
|
|
if (status != EFI_SUCCESS) {
|
2020-05-01 02:28:35 +08:00
|
|
|
efi_err("reserve_kernel_base(): alloc failed.\n");
|
2017-04-05 00:02:44 +08:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EFI_LOADER_CODE:
|
|
|
|
case EFI_LOADER_DATA:
|
|
|
|
/*
|
|
|
|
* These regions may be released and reallocated for
|
|
|
|
* another purpose (including EFI_RUNTIME_SERVICE_DATA)
|
|
|
|
* at any time during the execution of the OS loader,
|
|
|
|
* so we cannot consider them as safe.
|
|
|
|
*/
|
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* Treat any other allocation in the region as unsafe */
|
|
|
|
status = EFI_OUT_OF_RESOURCES;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
status = EFI_SUCCESS;
|
|
|
|
out:
|
efi/libstub: Rename efi_call_early/_runtime macros to be more intuitive
The macros efi_call_early and efi_call_runtime are used to call EFI
boot services and runtime services, respectively. However, the naming
is confusing, given that the early vs runtime distinction may suggest
that these are used for calling the same set of services either early
or late (== at runtime), while in reality, the sets of services they
can be used with are completely disjoint, and efi_call_runtime is also
only usable in 'early' code.
So do a global sweep to replace all occurrences with efi_bs_call or
efi_rt_call, respectively, where BS and RT match the idiom used by
the UEFI spec to refer to boot time or runtime services.
While at it, use 'func' as the macro parameter name for the function
pointers, which is less likely to collide and cause weird build errors.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Cc: Arvind Sankar <nivedita@alum.mit.edu>
Cc: Borislav Petkov <bp@alien8.de>
Cc: James Morse <james.morse@arm.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: https://lkml.kernel.org/r/20191224151025.32482-24-ardb@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2019-12-24 23:10:23 +08:00
|
|
|
efi_bs_call(free_pool, memory_map);
|
2017-04-05 00:02:44 +08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2019-12-24 23:10:19 +08:00
|
|
|
efi_status_t handle_kernel_image(unsigned long *image_addr,
|
2015-09-24 11:17:54 +08:00
|
|
|
unsigned long *image_size,
|
|
|
|
unsigned long *reserve_addr,
|
|
|
|
unsigned long *reserve_size,
|
|
|
|
unsigned long dram_base,
|
|
|
|
efi_loaded_image_t *image)
|
|
|
|
{
|
2019-10-30 01:37:53 +08:00
|
|
|
unsigned long kernel_base;
|
2015-09-24 11:17:54 +08:00
|
|
|
efi_status_t status;
|
|
|
|
|
2020-04-14 00:21:35 +08:00
|
|
|
/* use a 16 MiB aligned base for the decompressed kernel */
|
|
|
|
kernel_base = round_up(dram_base, SZ_16M) + TEXT_OFFSET;
|
2015-09-24 11:17:54 +08:00
|
|
|
|
2019-10-30 01:37:53 +08:00
|
|
|
/*
|
|
|
|
* Note that some platforms (notably, the Raspberry Pi 2) put
|
|
|
|
* spin-tables and other pieces of firmware at the base of RAM,
|
|
|
|
* abusing the fact that the window of TEXT_OFFSET bytes at the
|
|
|
|
* base of the kernel image is only partially used at the moment.
|
|
|
|
* (Up to 5 pages are used for the swapper page tables)
|
|
|
|
*/
|
2020-04-14 00:21:35 +08:00
|
|
|
status = reserve_kernel_base(kernel_base - 5 * PAGE_SIZE, reserve_addr,
|
|
|
|
reserve_size);
|
2015-09-24 11:17:54 +08:00
|
|
|
if (status != EFI_SUCCESS) {
|
2020-05-01 02:28:35 +08:00
|
|
|
efi_err("Unable to allocate memory for uncompressed kernel.\n");
|
2015-09-24 11:17:54 +08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2020-04-14 00:21:35 +08:00
|
|
|
*image_addr = kernel_base;
|
|
|
|
*image_size = 0;
|
2015-09-24 11:17:54 +08:00
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|