Skip to content

Commit d1770e9

Browse files
Ryan Robertsctmarinas
authored andcommitted
arm64/mm: Check pmd_table() in pmd_trans_huge()
Check for pmd_table() in pmd_trans_huge() rather then just checking for the PMD_TABLE_BIT. But ensure all present-invalid entries are handled correctly by always setting PTE_VALID before checking with pmd_table(). Cc: Will Deacon <will@kernel.org> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> Link: https://lore.kernel.org/r/20250221044227.1145393-8-anshuman.khandual@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent bfb1d2b commit d1770e9

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

arch/arm64/include/asm/pgtable.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -548,18 +548,6 @@ static inline int pmd_protnone(pmd_t pmd)
548548
#endif
549549

550550
#define pmd_present(pmd) pte_present(pmd_pte(pmd))
551-
552-
/*
553-
* THP definitions.
554-
*/
555-
556-
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
557-
static inline int pmd_trans_huge(pmd_t pmd)
558-
{
559-
return pmd_val(pmd) && pmd_present(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT);
560-
}
561-
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
562-
563551
#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
564552
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
565553
#define pmd_valid(pmd) pte_valid(pmd_pte(pmd))
@@ -746,6 +734,18 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
746734
#define pmd_leaf_size(pmd) (pmd_cont(pmd) ? CONT_PMD_SIZE : PMD_SIZE)
747735
#define pte_leaf_size(pte) (pte_cont(pte) ? CONT_PTE_SIZE : PAGE_SIZE)
748736

737+
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
738+
static inline int pmd_trans_huge(pmd_t pmd)
739+
{
740+
/*
741+
* If pmd is present-invalid, pmd_table() won't detect it
742+
* as a table, so force the valid bit for the comparison.
743+
*/
744+
return pmd_val(pmd) && pmd_present(pmd) &&
745+
!pmd_table(__pmd(pmd_val(pmd) | PTE_VALID));
746+
}
747+
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
748+
749749
#if defined(CONFIG_ARM64_64K_PAGES) || CONFIG_PGTABLE_LEVELS < 3
750750
static inline bool pud_sect(pud_t pud) { return false; }
751751
static inline bool pud_table(pud_t pud) { return true; }

0 commit comments

Comments
 (0)