diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index a1a7c6520a0954..ecea48affd7aa6 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -976,7 +976,14 @@ static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd) { - return pmd_leaf(pmd) && pmd_user(pmd); + /* + * page_table_check() must ignore THP split invalidation entries created by + * pmd_mkinvalid(). These retain _PAGE_LEAF so pmd_present()/pmd_leaf() stay + * true during the split, but they no longer describe a user-accessible + * mapping once both _PAGE_PRESENT and _PAGE_PROT_NONE are cleared. + */ + return (pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROT_NONE)) && + (pmd_val(pmd) & _PAGE_LEAF) && pmd_user(pmd); } static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)