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