aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/efi.h5
-rw-r--r--arch/x86/platform/efi/efi.c29
-rw-r--r--arch/x86/platform/efi/efi_64.c7
3 files changed, 26 insertions, 15 deletions
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index c9dcc181d4d1..36ff332da130 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -35,7 +35,7 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
35#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ 35#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \
36 efi_call_virt(f, a1, a2, a3, a4, a5, a6) 36 efi_call_virt(f, a1, a2, a3, a4, a5, a6)
37 37
38#define efi_ioremap(addr, size, type) ioremap_cache(addr, size) 38#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size)
39 39
40#else /* !CONFIG_X86_32 */ 40#else /* !CONFIG_X86_32 */
41 41
@@ -89,7 +89,7 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
89 (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) 89 (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
90 90
91extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, 91extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
92 u32 type); 92 u32 type, u64 attribute);
93 93
94#endif /* CONFIG_X86_32 */ 94#endif /* CONFIG_X86_32 */
95 95
@@ -98,6 +98,7 @@ extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
98extern int efi_memblock_x86_reserve_range(void); 98extern int efi_memblock_x86_reserve_range(void);
99extern void efi_call_phys_prelog(void); 99extern void efi_call_phys_prelog(void);
100extern void efi_call_phys_epilog(void); 100extern void efi_call_phys_epilog(void);
101extern void efi_memory_uc(u64 addr, unsigned long size);
101 102
102#ifndef CONFIG_EFI 103#ifndef CONFIG_EFI
103/* 104/*
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index aded2a91162a..cb34839c97c5 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -810,6 +810,16 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
810 return NULL; 810 return NULL;
811} 811}
812 812
813void efi_memory_uc(u64 addr, unsigned long size)
814{
815 unsigned long page_shift = 1UL << EFI_PAGE_SHIFT;
816 u64 npages;
817
818 npages = round_up(size, page_shift) / page_shift;
819 memrange_efi_to_native(&addr, &npages);
820 set_memory_uc(addr, npages);
821}
822
813/* 823/*
814 * This function will switch the EFI runtime services to virtual mode. 824 * This function will switch the EFI runtime services to virtual mode.
815 * Essentially, look through the EFI memmap and map every region that 825 * Essentially, look through the EFI memmap and map every region that
@@ -823,7 +833,7 @@ void __init efi_enter_virtual_mode(void)
823 efi_memory_desc_t *md, *prev_md = NULL; 833 efi_memory_desc_t *md, *prev_md = NULL;
824 efi_status_t status; 834 efi_status_t status;
825 unsigned long size; 835 unsigned long size;
826 u64 end, systab, addr, npages, end_pfn; 836 u64 end, systab, end_pfn;
827 void *p, *va, *new_memmap = NULL; 837 void *p, *va, *new_memmap = NULL;
828 int count = 0; 838 int count = 0;
829 839
@@ -879,10 +889,14 @@ void __init efi_enter_virtual_mode(void)
879 end_pfn = PFN_UP(end); 889 end_pfn = PFN_UP(end);
880 if (end_pfn <= max_low_pfn_mapped 890 if (end_pfn <= max_low_pfn_mapped
881 || (end_pfn > (1UL << (32 - PAGE_SHIFT)) 891 || (end_pfn > (1UL << (32 - PAGE_SHIFT))
882 && end_pfn <= max_pfn_mapped)) 892 && end_pfn <= max_pfn_mapped)) {
883 va = __va(md->phys_addr); 893 va = __va(md->phys_addr);
884 else 894
885 va = efi_ioremap(md->phys_addr, size, md->type); 895 if (!(md->attribute & EFI_MEMORY_WB))
896 efi_memory_uc((u64)(unsigned long)va, size);
897 } else
898 va = efi_ioremap(md->phys_addr, size,
899 md->type, md->attribute);
886 900
887 md->virt_addr = (u64) (unsigned long) va; 901 md->virt_addr = (u64) (unsigned long) va;
888 902
@@ -892,13 +906,6 @@ void __init efi_enter_virtual_mode(void)
892 continue; 906 continue;
893 } 907 }
894 908
895 if (!(md->attribute & EFI_MEMORY_WB)) {
896 addr = md->virt_addr;
897 npages = md->num_pages;
898 memrange_efi_to_native(&addr, &npages);
899 set_memory_uc(addr, npages);
900 }
901
902 systab = (u64) (unsigned long) efi_phys.systab; 909 systab = (u64) (unsigned long) efi_phys.systab;
903 if (md->phys_addr <= systab && systab < end) { 910 if (md->phys_addr <= systab && systab < end) {
904 systab += md->virt_addr - md->phys_addr; 911 systab += md->virt_addr - md->phys_addr;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ac3aa54e2654..95fd505dfeb6 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -82,7 +82,7 @@ void __init efi_call_phys_epilog(void)
82} 82}
83 83
84void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, 84void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
85 u32 type) 85 u32 type, u64 attribute)
86{ 86{
87 unsigned long last_map_pfn; 87 unsigned long last_map_pfn;
88 88
@@ -92,8 +92,11 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
92 last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); 92 last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size);
93 if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) { 93 if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) {
94 unsigned long top = last_map_pfn << PAGE_SHIFT; 94 unsigned long top = last_map_pfn << PAGE_SHIFT;
95 efi_ioremap(top, size - (top - phys_addr), type); 95 efi_ioremap(top, size - (top - phys_addr), type, attribute);
96 } 96 }
97 97
98 if (!(attribute & EFI_MEMORY_WB))
99 efi_memory_uc((u64)(unsigned long)__va(phys_addr), size);
100
98 return (void __iomem *)__va(phys_addr); 101 return (void __iomem *)__va(phys_addr);
99} 102}