1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 /* 4 * Copyright (c) 2021, Google LLC. 5 * Pasha Tatashin <pasha.tatashin@soleen.com> 6 */ 7 #ifndef __LINUX_PAGE_TABLE_CHECK_H 8 #define __LINUX_PAGE_TABLE_CHECK_H 9 10 #ifdef CONFIG_PAGE_TABLE_CHECK 11 #include <linux/jump_label.h> 12 13 extern struct static_key_true page_table_check_disabled; 14 extern struct page_ext_operations page_table_check_ops; 15 16 void __page_table_check_zero(struct page *page, unsigned int order); 17 void __page_table_check_pte_clear(struct mm_struct *mm, unsigned long addr, 18 pte_t pte); 19 void __page_table_check_pmd_clear(struct mm_struct *mm, unsigned long addr, 20 pmd_t pmd); 21 void __page_table_check_pud_clear(struct mm_struct *mm, unsigned long addr, 22 pud_t pud); 23 void __page_table_check_pte_set(struct mm_struct *mm, unsigned long addr, 24 pte_t *ptep, pte_t pte); 25 void __page_table_check_pmd_set(struct mm_struct *mm, unsigned long addr, 26 pmd_t *pmdp, pmd_t pmd); 27 void __page_table_check_pud_set(struct mm_struct *mm, unsigned long addr, 28 pud_t *pudp, pud_t pud); 29 void __page_table_check_pte_clear_range(struct mm_struct *mm, 30 unsigned long addr, 31 pmd_t pmd); 32 33 static inline void page_table_check_alloc(struct page *page, unsigned int order) 34 { 35 if (static_branch_likely(&page_table_check_disabled)) 36 return; 37 38 __page_table_check_zero(page, order); 39 } 40 41 static inline void page_table_check_free(struct page *page, unsigned int order) 42 { 43 if (static_branch_likely(&page_table_check_disabled)) 44 return; 45 46 __page_table_check_zero(page, order); 47 } 48 49 static inline void page_table_check_pte_clear(struct mm_struct *mm, 50 unsigned long addr, pte_t pte) 51 { 52 if (static_branch_likely(&page_table_check_disabled)) 53 return; 54 55 __page_table_check_pte_clear(mm, addr, pte); 56 } 57 58 static inline void page_table_check_pmd_clear(struct mm_struct *mm, 59 unsigned long addr, pmd_t pmd) 60 { 61 if (static_branch_likely(&page_table_check_disabled)) 62 return; 63 64 __page_table_check_pmd_clear(mm, addr, pmd); 65 } 66 67 static inline void page_table_check_pud_clear(struct mm_struct *mm, 68 unsigned long addr, pud_t pud) 69 { 70 if (static_branch_likely(&page_table_check_disabled)) 71 return; 72 73 __page_table_check_pud_clear(mm, addr, pud); 74 } 75 76 static inline void page_table_check_pte_set(struct mm_struct *mm, 77 unsigned long addr, pte_t *ptep, 78 pte_t pte) 79 { 80 if (static_branch_likely(&page_table_check_disabled)) 81 return; 82 83 __page_table_check_pte_set(mm, addr, ptep, pte); 84 } 85 86 static inline void page_table_check_pmd_set(struct mm_struct *mm, 87 unsigned long addr, pmd_t *pmdp, 88 pmd_t pmd) 89 { 90 if (static_branch_likely(&page_table_check_disabled)) 91 return; 92 93 __page_table_check_pmd_set(mm, addr, pmdp, pmd); 94 } 95 96 static inline void page_table_check_pud_set(struct mm_struct *mm, 97 unsigned long addr, pud_t *pudp, 98 pud_t pud) 99 { 100 if (static_branch_likely(&page_table_check_disabled)) 101 return; 102 103 __page_table_check_pud_set(mm, addr, pudp, pud); 104 } 105 106 static inline void page_table_check_pte_clear_range(struct mm_struct *mm, 107 unsigned long addr, 108 pmd_t pmd) 109 { 110 if (static_branch_likely(&page_table_check_disabled)) 111 return; 112 113 __page_table_check_pte_clear_range(mm, addr, pmd); 114 } 115 116 #else 117 118 static inline void page_table_check_alloc(struct page *page, unsigned int order) 119 { 120 } 121 122 static inline void page_table_check_free(struct page *page, unsigned int order) 123 { 124 } 125 126 static inline void page_table_check_pte_clear(struct mm_struct *mm, 127 unsigned long addr, pte_t pte) 128 { 129 } 130 131 static inline void page_table_check_pmd_clear(struct mm_struct *mm, 132 unsigned long addr, pmd_t pmd) 133 { 134 } 135 136 static inline void page_table_check_pud_clear(struct mm_struct *mm, 137 unsigned long addr, pud_t pud) 138 { 139 } 140 141 static inline void page_table_check_pte_set(struct mm_struct *mm, 142 unsigned long addr, pte_t *ptep, 143 pte_t pte) 144 { 145 } 146 147 static inline void page_table_check_pmd_set(struct mm_struct *mm, 148 unsigned long addr, pmd_t *pmdp, 149 pmd_t pmd) 150 { 151 } 152 153 static inline void page_table_check_pud_set(struct mm_struct *mm, 154 unsigned long addr, pud_t *pudp, 155 pud_t pud) 156 { 157 } 158 159 static inline void page_table_check_pte_clear_range(struct mm_struct *mm, 160 unsigned long addr, 161 pmd_t pmd) 162 { 163 } 164 165 #endif /* CONFIG_PAGE_TABLE_CHECK */ 166 #endif /* __LINUX_PAGE_TABLE_CHECK_H */ 167