mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
arm64/mm: move __check_safe_pte_update()
Patch series "arm64/mm: Standardize printing for pgtable entries", v3. Standardize printing for pgtable entries using recently introduced generic helper ptval_bytes_to_hex_str() in core MM which automatically enables 128 bits entries when added later. But first move __check_safe_pte_update() outside <asm/pgtable.h> to avoid a cyclic dependency while accessing these afore mentioned core MM helpers defined in <linux/pgtable.h>. This replaces the original page table entry print standardisation proposal which was part of the D128 series [1]. This patch (of 2): The page table entry print helpers and related macros which are defined in <linux/pgtable.h> will not be accessible in platform <asm/pgtable.h> which is basically caused by cycling dependency. Move __check_safe_pte_update() inside arch/arm64/mm/mmu.c as a preparation for subsequent usage of the afore mentioned generic MM helpers. While here drop IS_ENABLED(CONFIG_DEBUG_VM), although wrap __check_safe_pte_update() inside #ifdef CONFIG_DEBUG_VM that preserves the current code optimization which is achieved via the static inline functions. This does not cause any functional change. [david@kernel.org: aarch64-linux-ld error] Link: https://lore.kernel.org/99023678-fd8a-4eef-8e43-a07b504e3e96@kernel.org Link: https://lore.kernel.org/20260916044933.2689426-2-anshuman.khandual@arm.com Link: https://lore.kernel.org/linux-mm/20260729122452.3797443-11-anshuman.khandual@arm.com/ [1] Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Mike Rapoport <rppt@kernel.org> Cc: Lorenzo Stoakes <ljs@kernel.org>
This commit is contained in:
parent
7c7180be97
commit
b32f336987
|
|
@ -387,52 +387,13 @@ static inline pte_t __ptep_get(pte_t *ptep)
|
|||
extern void __sync_icache_dcache(pte_t pteval);
|
||||
bool pgattr_change_is_safe(pteval_t old, pteval_t new);
|
||||
|
||||
/*
|
||||
* PTE bits configuration in the presence of hardware Dirty Bit Management
|
||||
* (PTE_WRITE == PTE_DBM):
|
||||
*
|
||||
* Dirty Writable | PTE_RDONLY PTE_WRITE PTE_DIRTY (sw)
|
||||
* 0 0 | 1 0 0
|
||||
* 0 1 | 1 1 0
|
||||
* 1 0 | 1 0 1
|
||||
* 1 1 | 0 1 x
|
||||
*
|
||||
* When hardware DBM is not present, the software PTE_DIRTY bit is updated via
|
||||
* the page fault mechanism. Checking the dirty status of a pte becomes:
|
||||
*
|
||||
* PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY)
|
||||
*/
|
||||
|
||||
static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
|
||||
pte_t pte)
|
||||
#ifdef CONFIG_DEBUG_VM
|
||||
void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, pte_t pte);
|
||||
#else
|
||||
static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, pte_t pte)
|
||||
{
|
||||
pte_t old_pte;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DEBUG_VM))
|
||||
return;
|
||||
|
||||
old_pte = __ptep_get(ptep);
|
||||
|
||||
if (!pte_valid(old_pte) || !pte_valid(pte))
|
||||
return;
|
||||
if (mm != current->active_mm && atomic_read(&mm->mm_users) <= 1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Check for potential race with hardware updates of the pte
|
||||
* (__ptep_set_access_flags safely changes valid ptes without going
|
||||
* through an invalid entry).
|
||||
*/
|
||||
VM_WARN_ONCE(!pte_young(pte),
|
||||
"%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
|
||||
__func__, pte_val(old_pte), pte_val(pte));
|
||||
VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
|
||||
"%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
|
||||
__func__, pte_val(old_pte), pte_val(pte));
|
||||
VM_WARN_ONCE(!pgattr_change_is_safe(pte_val(old_pte), pte_val(pte)),
|
||||
"%s: unsafe attribute change: 0x%016llx -> 0x%016llx",
|
||||
__func__, pte_val(old_pte), pte_val(pte));
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_VM */
|
||||
|
||||
static inline void __sync_cache_and_tags(pte_t pte, unsigned int nr_pages)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2393,3 +2393,47 @@ int arch_set_user_pkey_access(int pkey, unsigned long init_val)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PTE bits configuration in the presence of hardware Dirty Bit Management
|
||||
* (PTE_WRITE == PTE_DBM):
|
||||
*
|
||||
* Dirty Writable | PTE_RDONLY PTE_WRITE PTE_DIRTY (sw)
|
||||
* 0 0 | 1 0 0
|
||||
* 0 1 | 1 1 0
|
||||
* 1 0 | 1 0 1
|
||||
* 1 1 | 0 1 x
|
||||
*
|
||||
* When hardware DBM is not present, the software PTE_DIRTY bit is updated via
|
||||
* the page fault mechanism. Checking the dirty status of a pte becomes:
|
||||
*
|
||||
* PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY)
|
||||
*/
|
||||
#ifdef CONFIG_DEBUG_VM
|
||||
void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep, pte_t pte)
|
||||
{
|
||||
pte_t old_pte;
|
||||
|
||||
old_pte = __ptep_get(ptep);
|
||||
|
||||
if (!pte_valid(old_pte) || !pte_valid(pte))
|
||||
return;
|
||||
if (mm != current->active_mm && atomic_read(&mm->mm_users) <= 1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Check for potential race with hardware updates of the pte
|
||||
* (__ptep_set_access_flags safely changes valid ptes without going
|
||||
* through an invalid entry).
|
||||
*/
|
||||
VM_WARN_ONCE(!pte_young(pte),
|
||||
"%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
|
||||
__func__, pte_val(old_pte), pte_val(pte));
|
||||
VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
|
||||
"%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
|
||||
__func__, pte_val(old_pte), pte_val(pte));
|
||||
VM_WARN_ONCE(!pgattr_change_is_safe(pte_val(old_pte), pte_val(pte)),
|
||||
"%s: unsafe attribute change: 0x%016llx -> 0x%016llx",
|
||||
__func__, pte_val(old_pte), pte_val(pte));
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_VM */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user