]> www.infradead.org Git - users/willy/xarray.git/commitdiff
arm64/mm: Set only the PTE_DIRTY bit while preserving the HW dirty state
authorAnshuman Khandual <anshuman.khandual@arm.com>
Thu, 13 Jul 2023 07:15:18 +0000 (12:45 +0530)
committerWill Deacon <will@kernel.org>
Thu, 27 Jul 2023 10:17:23 +0000 (11:17 +0100)
pte_mkdirty() creates dirty states both in SW and HW bits, which is really
not required, either in pte_wrprotect() or pte_modify() for preserving the
HW dirty state. Because pte_mkdirty() sets PTE_DIRTY and clears PTE_RDONLY
as pte_write() always evaluates to be true - otherwise pte_hw_dirty() will
not test out in the first place. Clearing PTE_RDONLY again is not required
here because the pte is already in pte_hw_dirty() but might soon loose its
dirty state thus requiring preservation in SW dirty bit i.e PTE_DIRTY.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20230713071518.628440-1-anshuman.khandual@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/pgtable.h

index 02b7abcf1f9fcdbc326c4e710d8c6e778f06b0db..72c2e84313606e5c27e58cc8603188a62899b893 100644 (file)
@@ -213,7 +213,7 @@ static inline pte_t pte_wrprotect(pte_t pte)
         * clear), set the PTE_DIRTY bit.
         */
        if (pte_hw_dirty(pte))
-               pte = pte_mkdirty(pte);
+               pte = set_pte_bit(pte, __pgprot(PTE_DIRTY));
 
        pte = clear_pte_bit(pte, __pgprot(PTE_WRITE));
        pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
@@ -824,7 +824,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
                              PTE_ATTRINDX_MASK;
        /* preserve the hardware dirty information */
        if (pte_hw_dirty(pte))
-               pte = pte_mkdirty(pte);
+               pte = set_pte_bit(pte, __pgprot(PTE_DIRTY));
+
        pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
        return pte;
 }