Skip to content

Commit

Permalink
x86: efi: Turn off efi_enabled after setup on mixed fw/kernel
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reported-by: Maxim Kammerer <[email protected]>
Signed-off-by: Olof Johansson <[email protected]>
Acked-by: Maarten Lankhorst <[email protected]>
Cc: [email protected] # 3.4 - 3.6
Cc: Matthew Garrett <[email protected]>
Signed-off-by: Matt Fleming <[email protected]>
  • Loading branch information
olofj authored and Matt Fleming committed Oct 25, 2012
1 parent 78bef24 commit 5189c2a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
/*
Expand Down
12 changes: 12 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,18 @@ void __init setup_arch(char **cmdline_p)
arch_init_ideal_nops();

register_refined_jiffies(CLOCK_TICK_RATE);

#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
Expand Down
18 changes: 10 additions & 8 deletions arch/x86/platform/efi/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,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;
Expand Down Expand Up @@ -420,7 +424,7 @@ void __init efi_reserve_boot_services(void)
}
}

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);
Expand All @@ -432,7 +436,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) {
Expand Down Expand Up @@ -684,12 +688,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)) {
Expand Down Expand Up @@ -723,7 +725,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;
Expand All @@ -735,7 +737,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;
}
Expand Down Expand Up @@ -834,7 +836,7 @@ void __init efi_enter_virtual_mode(void)
* non-native EFI
*/

if (!efi_native) {
if (!efi_is_native()) {
efi_unmap_memmap();
return;
}
Expand Down

0 comments on commit 5189c2a

Please sign in to comment.