diff options
-rw-r--r-- | arch/x86/include/asm/efi.h | 5 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 29 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_64.c | 7 |
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 | ||
91 | extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, | 91 | extern 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); | |||
98 | extern int efi_memblock_x86_reserve_range(void); | 98 | extern int efi_memblock_x86_reserve_range(void); |
99 | extern void efi_call_phys_prelog(void); | 99 | extern void efi_call_phys_prelog(void); |
100 | extern void efi_call_phys_epilog(void); | 100 | extern void efi_call_phys_epilog(void); |
101 | extern 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 | ||
813 | void 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 | ||
84 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, | 84 | void __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 | } |