diff options
Diffstat (limited to 'arch/x86/platform/efi/efi.c')
| -rw-r--r-- | arch/x86/platform/efi/efi.c | 47 | 
1 files changed, 28 insertions, 19 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index aded2a91162..ad4439145f8 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -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; @@ -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); @@ -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) { @@ -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)) { @@ -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; @@ -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;  	} @@ -810,6 +812,16 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr)  	return NULL;  } +void efi_memory_uc(u64 addr, unsigned long size) +{ +	unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; +	u64 npages; + +	npages = round_up(size, page_shift) / page_shift; +	memrange_efi_to_native(&addr, &npages); +	set_memory_uc(addr, npages); +} +  /*   * This function will switch the EFI runtime services to virtual mode.   * Essentially, look through the EFI memmap and map every region that @@ -823,7 +835,7 @@ void __init efi_enter_virtual_mode(void)  	efi_memory_desc_t *md, *prev_md = NULL;  	efi_status_t status;  	unsigned long size; -	u64 end, systab, addr, npages, end_pfn; +	u64 end, systab, end_pfn;  	void *p, *va, *new_memmap = NULL;  	int count = 0; @@ -834,7 +846,7 @@ void __init efi_enter_virtual_mode(void)  	 * non-native EFI  	 */ -	if (!efi_native) { +	if (!efi_is_native()) {  		efi_unmap_memmap();  		return;  	} @@ -879,10 +891,14 @@ void __init efi_enter_virtual_mode(void)  		end_pfn = PFN_UP(end);  		if (end_pfn <= max_low_pfn_mapped  		    || (end_pfn > (1UL << (32 - PAGE_SHIFT)) -			&& end_pfn <= max_pfn_mapped)) +			&& end_pfn <= max_pfn_mapped)) {  			va = __va(md->phys_addr); -		else -			va = efi_ioremap(md->phys_addr, size, md->type); + +			if (!(md->attribute & EFI_MEMORY_WB)) +				efi_memory_uc((u64)(unsigned long)va, size); +		} else +			va = efi_ioremap(md->phys_addr, size, +					 md->type, md->attribute);  		md->virt_addr = (u64) (unsigned long) va; @@ -892,13 +908,6 @@ void __init efi_enter_virtual_mode(void)  			continue;  		} -		if (!(md->attribute & EFI_MEMORY_WB)) { -			addr = md->virt_addr; -			npages = md->num_pages; -			memrange_efi_to_native(&addr, &npages); -			set_memory_uc(addr, npages); -		} -  		systab = (u64) (unsigned long) efi_phys.systab;  		if (md->phys_addr <= systab && systab < end) {  			systab += md->virt_addr - md->phys_addr;  |