[quantal][PATCH] x86: efi: Turn off efi_enabled after setup on mixed fw/kernel
Seth Forshee
seth.forshee at canonical.com
Tue Nov 27 15:50:31 UTC 2012
On Tue, Nov 27, 2012 at 09:13:30AM -0600, Chris J Arges wrote:
> SRU Justification:
>
> Impact: Booting i386 kernels on 64-bit efi firmware does not work on
> quantal.
>
> Fix: Upstream commit 5189c2a7c7769ee9d037d76c1a7b8550ccf3481c can be
> cherry-picked into quantal. This commit is already present in raring.
>
> Testcase: Properly boot an i386 quantal kernel on a device that has
> 64-bit EFI firmware.
>
> BugLink: http://launchpad.net/bugs/1082059
>
> From 8d0ea8f86b6c45ccb14a3f1acf312726cbfc04ad Mon Sep 17 00:00:00 2001
> From: Olof Johansson <olof at lixom.net>
> Date: Wed, 24 Oct 2012 10:00:44 -0700
> Subject: [PATCH] x86: efi: Turn off efi_enabled after setup on mixed
> fw/kernel
>
> 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 <marko.kohtala at gmail.com>
> Reported-by: Maxim Kammerer <mk at dee.su>
> Signed-off-by: Olof Johansson <olof at lixom.net>
> Acked-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
> Cc: stable at kernel.org # 3.4 - 3.6
If this was Cc stable, why don't we have it already? Seems like it
should be in all the upstream stable trees.
> Cc: Matthew Garrett <mjg at redhat.com>
> Signed-off-by: Matt Fleming <matt.fleming at intel.com>
> (cherry picked from commit 5189c2a7c7769ee9d037d76c1a7b8550ccf3481c)
>
> Conflicts:
>
> arch/x86/kernel/setup.c
> arch/x86/platform/efi/efi.c
>
> BugLink: http://launchpad.net/bugs/1082059
>
> Signed-off-by: Chris J Arges <chris.j.arges at canonical.com>
> ---
> arch/x86/include/asm/efi.h | 1 +
> arch/x86/kernel/setup.c | 12 ++++++++++++
> arch/x86/platform/efi/efi.c | 31 +++++++++++++++++++++++--------
> 3 files changed, 36 insertions(+), 8 deletions(-)
>
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index c9dcc18..029189d 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -98,6 +98,7 @@ extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
> 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
> /*
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 16be6dc..cea0aef 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -1036,6 +1036,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
> diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
> index f55a4ce..f9bcbac 100644
> --- 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,10 +423,21 @@ void __init efi_reserve_boot_services(void)
> }
> }
>
> -static void __init efi_free_boot_services(void)
> +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)
These changes were already present in the original commit. Does it make
sense to backport the patch(es) that originally adds these instead of
folding it into this backport?
> {
> void *p;
>
> + if (!efi_is_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;
> @@ -670,12 +685,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)) {
> @@ -709,7 +722,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;
> @@ -721,7 +734,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;
> }
> @@ -787,8 +800,10 @@ void __init efi_enter_virtual_mode(void)
> * non-native EFI
> */
>
> - if (!efi_native)
> - goto out;
> + if (!efi_is_native()) {
> + efi_unmap_memmap();
> + return;
> + }
Again, some of the changes here appear to be from an earlier commit, so
I have the same question as above.
>
> /* Merge contiguous regions of the same type and attribute */
> for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
> --
> 1.7.9.5
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list