From: Greg Kroah-Hartman Date: Mon, 29 Oct 2012 17:09:08 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.0.50~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=207c5a55dcc3989f00835eabdc5352d7b41fa317;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: efi-defer-freeing-boot-services-memory-until-after-acpi-init.patch x86-efi-turn-off-efi_enabled-after-setup-on-mixed-fw-kernel.patch --- diff --git a/queue-3.4/efi-defer-freeing-boot-services-memory-until-after-acpi-init.patch b/queue-3.4/efi-defer-freeing-boot-services-memory-until-after-acpi-init.patch new file mode 100644 index 00000000000..c3b41058813 --- /dev/null +++ b/queue-3.4/efi-defer-freeing-boot-services-memory-until-after-acpi-init.patch @@ -0,0 +1,122 @@ +From 785107923a83d8456bbd8564e288a24d84109a46 Mon Sep 17 00:00:00 2001 +From: Josh Triplett +Date: Fri, 28 Sep 2012 17:55:44 -0700 +Subject: efi: Defer freeing boot services memory until after ACPI init + +From: Josh Triplett + +commit 785107923a83d8456bbd8564e288a24d84109a46 upstream. + +Some new ACPI 5.0 tables reference resources stored in boot services +memory, so keep that memory around until we have ACPI and can extract +data from it. + +Signed-off-by: Josh Triplett +Link: http://lkml.kernel.org/r/baaa6d44bdc4eb0c58e5d1b4ccd2c729f854ac55.1348876882.git.josh@joshtriplett.org +Signed-off-by: H. Peter Anvin +Cc: Matt Fleming +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/platform/efi/efi.c | 31 ++++++++++++++++++------------- + include/linux/efi.h | 5 +++++ + init/main.c | 3 +++ + 3 files changed, 26 insertions(+), 13 deletions(-) + +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -419,10 +419,21 @@ void __init efi_reserve_boot_services(vo + } + } + +-static void __init efi_free_boot_services(void) ++static void __init efi_unmap_memmap(void) ++{ ++ if (memmap.map) { ++ early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); ++ memmap.map = NULL; ++ } ++} ++ ++void __init efi_free_boot_services(void) + { + void *p; + ++ if (!efi_native) ++ return; ++ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + efi_memory_desc_t *md = p; + unsigned long long start = md->phys_addr; +@@ -438,6 +449,8 @@ static void __init efi_free_boot_service + + free_bootmem_late(start, size); + } ++ ++ efi_unmap_memmap(); + } + + static int __init efi_systab_init(void *phys) +@@ -787,8 +800,10 @@ void __init efi_enter_virtual_mode(void) + * non-native EFI + */ + +- if (!efi_native) +- goto out; ++ if (!efi_native) { ++ efi_unmap_memmap(); ++ return; ++ } + + /* Merge contiguous regions of the same type and attribute */ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +@@ -878,13 +893,6 @@ void __init efi_enter_virtual_mode(void) + } + + /* +- * Thankfully, it does seem that no runtime services other than +- * SetVirtualAddressMap() will touch boot services code, so we can +- * get rid of it all at this point +- */ +- efi_free_boot_services(); +- +- /* + * Now that EFI is in virtual mode, update the function + * pointers in the runtime service table to the new virtual addresses. + * +@@ -907,9 +915,6 @@ void __init efi_enter_virtual_mode(void) + if (__supported_pte_mask & _PAGE_NX) + runtime_code_page_mkexec(); + +-out: +- early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); +- memmap.map = NULL; + kfree(new_memmap); + } + +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -496,6 +496,11 @@ extern void efi_map_pal_code (void); + extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg); + extern void efi_gettimeofday (struct timespec *ts); + extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ ++#ifdef CONFIG_X86 ++extern void efi_free_boot_services(void); ++#else ++static inline void efi_free_boot_services(void) {} ++#endif + extern u64 efi_get_iobase (void); + extern u32 efi_mem_type (unsigned long phys_addr); + extern u64 efi_mem_attributes (unsigned long phys_addr); +--- a/init/main.c ++++ b/init/main.c +@@ -630,6 +630,9 @@ asmlinkage void __init start_kernel(void + acpi_early_init(); /* before LAPIC and SMP init */ + sfi_init_late(); + ++ if (efi_enabled) ++ efi_free_boot_services(); ++ + ftrace_init(); + + /* Do the rest non-__init'ed, we're now alive */ diff --git a/queue-3.4/series b/queue-3.4/series index 262adc6956e..67ae4894fc8 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -47,3 +47,5 @@ cpufreq-powernow-k8-remove-usage-of-smp_processor_id-in-preemptible-code.patch revert-ath9k_hw-updated-ar9003-tx-gain-table-for-5ghz.patch x86-mm-find_early_table_space-based-on-ranges-that-are-actually-being-mapped.patch x86-mm-undo-incorrect-revert-in-arch-x86-mm-init.c.patch +efi-defer-freeing-boot-services-memory-until-after-acpi-init.patch +x86-efi-turn-off-efi_enabled-after-setup-on-mixed-fw-kernel.patch diff --git a/queue-3.4/x86-efi-turn-off-efi_enabled-after-setup-on-mixed-fw-kernel.patch b/queue-3.4/x86-efi-turn-off-efi_enabled-after-setup-on-mixed-fw-kernel.patch new file mode 100644 index 00000000000..af6e767c32b --- /dev/null +++ b/queue-3.4/x86-efi-turn-off-efi_enabled-after-setup-on-mixed-fw-kernel.patch @@ -0,0 +1,140 @@ +From 5189c2a7c7769ee9d037d76c1a7b8550ccf3481c Mon Sep 17 00:00:00 2001 +From: Olof Johansson +Date: Wed, 24 Oct 2012 10:00:44 -0700 +Subject: x86: efi: Turn off efi_enabled after setup on mixed fw/kernel + +From: Olof Johansson + +commit 5189c2a7c7769ee9d037d76c1a7b8550ccf3481c upstream. + +When 32-bit EFI is used with 64-bit kernel (or vice versa), turn off +efi_enabled once setup is done. Beyond setup, it is normally used to +determine if runtime services are available and we will have none. + +This will resolve issues stemming from efivars modprobe panicking on a +32/64-bit setup, as well as some reboot issues on similar setups. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=45991 + +Reported-by: Marko Kohtala +Reported-by: Maxim Kammerer +Signed-off-by: Olof Johansson +Acked-by: Maarten Lankhorst +Cc: Matthew Garrett +Signed-off-by: Matt Fleming +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/efi.h | 1 + + arch/x86/kernel/setup.c | 12 ++++++++++++ + arch/x86/platform/efi/efi.c | 18 ++++++++++-------- + 3 files changed, 23 insertions(+), 8 deletions(-) + +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -98,6 +98,7 @@ extern void efi_set_executable(efi_memor + extern int efi_memblock_x86_reserve_range(void); + extern void efi_call_phys_prelog(void); + extern void efi_call_phys_epilog(void); ++extern void efi_unmap_memmap(void); + + #ifndef CONFIG_EFI + /* +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1053,6 +1053,18 @@ void __init setup_arch(char **cmdline_p) + mcheck_init(); + + arch_init_ideal_nops(); ++ ++#ifdef CONFIG_EFI ++ /* Once setup is done above, disable efi_enabled on mismatched ++ * firmware/kernel archtectures since there is no support for ++ * runtime services. ++ */ ++ if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { ++ pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); ++ efi_unmap_memmap(); ++ efi_enabled = 0; ++ } ++#endif + } + + #ifdef CONFIG_X86_32 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -69,11 +69,15 @@ EXPORT_SYMBOL(efi); + struct efi_memory_map memmap; + + bool efi_64bit; +-static bool efi_native; + + static struct efi efi_phys __initdata; + static efi_system_table_t efi_systab __initdata; + ++static inline bool efi_is_native(void) ++{ ++ return IS_ENABLED(CONFIG_X86_64) == efi_64bit; ++} ++ + static int __init setup_noefi(char *arg) + { + efi_enabled = 0; +@@ -419,7 +423,7 @@ void __init efi_reserve_boot_services(vo + } + } + +-static void __init efi_unmap_memmap(void) ++void __init efi_unmap_memmap(void) + { + if (memmap.map) { + early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); +@@ -431,7 +435,7 @@ void __init efi_free_boot_services(void) + { + void *p; + +- if (!efi_native) ++ if (!efi_is_native()) + return; + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +@@ -683,12 +687,10 @@ void __init efi_init(void) + return; + } + efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; +- efi_native = !efi_64bit; + #else + efi_phys.systab = (efi_system_table_t *) + (boot_params.efi_info.efi_systab | + ((__u64)boot_params.efi_info.efi_systab_hi<<32)); +- efi_native = efi_64bit; + #endif + + if (efi_systab_init(efi_phys.systab)) { +@@ -722,7 +724,7 @@ void __init efi_init(void) + * that doesn't match the kernel 32/64-bit mode. + */ + +- if (!efi_native) ++ if (!efi_is_native()) + pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); + else if (efi_runtime_init()) { + efi_enabled = 0; +@@ -734,7 +736,7 @@ void __init efi_init(void) + return; + } + #ifdef CONFIG_X86_32 +- if (efi_native) { ++ if (efi_is_native()) { + x86_platform.get_wallclock = efi_get_time; + x86_platform.set_wallclock = efi_set_rtc_mmss; + } +@@ -800,7 +802,7 @@ void __init efi_enter_virtual_mode(void) + * non-native EFI + */ + +- if (!efi_native) { ++ if (!efi_is_native()) { + efi_unmap_memmap(); + return; + }