diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 09c3fc46879391d1fd5d717e1da2822f12ccd5bd..e29e5dc0b7506fd3ec72867f87e3d84a4ad0c223 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -61,8 +61,6 @@ extern asmlinkage unsigned long efi_call_phys(void *, ...); extern asmlinkage u64 efi_call(void *fp, ...); -#define efi_call_phys(f, args...) efi_call((f), args) - /* * struct efi_scratch - Scratch space used while switching to/from efi_mm * @phys_stack: stack used during EFI Mixed Mode @@ -115,8 +113,6 @@ extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size, extern struct efi_scratch efi_scratch; extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); extern int __init efi_memblock_x86_reserve_range(void); -extern pgd_t * __init efi_call_phys_prolog(void); -extern void __init efi_call_phys_epilog(pgd_t *save_pgd); extern void __init efi_print_memmap(void); extern void __init efi_memory_uc(u64 addr, unsigned long size); extern void __init efi_map_region(efi_memory_desc_t *md); @@ -177,6 +173,10 @@ extern efi_status_t efi_thunk_set_virtual_address_map( unsigned long descriptor_size, u32 descriptor_version, efi_memory_desc_t *virtual_map); +efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map); /* arch specific definitions used by the stub code */ diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 3ce32c31bb61fea5cd18ef94376e5f5d14b06bf5..50f8123e658a8c78afcc71327b08803afb682fc0 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -54,7 +54,7 @@ #include #include -static struct efi efi_phys __initdata; +struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; static efi_config_table_type_t arch_tables[] __initdata = { @@ -97,32 +97,6 @@ static int __init setup_add_efi_memmap(char *arg) } early_param("add_efi_memmap", setup_add_efi_memmap); -static efi_status_t __init phys_efi_set_virtual_address_map( - unsigned long memory_map_size, - unsigned long descriptor_size, - u32 descriptor_version, - efi_memory_desc_t *virtual_map) -{ - efi_status_t status; - unsigned long flags; - pgd_t *save_pgd; - - save_pgd = efi_call_phys_prolog(); - if (!save_pgd) - return EFI_ABORTED; - - /* Disable interrupts around EFI calls: */ - local_irq_save(flags); - status = efi_call_phys(efi_phys.set_virtual_address_map, - memory_map_size, descriptor_size, - descriptor_version, virtual_map); - local_irq_restore(flags); - - efi_call_phys_epilog(save_pgd); - - return status; -} - void __init efi_find_mirror(void) { efi_memory_desc_t *md; @@ -1042,7 +1016,7 @@ static void __init __efi_enter_virtual_mode(void) efi_sync_low_kernel_mappings(); if (!efi_is_mixed()) { - status = phys_efi_set_virtual_address_map( + status = efi_set_virtual_address_map( efi.memmap.desc_size * count, efi.memmap.desc_size, efi.memmap.desc_version, diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 9959657127f476ae3018894ffc31909ee2c6d79e..185950ade0e98b509edaaceead11e8566522e598 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -66,9 +66,16 @@ void __init efi_map_region(efi_memory_desc_t *md) void __init efi_map_region_fixed(efi_memory_desc_t *md) {} void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} -pgd_t * __init efi_call_phys_prolog(void) +extern struct efi efi_phys; + +efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map) { struct desc_ptr gdt_descr; + efi_status_t status; + unsigned long flags; pgd_t *save_pgd; /* Current pgd is swapper_pg_dir, we'll restore it later: */ @@ -80,14 +87,18 @@ pgd_t * __init efi_call_phys_prolog(void) gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); - return save_pgd; -} + /* Disable interrupts around EFI calls: */ + local_irq_save(flags); + status = efi_call_phys(efi_phys.set_virtual_address_map, + memory_map_size, descriptor_size, + descriptor_version, virtual_map); + local_irq_restore(flags); -void __init efi_call_phys_epilog(pgd_t *save_pgd) -{ load_fixmap_gdt(0); load_cr3(save_pgd); __flush_tlb_all(); + + return status; } void __init efi_runtime_update_mappings(void) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a72bbabbc5953e1f588e931c209fb041a52a236c..a7f11d1ff7c4cac7206e87053b4e1a1830624c9d 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -72,9 +72,9 @@ static void __init early_code_mapping_set_exec(int executable) } } -void __init efi_old_memmap_phys_epilog(pgd_t *save_pgd); +static void __init efi_old_memmap_phys_epilog(pgd_t *save_pgd); -pgd_t * __init efi_old_memmap_phys_prolog(void) +static pgd_t * __init efi_old_memmap_phys_prolog(void) { unsigned long vaddr, addr_pgd, addr_p4d, addr_pud; pgd_t *save_pgd, *pgd_k, *pgd_efi; @@ -144,7 +144,7 @@ pgd_t * __init efi_old_memmap_phys_prolog(void) return NULL; } -void __init efi_old_memmap_phys_epilog(pgd_t *save_pgd) +static void __init efi_old_memmap_phys_epilog(pgd_t *save_pgd) { /* * After the lock is released, the original page table is restored. @@ -185,23 +185,6 @@ void __init efi_old_memmap_phys_epilog(pgd_t *save_pgd) early_code_mapping_set_exec(0); } -pgd_t * __init efi_call_phys_prolog(void) -{ - if (efi_enabled(EFI_OLD_MEMMAP)) - return efi_old_memmap_phys_prolog(); - - efi_switch_mm(&efi_mm); - return efi_mm.pgd; -} - -void __init efi_call_phys_epilog(pgd_t *save_pgd) -{ - if (efi_enabled(EFI_OLD_MEMMAP)) - efi_old_memmap_phys_epilog(save_pgd); - else - efi_switch_mm(efi_scratch.prev_mm); -} - EXPORT_SYMBOL_GPL(efi_mm); /* @@ -1018,3 +1001,36 @@ void efi_thunk_runtime_setup(void) efi.query_capsule_caps = efi_thunk_query_capsule_caps; } #endif /* CONFIG_EFI_MIXED */ + +efi_status_t __init efi_set_virtual_address_map(unsigned long memory_map_size, + unsigned long descriptor_size, + u32 descriptor_version, + efi_memory_desc_t *virtual_map) +{ + efi_status_t status; + unsigned long flags; + pgd_t *save_pgd = NULL; + + if (efi_enabled(EFI_OLD_MEMMAP)) { + save_pgd = efi_old_memmap_phys_prolog(); + if (!save_pgd) + return EFI_ABORTED; + } else { + efi_switch_mm(&efi_mm); + } + + /* Disable interrupts around EFI calls: */ + local_irq_save(flags); + status = efi_call(efi.systab->runtime->set_virtual_address_map, + memory_map_size, descriptor_size, + descriptor_version, virtual_map); + local_irq_restore(flags); + + + if (save_pgd) + efi_old_memmap_phys_epilog(save_pgd); + else + efi_switch_mm(efi_scratch.prev_mm); + + return status; +}