| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * arch/arm/include/asm/pgtable.h |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 1995-2002 Russell King |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 8 | | - * published by the Free Software Foundation. |
|---|
| 9 | 6 | */ |
|---|
| 10 | 7 | #ifndef _ASMARM_PGTABLE_H |
|---|
| 11 | 8 | #define _ASMARM_PGTABLE_H |
|---|
| .. | .. |
|---|
| 13 | 10 | #include <linux/const.h> |
|---|
| 14 | 11 | #include <asm/proc-fns.h> |
|---|
| 15 | 12 | |
|---|
| 13 | +#ifndef __ASSEMBLY__ |
|---|
| 14 | +/* |
|---|
| 15 | + * ZERO_PAGE is a global shared page that is always zero: used |
|---|
| 16 | + * for zero-mapped memory areas etc.. |
|---|
| 17 | + */ |
|---|
| 18 | +extern struct page *empty_zero_page; |
|---|
| 19 | +#define ZERO_PAGE(vaddr) (empty_zero_page) |
|---|
| 20 | +#endif |
|---|
| 21 | + |
|---|
| 16 | 22 | #ifndef CONFIG_MMU |
|---|
| 17 | 23 | |
|---|
| 18 | | -#include <asm-generic/4level-fixup.h> |
|---|
| 24 | +#include <asm-generic/pgtable-nopud.h> |
|---|
| 19 | 25 | #include <asm/pgtable-nommu.h> |
|---|
| 20 | 26 | |
|---|
| 21 | 27 | #else |
|---|
| 22 | 28 | |
|---|
| 23 | | -#define __ARCH_USE_5LEVEL_HACK |
|---|
| 24 | 29 | #include <asm-generic/pgtable-nopud.h> |
|---|
| 25 | 30 | #include <asm/memory.h> |
|---|
| 26 | 31 | #include <asm/pgtable-hwdef.h> |
|---|
| .. | .. |
|---|
| 83 | 88 | |
|---|
| 84 | 89 | extern pgprot_t pgprot_user; |
|---|
| 85 | 90 | extern pgprot_t pgprot_kernel; |
|---|
| 86 | | -extern pgprot_t pgprot_hyp_device; |
|---|
| 87 | | -extern pgprot_t pgprot_s2; |
|---|
| 88 | | -extern pgprot_t pgprot_s2_device; |
|---|
| 89 | 91 | |
|---|
| 90 | 92 | #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) |
|---|
| 91 | 93 | |
|---|
| .. | .. |
|---|
| 98 | 100 | #define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY) |
|---|
| 99 | 101 | #define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN) |
|---|
| 100 | 102 | #define PAGE_KERNEL_EXEC pgprot_kernel |
|---|
| 101 | | -#define PAGE_HYP _MOD_PROT(pgprot_kernel, L_PTE_HYP | L_PTE_XN) |
|---|
| 102 | | -#define PAGE_HYP_EXEC _MOD_PROT(pgprot_kernel, L_PTE_HYP | L_PTE_RDONLY) |
|---|
| 103 | | -#define PAGE_HYP_RO _MOD_PROT(pgprot_kernel, L_PTE_HYP | L_PTE_RDONLY | L_PTE_XN) |
|---|
| 104 | | -#define PAGE_HYP_DEVICE _MOD_PROT(pgprot_hyp_device, L_PTE_HYP) |
|---|
| 105 | | -#define PAGE_S2 _MOD_PROT(pgprot_s2, L_PTE_S2_RDONLY | L_PTE_XN) |
|---|
| 106 | | -#define PAGE_S2_DEVICE _MOD_PROT(pgprot_s2_device, L_PTE_S2_RDONLY | L_PTE_XN) |
|---|
| 107 | 103 | |
|---|
| 108 | 104 | #define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE) |
|---|
| 109 | 105 | #define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) |
|---|
| .. | .. |
|---|
| 124 | 120 | |
|---|
| 125 | 121 | #define pgprot_stronglyordered(prot) \ |
|---|
| 126 | 122 | __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) |
|---|
| 123 | + |
|---|
| 124 | +#define pgprot_device(prot) \ |
|---|
| 125 | + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_SHARED | L_PTE_SHARED | L_PTE_DIRTY | L_PTE_XN) |
|---|
| 127 | 126 | |
|---|
| 128 | 127 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE |
|---|
| 129 | 128 | #define pgprot_dmacoherent(prot) \ |
|---|
| .. | .. |
|---|
| 166 | 165 | #define __S111 __PAGE_SHARED_EXEC |
|---|
| 167 | 166 | |
|---|
| 168 | 167 | #ifndef __ASSEMBLY__ |
|---|
| 169 | | -/* |
|---|
| 170 | | - * ZERO_PAGE is a global shared page that is always zero: used |
|---|
| 171 | | - * for zero-mapped memory areas etc.. |
|---|
| 172 | | - */ |
|---|
| 173 | | -extern struct page *empty_zero_page; |
|---|
| 174 | | -#define ZERO_PAGE(vaddr) (empty_zero_page) |
|---|
| 175 | | - |
|---|
| 176 | 168 | |
|---|
| 177 | 169 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
|---|
| 178 | | - |
|---|
| 179 | | -/* to find an entry in a page-table-directory */ |
|---|
| 180 | | -#define pgd_index(addr) ((addr) >> PGDIR_SHIFT) |
|---|
| 181 | | - |
|---|
| 182 | | -#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) |
|---|
| 183 | | - |
|---|
| 184 | | -/* to find an entry in a kernel page-table-directory */ |
|---|
| 185 | | -#define pgd_offset_k(addr) pgd_offset(&init_mm, addr) |
|---|
| 186 | 170 | |
|---|
| 187 | 171 | #define pmd_none(pmd) (!pmd_val(pmd)) |
|---|
| 188 | 172 | |
|---|
| .. | .. |
|---|
| 192 | 176 | } |
|---|
| 193 | 177 | |
|---|
| 194 | 178 | #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) |
|---|
| 195 | | - |
|---|
| 196 | | -#ifndef CONFIG_HIGHPTE |
|---|
| 197 | | -#define __pte_map(pmd) pmd_page_vaddr(*(pmd)) |
|---|
| 198 | | -#define __pte_unmap(pte) do { } while (0) |
|---|
| 199 | | -#else |
|---|
| 200 | | -#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd))) |
|---|
| 201 | | -#define __pte_unmap(pte) kunmap_atomic(pte) |
|---|
| 202 | | -#endif |
|---|
| 203 | | - |
|---|
| 204 | | -#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) |
|---|
| 205 | | - |
|---|
| 206 | | -#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr)) |
|---|
| 207 | | - |
|---|
| 208 | | -#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr)) |
|---|
| 209 | | -#define pte_unmap(pte) __pte_unmap(pte) |
|---|
| 210 | 179 | |
|---|
| 211 | 180 | #define pte_pfn(pte) ((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT) |
|---|
| 212 | 181 | #define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot)) |
|---|
| .. | .. |
|---|
| 252 | 221 | extern void __sync_icache_dcache(pte_t pteval); |
|---|
| 253 | 222 | #endif |
|---|
| 254 | 223 | |
|---|
| 255 | | -static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
|---|
| 256 | | - pte_t *ptep, pte_t pteval) |
|---|
| 257 | | -{ |
|---|
| 258 | | - unsigned long ext = 0; |
|---|
| 259 | | - |
|---|
| 260 | | - if (addr < TASK_SIZE && pte_valid_user(pteval)) { |
|---|
| 261 | | - if (!pte_special(pteval)) |
|---|
| 262 | | - __sync_icache_dcache(pteval); |
|---|
| 263 | | - ext |= PTE_EXT_NG; |
|---|
| 264 | | - } |
|---|
| 265 | | - |
|---|
| 266 | | - set_pte_ext(ptep, pteval, ext); |
|---|
| 267 | | -} |
|---|
| 224 | +void set_pte_at(struct mm_struct *mm, unsigned long addr, |
|---|
| 225 | + pte_t *ptep, pte_t pteval); |
|---|
| 268 | 226 | |
|---|
| 269 | 227 | static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot) |
|---|
| 270 | 228 | { |
|---|
| .. | .. |
|---|
| 360 | 318 | /* FIXME: this is not correct */ |
|---|
| 361 | 319 | #define kern_addr_valid(addr) (1) |
|---|
| 362 | 320 | |
|---|
| 363 | | -#include <asm-generic/pgtable.h> |
|---|
| 364 | | - |
|---|
| 365 | 321 | /* |
|---|
| 366 | 322 | * We provide our own arch_get_unmapped_area to cope with VIPT caches. |
|---|
| 367 | 323 | */ |
|---|
| 368 | 324 | #define HAVE_ARCH_UNMAPPED_AREA |
|---|
| 369 | 325 | #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN |
|---|
| 370 | | - |
|---|
| 371 | | -#define pgtable_cache_init() do { } while (0) |
|---|
| 372 | 326 | |
|---|
| 373 | 327 | #endif /* !__ASSEMBLY__ */ |
|---|
| 374 | 328 | |
|---|