Skip to content

Commit 3fee229

Browse files
Tong Tiangenakpm00
authored andcommitted
riscv/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK
As commit d283d42 ("x86: mm: add x86_64 support for page table check"), enable ARCH_SUPPORTS_PAGE_TABLE_CHECK on riscv. Add additional page table check stubs for page table helpers, these stubs can be used to check the existing page table entries. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Tong Tiangen <[email protected]> Reviewed-by: Pasha Tatashin <[email protected]> Cc: Anshuman Khandual <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Dave Hansen <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Kefeng Wang <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 42b2547 commit 3fee229

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ config RISCV
3838
select ARCH_SUPPORTS_ATOMIC_RMW
3939
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
4040
select ARCH_SUPPORTS_HUGETLBFS if MMU
41+
select ARCH_SUPPORTS_PAGE_TABLE_CHECK
4142
select ARCH_USE_MEMTEST
4243
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
4344
select ARCH_WANT_FRAME_POINTERS

arch/riscv/include/asm/pgtable.h

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@
114114
#include <asm/pgtable-32.h>
115115
#endif /* CONFIG_64BIT */
116116

117+
#include <linux/page_table_check.h>
118+
117119
#ifdef CONFIG_XIP_KERNEL
118120
#define XIP_FIXUP(addr) ({ \
119121
uintptr_t __a = (uintptr_t)(addr); \
@@ -315,6 +317,11 @@ static inline int pte_exec(pte_t pte)
315317
return pte_val(pte) & _PAGE_EXEC;
316318
}
317319

320+
static inline int pte_user(pte_t pte)
321+
{
322+
return pte_val(pte) & _PAGE_USER;
323+
}
324+
318325
static inline int pte_huge(pte_t pte)
319326
{
320327
return pte_present(pte) && (pte_val(pte) & _PAGE_LEAF);
@@ -446,7 +453,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
446453

447454
void flush_icache_pte(pte_t pte);
448455

449-
static inline void set_pte_at(struct mm_struct *mm,
456+
static inline void __set_pte_at(struct mm_struct *mm,
450457
unsigned long addr, pte_t *ptep, pte_t pteval)
451458
{
452459
if (pte_present(pteval) && pte_exec(pteval))
@@ -455,10 +462,17 @@ static inline void set_pte_at(struct mm_struct *mm,
455462
set_pte(ptep, pteval);
456463
}
457464

465+
static inline void set_pte_at(struct mm_struct *mm,
466+
unsigned long addr, pte_t *ptep, pte_t pteval)
467+
{
468+
page_table_check_pte_set(mm, addr, ptep, pteval);
469+
__set_pte_at(mm, addr, ptep, pteval);
470+
}
471+
458472
static inline void pte_clear(struct mm_struct *mm,
459473
unsigned long addr, pte_t *ptep)
460474
{
461-
set_pte_at(mm, addr, ptep, __pte(0));
475+
__set_pte_at(mm, addr, ptep, __pte(0));
462476
}
463477

464478
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
@@ -479,7 +493,11 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
479493
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
480494
unsigned long address, pte_t *ptep)
481495
{
482-
return __pte(atomic_long_xchg((atomic_long_t *)ptep, 0));
496+
pte_t pte = __pte(atomic_long_xchg((atomic_long_t *)ptep, 0));
497+
498+
page_table_check_pte_clear(mm, address, pte);
499+
500+
return pte;
483501
}
484502

485503
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
@@ -546,6 +564,13 @@ static inline unsigned long pmd_pfn(pmd_t pmd)
546564
return ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT);
547565
}
548566

567+
#define __pud_to_phys(pud) (pud_val(pud) >> _PAGE_PFN_SHIFT << PAGE_SHIFT)
568+
569+
static inline unsigned long pud_pfn(pud_t pud)
570+
{
571+
return ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT);
572+
}
573+
549574
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
550575
{
551576
return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
@@ -567,6 +592,11 @@ static inline int pmd_young(pmd_t pmd)
567592
return pte_young(pmd_pte(pmd));
568593
}
569594

595+
static inline int pmd_user(pmd_t pmd)
596+
{
597+
return pte_user(pmd_pte(pmd));
598+
}
599+
570600
static inline pmd_t pmd_mkold(pmd_t pmd)
571601
{
572602
return pte_pmd(pte_mkold(pmd_pte(pmd)));
@@ -600,15 +630,39 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd)
600630
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
601631
pmd_t *pmdp, pmd_t pmd)
602632
{
603-
return set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd));
633+
page_table_check_pmd_set(mm, addr, pmdp, pmd);
634+
return __set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd));
635+
}
636+
637+
static inline int pud_user(pud_t pud)
638+
{
639+
return pte_user(pud_pte(pud));
604640
}
605641

606642
static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
607643
pud_t *pudp, pud_t pud)
608644
{
609-
return set_pte_at(mm, addr, (pte_t *)pudp, pud_pte(pud));
645+
page_table_check_pud_set(mm, addr, pudp, pud);
646+
return __set_pte_at(mm, addr, (pte_t *)pudp, pud_pte(pud));
647+
}
648+
649+
#ifdef CONFIG_PAGE_TABLE_CHECK
650+
static inline bool pte_user_accessible_page(pte_t pte)
651+
{
652+
return pte_present(pte) && pte_user(pte);
653+
}
654+
655+
static inline bool pmd_user_accessible_page(pmd_t pmd)
656+
{
657+
return pmd_leaf(pmd) && pmd_user(pmd);
610658
}
611659

660+
static inline bool pud_user_accessible_page(pud_t pud)
661+
{
662+
return pud_leaf(pud) && pud_user(pud);
663+
}
664+
#endif
665+
612666
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
613667
static inline int pmd_trans_huge(pmd_t pmd)
614668
{
@@ -634,7 +688,11 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
634688
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
635689
unsigned long address, pmd_t *pmdp)
636690
{
637-
return pte_pmd(ptep_get_and_clear(mm, address, (pte_t *)pmdp));
691+
pmd_t pmd = __pmd(atomic_long_xchg((atomic_long_t *)pmdp, 0));
692+
693+
page_table_check_pmd_clear(mm, address, pmd);
694+
695+
return pmd;
638696
}
639697

640698
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
@@ -648,6 +706,7 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
648706
static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
649707
unsigned long address, pmd_t *pmdp, pmd_t pmd)
650708
{
709+
page_table_check_pmd_set(vma->vm_mm, address, pmdp, pmd);
651710
return __pmd(atomic_long_xchg((atomic_long_t *)pmdp, pmd_val(pmd)));
652711
}
653712
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */

0 commit comments

Comments
 (0)