1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 /* 4 * Copyright (c) 2021, Google LLC. 5 * Pasha Tatashin <[email protected]> 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, pte_t pte); 18 void __page_table_check_pmd_clear(struct mm_struct *mm, pmd_t pmd); 19 void __page_table_check_pud_clear(struct mm_struct *mm, pud_t pud); 20 void __page_table_check_pte_set(struct mm_struct *mm, pte_t *ptep, pte_t pte); 21 void __page_table_check_pmd_set(struct mm_struct *mm, pmd_t *pmdp, pmd_t pmd); 22 void __page_table_check_pud_set(struct mm_struct *mm, pud_t *pudp, pud_t pud); 23 void __page_table_check_pte_clear_range(struct mm_struct *mm, 24 unsigned long addr, 25 pmd_t pmd); 26 27 static inline void page_table_check_alloc(struct page *page, unsigned int order) 28 { 29 if (static_branch_likely(&page_table_check_disabled)) 30 return; 31 32 __page_table_check_zero(page, order); 33 } 34 35 static inline void page_table_check_free(struct page *page, unsigned int order) 36 { 37 if (static_branch_likely(&page_table_check_disabled)) 38 return; 39 40 __page_table_check_zero(page, order); 41 } 42 43 static inline void page_table_check_pte_clear(struct mm_struct *mm, pte_t pte) 44 { 45 if (static_branch_likely(&page_table_check_disabled)) 46 return; 47 48 __page_table_check_pte_clear(mm, pte); 49 } 50 51 static inline void page_table_check_pmd_clear(struct mm_struct *mm, pmd_t pmd) 52 { 53 if (static_branch_likely(&page_table_check_disabled)) 54 return; 55 56 __page_table_check_pmd_clear(mm, pmd); 57 } 58 59 static inline void page_table_check_pud_clear(struct mm_struct *mm, pud_t pud) 60 { 61 if (static_branch_likely(&page_table_check_disabled)) 62 return; 63 64 __page_table_check_pud_clear(mm, pud); 65 } 66 67 static inline void page_table_check_pte_set(struct mm_struct *mm, pte_t *ptep, 68 pte_t pte) 69 { 70 if (static_branch_likely(&page_table_check_disabled)) 71 return; 72 73 __page_table_check_pte_set(mm, ptep, pte); 74 } 75 76 static inline void page_table_check_pmd_set(struct mm_struct *mm, pmd_t *pmdp, 77 pmd_t pmd) 78 { 79 if (static_branch_likely(&page_table_check_disabled)) 80 return; 81 82 __page_table_check_pmd_set(mm, pmdp, pmd); 83 } 84 85 static inline void page_table_check_pud_set(struct mm_struct *mm, pud_t *pudp, 86 pud_t pud) 87 { 88 if (static_branch_likely(&page_table_check_disabled)) 89 return; 90 91 __page_table_check_pud_set(mm, pudp, pud); 92 } 93 94 static inline void page_table_check_pte_clear_range(struct mm_struct *mm, 95 unsigned long addr, 96 pmd_t pmd) 97 { 98 if (static_branch_likely(&page_table_check_disabled)) 99 return; 100 101 __page_table_check_pte_clear_range(mm, addr, pmd); 102 } 103 104 #else 105 106 static inline void page_table_check_alloc(struct page *page, unsigned int order) 107 { 108 } 109 110 static inline void page_table_check_free(struct page *page, unsigned int order) 111 { 112 } 113 114 static inline void page_table_check_pte_clear(struct mm_struct *mm, pte_t pte) 115 { 116 } 117 118 static inline void page_table_check_pmd_clear(struct mm_struct *mm, pmd_t pmd) 119 { 120 } 121 122 static inline void page_table_check_pud_clear(struct mm_struct *mm, pud_t pud) 123 { 124 } 125 126 static inline void page_table_check_pte_set(struct mm_struct *mm, pte_t *ptep, 127 pte_t pte) 128 { 129 } 130 131 static inline void page_table_check_pmd_set(struct mm_struct *mm, pmd_t *pmdp, 132 pmd_t pmd) 133 { 134 } 135 136 static inline void page_table_check_pud_set(struct mm_struct *mm, pud_t *pudp, 137 pud_t pud) 138 { 139 } 140 141 static inline void page_table_check_pte_clear_range(struct mm_struct *mm, 142 unsigned long addr, 143 pmd_t pmd) 144 { 145 } 146 147 #endif /* CONFIG_PAGE_TABLE_CHECK */ 148 #endif /* __LINUX_PAGE_TABLE_CHECK_H */ 149