]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64: mm: Permit PTE SW bits to change in live mappings
authorRyan Roberts <ryan.roberts@arm.com>
Wed, 19 Jun 2024 12:18:56 +0000 (13:18 +0100)
committerWill Deacon <will@kernel.org>
Wed, 19 Jun 2024 13:05:03 +0000 (14:05 +0100)
Previously pgattr_change_is_safe() was overly-strict and complained
(e.g. "[  116.262743] __check_safe_pte_update: unsafe attribute change:
0x0560000043768fc3 -> 0x0160000043768fc3") if it saw any SW bits change
in a live PTE. There is no such restriction on SW bits in the Arm ARM.

Until now, no SW bits have been updated in live mappings via the
set_ptes() route. PTE_DIRTY would be updated live, but this is handled
by ptep_set_access_flags() which does not call pgattr_change_is_safe().
However, with the introduction of uffd-wp for arm64, there is core-mm
code that does ptep_get(); pte_clear_uffd_wp(); set_ptes(); which
triggers this false warning.

Silence this warning by masking out the SW bits during checks.

The bug isn't technically in the highlighted commit below, but that's
where bisecting would likely lead as its what made the bug user-visible.

Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Fixes: 5b32510af77b ("arm64/mm: Add uffd write-protect support")
Link: https://lore.kernel.org/r/20240619121859.4153966-1-ryan.roberts@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/pgtable-hwdef.h
arch/arm64/mm/mmu.c

index 9943ff0af4c96da40395d5926f1837757f10a897..1f60aa1bc750cb6485e9b407fbc9b78ee1f50d38 100644 (file)
 #define PTE_CONT               (_AT(pteval_t, 1) << 52)        /* Contiguous range */
 #define PTE_PXN                        (_AT(pteval_t, 1) << 53)        /* Privileged XN */
 #define PTE_UXN                        (_AT(pteval_t, 1) << 54)        /* User XN */
+#define PTE_SWBITS_MASK                _AT(pteval_t, (BIT(63) | GENMASK(58, 55)))
 
 #define PTE_ADDR_LOW           (((_AT(pteval_t, 1) << (50 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
 #ifdef CONFIG_ARM64_PA_BITS_52
index c927e9312f102ec14384b51b22cf5d3a1740f067..353ea5dc32b8504328bea0f98a424f9be983fbcf 100644 (file)
@@ -124,7 +124,8 @@ bool pgattr_change_is_safe(u64 old, u64 new)
         * The following mapping attributes may be updated in live
         * kernel mappings without the need for break-before-make.
         */
-       pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG;
+       pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG |
+                       PTE_SWBITS_MASK;
 
        /* creating or taking down mappings is always safe */
        if (!pte_valid(__pte(old)) || !pte_valid(__pte(new)))