26
26
#include <asm/pkru.h>
27
27
#include <asm/fpu/api.h>
28
28
#include <asm-generic/pgtable_uffd.h>
29
+ #include <linux/page_table_check.h>
29
30
30
31
extern pgd_t early_top_pgt [PTRS_PER_PGD ];
31
32
bool __init __early_make_pgtable (unsigned long address , pmdval_t pmd );
@@ -1006,18 +1007,21 @@ static inline pud_t native_local_pudp_get_and_clear(pud_t *pudp)
1006
1007
static inline void set_pte_at (struct mm_struct * mm , unsigned long addr ,
1007
1008
pte_t * ptep , pte_t pte )
1008
1009
{
1010
+ page_table_check_pte_set (mm , addr , ptep , pte );
1009
1011
set_pte (ptep , pte );
1010
1012
}
1011
1013
1012
1014
static inline void set_pmd_at (struct mm_struct * mm , unsigned long addr ,
1013
1015
pmd_t * pmdp , pmd_t pmd )
1014
1016
{
1017
+ page_table_check_pmd_set (mm , addr , pmdp , pmd );
1015
1018
set_pmd (pmdp , pmd );
1016
1019
}
1017
1020
1018
1021
static inline void set_pud_at (struct mm_struct * mm , unsigned long addr ,
1019
1022
pud_t * pudp , pud_t pud )
1020
1023
{
1024
+ page_table_check_pud_set (mm , addr , pudp , pud );
1021
1025
native_set_pud (pudp , pud );
1022
1026
}
1023
1027
@@ -1048,6 +1052,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
1048
1052
pte_t * ptep )
1049
1053
{
1050
1054
pte_t pte = native_ptep_get_and_clear (ptep );
1055
+ page_table_check_pte_clear (mm , addr , pte );
1051
1056
return pte ;
1052
1057
}
1053
1058
@@ -1063,12 +1068,23 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
1063
1068
* care about updates and native needs no locking
1064
1069
*/
1065
1070
pte = native_local_ptep_get_and_clear (ptep );
1071
+ page_table_check_pte_clear (mm , addr , pte );
1066
1072
} else {
1067
1073
pte = ptep_get_and_clear (mm , addr , ptep );
1068
1074
}
1069
1075
return pte ;
1070
1076
}
1071
1077
1078
+ #define __HAVE_ARCH_PTEP_CLEAR
1079
+ static inline void ptep_clear (struct mm_struct * mm , unsigned long addr ,
1080
+ pte_t * ptep )
1081
+ {
1082
+ if (IS_ENABLED (CONFIG_PAGE_TABLE_CHECK ))
1083
+ ptep_get_and_clear (mm , addr , ptep );
1084
+ else
1085
+ pte_clear (mm , addr , ptep );
1086
+ }
1087
+
1072
1088
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
1073
1089
static inline void ptep_set_wrprotect (struct mm_struct * mm ,
1074
1090
unsigned long addr , pte_t * ptep )
@@ -1109,14 +1125,22 @@ static inline int pmd_write(pmd_t pmd)
1109
1125
static inline pmd_t pmdp_huge_get_and_clear (struct mm_struct * mm , unsigned long addr ,
1110
1126
pmd_t * pmdp )
1111
1127
{
1112
- return native_pmdp_get_and_clear (pmdp );
1128
+ pmd_t pmd = native_pmdp_get_and_clear (pmdp );
1129
+
1130
+ page_table_check_pmd_clear (mm , addr , pmd );
1131
+
1132
+ return pmd ;
1113
1133
}
1114
1134
1115
1135
#define __HAVE_ARCH_PUDP_HUGE_GET_AND_CLEAR
1116
1136
static inline pud_t pudp_huge_get_and_clear (struct mm_struct * mm ,
1117
1137
unsigned long addr , pud_t * pudp )
1118
1138
{
1119
- return native_pudp_get_and_clear (pudp );
1139
+ pud_t pud = native_pudp_get_and_clear (pudp );
1140
+
1141
+ page_table_check_pud_clear (mm , addr , pud );
1142
+
1143
+ return pud ;
1120
1144
}
1121
1145
1122
1146
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
@@ -1137,6 +1161,7 @@ static inline int pud_write(pud_t pud)
1137
1161
static inline pmd_t pmdp_establish (struct vm_area_struct * vma ,
1138
1162
unsigned long address , pmd_t * pmdp , pmd_t pmd )
1139
1163
{
1164
+ page_table_check_pmd_set (vma -> vm_mm , address , pmdp , pmd );
1140
1165
if (IS_ENABLED (CONFIG_SMP )) {
1141
1166
return xchg (pmdp , pmd );
1142
1167
} else {
0 commit comments