Commit 948ef73f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull EFI updates from Ard Biesheuvel:
 "Again not a busy cycle for EFI, just some minor tweaks and bug fixes:

   - Enable boot graphics resource table (BGRT) on Xen/x86

   - Correct a misguided assumption in the memory attributes table
     sanity check

   - Start tagging efi_mem_reserve()'d regions as MEMBLOCK_RSRV_KERN

   - Some other minor fixes and cleanups"

* tag 'efi-next-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efi/capsule-loader: fix incorrect sizeof in phys array reallocation
  efi: Tag memblock reservations of boot services regions as RSRV_KERN
  memblock: Permit existing reserved regions to be marked RSRV_KERN
  efi/memattr: Fix thinko in table size sanity check
  efi: libstub: fix type of fdt 32 and 64bit variables
  efi: Drop unused efi_range_is_wc() function
  efi: Enable BGRT loading under Xen
  efi: make efi_mem_type() and efi_mem_attributes() work on Xen PV
parents f0bf3eac 48a42821
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ int __efi_capsule_setup_info(struct capsule_info *cap_info)
	cap_info->pages = temp_page;

	temp_page = krealloc(cap_info->phys,
			     pages_needed * sizeof(phys_addr_t *),
			     pages_needed * sizeof(phys_addr_t),
			     GFP_KERNEL | __GFP_ZERO);
	if (!temp_page)
		return -ENOMEM;
+5 −2
Original line number Diff line number Diff line
@@ -29,11 +29,12 @@ void __init efi_bgrt_init(struct acpi_table_header *table)
	void *image;
	struct bmp_header bmp_header;
	struct acpi_table_bgrt *bgrt = &bgrt_tab;
	int mem_type;

	if (acpi_disabled)
		return;

	if (!efi_enabled(EFI_MEMMAP))
	if (!efi_enabled(EFI_MEMMAP) && !efi_enabled(EFI_PARAVIRT))
		return;

	if (table->length < sizeof(bgrt_tab)) {
@@ -62,7 +63,9 @@ void __init efi_bgrt_init(struct acpi_table_header *table)
		goto out;
	}

	if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
	mem_type = efi_mem_type(bgrt->image_address);
	if (mem_type != EFI_BOOT_SERVICES_DATA &&
	    mem_type != EFI_ACPI_RECLAIM_MEMORY) {
		pr_notice("Ignoring BGRT: invalid image address\n");
		goto out;
	}
+12 −19
Original line number Diff line number Diff line
@@ -600,7 +600,9 @@ void __init efi_mem_reserve(phys_addr_t addr, u64 size)
		return;

	if (!memblock_is_region_reserved(addr, size))
		memblock_reserve(addr, size);
		memblock_reserve_kern(addr, size);
	else
		memblock_reserved_mark_kern(addr, size);

	/*
	 * Some architectures (x86) reserve all boot services ranges
@@ -983,18 +985,12 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
 */
u64 efi_mem_attributes(unsigned long phys_addr)
{
	efi_memory_desc_t *md;
	efi_memory_desc_t md;

	if (!efi_enabled(EFI_MEMMAP))
	if (efi_mem_desc_lookup(phys_addr, &md))
		return 0;

	for_each_efi_memory_desc(md) {
		if ((md->phys_addr <= phys_addr) &&
		    (phys_addr < (md->phys_addr +
		    (md->num_pages << EFI_PAGE_SHIFT))))
			return md->attribute;
	}
	return 0;
	return md.attribute;
}

/*
@@ -1007,18 +1003,15 @@ u64 efi_mem_attributes(unsigned long phys_addr)
 */
int efi_mem_type(unsigned long phys_addr)
{
	const efi_memory_desc_t *md;
	efi_memory_desc_t md;

	if (!efi_enabled(EFI_MEMMAP))
	if (!efi_enabled(EFI_MEMMAP) && !efi_enabled(EFI_PARAVIRT))
		return -ENOTSUPP;

	for_each_efi_memory_desc(md) {
		if ((md->phys_addr <= phys_addr) &&
		    (phys_addr < (md->phys_addr +
				  (md->num_pages << EFI_PAGE_SHIFT))))
			return md->type;
	}
	if (efi_mem_desc_lookup(phys_addr, &md))
		return -EINVAL;

	return md.type;
}

int efi_status_to_err(efi_status_t status)
+6 −6
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
{
	int node, num_rsv;
	int status;
	u32 fdt_val32;
	u64 fdt_val64;
	fdt32_t fdt_val32;
	fdt64_t fdt_val64;

	/* Do some checks on provided FDT, if it exists: */
	if (orig_fdt) {
@@ -100,13 +100,13 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
	if (status)
		goto fdt_set_fail;

	fdt_val64 = U64_MAX; /* placeholder */
	fdt_val64 = cpu_to_fdt64(U64_MAX); /* placeholder */

	status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64);
	if (status)
		goto fdt_set_fail;

	fdt_val32 = U32_MAX; /* placeholder */
	fdt_val32 = cpu_to_fdt32(U32_MAX); /* placeholder */

	status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32);
	if (status)
@@ -147,8 +147,8 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
{
	int node = fdt_path_offset(fdt, "/chosen");
	u64 fdt_val64;
	u32 fdt_val32;
	fdt64_t fdt_val64;
	fdt32_t fdt_val32;
	int err;

	if (node < 0)
+28 −9
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ unsigned long __ro_after_init efi_mem_attr_table = EFI_INVALID_TABLE_ADDR;
void __init efi_memattr_init(void)
{
	efi_memory_attributes_table_t *tbl;
	unsigned long size;

	if (efi_mem_attr_table == EFI_INVALID_TABLE_ADDR)
		return;
@@ -40,22 +39,42 @@ void __init efi_memattr_init(void)
		goto unmap;
	}

	/*
	 * The EFI memory attributes table descriptors might potentially be
	 * smaller than those used by the EFI memory map, as long as they can
	 * fit a efi_memory_desc_t. However, a larger descriptor size makes no
	 * sense, and might be an indication that the table is corrupted.
	 *
	 * The only exception is kexec_load(), where the EFI memory map is
	 * reconstructed by user space, and may use a smaller descriptor size
	 * than the original. Given that, ignoring this companion table is
	 * still the right thing to do here, but don't complain too loudly when
	 * this happens.
	 */
	if (tbl->desc_size < sizeof(efi_memory_desc_t) ||
	    tbl->desc_size > efi.memmap.desc_size) {
		pr_warn("Unexpected EFI Memory Attributes descriptor size %u (expected: %lu)\n",
			tbl->desc_size, efi.memmap.desc_size);
		goto unmap;
	}

	/*
	 * Sanity check: the Memory Attributes Table contains up to 3 entries
	 * for each entry of type EfiRuntimeServicesCode in the EFI memory map.
	 * So if the size of the table exceeds 3x the size of the entire EFI
	 * memory map, there is clearly something wrong, and the table should
	 * just be ignored altogether.
	 * Sanity check: the Memory Attributes Table contains multiple entries
	 * for each EFI runtime services code or data region in the EFI memory
	 * map, each with the permission attributes that may be applied when
	 * mapping the region.  There is no upper bound for the number of
	 * entries, as it could conceivably contain more entries than the EFI
	 * memory map itself. So pick an arbitrary limit of 64k, which is
	 * ludicrously high. This prevents a corrupted table from eating all
	 * system RAM.
	 */
	size = tbl->num_entries * tbl->desc_size;
	if (size > 3 * efi.memmap.nr_map * efi.memmap.desc_size) {
	if (tbl->num_entries > SZ_64K) {
		pr_warn(FW_BUG "Corrupted EFI Memory Attributes Table detected! (version == %u, desc_size == %u, num_entries == %u)\n",
			tbl->version, tbl->desc_size, tbl->num_entries);
		goto unmap;
	}

	tbl_size = sizeof(*tbl) + size;
	tbl_size = sizeof(*tbl) + tbl->num_entries * tbl->desc_size;
	memblock_reserve(efi_mem_attr_table, tbl_size);
	set_bit(EFI_MEM_ATTR, &efi.flags);

Loading