aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-10-03 10:46:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-10-03 10:46:41 -0400
commita758379b031f50b9def094aad071ef547a5cb335 (patch)
tree3a29fedfd77b578a568916ce4c3b6cf2750b8a77 /arch
parent14f97d9713283adfadf2193e287e21d079f72ee7 (diff)
parent0ce3cc008ec04258b6a6314b09f1a6012810881a (diff)
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI fixes from Ingo Molnar: "Two EFI fixes: one for x86, one for ARM, fixing a boot crash bug that can trigger under newer EFI firmware" * 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME regions x86/efi: Fix boot crash by mapping EFI memmap entries bottom-up at runtime, instead of top-down
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/kernel/efi.c3
-rw-r--r--arch/x86/platform/efi/efi.c67
2 files changed, 68 insertions, 2 deletions
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index e8ca6eaedd02..13671a9cf016 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -258,7 +258,8 @@ static bool __init efi_virtmap_init(void)
258 */ 258 */
259 if (!is_normal_ram(md)) 259 if (!is_normal_ram(md))
260 prot = __pgprot(PROT_DEVICE_nGnRE); 260 prot = __pgprot(PROT_DEVICE_nGnRE);
261 else if (md->type == EFI_RUNTIME_SERVICES_CODE) 261 else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
262 !PAGE_ALIGNED(md->phys_addr))
262 prot = PAGE_KERNEL_EXEC; 263 prot = PAGE_KERNEL_EXEC;
263 else 264 else
264 prot = PAGE_KERNEL; 265 prot = PAGE_KERNEL;
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 1db84c0758b7..6a28ded74211 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -705,6 +705,70 @@ out:
705} 705}
706 706
707/* 707/*
708 * Iterate the EFI memory map in reverse order because the regions
709 * will be mapped top-down. The end result is the same as if we had
710 * mapped things forward, but doesn't require us to change the
711 * existing implementation of efi_map_region().
712 */
713static inline void *efi_map_next_entry_reverse(void *entry)
714{
715 /* Initial call */
716 if (!entry)
717 return memmap.map_end - memmap.desc_size;
718
719 entry -= memmap.desc_size;
720 if (entry < memmap.map)
721 return NULL;
722
723 return entry;
724}
725
726/*
727 * efi_map_next_entry - Return the next EFI memory map descriptor
728 * @entry: Previous EFI memory map descriptor
729 *
730 * This is a helper function to iterate over the EFI memory map, which
731 * we do in different orders depending on the current configuration.
732 *
733 * To begin traversing the memory map @entry must be %NULL.
734 *
735 * Returns %NULL when we reach the end of the memory map.
736 */
737static void *efi_map_next_entry(void *entry)
738{
739 if (!efi_enabled(EFI_OLD_MEMMAP) && efi_enabled(EFI_64BIT)) {
740 /*
741 * Starting in UEFI v2.5 the EFI_PROPERTIES_TABLE
742 * config table feature requires us to map all entries
743 * in the same order as they appear in the EFI memory
744 * map. That is to say, entry N must have a lower
745 * virtual address than entry N+1. This is because the
746 * firmware toolchain leaves relative references in
747 * the code/data sections, which are split and become
748 * separate EFI memory regions. Mapping things
749 * out-of-order leads to the firmware accessing
750 * unmapped addresses.
751 *
752 * Since we need to map things this way whether or not
753 * the kernel actually makes use of
754 * EFI_PROPERTIES_TABLE, let's just switch to this
755 * scheme by default for 64-bit.
756 */
757 return efi_map_next_entry_reverse(entry);
758 }
759
760 /* Initial call */
761 if (!entry)
762 return memmap.map;
763
764 entry += memmap.desc_size;
765 if (entry >= memmap.map_end)
766 return NULL;
767
768 return entry;
769}
770
771/*
708 * Map the efi memory ranges of the runtime services and update new_mmap with 772 * Map the efi memory ranges of the runtime services and update new_mmap with
709 * virtual addresses. 773 * virtual addresses.
710 */ 774 */
@@ -714,7 +778,8 @@ static void * __init efi_map_regions(int *count, int *pg_shift)
714 unsigned long left = 0; 778 unsigned long left = 0;
715 efi_memory_desc_t *md; 779 efi_memory_desc_t *md;
716 780
717 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { 781 p = NULL;
782 while ((p = efi_map_next_entry(p))) {
718 md = p; 783 md = p;
719 if (!(md->attribute & EFI_MEMORY_RUNTIME)) { 784 if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
720#ifdef CONFIG_X86_64 785#ifdef CONFIG_X86_64