Skip to content

Commit

Permalink
Merge tag 'efi-fixes-for-v6.8-1' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/efi/efi

Pull EFI fixes from Ard Biesheuvel:
 "The only notable change here is the patch that changes the way we deal
  with spurious errors from the EFI memory attribute protocol. This will
  be backported to v6.6, and is intended to ensure that we will not
  paint ourselves into a corner when we tighten this further in order to
  comply with MS requirements on signed EFI code.

  Note that this protocol does not currently exist in x86 production
  systems in the field, only in Microsoft's fork of OVMF, but it will be
  mandatory for Windows logo certification for x86 PCs in the future.

   - Tighten ELF relocation checks on the RISC-V EFI stub

   - Give up if the new EFI memory attributes protocol fails spuriously
     on x86

   - Take care not to place the kernel in the lowest 16 MB of DRAM on
     x86

   - Omit special purpose EFI memory from memblock

   - Some fixes for the CXL CPER reporting code

   - Make the PE/COFF layout of mixed-mode capable images comply with a
     strict interpretation of the spec"

* tag 'efi-fixes-for-v6.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  x86/efistub: Use 1:1 file:memory mapping for PE/COFF .compat section
  cxl/trace: Remove unnecessary memcpy's
  cxl/cper: Fix errant CPER prints for CXL events
  efi: Don't add memblocks for soft-reserved memory
  efi: runtime: Fix potential overflow of soft-reserved region size
  efi/libstub: Add one kernel-doc comment
  x86/efistub: Avoid placing the kernel below LOAD_PHYSICAL_ADDR
  x86/efistub: Give up if memory attribute protocol returns an error
  riscv/efistub: Tighten ELF relocation check
  riscv/efistub: Ensure GP-relative addressing is not used
  • Loading branch information
torvalds committed Feb 9, 2024
2 parents 5ddfc24 + 1ad55ce commit e6f39a9
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 73 deletions.
14 changes: 6 additions & 8 deletions arch/x86/boot/header.S
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ extra_header_fields:
.word 0 # MinorSubsystemVersion
.long 0 # Win32VersionValue

.long setup_size + ZO__end + pecompat_vsize
# SizeOfImage
.long setup_size + ZO__end # SizeOfImage

.long salign # SizeOfHeaders
.long 0 # CheckSum
Expand Down Expand Up @@ -143,7 +142,7 @@ section_table:
.ascii ".setup"
.byte 0
.byte 0
.long setup_size - salign # VirtualSize
.long pecompat_fstart - salign # VirtualSize
.long salign # VirtualAddress
.long pecompat_fstart - salign # SizeOfRawData
.long salign # PointerToRawData
Expand All @@ -156,8 +155,8 @@ section_table:
#ifdef CONFIG_EFI_MIXED
.asciz ".compat"

.long 8 # VirtualSize
.long setup_size + ZO__end # VirtualAddress
.long pecompat_fsize # VirtualSize
.long pecompat_fstart # VirtualAddress
.long pecompat_fsize # SizeOfRawData
.long pecompat_fstart # PointerToRawData

Expand All @@ -172,17 +171,16 @@ section_table:
* modes this image supports.
*/
.pushsection ".pecompat", "a", @progbits
.balign falign
.set pecompat_vsize, salign
.balign salign
.globl pecompat_fstart
pecompat_fstart:
.byte 0x1 # Version
.byte 8 # Size
.word IMAGE_FILE_MACHINE_I386 # PE machine type
.long setup_size + ZO_efi32_pe_entry # Entrypoint
.byte 0x0 # Sentinel
.popsection
#else
.set pecompat_vsize, 0
.set pecompat_fstart, setup_size
#endif
.ascii ".text"
Expand Down
6 changes: 3 additions & 3 deletions arch/x86/boot/setup.ld
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ SECTIONS
.text : { *(.text .text.*) }
.text32 : { *(.text32) }

.pecompat : { *(.pecompat) }
PROVIDE(pecompat_fsize = setup_size - pecompat_fstart);

. = ALIGN(16);
.rodata : { *(.rodata*) }

Expand All @@ -36,9 +39,6 @@ SECTIONS
. = ALIGN(16);
.data : { *(.data*) }

.pecompat : { *(.pecompat) }
PROVIDE(pecompat_fsize = setup_size - pecompat_fstart);

.signature : {
setup_sig = .;
LONG(0x5a5aaa55)
Expand Down
26 changes: 0 additions & 26 deletions drivers/acpi/apei/ghes.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,32 +680,6 @@ static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
static DECLARE_RWSEM(cxl_cper_rw_sem);
static cxl_cper_callback cper_callback;

/* CXL Event record UUIDs are formatted as GUIDs and reported in section type */

/*
* General Media Event Record
* CXL rev 3.0 Section 8.2.9.2.1.1; Table 8-43
*/
#define CPER_SEC_CXL_GEN_MEDIA_GUID \
GUID_INIT(0xfbcd0a77, 0xc260, 0x417f, \
0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6)

/*
* DRAM Event Record
* CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
*/
#define CPER_SEC_CXL_DRAM_GUID \
GUID_INIT(0x601dcbb3, 0x9c06, 0x4eab, \
0xb8, 0xaf, 0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24)

/*
* Memory Module Event Record
* CXL rev 3.0 section 8.2.9.2.1.3; Table 8-45
*/
#define CPER_SEC_CXL_MEM_MODULE_GUID \
GUID_INIT(0xfe927475, 0xdd59, 0x4339, \
0xa5, 0x86, 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74)

static void cxl_cper_post_event(enum cxl_event_type event_type,
struct cxl_cper_event_rec *rec)
{
Expand Down
6 changes: 3 additions & 3 deletions drivers/cxl/core/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ TRACE_EVENT(cxl_general_media,

TP_fast_assign(
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
memcpy(&__entry->hdr_uuid, &CXL_EVENT_GEN_MEDIA_UUID, sizeof(uuid_t));
__entry->hdr_uuid = CXL_EVENT_GEN_MEDIA_UUID;

/* General Media */
__entry->dpa = le64_to_cpu(rec->phys_addr);
Expand Down Expand Up @@ -425,7 +425,7 @@ TRACE_EVENT(cxl_dram,

TP_fast_assign(
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
memcpy(&__entry->hdr_uuid, &CXL_EVENT_DRAM_UUID, sizeof(uuid_t));
__entry->hdr_uuid = CXL_EVENT_DRAM_UUID;

/* DRAM */
__entry->dpa = le64_to_cpu(rec->phys_addr);
Expand Down Expand Up @@ -573,7 +573,7 @@ TRACE_EVENT(cxl_memory_module,

TP_fast_assign(
CXL_EVT_TP_fast_assign(cxlmd, log, rec->hdr);
memcpy(&__entry->hdr_uuid, &CXL_EVENT_MEM_MODULE_UUID, sizeof(uuid_t));
__entry->hdr_uuid = CXL_EVENT_MEM_MODULE_UUID;

/* Memory Module Event */
__entry->event_type = rec->event_type;
Expand Down
2 changes: 1 addition & 1 deletion drivers/firmware/efi/arm-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static int __init arm_enable_runtime_services(void)
efi_memory_desc_t *md;

for_each_efi_memory_desc(md) {
int md_size = md->num_pages << EFI_PAGE_SHIFT;
u64 md_size = md->num_pages << EFI_PAGE_SHIFT;
struct resource *res;

if (!(md->attribute & EFI_MEMORY_SP))
Expand Down
19 changes: 19 additions & 0 deletions drivers/firmware/efi/cper.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,17 @@ static void cper_print_tstamp(const char *pfx,
}
}

struct ignore_section {
guid_t guid;
const char *name;
};

static const struct ignore_section ignore_sections[] = {
{ .guid = CPER_SEC_CXL_GEN_MEDIA_GUID, .name = "CXL General Media Event" },
{ .guid = CPER_SEC_CXL_DRAM_GUID, .name = "CXL DRAM Event" },
{ .guid = CPER_SEC_CXL_MEM_MODULE_GUID, .name = "CXL Memory Module Event" },
};

static void
cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata,
int sec_no)
Expand All @@ -543,6 +554,14 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);

snprintf(newpfx, sizeof(newpfx), "%s ", pfx);

for (int i = 0; i < ARRAY_SIZE(ignore_sections); i++) {
if (guid_equal(sec_type, &ignore_sections[i].guid)) {
printk("%ssection_type: %s\n", newpfx, ignore_sections[i].name);
return;
}
}

if (guid_equal(sec_type, &CPER_SEC_PROC_GENERIC)) {
struct cper_sec_proc_generic *proc_err = acpi_hest_get_payload(gdata);

Expand Down
19 changes: 10 additions & 9 deletions drivers/firmware/efi/efi-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,6 @@ static __init int is_usable_memory(efi_memory_desc_t *md)
case EFI_BOOT_SERVICES_DATA:
case EFI_CONVENTIONAL_MEMORY:
case EFI_PERSISTENT_MEMORY:
/*
* Special purpose memory is 'soft reserved', which means it
* is set aside initially, but can be hotplugged back in or
* be assigned to the dax driver after boot.
*/
if (efi_soft_reserve_enabled() &&
(md->attribute & EFI_MEMORY_SP))
return false;

/*
* According to the spec, these regions are no longer reserved
* after calling ExitBootServices(). However, we can only use
Expand Down Expand Up @@ -196,6 +187,16 @@ static __init void reserve_regions(void)
size = npages << PAGE_SHIFT;

if (is_memory(md)) {
/*
* Special purpose memory is 'soft reserved', which
* means it is set aside initially. Don't add a memblock
* for it now so that it can be hotplugged back in or
* be assigned to the dax driver after boot.
*/
if (efi_soft_reserve_enabled() &&
(md->attribute & EFI_MEMORY_SP))
continue;

early_init_dt_add_memory_arch(paddr, size);

if (!is_usable_memory(md))
Expand Down
4 changes: 2 additions & 2 deletions drivers/firmware/efi/libstub/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \
-DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \
-DEFI_HAVE_STRCMP -fno-builtin -fpic \
$(call cc-option,-mno-single-pic-base)
cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE
cflags-$(CONFIG_RISCV) += -fpic -DNO_ALTERNATIVE -mno-relax
cflags-$(CONFIG_LOONGARCH) += -fpie

cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt
Expand Down Expand Up @@ -143,7 +143,7 @@ STUBCOPY_RELOC-$(CONFIG_ARM64) := R_AARCH64_ABS
# exist.
STUBCOPY_FLAGS-$(CONFIG_RISCV) += --prefix-alloc-sections=.init \
--prefix-symbols=__efistub_
STUBCOPY_RELOC-$(CONFIG_RISCV) := R_RISCV_HI20
STUBCOPY_RELOC-$(CONFIG_RISCV) := -E R_RISCV_HI20\|R_RISCV_$(BITS)\|R_RISCV_RELAX

# For LoongArch, keep all the symbols in .init section and make sure that no
# absolute symbols references exist.
Expand Down
1 change: 1 addition & 0 deletions drivers/firmware/efi/libstub/alignedmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* @max: the address that the last allocated memory page shall not
* exceed
* @align: minimum alignment of the base of the allocation
* @memory_type: the type of memory to allocate
*
* Allocate pages as EFI_LOADER_DATA. The allocated pages are aligned according
* to @align, which should be >= EFI_ALLOC_ALIGN. The last allocated page will
Expand Down
3 changes: 2 additions & 1 deletion drivers/firmware/efi/libstub/efistub.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);

efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
unsigned long *addr, unsigned long random_seed,
int memory_type, unsigned long alloc_limit);
int memory_type, unsigned long alloc_min,
unsigned long alloc_max);

efi_status_t efi_random_get_seed(void);

Expand Down
2 changes: 1 addition & 1 deletion drivers/firmware/efi/libstub/kaslr.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ efi_status_t efi_kaslr_relocate_kernel(unsigned long *image_addr,
*/
status = efi_random_alloc(*reserve_size, min_kimg_align,
reserve_addr, phys_seed,
EFI_LOADER_CODE, EFI_ALLOC_LIMIT);
EFI_LOADER_CODE, 0, EFI_ALLOC_LIMIT);
if (status != EFI_SUCCESS)
efi_warn("efi_random_alloc() failed: 0x%lx\n", status);
} else {
Expand Down
12 changes: 7 additions & 5 deletions drivers/firmware/efi/libstub/randomalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
unsigned long size,
unsigned long align_shift,
u64 alloc_limit)
u64 alloc_min, u64 alloc_max)
{
unsigned long align = 1UL << align_shift;
u64 first_slot, last_slot, region_end;
Expand All @@ -30,11 +30,11 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
return 0;

region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1,
alloc_limit);
alloc_max);
if (region_end < size)
return 0;

first_slot = round_up(md->phys_addr, align);
first_slot = round_up(max(md->phys_addr, alloc_min), align);
last_slot = round_down(region_end - size + 1, align);

if (first_slot > last_slot)
Expand All @@ -56,7 +56,8 @@ efi_status_t efi_random_alloc(unsigned long size,
unsigned long *addr,
unsigned long random_seed,
int memory_type,
unsigned long alloc_limit)
unsigned long alloc_min,
unsigned long alloc_max)
{
unsigned long total_slots = 0, target_slot;
unsigned long total_mirrored_slots = 0;
Expand All @@ -78,7 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size,
efi_memory_desc_t *md = (void *)map->map + map_offset;
unsigned long slots;

slots = get_entry_num_slots(md, size, ilog2(align), alloc_limit);
slots = get_entry_num_slots(md, size, ilog2(align), alloc_min,
alloc_max);
MD_NUM_SLOTS(md) = slots;
total_slots += slots;
if (md->attribute & EFI_MEMORY_MORE_RELIABLE)
Expand Down
25 changes: 15 additions & 10 deletions drivers/firmware/efi/libstub/x86-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
}
}

void efi_adjust_memory_range_protection(unsigned long start,
unsigned long size)
efi_status_t efi_adjust_memory_range_protection(unsigned long start,
unsigned long size)
{
efi_status_t status;
efi_gcd_memory_space_desc_t desc;
Expand All @@ -236,13 +236,17 @@ void efi_adjust_memory_range_protection(unsigned long start,
rounded_end = roundup(start + size, EFI_PAGE_SIZE);

if (memattr != NULL) {
efi_call_proto(memattr, clear_memory_attributes, rounded_start,
rounded_end - rounded_start, EFI_MEMORY_XP);
return;
status = efi_call_proto(memattr, clear_memory_attributes,
rounded_start,
rounded_end - rounded_start,
EFI_MEMORY_XP);
if (status != EFI_SUCCESS)
efi_warn("Failed to clear EFI_MEMORY_XP attribute\n");
return status;
}

if (efi_dxe_table == NULL)
return;
return EFI_SUCCESS;

/*
* Don't modify memory region attributes, they are
Expand All @@ -255,7 +259,7 @@ void efi_adjust_memory_range_protection(unsigned long start,
status = efi_dxe_call(get_memory_space_descriptor, start, &desc);

if (status != EFI_SUCCESS)
return;
break;

next = desc.base_address + desc.length;

Expand All @@ -280,8 +284,10 @@ void efi_adjust_memory_range_protection(unsigned long start,
unprotect_start,
unprotect_start + unprotect_size,
status);
break;
}
}
return EFI_SUCCESS;
}

static void setup_unaccepted_memory(void)
Expand Down Expand Up @@ -793,6 +799,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)

status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr,
seed[0], EFI_LOADER_CODE,
LOAD_PHYSICAL_ADDR,
EFI_X86_KERNEL_ALLOC_LIMIT);
if (status != EFI_SUCCESS)
return status;
Expand All @@ -805,9 +812,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)

*kernel_entry = addr + entry;

efi_adjust_memory_range_protection(addr, kernel_total_size);

return EFI_SUCCESS;
return efi_adjust_memory_range_protection(addr, kernel_total_size);
}

static void __noreturn enter_kernel(unsigned long kernel_addr,
Expand Down
4 changes: 2 additions & 2 deletions drivers/firmware/efi/libstub/x86-stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
extern void trampoline_32bit_src(void *, bool);
extern const u16 trampoline_ljmp_imm_offset;

void efi_adjust_memory_range_protection(unsigned long start,
unsigned long size);
efi_status_t efi_adjust_memory_range_protection(unsigned long start,
unsigned long size);

#ifdef CONFIG_X86_64
efi_status_t efi_setup_5level_paging(void);
Expand Down
2 changes: 1 addition & 1 deletion drivers/firmware/efi/libstub/zboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab)
}

status = efi_random_alloc(alloc_size, min_kimg_align, &image_base,
seed, EFI_LOADER_CODE, EFI_ALLOC_LIMIT);
seed, EFI_LOADER_CODE, 0, EFI_ALLOC_LIMIT);
if (status != EFI_SUCCESS) {
efi_err("Failed to allocate memory\n");
goto free_cmdline;
Expand Down
2 changes: 1 addition & 1 deletion drivers/firmware/efi/riscv-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static int __init riscv_enable_runtime_services(void)
efi_memory_desc_t *md;

for_each_efi_memory_desc(md) {
int md_size = md->num_pages << EFI_PAGE_SHIFT;
u64 md_size = md->num_pages << EFI_PAGE_SHIFT;
struct resource *res;

if (!(md->attribute & EFI_MEMORY_SP))
Expand Down
Loading

0 comments on commit e6f39a9

Please sign in to comment.