lkml.org 
[lkml]   [2022]   [Feb]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v11 24/45] x86/compressed/acpi: Move EFI detection to helper
    Date
    From: Michael Roth <michael.roth@amd.com>

    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.

    Signed-off-by: Michael Roth <michael.roth@amd.com>
    Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
    ---
    arch/x86/boot/compressed/Makefile | 1 +
    arch/x86/boot/compressed/acpi.c | 28 +++++++----------
    arch/x86/boot/compressed/efi.c | 50 +++++++++++++++++++++++++++++++
    arch/x86/boot/compressed/misc.h | 16 ++++++++++
    4 files changed, 77 insertions(+), 18 deletions(-)
    create mode 100644 arch/x86/boot/compressed/efi.c

    diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
    index 6115274fe10f..e69c3d2e0628 100644
    --- a/arch/x86/boot/compressed/Makefile
    +++ b/arch/x86/boot/compressed/Makefile
    @@ -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
    diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
    index 8bcbcee54aa1..db6c561920f0 100644
    --- a/arch/x86/boot/compressed/acpi.c
    +++ b/arch/x86/boot/compressed/acpi.c
    @@ -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)
    diff --git a/arch/x86/boot/compressed/efi.c b/arch/x86/boot/compressed/efi.c
    new file mode 100644
    index 000000000000..bad0ce3e2ef6
    --- /dev/null
    +++ b/arch/x86/boot/compressed/efi.c
    @@ -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;
    +}
    diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
    index 01cc13c12059..fede1afa39e9 100644
    --- a/arch/x86/boot/compressed/misc.h
    +++ b/arch/x86/boot/compressed/misc.h
    @@ -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 */
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-02-24 18:02    [W:3.616 / U:0.196 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site