Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84a87c62 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi into core/efi



Pull EFI updates from Matt Fleming:

 - Fixes and cleanups for SMBIOS 3.0 DMI code. (Ivan Khoronzhuk)

 - A new efi=debug command line option that enables debug output in the
   EFI boot stub and results in less verbose EFI memory map output by
   default. (Borislav Petkov)

 - Disable interrupts around EFI calls and use a more standard page
   table saving and restoring idiom when making EFI calls. (Ingo Molnar)

 - Reduce the number of memory allocations performed when allocating the
   FDT in EFI boot stub by retrieving size from the FDT header in the
   EFI config table. (Ard Biesheuvel)

Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents e42391cd a643375f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1036,7 +1036,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			Format: {"off" | "on" | "skip[mbr]"}

	efi=		[EFI]
			Format: { "old_map", "nochunk", "noruntime" }
			Format: { "old_map", "nochunk", "noruntime", "debug" }
			old_map [X86-64]: switch to the old ioremap-based EFI
			runtime services mapping. 32-bit still uses this one by
			default.
@@ -1044,6 +1044,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			boot stub, as chunking can cause problems with some
			firmware implementations.
			noruntime : disable EFI runtime services support
			debug: enable misc debug output

	efi_no_storage_paranoia [EFI; X86]
			Using this parameter you can use more than 50% of
+4 −2
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#define _ASM_X86_EFI_H

#include <asm/i387.h>
#include <asm/pgtable.h>

/*
 * We map the EFI regions needed for runtime services non-contiguously,
 * with preserved alignment on virtual addresses starting from -4G down
@@ -89,8 +91,8 @@ 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 void __init efi_call_phys_prolog(void);
extern void __init efi_call_phys_epilog(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_unmap_memmap(void);
extern void __init efi_memory_uc(u64 addr, unsigned long size);
extern void __init efi_map_region(efi_memory_desc_t *md);
+14 −3
Original line number Diff line number Diff line
@@ -85,12 +85,20 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
	efi_memory_desc_t *virtual_map)
{
	efi_status_t status;
	unsigned long flags;
	pgd_t *save_pgd;

	efi_call_phys_prolog();
	save_pgd = efi_call_phys_prolog();

	/* 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);
	efi_call_phys_epilog();
	local_irq_restore(flags);

	efi_call_phys_epilog(save_pgd);

	return status;
}

@@ -491,6 +499,7 @@ void __init efi_init(void)
	if (efi_memmap_init())
		return;

	if (efi_enabled(EFI_DBG))
		print_efi_memmap();
}

@@ -939,6 +948,8 @@ static int __init arch_parse_efi_cmdline(char *str)
{
	if (parse_option_str(str, "old_map"))
		set_bit(EFI_OLD_MEMMAP, &efi.flags);
	if (parse_option_str(str, "debug"))
		set_bit(EFI_DBG, &efi.flags);

	return 0;
}
+11 −11
Original line number Diff line number Diff line
@@ -33,11 +33,10 @@

/*
 * To make EFI call EFI runtime service in physical addressing mode we need
 * prolog/epilog before/after the invocation to disable interrupt, to
 * claim EFI runtime service handler exclusively and to duplicate a memory in
 * low memory space say 0 - 3G.
 * prolog/epilog before/after the invocation to claim the EFI runtime service
 * handler exclusively and to duplicate a memory mapping in low memory space,
 * say 0 - 3G.
 */
static unsigned long efi_rt_eflags;

void efi_sync_low_kernel_mappings(void) {}
void __init efi_dump_pagetable(void) {}
@@ -57,21 +56,24 @@ 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) {}

void __init efi_call_phys_prolog(void)
pgd_t * __init efi_call_phys_prolog(void)
{
	struct desc_ptr gdt_descr;
	pgd_t *save_pgd;

	local_irq_save(efi_rt_eflags);

	/* Current pgd is swapper_pg_dir, we'll restore it later: */
	save_pgd = swapper_pg_dir;
	load_cr3(initial_page_table);
	__flush_tlb_all();

	gdt_descr.address = __pa(get_cpu_gdt_table(0));
	gdt_descr.size = GDT_SIZE - 1;
	load_gdt(&gdt_descr);

	return save_pgd;
}

void __init efi_call_phys_epilog(void)
void __init efi_call_phys_epilog(pgd_t *save_pgd)
{
	struct desc_ptr gdt_descr;

@@ -79,10 +81,8 @@ void __init efi_call_phys_epilog(void)
	gdt_descr.size = GDT_SIZE - 1;
	load_gdt(&gdt_descr);

	load_cr3(swapper_pg_dir);
	load_cr3(save_pgd);
	__flush_tlb_all();

	local_irq_restore(efi_rt_eflags);
}

void __init efi_runtime_mkexec(void)
+16 −13
Original line number Diff line number Diff line
@@ -41,9 +41,6 @@
#include <asm/realmode.h>
#include <asm/time.h>

static pgd_t *save_pgd __initdata;
static unsigned long efi_flags __initdata;

/*
 * We allocate runtime services regions bottom-up, starting from -4G, i.e.
 * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G.
@@ -78,17 +75,18 @@ static void __init early_code_mapping_set_exec(int executable)
	}
}

void __init efi_call_phys_prolog(void)
pgd_t * __init efi_call_phys_prolog(void)
{
	unsigned long vaddress;
	pgd_t *save_pgd;

	int pgd;
	int n_pgds;

	if (!efi_enabled(EFI_OLD_MEMMAP))
		return;
		return NULL;

	early_code_mapping_set_exec(1);
	local_irq_save(efi_flags);

	n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
	save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
@@ -99,24 +97,29 @@ void __init efi_call_phys_prolog(void)
		set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
	}
	__flush_tlb_all();

	return save_pgd;
}

void __init efi_call_phys_epilog(void)
void __init efi_call_phys_epilog(pgd_t *save_pgd)
{
	/*
	 * After the lock is released, the original page table is restored.
	 */
	int pgd;
	int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
	int pgd_idx;
	int nr_pgds;

	if (!efi_enabled(EFI_OLD_MEMMAP))
	if (!save_pgd)
		return;

	for (pgd = 0; pgd < n_pgds; pgd++)
		set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
	nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);

	for (pgd_idx = 0; pgd_idx < nr_pgds; pgd_idx++)
		set_pgd(pgd_offset_k(pgd_idx * PGDIR_SIZE), save_pgd[pgd_idx]);

	kfree(save_pgd);

	__flush_tlb_all();
	local_irq_restore(efi_flags);
	early_code_mapping_set_exec(0);
}

Loading