x86/compressed/acpi: Move EFI detection to helper
Future patches for SEV-SNP-validated CPUID will also require early parsing of the EFI configuration. Incrementally move the related code into a set of helpers that can be re-used for that purpose. First, carve out the functionality which determines the EFI environment type the machine is booting on. [ bp: Massage commit message. ] Signed-off-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20220307213356.2797205-25-brijesh.singh@amd.com
This commit is contained in:
parent
469693d8f6
commit
7c4146e888
|
@ -103,6 +103,7 @@ endif
|
|||
vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o
|
||||
|
||||
vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o
|
||||
vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
|
||||
efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a
|
||||
|
||||
$(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE
|
||||
|
|
|
@ -87,7 +87,7 @@ static acpi_physical_address kexec_get_rsdp_addr(void)
|
|||
efi_system_table_64_t *systab;
|
||||
struct efi_setup_data *esd;
|
||||
struct efi_info *ei;
|
||||
char *sig;
|
||||
enum efi_type et;
|
||||
|
||||
esd = (struct efi_setup_data *)get_kexec_setup_data_addr();
|
||||
if (!esd)
|
||||
|
@ -98,10 +98,9 @@ static acpi_physical_address kexec_get_rsdp_addr(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ei = &boot_params->efi_info;
|
||||
sig = (char *)&ei->efi_loader_signature;
|
||||
if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
|
||||
debug_putstr("Wrong kexec EFI loader signature.\n");
|
||||
et = efi_get_type(boot_params);
|
||||
if (et != EFI_TYPE_64) {
|
||||
debug_putstr("Unexpected kexec EFI environment (expected 64-bit EFI).\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -122,29 +121,22 @@ static acpi_physical_address efi_get_rsdp_addr(void)
|
|||
unsigned long systab, config_tables;
|
||||
unsigned int nr_tables;
|
||||
struct efi_info *ei;
|
||||
enum efi_type et;
|
||||
bool efi_64;
|
||||
char *sig;
|
||||
|
||||
ei = &boot_params->efi_info;
|
||||
sig = (char *)&ei->efi_loader_signature;
|
||||
|
||||
if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
|
||||
et = efi_get_type(boot_params);
|
||||
if (et == EFI_TYPE_64)
|
||||
efi_64 = true;
|
||||
} else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) {
|
||||
else if (et == EFI_TYPE_32)
|
||||
efi_64 = false;
|
||||
} else {
|
||||
debug_putstr("Wrong EFI loader signature.\n");
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get systab from boot params. */
|
||||
ei = &boot_params->efi_info;
|
||||
#ifdef CONFIG_X86_64
|
||||
systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
|
||||
#else
|
||||
if (ei->efi_systab_hi || ei->efi_memmap_hi) {
|
||||
debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
|
||||
return 0;
|
||||
}
|
||||
systab = ei->efi_systab;
|
||||
#endif
|
||||
if (!systab)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Helpers for early access to EFI configuration table.
|
||||
*
|
||||
* Originally derived from arch/x86/boot/compressed/acpi.c
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include <linux/efi.h>
|
||||
#include <asm/efi.h>
|
||||
|
||||
/**
|
||||
* efi_get_type - Given a pointer to boot_params, determine the type of EFI environment.
|
||||
*
|
||||
* @bp: pointer to boot_params
|
||||
*
|
||||
* Return: EFI_TYPE_{32,64} for valid EFI environments, EFI_TYPE_NONE otherwise.
|
||||
*/
|
||||
enum efi_type efi_get_type(struct boot_params *bp)
|
||||
{
|
||||
struct efi_info *ei;
|
||||
enum efi_type et;
|
||||
const char *sig;
|
||||
|
||||
ei = &bp->efi_info;
|
||||
sig = (char *)&ei->efi_loader_signature;
|
||||
|
||||
if (!strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) {
|
||||
et = EFI_TYPE_64;
|
||||
} else if (!strncmp(sig, EFI32_LOADER_SIGNATURE, 4)) {
|
||||
et = EFI_TYPE_32;
|
||||
} else {
|
||||
debug_putstr("No EFI environment detected.\n");
|
||||
et = EFI_TYPE_NONE;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_X86_64
|
||||
/*
|
||||
* Existing callers like acpi.c treat this case as an indicator to
|
||||
* fall-through to non-EFI, rather than an error, so maintain that
|
||||
* functionality here as well.
|
||||
*/
|
||||
if (ei->efi_systab_hi || ei->efi_memmap_hi) {
|
||||
debug_putstr("EFI system table is located above 4GB and cannot be accessed.\n");
|
||||
et = EFI_TYPE_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return et;
|
||||
}
|
|
@ -176,4 +176,20 @@ void boot_stage2_vc(void);
|
|||
|
||||
unsigned long sev_verify_cbit(unsigned long cr3);
|
||||
|
||||
enum efi_type {
|
||||
EFI_TYPE_64,
|
||||
EFI_TYPE_32,
|
||||
EFI_TYPE_NONE,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
/* helpers for early EFI config table access */
|
||||
enum efi_type efi_get_type(struct boot_params *bp);
|
||||
#else
|
||||
static inline enum efi_type efi_get_type(struct boot_params *bp)
|
||||
{
|
||||
return EFI_TYPE_NONE;
|
||||
}
|
||||
#endif /* CONFIG_EFI */
|
||||
|
||||
#endif /* BOOT_COMPRESSED_MISC_H */
|
||||
|
|
Loading…
Reference in New Issue