aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/init_64.c40
-rw-r--r--include/asm-x86/page_64.h4
-rw-r--r--include/asm-x86/pgtable.h2
3 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 77d129d62c97..57d5eff754c9 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -202,6 +202,46 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval)
202} 202}
203 203
204/* 204/*
205 * Create large page table mappings for a range of physical addresses.
206 */
207static void __init __init_extra_mapping(unsigned long phys, unsigned long size,
208 pgprot_t prot)
209{
210 pgd_t *pgd;
211 pud_t *pud;
212 pmd_t *pmd;
213
214 BUG_ON((phys & ~PMD_MASK) || (size & ~PMD_MASK));
215 for (; size; phys += PMD_SIZE, size -= PMD_SIZE) {
216 pgd = pgd_offset_k((unsigned long)__va(phys));
217 if (pgd_none(*pgd)) {
218 pud = (pud_t *) spp_getpage();
219 set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
220 _PAGE_USER));
221 }
222 pud = pud_offset(pgd, (unsigned long)__va(phys));
223 if (pud_none(*pud)) {
224 pmd = (pmd_t *) spp_getpage();
225 set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
226 _PAGE_USER));
227 }
228 pmd = pmd_offset(pud, phys);
229 BUG_ON(!pmd_none(*pmd));
230 set_pmd(pmd, __pmd(phys | pgprot_val(prot)));
231 }
232}
233
234void __init init_extra_mapping_wb(unsigned long phys, unsigned long size)
235{
236 __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE);
237}
238
239void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
240{
241 __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE_NOCACHE);
242}
243
244/*
205 * The head.S code sets up the kernel high mapping: 245 * The head.S code sets up the kernel high mapping:
206 * 246 *
207 * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text) 247 * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text)
diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
index 010d12db80dc..c6916c83e6b1 100644
--- a/include/asm-x86/page_64.h
+++ b/include/asm-x86/page_64.h
@@ -91,6 +91,10 @@ extern unsigned long init_memory_mapping(unsigned long start,
91 unsigned long end); 91 unsigned long end);
92 92
93extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); 93extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
94
95extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
96extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
97
94#endif /* !__ASSEMBLY__ */ 98#endif /* !__ASSEMBLY__ */
95 99
96#ifdef CONFIG_FLATMEM 100#ifdef CONFIG_FLATMEM
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 64de07e25329..49cbd76b9547 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -91,6 +91,7 @@
91#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER) 91#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
92#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT) 92#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
93#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) 93#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
94#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
94#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) 95#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
95 96
96#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) 97#define PAGE_KERNEL __pgprot(__PAGE_KERNEL)
@@ -102,6 +103,7 @@
102#define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS) 103#define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS)
103#define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE) 104#define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE)
104#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) 105#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE)
106#define PAGE_KERNEL_LARGE_NOCACHE __pgprot(__PAGE_KERNEL_LARGE_NOCACHE)
105#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) 107#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)
106#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) 108#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL)
107#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE) 109#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)