Skip to content

Commit

Permalink
Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/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
  • Loading branch information
Linus Torvalds committed Feb 2, 2017
2 parents 027eb72 + c8f325a commit c67b42f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
16 changes: 16 additions & 0 deletions arch/x86/platform/efi/efi_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,22 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)

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
* mapped and addressable with 32-bit pointers. Map the kernel
Expand Down
14 changes: 3 additions & 11 deletions drivers/firmware/efi/libstub/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
struct exit_boot_struct {
efi_memory_desc_t *runtime_map;
int *runtime_entry_count;
void *new_fdt_addr;
};

static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
Expand All @@ -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,
p->runtime_map, p->runtime_entry_count);

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

/*
Expand Down Expand Up @@ -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_entry_count = &runtime_entry_count;
priv.new_fdt_addr = (void *)*new_fdt_addr;
status = efi_exit_boot_services(sys_table, handle, &map, &priv,
exit_boot_func);

if (status == EFI_SUCCESS) {
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 */
svam = sys_table->runtime->set_virtual_address_map;
status = svam(runtime_entry_count * desc_size, desc_size,
Expand Down

0 comments on commit c67b42f

Please sign in to comment.