Skip to content

Commit d283d42

Browse files
soleentorvalds
authored andcommitted
x86: mm: add x86_64 support for page table check
Add page table check hooks into routines that modify user page tables. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Pasha Tatashin <[email protected]> Cc: Aneesh Kumar K.V <[email protected]> Cc: Dave Hansen <[email protected]> Cc: David Rientjes <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Greg Thelen <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Slaby <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Kees Cook <[email protected]> Cc: Masahiro Yamada <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Muchun Song <[email protected]> Cc: Paul Turner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sami Tolvanen <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Wei Xu <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent df4e817 commit d283d42

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

arch/x86/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ config X86
104104
select ARCH_SUPPORTS_ACPI
105105
select ARCH_SUPPORTS_ATOMIC_RMW
106106
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
107+
select ARCH_SUPPORTS_PAGE_TABLE_CHECK if X86_64
107108
select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
108109
select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096
109110
select ARCH_SUPPORTS_LTO_CLANG

arch/x86/include/asm/pgtable.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <asm/pkru.h>
2727
#include <asm/fpu/api.h>
2828
#include <asm-generic/pgtable_uffd.h>
29+
#include <linux/page_table_check.h>
2930

3031
extern pgd_t early_top_pgt[PTRS_PER_PGD];
3132
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)
10061007
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
10071008
pte_t *ptep, pte_t pte)
10081009
{
1010+
page_table_check_pte_set(mm, addr, ptep, pte);
10091011
set_pte(ptep, pte);
10101012
}
10111013

10121014
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
10131015
pmd_t *pmdp, pmd_t pmd)
10141016
{
1017+
page_table_check_pmd_set(mm, addr, pmdp, pmd);
10151018
set_pmd(pmdp, pmd);
10161019
}
10171020

10181021
static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
10191022
pud_t *pudp, pud_t pud)
10201023
{
1024+
page_table_check_pud_set(mm, addr, pudp, pud);
10211025
native_set_pud(pudp, pud);
10221026
}
10231027

@@ -1048,6 +1052,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
10481052
pte_t *ptep)
10491053
{
10501054
pte_t pte = native_ptep_get_and_clear(ptep);
1055+
page_table_check_pte_clear(mm, addr, pte);
10511056
return pte;
10521057
}
10531058

@@ -1063,12 +1068,23 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
10631068
* care about updates and native needs no locking
10641069
*/
10651070
pte = native_local_ptep_get_and_clear(ptep);
1071+
page_table_check_pte_clear(mm, addr, pte);
10661072
} else {
10671073
pte = ptep_get_and_clear(mm, addr, ptep);
10681074
}
10691075
return pte;
10701076
}
10711077

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+
10721088
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
10731089
static inline void ptep_set_wrprotect(struct mm_struct *mm,
10741090
unsigned long addr, pte_t *ptep)
@@ -1109,14 +1125,22 @@ static inline int pmd_write(pmd_t pmd)
11091125
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long addr,
11101126
pmd_t *pmdp)
11111127
{
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;
11131133
}
11141134

11151135
#define __HAVE_ARCH_PUDP_HUGE_GET_AND_CLEAR
11161136
static inline pud_t pudp_huge_get_and_clear(struct mm_struct *mm,
11171137
unsigned long addr, pud_t *pudp)
11181138
{
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;
11201144
}
11211145

11221146
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
@@ -1137,6 +1161,7 @@ static inline int pud_write(pud_t pud)
11371161
static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
11381162
unsigned long address, pmd_t *pmdp, pmd_t pmd)
11391163
{
1164+
page_table_check_pmd_set(vma->vm_mm, address, pmdp, pmd);
11401165
if (IS_ENABLED(CONFIG_SMP)) {
11411166
return xchg(pmdp, pmd);
11421167
} else {

0 commit comments

Comments
 (0)