1 // SPDX-License-Identifier: GPL-2.0-only 1 2 // Copyright 2023 Google LLC 3 // Author: Ard Biesheuvel <ardb@google.com> 4 5 #include <linux/types.h> 6 #include <linux/sizes.h> 7 8 #include <asm/memory.h> 9 #include <asm/pgalloc.h> 10 #include <asm/pgtable.h> 11 12 #include "pi.h" 13 14 /** 15 * map_range - Map a contiguous range of physi 16 * 17 * @pte: Address of physical po 18 * allocate page tables f 19 * @start: Virtual address of the 20 * @end: Virtual address of the 21 * @pa: Physical address of th 22 * @prot: Access permissions of 23 * @level: Translation level for 24 * @tbl: The level @level page 25 * @may_use_cont: Whether the use of the 26 * @va_offset: Offset between a physi 27 * in the VA space 28 */ 29 void __init map_range(u64 *pte, u64 start, u64 30 int level, pte_t *tbl, b 31 { 32 u64 cmask = (level == 3) ? CONT_PTE_SI 33 u64 protval = pgprot_val(prot) & ~PTE_ 34 int lshift = (3 - level) * (PAGE_SHIFT 35 u64 lmask = (PAGE_SIZE << lshift) - 1; 36 37 start &= PAGE_MASK; 38 pa &= PAGE_MASK; 39 40 /* Advance tbl to the entry that cover 41 tbl += (start >> (lshift + PAGE_SHIFT) 42 43 /* 44 * Set the right block/page bits for t 45 * clearing the mapping 46 */ 47 if (protval) 48 protval |= (level < 3) ? PMD_T 49 50 while (start < end) { 51 u64 next = min((start | lmask) 52 53 if (level < 3 && (start | next 54 /* 55 * This chunk needs a 56 * table mapping if ne 57 */ 58 if (pte_none(*tbl)) { 59 *tbl = __pte(_ 60 P 61 *pte += PTRS_P 62 } 63 map_range(pte, start, 64 (pte_t *)(__ 65 may_use_cont 66 } else { 67 /* 68 * Start a contiguous 69 * suitably aligned 70 */ 71 if (((start | pa) & cm 72 protval |= PTE 73 74 /* 75 * Clear the contiguou 76 * range does not cove 77 */ 78 if ((end & ~cmask) <= 79 protval &= ~PT 80 81 /* Put down a block or 82 *tbl = __pte(__phys_to 83 } 84 pa += next - start; 85 start = next; 86 tbl++; 87 } 88 } 89 90 asmlinkage u64 __init create_init_idmap(pgd_t 91 { 92 u64 ptep = (u64)pg_dir + PAGE_SIZE; 93 pgprot_t text_prot = PAGE_KERNEL_ROX; 94 pgprot_t data_prot = PAGE_KERNEL; 95 96 pgprot_val(text_prot) &= ~clrmask; 97 pgprot_val(data_prot) &= ~clrmask; 98 99 map_range(&ptep, (u64)_stext, (u64)__i 100 text_prot, IDMAP_ROOT_LEVEL, 101 map_range(&ptep, (u64)__initdata_begin 102 data_prot, IDMAP_ROOT_LEVEL, 103 104 return ptep; 105 } 106
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.