When a pmd entry is invalidated by pmd_mkinvalid,pmd_present should return true. So introduce a _PAGE_PRESENT_INVALID_SHIFT bit to check if a pmd is present but invalidated by pmd_mkinvalid. Signed-off-by: Hongchen Zhang <zhanghongchen@xxxxxxxxxxx> --- arch/mips/include/asm/pgtable-64.h | 2 +- arch/mips/include/asm/pgtable-bits.h | 5 +++++ arch/mips/include/asm/pgtable.h | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index 41921ac..1c5ef41 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h @@ -265,7 +265,7 @@ static inline int pmd_present(pmd_t pmd) { #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) - return pmd_val(pmd) & _PAGE_PRESENT; + return pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PRESENT_INVALID); #endif return pmd_val(pmd) != (unsigned long) invalid_pte_table; diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 2362842..3c176a1e 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -49,6 +49,7 @@ enum pgtable_bits { /* Used only by software (masked out before writing EntryLo*) */ _PAGE_PRESENT_SHIFT = 24, + _PAGE_PRESENT_INVALID_SHIFT, _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, _PAGE_MODIFIED_SHIFT, @@ -80,6 +81,7 @@ enum pgtable_bits { /* Used only by software (masked out before writing EntryLo*) */ _PAGE_PRESENT_SHIFT = _CACHE_SHIFT + 3, + _PAGE_PRESENT_INVALID_SHIFT, _PAGE_NO_READ_SHIFT, _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, @@ -98,6 +100,7 @@ enum pgtable_bits { enum pgtable_bits { /* Used only by software (writes to EntryLo ignored) */ _PAGE_PRESENT_SHIFT, + _PAGE_PRESENT_INVALID_SHIFT, _PAGE_NO_READ_SHIFT, _PAGE_WRITE_SHIFT, _PAGE_ACCESSED_SHIFT, @@ -122,6 +125,7 @@ enum pgtable_bits { enum pgtable_bits { /* Used only by software (masked out before writing EntryLo*) */ _PAGE_PRESENT_SHIFT, + _PAGE_PRESENT_INVALID_SHIFT, #if !defined(CONFIG_CPU_HAS_RIXI) _PAGE_NO_READ_SHIFT, #endif @@ -152,6 +156,7 @@ enum pgtable_bits { /* Used only by software */ #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) +#define _PAGE_PRESENT_INVALID (1 << _PAGE_PRESENT_INVALID_SHIFT) #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 374c632..cc80211 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -698,7 +698,8 @@ 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 | _PAGE_VALID | _PAGE_DIRTY); + pmd_val(pmd) |= _PAGE_PRESENT_INVALID; + pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID); return pmd; } -- 1.8.3.1