LoongArch: Let pmd_present() return true when splitting pmd
authorHongchen Zhang <zhanghongchen@loongson.cn>
Thu, 15 Jun 2023 06:35:52 +0000 (14:35 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Thu, 15 Jun 2023 06:35:52 +0000 (14:35 +0800)
When we split a pmd into ptes, pmd_present() and pmd_trans_huge() should
return true, otherwise it would be treated as a swap pmd.

This is the same as arm64 does in commit b65399f6111b ("arm64/mm: Change
THP helpers to comply with generic MM semantics"), we also add a new bit
named _PAGE_PRESENT_INVALID for LoongArch.

Signed-off-by: Hongchen Zhang <zhanghongchen@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/pgtable-bits.h
arch/loongarch/include/asm/pgtable.h

index 8b98d22..de46a6b 100644 (file)
 #define        _PAGE_PFN_SHIFT         12
 #define        _PAGE_SWP_EXCLUSIVE_SHIFT 23
 #define        _PAGE_PFN_END_SHIFT     48
+#define        _PAGE_PRESENT_INVALID_SHIFT 60
 #define        _PAGE_NO_READ_SHIFT     61
 #define        _PAGE_NO_EXEC_SHIFT     62
 #define        _PAGE_RPLV_SHIFT        63
 
 /* Used by software */
 #define _PAGE_PRESENT          (_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
+#define _PAGE_PRESENT_INVALID  (_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT)
 #define _PAGE_WRITE            (_ULCAST_(1) << _PAGE_WRITE_SHIFT)
 #define _PAGE_ACCESSED         (_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
 #define _PAGE_MODIFIED         (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
index d28fb9d..9a9f9ff 100644 (file)
@@ -213,7 +213,7 @@ static inline int pmd_bad(pmd_t pmd)
 static inline int pmd_present(pmd_t pmd)
 {
        if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
-               return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE));
+               return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PRESENT_INVALID));
 
        return pmd_val(pmd) != (unsigned long)invalid_pte_table;
 }
@@ -558,6 +558,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
 
 static inline pmd_t pmd_mkinvalid(pmd_t pmd)
 {
+       pmd_val(pmd) |= _PAGE_PRESENT_INVALID;
        pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY | _PAGE_PROTNONE);
 
        return pmd;