Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c67b42f3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI fixes from Ingo Molnar:
 "Two EFI boot fixes, one for arm64 and one for x86 systems with certain
  firmware versions"

* 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/fdt: Avoid FDT manipulation after ExitBootServices()
  x86/efi: Always map the first physical page into the EFI pagetables
parents 027eb72c c8f325a5
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -268,6 +268,22 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)


	efi_scratch.use_pgd = true;
	efi_scratch.use_pgd = true;


	/*
	 * Certain firmware versions are way too sentimential and still believe
	 * they are exclusive and unquestionable owners of the first physical page,
	 * even though they explicitly mark it as EFI_CONVENTIONAL_MEMORY
	 * (but then write-access it later during SetVirtualAddressMap()).
	 *
	 * Create a 1:1 mapping for this page, to avoid triple faults during early
	 * boot with such firmware. We are free to hand this page to the BIOS,
	 * as trim_bios_range() will reserve the first page and isolate it away
	 * from memory allocators anyway.
	 */
	if (kernel_map_pages_in_pgd(pgd, 0x0, 0x0, 1, _PAGE_RW)) {
		pr_err("Failed to create 1:1 mapping for the first page!\n");
		return 1;
	}

	/*
	/*
	 * When making calls to the firmware everything needs to be 1:1
	 * When making calls to the firmware everything needs to be 1:1
	 * mapped and addressable with 32-bit pointers. Map the kernel
	 * mapped and addressable with 32-bit pointers. Map the kernel
+3 −11
Original line number Original line Diff line number Diff line
@@ -187,6 +187,7 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
struct exit_boot_struct {
struct exit_boot_struct {
	efi_memory_desc_t *runtime_map;
	efi_memory_desc_t *runtime_map;
	int *runtime_entry_count;
	int *runtime_entry_count;
	void *new_fdt_addr;
};
};


static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
@@ -202,7 +203,7 @@ static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
	efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
	efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
			p->runtime_map, p->runtime_entry_count);
			p->runtime_map, p->runtime_entry_count);


	return EFI_SUCCESS;
	return update_fdt_memmap(p->new_fdt_addr, map);
}
}


/*
/*
@@ -300,22 +301,13 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,


	priv.runtime_map = runtime_map;
	priv.runtime_map = runtime_map;
	priv.runtime_entry_count = &runtime_entry_count;
	priv.runtime_entry_count = &runtime_entry_count;
	priv.new_fdt_addr = (void *)*new_fdt_addr;
	status = efi_exit_boot_services(sys_table, handle, &map, &priv,
	status = efi_exit_boot_services(sys_table, handle, &map, &priv,
					exit_boot_func);
					exit_boot_func);


	if (status == EFI_SUCCESS) {
	if (status == EFI_SUCCESS) {
		efi_set_virtual_address_map_t *svam;
		efi_set_virtual_address_map_t *svam;


		status = update_fdt_memmap((void *)*new_fdt_addr, &map);
		if (status != EFI_SUCCESS) {
			/*
			 * The kernel won't get far without the memory map, but
			 * may still be able to print something meaningful so
			 * return success here.
			 */
			return EFI_SUCCESS;
		}

		/* Install the new virtual address map */
		/* Install the new virtual address map */
		svam = sys_table->runtime->set_virtual_address_map;
		svam = sys_table->runtime->set_virtual_address_map;
		status = svam(runtime_entry_count * desc_size, desc_size,
		status = svam(runtime_entry_count * desc_size, desc_size,