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