From: Ard Biesheuvel Date: Fri, 18 Nov 2022 08:13:57 +0000 (+0100) Subject: Merge tag 'efi-zboot-direct-for-v6.2' into efi/next X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=977122898ea5e3d568014ec9fe089cfba7c73e76;p=linux.git Merge tag 'efi-zboot-direct-for-v6.2' into efi/next --- 977122898ea5e3d568014ec9fe089cfba7c73e76 diff --cc drivers/firmware/efi/libstub/Makefile index ef5045a53ce09,402dfb30ddc7a..e19dd1106fa13 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@@ -79,13 -82,14 +82,14 @@@ lib-$(CONFIG_EFI_PARAMS_FROM_FDT) += fd $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(call if_changed_rule,cc_o_c) - lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o + lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \ + screen_info.o efi-stub-entry.o lib-$(CONFIG_ARM) += arm32-stub.o - lib-$(CONFIG_ARM64) += arm64-stub.o smbios.o -lib-$(CONFIG_ARM64) += arm64.o arm64-stub.o arm64-entry.o ++lib-$(CONFIG_ARM64) += arm64.o arm64-stub.o arm64-entry.o smbios.o lib-$(CONFIG_X86) += x86-stub.o - lib-$(CONFIG_RISCV) += riscv-stub.o - lib-$(CONFIG_LOONGARCH) += loongarch-stub.o + lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o + lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) diff --cc drivers/firmware/efi/libstub/arm64.c index 0000000000000,d2e94972c5fad..ff2d18c42ee74 mode 000000,100644..100644 --- a/drivers/firmware/efi/libstub/arm64.c +++ b/drivers/firmware/efi/libstub/arm64.c @@@ -1,0 -1,61 +1,76 @@@ + // SPDX-License-Identifier: GPL-2.0 + /* + * Copyright (C) 2013, 2014 Linaro Ltd; + * + * This file implements the EFI boot stub for the arm64 kernel. + * Adapted from ARM version by Mark Salter + */ + + + #include + #include + #include + #include + + #include "efistub.h" + ++static bool system_needs_vamap(void) ++{ ++ const u8 *type1_family = efi_get_smbios_string(1, family); ++ ++ /* ++ * Ampere Altra machines crash in SetTime() if SetVirtualAddressMap() ++ * has not been called prior. ++ */ ++ if (!type1_family || strcmp(type1_family, "Altra")) ++ return false; ++ ++ efi_warn("Working around broken SetVirtualAddressMap()\n"); ++ return true; ++} ++ + efi_status_t check_platform_features(void) + { + u64 tg; + + /* + * If we have 48 bits of VA space for TTBR0 mappings, we can map the + * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is + * unnecessary. + */ - if (VA_BITS_MIN >= 48) ++ if (VA_BITS_MIN >= 48 && !system_needs_vamap()) + efi_novamap = true; + + /* UEFI mandates support for 4 KB granularity, no need to check */ + if (IS_ENABLED(CONFIG_ARM64_4K_PAGES)) + return EFI_SUCCESS; + + tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf; + if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) { + if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) + efi_err("This 64 KB granular kernel is not supported by your CPU\n"); + else + efi_err("This 16 KB granular kernel is not supported by your CPU\n"); + return EFI_UNSUPPORTED; + } + return EFI_SUCCESS; + } + + void efi_cache_sync_image(unsigned long image_base, + unsigned long alloc_size, + unsigned long code_size) + { + u32 ctr = read_cpuid_effective_cachetype(); + u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr, + CTR_EL0_DminLine_SHIFT); + + do { + asm("dc civac, %0" :: "r"(image_base)); + image_base += lsize; + alloc_size -= lsize; + } while (alloc_size >= lsize); + + asm("ic ialluis"); + dsb(ish); + isb(); + } diff --cc drivers/firmware/efi/libstub/efistub.h index eb03d5a9aac88,b5e1095b00162..21b01d6c77ba3 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@@ -975,32 -983,11 +983,39 @@@ efi_enable_reset_attack_mitigation(void void efi_retrieve_tpm2_eventlog(void); + struct screen_info *alloc_screen_info(void); + void free_screen_info(struct screen_info *si); + + void efi_cache_sync_image(unsigned long image_base, + unsigned long alloc_size, + unsigned long code_size); + +struct efi_smbios_record { + u8 type; + u8 length; + u16 handle; +}; + +struct efi_smbios_type1_record { + struct efi_smbios_record header; + + u8 manufacturer; + u8 product_name; + u8 version; + u8 serial_number; + efi_guid_t uuid; + u8 wakeup_type; + u8 sku_number; + u8 family; +}; + +#define efi_get_smbios_string(__type, __name) ({ \ + int size = sizeof(struct efi_smbios_type ## __type ## _record); \ + int off = offsetof(struct efi_smbios_type ## __type ## _record, \ + __name); \ + __efi_get_smbios_string(__type, off, size); \ +}) + +const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize); + #endif