diff options
-rw-r--r-- | arch/x86/mm/init_64.c | 40 | ||||
-rw-r--r-- | include/asm-x86/page_64.h | 4 | ||||
-rw-r--r-- | include/asm-x86/pgtable.h | 2 |
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 | */ | ||
207 | static 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 | |||
234 | void __init init_extra_mapping_wb(unsigned long phys, unsigned long size) | ||
235 | { | ||
236 | __init_extra_mapping(phys, size, PAGE_KERNEL_LARGE); | ||
237 | } | ||
238 | |||
239 | void __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 | ||
93 | extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); | 93 | extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn); |
94 | |||
95 | extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); | ||
96 | extern 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) |