summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYongqin Liu <yongqin.liu@linaro.org>2023-07-28 19:28:15 +0800
committerYongqin Liu <yongqin.liu@linaro.org>2023-07-28 19:28:15 +0800
commit1cf0604b010f1173e1f352ceda85deeebfe069cd (patch)
treeee055ff11c21968a0995c4ad9261206570bf2568
parent46af271fd87be325e4ccb226f6062437ae52eb3c (diff)
downloadomap-modules-android-mainline.tar.gz
patchsets: workaround for __pte_offset_map_lock undefined with modpostandroid-mainline
where pte_offset_map_lock and pte_offset_map are called in out of tree module Signed-off-by: Yongqin Liu <yongqin.liu@linaro.org> Change-Id: I4d8b8306ecc61b165ea2c244b3a005201086e903
-rw-r--r--patchsets/0001-Revert-mm-pgtable-allow-pte_offset_map-_lock-to-fail.patch191
-rw-r--r--patchsets/0002-Revert-mm-ptep_get-conversion.patch2156
-rw-r--r--patchsets/0003-Revert-mm-memory-handle_pte_fault-use-pte_offset_map.patch130
-rw-r--r--patchsets/0004-Revert-mm-memory-allow-pte_offset_map-_lock-to-fail.patch422
-rw-r--r--patchsets/0005-Revert-mm-pgtable-delete-pmd_trans_unstable-and-frie.patch163
-rw-r--r--patchsets/0006-Revert-mm-mremap-retry-if-either-pte_offset_map_-loc.patch117
-rw-r--r--patchsets/0007-Revert-mm-page_vma_mapped-pte_offset_map_nolock-not-.patch89
-rwxr-xr-xpatchsets/apply.sh13
8 files changed, 3281 insertions, 0 deletions
diff --git a/patchsets/0001-Revert-mm-pgtable-allow-pte_offset_map-_lock-to-fail.patch b/patchsets/0001-Revert-mm-pgtable-allow-pte_offset_map-_lock-to-fail.patch
new file mode 100644
index 0000000..9c890b5
--- /dev/null
+++ b/patchsets/0001-Revert-mm-pgtable-allow-pte_offset_map-_lock-to-fail.patch
@@ -0,0 +1,191 @@
+From 7d1a899f667cf3ced1089821d74ea9e456428103 Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 15:52:11 +0800
+Subject: [PATCH 1/7] Revert "mm/pgtable: allow pte_offset_map[_lock]() to
+ fail"
+
+This reverts commit 0d940a9b270b9220dcff74d8e9123c9788365751.
+---
+ Documentation/mm/split_page_table_lock.rst | 17 +++----
+ include/linux/mm.h | 27 ++++-------
+ include/linux/pgtable.h | 22 +++------
+ mm/pgtable-generic.c | 56 ----------------------
+ 4 files changed, 21 insertions(+), 101 deletions(-)
+
+diff --git a/Documentation/mm/split_page_table_lock.rst b/Documentation/mm/split_page_table_lock.rst
+index a834fad9de12..50ee0dfc95be 100644
+--- a/Documentation/mm/split_page_table_lock.rst
++++ b/Documentation/mm/split_page_table_lock.rst
+@@ -14,20 +14,15 @@ tables. Access to higher level tables protected by mm->page_table_lock.
+ There are helpers to lock/unlock a table and other accessor functions:
+
+ - pte_offset_map_lock()
+- maps PTE and takes PTE table lock, returns pointer to PTE with
+- pointer to its PTE table lock, or returns NULL if no PTE table;
+- - pte_offset_map_nolock()
+- maps PTE, returns pointer to PTE with pointer to its PTE table
+- lock (not taken), or returns NULL if no PTE table;
+- - pte_offset_map()
+- maps PTE, returns pointer to PTE, or returns NULL if no PTE table;
+- - pte_unmap()
+- unmaps PTE table;
++ maps pte and takes PTE table lock, returns pointer to the taken
++ lock;
+ - pte_unmap_unlock()
+ unlocks and unmaps PTE table;
+ - pte_alloc_map_lock()
+- allocates PTE table if needed and takes its lock, returns pointer to
+- PTE with pointer to its lock, or returns NULL if allocation failed;
++ allocates PTE table if needed and take the lock, returns pointer
++ to taken lock or NULL if allocation failed;
++ - pte_lockptr()
++ returns pointer to PTE table lock;
+ - pmd_lock()
+ takes PMD table lock, returns pointer to taken lock;
+ - pmd_lockptr()
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index ae866bc9bad6..09bd0eaf1253 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2824,25 +2824,14 @@ static inline void pgtable_pte_page_dtor(struct page *page)
+ dec_lruvec_page_state(page, NR_PAGETABLE);
+ }
+
+-pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp);
+-static inline pte_t *pte_offset_map(pmd_t *pmd, unsigned long addr)
+-{
+- return __pte_offset_map(pmd, addr, NULL);
+-}
+-
+-pte_t *__pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd,
+- unsigned long addr, spinlock_t **ptlp);
+-static inline pte_t *pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd,
+- unsigned long addr, spinlock_t **ptlp)
+-{
+- pte_t *pte;
+-
+- __cond_lock(*ptlp, pte = __pte_offset_map_lock(mm, pmd, addr, ptlp));
+- return pte;
+-}
+-
+-pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd,
+- unsigned long addr, spinlock_t **ptlp);
++#define pte_offset_map_lock(mm, pmd, address, ptlp) \
++({ \
++ spinlock_t *__ptl = pte_lockptr(mm, pmd); \
++ pte_t *__pte = pte_offset_map(pmd, address); \
++ *(ptlp) = __ptl; \
++ spin_lock(__ptl); \
++ __pte; \
++})
+
+ #define pte_unmap_unlock(pte, ptl) do { \
+ spin_unlock(ptl); \
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index 5063b482e34f..e4e9734ac395 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -94,22 +94,14 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
+ #define pte_offset_kernel pte_offset_kernel
+ #endif
+
+-#ifdef CONFIG_HIGHPTE
+-#define __pte_map(pmd, address) \
+- ((pte_t *)kmap_local_page(pmd_page(*(pmd))) + pte_index((address)))
+-#define pte_unmap(pte) do { \
+- kunmap_local((pte)); \
+- /* rcu_read_unlock() to be added later */ \
+-} while (0)
++#if defined(CONFIG_HIGHPTE)
++#define pte_offset_map(dir, address) \
++ ((pte_t *)kmap_local_page(pmd_page(*(dir))) + \
++ pte_index((address)))
++#define pte_unmap(pte) kunmap_local((pte))
+ #else
+-static inline pte_t *__pte_map(pmd_t *pmd, unsigned long address)
+-{
+- return pte_offset_kernel(pmd, address);
+-}
+-static inline void pte_unmap(pte_t *pte)
+-{
+- /* rcu_read_unlock() to be added later */
+-}
++#define pte_offset_map(dir, address) pte_offset_kernel((dir), (address))
++#define pte_unmap(pte) ((void)(pte)) /* NOP */
+ #endif
+
+ /* Find an entry in the second-level page table.. */
+diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
+index 4d454953046f..e6c582e659c9 100644
+--- a/mm/pgtable-generic.c
++++ b/mm/pgtable-generic.c
+@@ -10,8 +10,6 @@
+ #include <linux/pagemap.h>
+ #include <linux/hugetlb.h>
+ #include <linux/pgtable.h>
+-#include <linux/swap.h>
+-#include <linux/swapops.h>
+ #include <linux/mm_inline.h>
+ #include <asm/tlb.h>
+
+@@ -231,57 +229,3 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
+ }
+ #endif
+ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+-
+-pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp)
+-{
+- pmd_t pmdval;
+-
+- /* rcu_read_lock() to be added later */
+- pmdval = pmdp_get_lockless(pmd);
+- if (pmdvalp)
+- *pmdvalp = pmdval;
+- if (unlikely(pmd_none(pmdval) || is_pmd_migration_entry(pmdval)))
+- goto nomap;
+- if (unlikely(pmd_trans_huge(pmdval) || pmd_devmap(pmdval)))
+- goto nomap;
+- if (unlikely(pmd_bad(pmdval))) {
+- pmd_clear_bad(pmd);
+- goto nomap;
+- }
+- return __pte_map(&pmdval, addr);
+-nomap:
+- /* rcu_read_unlock() to be added later */
+- return NULL;
+-}
+-
+-pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd,
+- unsigned long addr, spinlock_t **ptlp)
+-{
+- pmd_t pmdval;
+- pte_t *pte;
+-
+- pte = __pte_offset_map(pmd, addr, &pmdval);
+- if (likely(pte))
+- *ptlp = pte_lockptr(mm, &pmdval);
+- return pte;
+-}
+-
+-pte_t *__pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd,
+- unsigned long addr, spinlock_t **ptlp)
+-{
+- spinlock_t *ptl;
+- pmd_t pmdval;
+- pte_t *pte;
+-again:
+- pte = __pte_offset_map(pmd, addr, &pmdval);
+- if (unlikely(!pte))
+- return pte;
+- ptl = pte_lockptr(mm, &pmdval);
+- spin_lock(ptl);
+- if (likely(pmd_same(pmdval, pmdp_get_lockless(pmd)))) {
+- *ptlp = ptl;
+- return pte;
+- }
+- pte_unmap_unlock(pte, ptl);
+- goto again;
+-}
+--
+2.25.1
+
diff --git a/patchsets/0002-Revert-mm-ptep_get-conversion.patch b/patchsets/0002-Revert-mm-ptep_get-conversion.patch
new file mode 100644
index 0000000..786f5b0
--- /dev/null
+++ b/patchsets/0002-Revert-mm-ptep_get-conversion.patch
@@ -0,0 +1,2156 @@
+From 6711d1b3005adb3d3dc93568fe3b30df923540ec Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 16:01:59 +0800
+Subject: [PATCH 2/7] Revert "mm: ptep_get() conversion"
+
+This reverts commit c33c794828f21217f72ce6fc140e0d34e0d56bff.
+---
+ .../drm/i915/gem/selftests/i915_gem_mman.c | 8 +-
+ drivers/misc/sgi-gru/grufault.c | 2 +-
+ drivers/vfio/vfio_iommu_type1.c | 7 +-
+ drivers/xen/privcmd.c | 2 +-
+ fs/proc/task_mmu.c | 33 +++---
+ fs/userfaultfd.c | 6 +-
+ include/linux/hugetlb.h | 4 -
+ include/linux/mm_inline.h | 2 +-
+ include/linux/pgtable.h | 6 +-
+ kernel/events/uprobes.c | 2 +-
+ mm/damon/ops-common.c | 2 +-
+ mm/damon/paddr.c | 2 +-
+ mm/damon/vaddr.c | 10 +-
+ mm/filemap.c | 2 +-
+ mm/gup.c | 21 ++--
+ mm/highmem.c | 12 +--
+ mm/hmm.c | 2 +-
+ mm/huge_memory.c | 4 +-
+ mm/hugetlb.c | 2 +-
+ mm/hugetlb_vmemmap.c | 6 +-
+ mm/kasan/init.c | 9 +-
+ mm/kasan/shadow.c | 10 +-
+ mm/khugepaged.c | 22 ++--
+ mm/ksm.c | 22 ++--
+ mm/madvise.c | 6 +-
+ mm/mapping_dirty_helpers.c | 4 +-
+ mm/memcontrol.c | 4 +-
+ mm/memory-failure.c | 26 +++--
+ mm/memory.c | 100 ++++++++----------
+ mm/mempolicy.c | 6 +-
+ mm/migrate.c | 14 ++-
+ mm/migrate_device.c | 15 ++-
+ mm/mincore.c | 2 +-
+ mm/mlock.c | 6 +-
+ mm/mprotect.c | 8 +-
+ mm/mremap.c | 2 +-
+ mm/page_table_check.c | 4 +-
+ mm/page_vma_mapped.c | 27 ++---
+ mm/pgtable-generic.c | 2 +-
+ mm/rmap.c | 34 +++---
+ mm/sparse-vmemmap.c | 8 +-
+ mm/swap_state.c | 8 +-
+ mm/swapfile.c | 20 ++--
+ mm/userfaultfd.c | 4 +-
+ mm/vmalloc.c | 6 +-
+ mm/vmscan.c | 14 ++-
+ virt/kvm/kvm_main.c | 11 +-
+ 47 files changed, 228 insertions(+), 301 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+index 01e271b6ad21..56279908ed30 100644
+--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
++++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+@@ -1681,9 +1681,7 @@ static int igt_mmap_gpu(void *arg)
+
+ static int check_present_pte(pte_t *pte, unsigned long addr, void *data)
+ {
+- pte_t ptent = ptep_get(pte);
+-
+- if (!pte_present(ptent) || pte_none(ptent)) {
++ if (!pte_present(*pte) || pte_none(*pte)) {
+ pr_err("missing PTE:%lx\n",
+ (addr - (unsigned long)data) >> PAGE_SHIFT);
+ return -EINVAL;
+@@ -1694,9 +1692,7 @@ static int check_present_pte(pte_t *pte, unsigned long addr, void *data)
+
+ static int check_absent_pte(pte_t *pte, unsigned long addr, void *data)
+ {
+- pte_t ptent = ptep_get(pte);
+-
+- if (pte_present(ptent) && !pte_none(ptent)) {
++ if (pte_present(*pte) && !pte_none(*pte)) {
+ pr_err("present PTE:%lx; expected to be revoked\n",
+ (addr - (unsigned long)data) >> PAGE_SHIFT);
+ return -EINVAL;
+diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
+index 629edb6486de..378cf02a2aa1 100644
+--- a/drivers/misc/sgi-gru/grufault.c
++++ b/drivers/misc/sgi-gru/grufault.c
+@@ -228,7 +228,7 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
+ goto err;
+ #ifdef CONFIG_X86_64
+ if (unlikely(pmd_large(*pmdp)))
+- pte = ptep_get((pte_t *)pmdp);
++ pte = *(pte_t *) pmdp;
+ else
+ #endif
+ pte = *pte_offset_kernel(pmdp, vaddr);
+diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
+index ebe0ad31d0b0..306e6f1d1c70 100644
+--- a/drivers/vfio/vfio_iommu_type1.c
++++ b/drivers/vfio/vfio_iommu_type1.c
+@@ -514,7 +514,6 @@ static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
+ bool write_fault)
+ {
+ pte_t *ptep;
+- pte_t pte;
+ spinlock_t *ptl;
+ int ret;
+
+@@ -537,12 +536,10 @@ static int follow_fault_pfn(struct vm_area_struct *vma, struct mm_struct *mm,
+ return ret;
+ }
+
+- pte = ptep_get(ptep);
+-
+- if (write_fault && !pte_write(pte))
++ if (write_fault && !pte_write(*ptep))
+ ret = -EFAULT;
+ else
+- *pfn = pte_pfn(pte);
++ *pfn = pte_pfn(*ptep);
+
+ pte_unmap_unlock(ptep, ptl);
+ return ret;
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
+index f447cd37cc4c..e2f580e30a86 100644
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -949,7 +949,7 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
+ */
+ static int is_mapped_fn(pte_t *pte, unsigned long addr, void *data)
+ {
+- return pte_none(ptep_get(pte)) ? 0 : -EBUSY;
++ return pte_none(*pte) ? 0 : -EBUSY;
+ }
+
+ static int privcmd_vma_range_is_mapped(
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 507cd4e59d07..0d63b6a0f0d8 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -538,14 +538,13 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
+ bool locked = !!(vma->vm_flags & VM_LOCKED);
+ struct page *page = NULL;
+ bool migration = false, young = false, dirty = false;
+- pte_t ptent = ptep_get(pte);
+
+- if (pte_present(ptent)) {
+- page = vm_normal_page(vma, addr, ptent);
+- young = pte_young(ptent);
+- dirty = pte_dirty(ptent);
+- } else if (is_swap_pte(ptent)) {
+- swp_entry_t swpent = pte_to_swp_entry(ptent);
++ if (pte_present(*pte)) {
++ page = vm_normal_page(vma, addr, *pte);
++ young = pte_young(*pte);
++ dirty = pte_dirty(*pte);
++ } else if (is_swap_pte(*pte)) {
++ swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+ if (!non_swap_entry(swpent)) {
+ int mapcount;
+@@ -733,12 +732,11 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+ struct mem_size_stats *mss = walk->private;
+ struct vm_area_struct *vma = walk->vma;
+ struct page *page = NULL;
+- pte_t ptent = ptep_get(pte);
+
+- if (pte_present(ptent)) {
+- page = vm_normal_page(vma, addr, ptent);
+- } else if (is_swap_pte(ptent)) {
+- swp_entry_t swpent = pte_to_swp_entry(ptent);
++ if (pte_present(*pte)) {
++ page = vm_normal_page(vma, addr, *pte);
++ } else if (is_swap_pte(*pte)) {
++ swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+ if (is_pfn_swap_entry(swpent))
+ page = pfn_swap_entry_to_page(swpent);
+@@ -1107,7 +1105,7 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma,
+ * Documentation/admin-guide/mm/soft-dirty.rst for full description
+ * of how soft-dirty works.
+ */
+- pte_t ptent = ptep_get(pte);
++ pte_t ptent = *pte;
+
+ if (pte_present(ptent)) {
+ pte_t old_pte;
+@@ -1196,7 +1194,7 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
+ return 0;
+ }
+ for (; addr != end; pte++, addr += PAGE_SIZE) {
+- ptent = ptep_get(pte);
++ ptent = *pte;
+
+ if (cp->type == CLEAR_REFS_SOFT_DIRTY) {
+ clear_soft_dirty(vma, addr, pte);
+@@ -1552,7 +1550,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
+ for (; addr < end; pte++, addr += PAGE_SIZE) {
+ pagemap_entry_t pme;
+
+- pme = pte_to_pagemap_entry(pm, vma, addr, ptep_get(pte));
++ pme = pte_to_pagemap_entry(pm, vma, addr, *pte);
+ err = add_to_pagemap(addr, &pme, pm);
+ if (err)
+ break;
+@@ -1895,11 +1893,10 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
+ return 0;
+ }
+ do {
+- pte_t ptent = ptep_get(pte);
+- struct page *page = can_gather_numa_stats(ptent, vma, addr);
++ struct page *page = can_gather_numa_stats(*pte, vma, addr);
+ if (!page)
+ continue;
+- gather_stats(page, md, pte_dirty(ptent), 1);
++ gather_stats(page, md, pte_dirty(*pte), 1);
+
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ pte_unmap_unlock(orig_pte, ptl);
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 7cecd49e078b..bbe5633b1b97 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -335,7 +335,6 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ pud_t *pud;
+ pmd_t *pmd, _pmd;
+ pte_t *pte;
+- pte_t ptent;
+ bool ret = true;
+
+ mmap_assert_locked(mm);
+@@ -375,10 +374,9 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ * changes under us. PTE markers should be handled the same as none
+ * ptes here.
+ */
+- ptent = ptep_get(pte);
+- if (pte_none_mostly(ptent))
++ if (pte_none_mostly(*pte))
+ ret = true;
+- if (!pte_write(ptent) && (reason & VM_UFFD_WP))
++ if (!pte_write(*pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index ca3c8e10f24a..86f6a5abda46 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -1179,11 +1179,7 @@ static inline void hugetlb_count_sub(long l, struct mm_struct *mm)
+ static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+ {
+-#ifdef CONFIG_MMU
+- return ptep_get(ptep);
+-#else
+ return *ptep;
+-#endif
+ }
+
+ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
+index 21d6c72bcc71..e9cdeb290841 100644
+--- a/include/linux/mm_inline.h
++++ b/include/linux/mm_inline.h
+@@ -543,7 +543,7 @@ pte_install_uffd_wp_if_needed(struct vm_area_struct *vma, unsigned long addr,
+ bool arm_uffd_pte = false;
+
+ /* The current status of the pte should be "cleared" before calling */
+- WARN_ON_ONCE(!pte_none(ptep_get(pte)));
++ WARN_ON_ONCE(!pte_none(*pte));
+
+ /*
+ * NOTE: userfaultfd_wp_unpopulated() doesn't need this whole
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index e4e9734ac395..8a79afab07cc 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -223,7 +223,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long address,
+ pte_t *ptep)
+ {
+- pte_t pte = ptep_get(ptep);
++ pte_t pte = *ptep;
+ int r = 1;
+ if (!pte_young(pte))
+ r = 0;
+@@ -310,7 +310,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long address,
+ pte_t *ptep)
+ {
+- pte_t pte = ptep_get(ptep);
++ pte_t pte = *ptep;
+ pte_clear(mm, address, ptep);
+ page_table_check_pte_clear(mm, address, pte);
+ return pte;
+@@ -511,7 +511,7 @@ extern pud_t pudp_huge_clear_flush(struct vm_area_struct *vma,
+ struct mm_struct;
+ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
+ {
+- pte_t old_pte = ptep_get(ptep);
++ pte_t old_pte = *ptep;
+ set_pte_at(mm, address, ptep, pte_wrprotect(old_pte));
+ }
+ #endif
+diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
+index f0ac5b874919..607d742caa61 100644
+--- a/kernel/events/uprobes.c
++++ b/kernel/events/uprobes.c
+@@ -192,7 +192,7 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
+ inc_mm_counter(mm, MM_ANONPAGES);
+ }
+
+- flush_cache_page(vma, addr, pte_pfn(ptep_get(pvmw.pte)));
++ flush_cache_page(vma, addr, pte_pfn(*pvmw.pte));
+ ptep_clear_flush_notify(vma, addr, pvmw.pte);
+ if (new_page)
+ set_pte_at_notify(mm, addr, pvmw.pte,
+diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
+index e940802a15a4..d4ab81229136 100644
+--- a/mm/damon/ops-common.c
++++ b/mm/damon/ops-common.c
+@@ -39,7 +39,7 @@ struct folio *damon_get_folio(unsigned long pfn)
+
+ void damon_ptep_mkold(pte_t *pte, struct vm_area_struct *vma, unsigned long addr)
+ {
+- struct folio *folio = damon_get_folio(pte_pfn(ptep_get(pte)));
++ struct folio *folio = damon_get_folio(pte_pfn(*pte));
+
+ if (!folio)
+ return;
+diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
+index 40801e38fcf0..5b3a3463d078 100644
+--- a/mm/damon/paddr.c
++++ b/mm/damon/paddr.c
+@@ -89,7 +89,7 @@ static bool __damon_pa_young(struct folio *folio, struct vm_area_struct *vma,
+ while (page_vma_mapped_walk(&pvmw)) {
+ addr = pvmw.address;
+ if (pvmw.pte) {
+- *accessed = pte_young(ptep_get(pvmw.pte)) ||
++ *accessed = pte_young(*pvmw.pte) ||
+ !folio_test_idle(folio) ||
+ mmu_notifier_test_young(vma->vm_mm, addr);
+ } else {
+diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
+index 2fcc9731528a..e814f66dfc2e 100644
+--- a/mm/damon/vaddr.c
++++ b/mm/damon/vaddr.c
+@@ -323,7 +323,7 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr,
+ walk->action = ACTION_AGAIN;
+ return 0;
+ }
+- if (!pte_present(ptep_get(pte)))
++ if (!pte_present(*pte))
+ goto out;
+ damon_ptep_mkold(pte, walk->vma, addr);
+ out:
+@@ -433,7 +433,6 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr,
+ unsigned long next, struct mm_walk *walk)
+ {
+ pte_t *pte;
+- pte_t ptent;
+ spinlock_t *ptl;
+ struct folio *folio;
+ struct damon_young_walk_private *priv = walk->private;
+@@ -472,13 +471,12 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr,
+ walk->action = ACTION_AGAIN;
+ return 0;
+ }
+- ptent = ptep_get(pte);
+- if (!pte_present(ptent))
++ if (!pte_present(*pte))
+ goto out;
+- folio = damon_get_folio(pte_pfn(ptent));
++ folio = damon_get_folio(pte_pfn(*pte));
+ if (!folio)
+ goto out;
+- if (pte_young(ptent) || !folio_test_idle(folio) ||
++ if (pte_young(*pte) || !folio_test_idle(folio) ||
+ mmu_notifier_test_young(walk->mm, addr))
+ priv->young = true;
+ *priv->folio_sz = folio_size(folio);
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 9e44a49bbd74..91726ad1b86f 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -3540,7 +3540,7 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,
+ * handled in the specific fault path, and it'll prohibit the
+ * fault-around logic.
+ */
+- if (!pte_none(ptep_get(vmf->pte)))
++ if (!pte_none(*vmf->pte))
+ goto unlock;
+
+ /* We're about to handle the fault */
+diff --git a/mm/gup.c b/mm/gup.c
+index 48c1659314b0..e934c9d3dd37 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -521,14 +521,13 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address,
+ pte_t *pte, unsigned int flags)
+ {
+ if (flags & FOLL_TOUCH) {
+- pte_t orig_entry = ptep_get(pte);
+- pte_t entry = orig_entry;
++ pte_t entry = *pte;
+
+ if (flags & FOLL_WRITE)
+ entry = pte_mkdirty(entry);
+ entry = pte_mkyoung(entry);
+
+- if (!pte_same(orig_entry, entry)) {
++ if (!pte_same(*pte, entry)) {
+ set_pte_at(vma->vm_mm, address, pte, entry);
+ update_mmu_cache(vma, address, pte);
+ }
+@@ -594,7 +593,7 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
+ ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (!ptep)
+ return no_page_table(vma, flags);
+- pte = ptep_get(ptep);
++ pte = *ptep;
+ if (!pte_present(pte))
+ goto no_page;
+ if (pte_protnone(pte) && !gup_can_follow_protnone(flags))
+@@ -866,7 +865,6 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+- pte_t entry;
+ int ret = -EFAULT;
+
+ /* user gate pages are read-only */
+@@ -890,17 +888,16 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
+ pte = pte_offset_map(pmd, address);
+ if (!pte)
+ return -EFAULT;
+- entry = ptep_get(pte);
+- if (pte_none(entry))
++ if (pte_none(*pte))
+ goto unmap;
+ *vma = get_gate_vma(mm);
+ if (!page)
+ goto out;
+- *page = vm_normal_page(*vma, address, entry);
++ *page = vm_normal_page(*vma, address, *pte);
+ if (!*page) {
+- if ((gup_flags & FOLL_DUMP) || !is_zero_pfn(pte_pfn(entry)))
++ if ((gup_flags & FOLL_DUMP) || !is_zero_pfn(pte_pfn(*pte)))
+ goto unmap;
+- *page = pte_page(entry);
++ *page = pte_page(*pte);
+ }
+ ret = try_grab_page(*page, gup_flags);
+ if (unlikely(ret))
+@@ -2543,7 +2540,7 @@ static int gup_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr,
+ }
+
+ if (unlikely(pmd_val(pmd) != pmd_val(*pmdp)) ||
+- unlikely(pte_val(pte) != pte_val(ptep_get(ptep)))) {
++ unlikely(pte_val(pte) != pte_val(*ptep))) {
+ gup_put_folio(folio, 1, flags);
+ goto pte_unmap;
+ }
+@@ -2740,7 +2737,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
+ if (!folio)
+ return 0;
+
+- if (unlikely(pte_val(pte) != pte_val(ptep_get(ptep)))) {
++ if (unlikely(pte_val(pte) != pte_val(*ptep))) {
+ gup_put_folio(folio, refs, flags);
+ return 0;
+ }
+diff --git a/mm/highmem.c b/mm/highmem.c
+index e19269093a93..db251e77f98f 100644
+--- a/mm/highmem.c
++++ b/mm/highmem.c
+@@ -161,7 +161,7 @@ struct page *__kmap_to_page(void *vaddr)
+ /* kmap() mappings */
+ if (WARN_ON_ONCE(addr >= PKMAP_ADDR(0) &&
+ addr < PKMAP_ADDR(LAST_PKMAP)))
+- return pte_page(ptep_get(&pkmap_page_table[PKMAP_NR(addr)]));
++ return pte_page(pkmap_page_table[PKMAP_NR(addr)]);
+
+ /* kmap_local_page() mappings */
+ if (WARN_ON_ONCE(base >= __fix_to_virt(FIX_KMAP_END) &&
+@@ -191,7 +191,6 @@ static void flush_all_zero_pkmaps(void)
+
+ for (i = 0; i < LAST_PKMAP; i++) {
+ struct page *page;
+- pte_t ptent;
+
+ /*
+ * zero means we don't have anything to do,
+@@ -204,8 +203,7 @@ static void flush_all_zero_pkmaps(void)
+ pkmap_count[i] = 0;
+
+ /* sanity check */
+- ptent = ptep_get(&pkmap_page_table[i]);
+- BUG_ON(pte_none(ptent));
++ BUG_ON(pte_none(pkmap_page_table[i]));
+
+ /*
+ * Don't need an atomic fetch-and-clear op here;
+@@ -214,7 +212,7 @@ static void flush_all_zero_pkmaps(void)
+ * getting the kmap_lock (which is held here).
+ * So no dangers, even with speculative execution.
+ */
+- page = pte_page(ptent);
++ page = pte_page(pkmap_page_table[i]);
+ pte_clear(&init_mm, PKMAP_ADDR(i), &pkmap_page_table[i]);
+
+ set_page_address(page, NULL);
+@@ -513,7 +511,7 @@ static inline bool kmap_high_unmap_local(unsigned long vaddr)
+ {
+ #ifdef ARCH_NEEDS_KMAP_HIGH_GET
+ if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
+- kunmap_high(pte_page(ptep_get(&pkmap_page_table[PKMAP_NR(vaddr)])));
++ kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
+ return true;
+ }
+ #endif
+@@ -550,7 +548,7 @@ void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
+ idx = arch_kmap_local_map_idx(kmap_local_idx_push(), pfn);
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ kmap_pte = kmap_get_pte(vaddr, idx);
+- BUG_ON(!pte_none(ptep_get(kmap_pte)));
++ BUG_ON(!pte_none(*kmap_pte));
+ pteval = pfn_pte(pfn, prot);
+ arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte, pteval);
+ arch_kmap_local_post_map(vaddr, pteval);
+diff --git a/mm/hmm.c b/mm/hmm.c
+index 855e25e59d8f..b1a9159d7c92 100644
+--- a/mm/hmm.c
++++ b/mm/hmm.c
+@@ -228,7 +228,7 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
+ struct hmm_range *range = hmm_vma_walk->range;
+ unsigned int required_fault;
+ unsigned long cpu_flags;
+- pte_t pte = ptep_get(ptep);
++ pte_t pte = *ptep;
+ uint64_t pfn_req_flags = *hmm_pfn;
+
+ if (pte_none_mostly(pte)) {
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index eb3678360b97..a37e86c09c5e 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2063,7 +2063,7 @@ static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
+ entry = pte_mkspecial(entry);
+ if (pmd_uffd_wp(old_pmd))
+ entry = pte_mkuffd_wp(entry);
+- VM_BUG_ON(!pte_none(ptep_get(pte)));
++ VM_BUG_ON(!pte_none(*pte));
+ set_pte_at(mm, addr, pte, entry);
+ pte++;
+ }
+@@ -2257,7 +2257,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
+ entry = pte_mkuffd_wp(entry);
+ page_add_anon_rmap(page + i, vma, addr, false);
+ }
+- VM_BUG_ON(!pte_none(ptep_get(pte)));
++ VM_BUG_ON(!pte_none(*pte));
+ set_pte_at(mm, addr, pte, entry);
+ pte++;
+ }
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index bce28cca73a1..f5bedf71503c 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7246,7 +7246,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
+ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+ }
+ }
+- BUG_ON(pte && pte_present(ptep_get(pte)) && !pte_huge(ptep_get(pte)));
++ BUG_ON(pte && pte_present(*pte) && !pte_huge(*pte));
+
+ return pte;
+ }
+diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
+index c2007ef5e9b0..f42079b73f82 100644
+--- a/mm/hugetlb_vmemmap.c
++++ b/mm/hugetlb_vmemmap.c
+@@ -105,7 +105,7 @@ static void vmemmap_pte_range(pmd_t *pmd, unsigned long addr,
+ * remapping (which is calling @walk->remap_pte).
+ */
+ if (!walk->reuse_page) {
+- walk->reuse_page = pte_page(ptep_get(pte));
++ walk->reuse_page = pte_page(*pte);
+ /*
+ * Because the reuse address is part of the range that we are
+ * walking, skip the reuse address range.
+@@ -239,7 +239,7 @@ static void vmemmap_remap_pte(pte_t *pte, unsigned long addr,
+ * to the tail pages.
+ */
+ pgprot_t pgprot = PAGE_KERNEL_RO;
+- struct page *page = pte_page(ptep_get(pte));
++ struct page *page = pte_page(*pte);
+ pte_t entry;
+
+ /* Remapping the head page requires r/w */
+@@ -286,7 +286,7 @@ static void vmemmap_restore_pte(pte_t *pte, unsigned long addr,
+ struct page *page;
+ void *to;
+
+- BUG_ON(pte_page(ptep_get(pte)) != walk->reuse_page);
++ BUG_ON(pte_page(*pte) != walk->reuse_page);
+
+ page = list_first_entry(walk->vmemmap_pages, struct page, lru);
+ list_del(&page->lru);
+diff --git a/mm/kasan/init.c b/mm/kasan/init.c
+index dcfec277e839..cc64ed6858c6 100644
+--- a/mm/kasan/init.c
++++ b/mm/kasan/init.c
+@@ -286,7 +286,7 @@ static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
+
+ for (i = 0; i < PTRS_PER_PTE; i++) {
+ pte = pte_start + i;
+- if (!pte_none(ptep_get(pte)))
++ if (!pte_none(*pte))
+ return;
+ }
+
+@@ -343,19 +343,16 @@ static void kasan_remove_pte_table(pte_t *pte, unsigned long addr,
+ unsigned long end)
+ {
+ unsigned long next;
+- pte_t ptent;
+
+ for (; addr < end; addr = next, pte++) {
+ next = (addr + PAGE_SIZE) & PAGE_MASK;
+ if (next > end)
+ next = end;
+
+- ptent = ptep_get(pte);
+-
+- if (!pte_present(ptent))
++ if (!pte_present(*pte))
+ continue;
+
+- if (WARN_ON(!kasan_early_shadow_page_entry(ptent)))
++ if (WARN_ON(!kasan_early_shadow_page_entry(*pte)))
+ continue;
+ pte_clear(&init_mm, addr, pte);
+ }
+diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
+index dd772f9d0f08..3e62728ae25d 100644
+--- a/mm/kasan/shadow.c
++++ b/mm/kasan/shadow.c
+@@ -226,7 +226,7 @@ static bool shadow_mapped(unsigned long addr)
+ if (pmd_bad(*pmd))
+ return true;
+ pte = pte_offset_kernel(pmd, addr);
+- return !pte_none(ptep_get(pte));
++ return !pte_none(*pte);
+ }
+
+ static int __meminit kasan_mem_notifier(struct notifier_block *nb,
+@@ -317,7 +317,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
+ unsigned long page;
+ pte_t pte;
+
+- if (likely(!pte_none(ptep_get(ptep))))
++ if (likely(!pte_none(*ptep)))
+ return 0;
+
+ page = __get_free_page(GFP_KERNEL);
+@@ -328,7 +328,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
+ pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL);
+
+ spin_lock(&init_mm.page_table_lock);
+- if (likely(pte_none(ptep_get(ptep)))) {
++ if (likely(pte_none(*ptep))) {
+ set_pte_at(&init_mm, addr, ptep, pte);
+ page = 0;
+ }
+@@ -418,11 +418,11 @@ static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
+ {
+ unsigned long page;
+
+- page = (unsigned long)__va(pte_pfn(ptep_get(ptep)) << PAGE_SHIFT);
++ page = (unsigned long)__va(pte_pfn(*ptep) << PAGE_SHIFT);
+
+ spin_lock(&init_mm.page_table_lock);
+
+- if (likely(!pte_none(ptep_get(ptep)))) {
++ if (likely(!pte_none(*ptep))) {
+ pte_clear(&init_mm, addr, ptep);
+ free_page(page);
+ }
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 3beb4ad2ee5e..4d085864f005 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -511,7 +511,7 @@ static void release_pte_pages(pte_t *pte, pte_t *_pte,
+ struct folio *folio, *tmp;
+
+ while (--_pte >= pte) {
+- pte_t pteval = ptep_get(_pte);
++ pte_t pteval = *_pte;
+ unsigned long pfn;
+
+ if (pte_none(pteval))
+@@ -555,7 +555,7 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
+
+ for (_pte = pte; _pte < pte + HPAGE_PMD_NR;
+ _pte++, address += PAGE_SIZE) {
+- pte_t pteval = ptep_get(_pte);
++ pte_t pteval = *_pte;
+ if (pte_none(pteval) || (pte_present(pteval) &&
+ is_zero_pfn(pte_pfn(pteval)))) {
+ ++none_or_zero;
+@@ -699,7 +699,7 @@ static void __collapse_huge_page_copy_succeeded(pte_t *pte,
+
+ for (_pte = pte; _pte < pte + HPAGE_PMD_NR;
+ _pte++, address += PAGE_SIZE) {
+- pteval = ptep_get(_pte);
++ pteval = *_pte;
+ if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) {
+ add_mm_counter(vma->vm_mm, MM_ANONPAGES, 1);
+ if (is_zero_pfn(pte_pfn(pteval))) {
+@@ -797,7 +797,7 @@ static int __collapse_huge_page_copy(pte_t *pte,
+ */
+ for (_pte = pte, _address = address; _pte < pte + HPAGE_PMD_NR;
+ _pte++, page++, _address += PAGE_SIZE) {
+- pteval = ptep_get(_pte);
++ pteval = *_pte;
+ if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) {
+ clear_user_highpage(page, _address);
+ continue;
+@@ -1274,7 +1274,7 @@ static int hpage_collapse_scan_pmd(struct mm_struct *mm,
+
+ for (_address = address, _pte = pte; _pte < pte + HPAGE_PMD_NR;
+ _pte++, _address += PAGE_SIZE) {
+- pte_t pteval = ptep_get(_pte);
++ pte_t pteval = *_pte;
+ if (is_swap_pte(pteval)) {
+ ++unmapped;
+ if (!cc->is_khugepaged ||
+@@ -1650,19 +1650,18 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
+ for (i = 0, addr = haddr, pte = start_pte;
+ i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE, pte++) {
+ struct page *page;
+- pte_t ptent = ptep_get(pte);
+
+ /* empty pte, skip */
+- if (pte_none(ptent))
++ if (pte_none(*pte))
+ continue;
+
+ /* page swapped out, abort */
+- if (!pte_present(ptent)) {
++ if (!pte_present(*pte)) {
+ result = SCAN_PTE_NON_PRESENT;
+ goto abort;
+ }
+
+- page = vm_normal_page(vma, addr, ptent);
++ page = vm_normal_page(vma, addr, *pte);
+ if (WARN_ON_ONCE(page && is_zone_device_page(page)))
+ page = NULL;
+ /*
+@@ -1678,11 +1677,10 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
+ for (i = 0, addr = haddr, pte = start_pte;
+ i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE, pte++) {
+ struct page *page;
+- pte_t ptent = ptep_get(pte);
+
+- if (pte_none(ptent))
++ if (pte_none(*pte))
+ continue;
+- page = vm_normal_page(vma, addr, ptent);
++ page = vm_normal_page(vma, addr, *pte);
+ if (WARN_ON_ONCE(page && is_zone_device_page(page)))
+ goto abort;
+ page_remove_rmap(page, vma, false);
+diff --git a/mm/ksm.c b/mm/ksm.c
+index ba266359da55..150b857314ef 100644
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -429,17 +429,15 @@ static int break_ksm_pmd_entry(pmd_t *pmd, unsigned long addr, unsigned long nex
+ struct page *page = NULL;
+ spinlock_t *ptl;
+ pte_t *pte;
+- pte_t ptent;
+ int ret;
+
+ pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
+ if (!pte)
+ return 0;
+- ptent = ptep_get(pte);
+- if (pte_present(ptent)) {
+- page = vm_normal_page(walk->vma, addr, ptent);
+- } else if (!pte_none(ptent)) {
+- swp_entry_t entry = pte_to_swp_entry(ptent);
++ if (pte_present(*pte)) {
++ page = vm_normal_page(walk->vma, addr, *pte);
++ } else if (!pte_none(*pte)) {
++ swp_entry_t entry = pte_to_swp_entry(*pte);
+
+ /*
+ * As KSM pages remain KSM pages until freed, no need to wait
+@@ -1087,7 +1085,6 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
+ int err = -EFAULT;
+ struct mmu_notifier_range range;
+ bool anon_exclusive;
+- pte_t entry;
+
+ pvmw.address = page_address_in_vma(page, vma);
+ if (pvmw.address == -EFAULT)
+@@ -1105,9 +1102,10 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
+ goto out_unlock;
+
+ anon_exclusive = PageAnonExclusive(page);
+- entry = ptep_get(pvmw.pte);
+- if (pte_write(entry) || pte_dirty(entry) ||
++ if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) ||
+ anon_exclusive || mm_tlb_flush_pending(mm)) {
++ pte_t entry;
++
+ swapped = PageSwapCache(page);
+ flush_cache_page(vma, pvmw.address, page_to_pfn(page));
+ /*
+@@ -1149,7 +1147,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page,
+
+ set_pte_at_notify(mm, pvmw.address, pvmw.pte, entry);
+ }
+- *orig_pte = entry;
++ *orig_pte = *pvmw.pte;
+ err = 0;
+
+ out_unlock:
+@@ -1206,7 +1204,7 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
+ ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ if (!ptep)
+ goto out_mn;
+- if (!pte_same(ptep_get(ptep), orig_pte)) {
++ if (!pte_same(*ptep, orig_pte)) {
+ pte_unmap_unlock(ptep, ptl);
+ goto out_mn;
+ }
+@@ -1233,7 +1231,7 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
+ dec_mm_counter(mm, MM_ANONPAGES);
+ }
+
+- flush_cache_page(vma, addr, pte_pfn(ptep_get(ptep)));
++ flush_cache_page(vma, addr, pte_pfn(*ptep));
+ /*
+ * No need to notify as we are replacing a read only page with another
+ * read only page with the same content.
+diff --git a/mm/madvise.c b/mm/madvise.c
+index 886f06066622..9b3c9610052f 100644
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -207,7 +207,7 @@ static int swapin_walk_pmd_entry(pmd_t *pmd, unsigned long start,
+ break;
+ }
+
+- pte = ptep_get(ptep);
++ pte = *ptep;
+ if (!is_swap_pte(pte))
+ continue;
+ entry = pte_to_swp_entry(pte);
+@@ -438,7 +438,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
+ flush_tlb_batched_pending(mm);
+ arch_enter_lazy_mmu_mode();
+ for (; addr < end; pte++, addr += PAGE_SIZE) {
+- ptent = ptep_get(pte);
++ ptent = *pte;
+
+ if (pte_none(ptent))
+ continue;
+@@ -642,7 +642,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
+ flush_tlb_batched_pending(mm);
+ arch_enter_lazy_mmu_mode();
+ for (; addr != end; pte++, addr += PAGE_SIZE) {
+- ptent = ptep_get(pte);
++ ptent = *pte;
+
+ if (pte_none(ptent))
+ continue;
+diff --git a/mm/mapping_dirty_helpers.c b/mm/mapping_dirty_helpers.c
+index a26dd8bcfcdb..87b4beeda4fa 100644
+--- a/mm/mapping_dirty_helpers.c
++++ b/mm/mapping_dirty_helpers.c
+@@ -35,7 +35,7 @@ static int wp_pte(pte_t *pte, unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
+ {
+ struct wp_walk *wpwalk = walk->private;
+- pte_t ptent = ptep_get(pte);
++ pte_t ptent = *pte;
+
+ if (pte_write(ptent)) {
+ pte_t old_pte = ptep_modify_prot_start(walk->vma, addr, pte);
+@@ -91,7 +91,7 @@ static int clean_record_pte(pte_t *pte, unsigned long addr,
+ {
+ struct wp_walk *wpwalk = walk->private;
+ struct clean_walk *cwalk = to_clean_walk(wpwalk);
+- pte_t ptent = ptep_get(pte);
++ pte_t ptent = *pte;
+
+ if (pte_dirty(ptent)) {
+ pgoff_t pgoff = ((addr - walk->vma->vm_start) >> PAGE_SHIFT) +
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index e8ca4bdcb03c..5f0fc89d4212 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -6014,7 +6014,7 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd,
+ if (!pte)
+ return 0;
+ for (; addr != end; pte++, addr += PAGE_SIZE)
+- if (get_mctgt_type(vma, addr, ptep_get(pte), NULL))
++ if (get_mctgt_type(vma, addr, *pte, NULL))
+ mc.precharge++; /* increment precharge temporarily */
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
+@@ -6235,7 +6235,7 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
+ if (!pte)
+ return 0;
+ for (; addr != end; addr += PAGE_SIZE) {
+- pte_t ptent = ptep_get(pte++);
++ pte_t ptent = *(pte++);
+ bool device = false;
+ swp_entry_t ent;
+
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index e245191e6b04..d5116f0eb1b6 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -6,16 +6,16 @@
+ * High level machine check handler. Handles pages reported by the
+ * hardware as being corrupted usually due to a multi-bit ECC memory or cache
+ * failure.
+- *
++ *
+ * In addition there is a "soft offline" entry point that allows stop using
+ * not-yet-corrupted-by-suspicious pages without killing anything.
+ *
+ * Handles page cache pages in various states. The tricky part
+- * here is that we can access any page asynchronously in respect to
+- * other VM users, because memory failures could happen anytime and
+- * anywhere. This could violate some of their assumptions. This is why
+- * this code has to be extremely careful. Generally it tries to use
+- * normal locking rules, as in get the standard locks, even if that means
++ * here is that we can access any page asynchronously in respect to
++ * other VM users, because memory failures could happen anytime and
++ * anywhere. This could violate some of their assumptions. This is why
++ * this code has to be extremely careful. Generally it tries to use
++ * normal locking rules, as in get the standard locks, even if that means
+ * the error handling takes potentially a long time.
+ *
+ * It can be very tempting to add handling for obscure cases here.
+@@ -25,12 +25,12 @@
+ * https://git.kernel.org/cgit/utils/cpu/mce/mce-test.git/
+ * - The case actually shows up as a frequent (top 10) page state in
+ * tools/mm/page-types when running a real workload.
+- *
++ *
+ * There are several operations here with exponential complexity because
+- * of unsuitable VM data structures. For example the operation to map back
+- * from RMAP chains to processes has to walk the complete process list and
++ * of unsuitable VM data structures. For example the operation to map back
++ * from RMAP chains to processes has to walk the complete process list and
+ * has non linear complexity with the number. But since memory corruptions
+- * are rare we hope to get away with this. This avoids impacting the core
++ * are rare we hope to get away with this. This avoids impacting the core
+ * VM.
+ */
+
+@@ -386,7 +386,6 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+- pte_t ptent;
+
+ VM_BUG_ON_VMA(address == -EFAULT, vma);
+ pgd = pgd_offset(vma->vm_mm, address);
+@@ -408,8 +407,7 @@ static unsigned long dev_pagemap_mapping_shift(struct vm_area_struct *vma,
+ pte = pte_offset_map(pmd, address);
+ if (!pte)
+ return 0;
+- ptent = ptep_get(pte);
+- if (pte_present(ptent) && pte_devmap(ptent))
++ if (pte_present(*pte) && pte_devmap(*pte))
+ ret = PAGE_SHIFT;
+ pte_unmap(pte);
+ return ret;
+@@ -801,7 +799,7 @@ static int hwpoison_pte_range(pmd_t *pmdp, unsigned long addr,
+ goto out;
+
+ for (; addr != end; ptep++, addr += PAGE_SIZE) {
+- ret = check_hwpoisoned_entry(ptep_get(ptep), addr, PAGE_SHIFT,
++ ret = check_hwpoisoned_entry(*ptep, addr, PAGE_SHIFT,
+ hwp->pfn, &hwp->tk);
+ if (ret == 1)
+ break;
+diff --git a/mm/memory.c b/mm/memory.c
+index 25d4d5c7da22..dd51e4bea8c2 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -700,17 +700,15 @@ static void restore_exclusive_pte(struct vm_area_struct *vma,
+ struct page *page, unsigned long address,
+ pte_t *ptep)
+ {
+- pte_t orig_pte;
+ pte_t pte;
+ swp_entry_t entry;
+
+- orig_pte = ptep_get(ptep);
+ pte = pte_mkold(mk_pte(page, READ_ONCE(vma->vm_page_prot)));
+- if (pte_swp_soft_dirty(orig_pte))
++ if (pte_swp_soft_dirty(*ptep))
+ pte = pte_mksoft_dirty(pte);
+
+- entry = pte_to_swp_entry(orig_pte);
+- if (pte_swp_uffd_wp(orig_pte))
++ entry = pte_to_swp_entry(*ptep);
++ if (pte_swp_uffd_wp(*ptep))
+ pte = pte_mkuffd_wp(pte);
+ else if (is_writable_device_exclusive_entry(entry))
+ pte = maybe_mkwrite(pte_mkdirty(pte), vma);
+@@ -747,7 +745,7 @@ static int
+ try_restore_exclusive_pte(pte_t *src_pte, struct vm_area_struct *vma,
+ unsigned long addr)
+ {
+- swp_entry_t entry = pte_to_swp_entry(ptep_get(src_pte));
++ swp_entry_t entry = pte_to_swp_entry(*src_pte);
+ struct page *page = pfn_swap_entry_to_page(entry);
+
+ if (trylock_page(page)) {
+@@ -771,10 +769,9 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+ struct vm_area_struct *src_vma, unsigned long addr, int *rss)
+ {
+ unsigned long vm_flags = dst_vma->vm_flags;
+- pte_t orig_pte = ptep_get(src_pte);
+- pte_t pte = orig_pte;
++ pte_t pte = *src_pte;
+ struct page *page;
+- swp_entry_t entry = pte_to_swp_entry(orig_pte);
++ swp_entry_t entry = pte_to_swp_entry(pte);
+
+ if (likely(!non_swap_entry(entry))) {
+ if (swap_duplicate(entry) < 0)
+@@ -789,8 +786,8 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+ spin_unlock(&mmlist_lock);
+ }
+ /* Mark the swap entry as shared. */
+- if (pte_swp_exclusive(orig_pte)) {
+- pte = pte_swp_clear_exclusive(orig_pte);
++ if (pte_swp_exclusive(*src_pte)) {
++ pte = pte_swp_clear_exclusive(*src_pte);
+ set_pte_at(src_mm, addr, src_pte, pte);
+ }
+ rss[MM_SWAPENTS]++;
+@@ -809,9 +806,9 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+ entry = make_readable_migration_entry(
+ swp_offset(entry));
+ pte = swp_entry_to_pte(entry);
+- if (pte_swp_soft_dirty(orig_pte))
++ if (pte_swp_soft_dirty(*src_pte))
+ pte = pte_swp_mksoft_dirty(pte);
+- if (pte_swp_uffd_wp(orig_pte))
++ if (pte_swp_uffd_wp(*src_pte))
+ pte = pte_swp_mkuffd_wp(pte);
+ set_pte_at(src_mm, addr, src_pte, pte);
+ }
+@@ -844,7 +841,7 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
+ entry = make_readable_device_private_entry(
+ swp_offset(entry));
+ pte = swp_entry_to_pte(entry);
+- if (pte_swp_uffd_wp(orig_pte))
++ if (pte_swp_uffd_wp(*src_pte))
+ pte = pte_swp_mkuffd_wp(pte);
+ set_pte_at(src_mm, addr, src_pte, pte);
+ }
+@@ -908,7 +905,7 @@ copy_present_page(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
+ /* All done, just insert the new page copy in the child */
+ pte = mk_pte(&new_folio->page, dst_vma->vm_page_prot);
+ pte = maybe_mkwrite(pte_mkdirty(pte), dst_vma);
+- if (userfaultfd_pte_wp(dst_vma, ptep_get(src_pte)))
++ if (userfaultfd_pte_wp(dst_vma, *src_pte))
+ /* Uffd-wp needs to be delivered to dest pte as well */
+ pte = pte_mkuffd_wp(pte);
+ set_pte_at(dst_vma->vm_mm, addr, dst_pte, pte);
+@@ -926,7 +923,7 @@ copy_present_pte(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ {
+ struct mm_struct *src_mm = src_vma->vm_mm;
+ unsigned long vm_flags = src_vma->vm_flags;
+- pte_t pte = ptep_get(src_pte);
++ pte_t pte = *src_pte;
+ struct page *page;
+ struct folio *folio;
+
+@@ -1006,7 +1003,6 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ struct mm_struct *src_mm = src_vma->vm_mm;
+ pte_t *orig_src_pte, *orig_dst_pte;
+ pte_t *src_pte, *dst_pte;
+- pte_t ptent;
+ spinlock_t *src_ptl, *dst_ptl;
+ int progress, ret = 0;
+ int rss[NR_MM_COUNTERS];
+@@ -1052,18 +1048,17 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ spin_needbreak(src_ptl) || spin_needbreak(dst_ptl))
+ break;
+ }
+- ptent = ptep_get(src_pte);
+- if (pte_none(ptent)) {
++ if (pte_none(*src_pte)) {
+ progress++;
+ continue;
+ }
+- if (unlikely(!pte_present(ptent))) {
++ if (unlikely(!pte_present(*src_pte))) {
+ ret = copy_nonpresent_pte(dst_mm, src_mm,
+ dst_pte, src_pte,
+ dst_vma, src_vma,
+ addr, rss);
+ if (ret == -EIO) {
+- entry = pte_to_swp_entry(ptep_get(src_pte));
++ entry = pte_to_swp_entry(*src_pte);
+ break;
+ } else if (ret == -EBUSY) {
+ break;
+@@ -1413,7 +1408,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+ flush_tlb_batched_pending(mm);
+ arch_enter_lazy_mmu_mode();
+ do {
+- pte_t ptent = ptep_get(pte);
++ pte_t ptent = *pte;
+ struct page *page;
+
+ if (pte_none(ptent))
+@@ -1828,7 +1823,7 @@ static int validate_page_before_insert(struct page *page)
+ static int insert_page_into_pte_locked(struct vm_area_struct *vma, pte_t *pte,
+ unsigned long addr, struct page *page, pgprot_t prot)
+ {
+- if (!pte_none(ptep_get(pte)))
++ if (!pte_none(*pte))
+ return -EBUSY;
+ /* Ok, finally just insert the thing.. */
+ get_page(page);
+@@ -2122,8 +2117,7 @@ static vm_fault_t insert_pfn(struct vm_area_struct *vma, unsigned long addr,
+ pte = get_locked_pte(mm, addr, &ptl);
+ if (!pte)
+ return VM_FAULT_OOM;
+- entry = ptep_get(pte);
+- if (!pte_none(entry)) {
++ if (!pte_none(*pte)) {
+ if (mkwrite) {
+ /*
+ * For read faults on private mappings the PFN passed
+@@ -2135,11 +2129,11 @@ static vm_fault_t insert_pfn(struct vm_area_struct *vma, unsigned long addr,
+ * allocation and mapping invalidation so just skip the
+ * update.
+ */
+- if (pte_pfn(entry) != pfn_t_to_pfn(pfn)) {
+- WARN_ON_ONCE(!is_zero_pfn(pte_pfn(entry)));
++ if (pte_pfn(*pte) != pfn_t_to_pfn(pfn)) {
++ WARN_ON_ONCE(!is_zero_pfn(pte_pfn(*pte)));
+ goto out_unlock;
+ }
+- entry = pte_mkyoung(entry);
++ entry = pte_mkyoung(*pte);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ if (ptep_set_access_flags(vma, addr, pte, entry, 1))
+ update_mmu_cache(vma, addr, pte);
+@@ -2351,7 +2345,7 @@ static int remap_pte_range(struct mm_struct *mm, pmd_t *pmd,
+ return -ENOMEM;
+ arch_enter_lazy_mmu_mode();
+ do {
+- BUG_ON(!pte_none(ptep_get(pte)));
++ BUG_ON(!pte_none(*pte));
+ if (!pfn_modify_allowed(pfn, prot)) {
+ err = -EACCES;
+ break;
+@@ -2592,7 +2586,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+
+ if (fn) {
+ do {
+- if (create || !pte_none(ptep_get(pte))) {
++ if (create || !pte_none(*pte)) {
+ err = fn(pte++, addr, data);
+ if (err)
+ break;
+@@ -2794,7 +2788,7 @@ static inline int pte_unmap_same(struct vm_fault *vmf)
+ #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPTION)
+ if (sizeof(pte_t) > sizeof(unsigned long)) {
+ spin_lock(vmf->ptl);
+- same = pte_same(ptep_get(vmf->pte), vmf->orig_pte);
++ same = pte_same(*vmf->pte, vmf->orig_pte);
+ spin_unlock(vmf->ptl);
+ }
+ #endif
+@@ -2845,7 +2839,7 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
+ pte_t entry;
+
+ vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
+- if (unlikely(!vmf->pte || !pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
++ if (unlikely(!vmf->pte || !pte_same(*vmf->pte, vmf->orig_pte))) {
+ /*
+ * Other thread has already handled the fault
+ * and update local tlb only
+@@ -2873,7 +2867,7 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
+
+ /* Re-validate under PTL if the page is still mapped */
+ vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
+- if (unlikely(!vmf->pte || !pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
++ if (unlikely(!vmf->pte || !pte_same(*vmf->pte, vmf->orig_pte))) {
+ /* The PTE changed under us, update local tlb */
+ if (vmf->pte)
+ update_mmu_tlb(vma, addr, vmf->pte);
+@@ -3121,7 +3115,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
+ * Re-check the pte - we dropped the lock
+ */
+ vmf->pte = pte_offset_map_lock(mm, vmf->pmd, vmf->address, &vmf->ptl);
+- if (likely(vmf->pte && pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
++ if (likely(vmf->pte && pte_same(*vmf->pte, vmf->orig_pte))) {
+ if (old_folio) {
+ if (!folio_test_anon(old_folio)) {
+ dec_mm_counter(mm, mm_counter_file(&old_folio->page));
+@@ -3248,7 +3242,7 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf)
+ * We might have raced with another page fault while we released the
+ * pte_offset_map_lock.
+ */
+- if (!pte_same(ptep_get(vmf->pte), vmf->orig_pte)) {
++ if (!pte_same(*vmf->pte, vmf->orig_pte)) {
+ update_mmu_tlb(vmf->vma, vmf->address, vmf->pte);
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ return VM_FAULT_NOPAGE;
+@@ -3343,7 +3337,7 @@ static vm_fault_t do_wp_page(struct vm_fault *vmf)
+ struct folio *folio = NULL;
+
+ if (likely(!unshare)) {
+- if (userfaultfd_pte_wp(vma, ptep_get(vmf->pte))) {
++ if (userfaultfd_pte_wp(vma, *vmf->pte)) {
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ return handle_userfault(vmf, VM_UFFD_WP);
+ }
+@@ -3605,7 +3599,7 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)
+
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
+ &vmf->ptl);
+- if (likely(vmf->pte && pte_same(ptep_get(vmf->pte), vmf->orig_pte)))
++ if (likely(vmf->pte && pte_same(*vmf->pte, vmf->orig_pte)))
+ restore_exclusive_pte(vma, vmf->page, vmf->address, vmf->pte);
+
+ if (vmf->pte)
+@@ -3650,7 +3644,7 @@ static vm_fault_t pte_marker_clear(struct vm_fault *vmf)
+ * quickly from a PTE_MARKER_UFFD_WP into PTE_MARKER_SWAPIN_ERROR.
+ * So is_pte_marker() check is not enough to safely drop the pte.
+ */
+- if (pte_same(vmf->orig_pte, ptep_get(vmf->pte)))
++ if (pte_same(vmf->orig_pte, *vmf->pte))
+ pte_clear(vmf->vma->vm_mm, vmf->address, vmf->pte);
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ return 0;
+@@ -3746,8 +3740,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+ if (unlikely(!vmf->pte ||
+- !pte_same(ptep_get(vmf->pte),
+- vmf->orig_pte)))
++ !pte_same(*vmf->pte, vmf->orig_pte)))
+ goto unlock;
+
+ /*
+@@ -3824,8 +3817,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ */
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+- if (likely(vmf->pte &&
+- pte_same(ptep_get(vmf->pte), vmf->orig_pte)))
++ if (likely(vmf->pte && pte_same(*vmf->pte, vmf->orig_pte)))
+ ret = VM_FAULT_OOM;
+ goto unlock;
+ }
+@@ -3895,7 +3887,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ */
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
+ &vmf->ptl);
+- if (unlikely(!vmf->pte || !pte_same(ptep_get(vmf->pte), vmf->orig_pte)))
++ if (unlikely(!vmf->pte || !pte_same(*vmf->pte, vmf->orig_pte)))
+ goto out_nomap;
+
+ if (unlikely(!folio_test_uptodate(folio))) {
+@@ -4340,9 +4332,9 @@ void do_set_pte(struct vm_fault *vmf, struct page *page, unsigned long addr)
+ static bool vmf_pte_changed(struct vm_fault *vmf)
+ {
+ if (vmf->flags & FAULT_FLAG_ORIG_PTE_VALID)
+- return !pte_same(ptep_get(vmf->pte), vmf->orig_pte);
++ return !pte_same(*vmf->pte, vmf->orig_pte);
+
+- return !pte_none(ptep_get(vmf->pte));
++ return !pte_none(*vmf->pte);
+ }
+
+ /**
+@@ -4652,7 +4644,7 @@ static vm_fault_t do_fault(struct vm_fault *vmf)
+ * we don't have concurrent modification by hardware
+ * followed by an update.
+ */
+- if (unlikely(pte_none(ptep_get(vmf->pte))))
++ if (unlikely(pte_none(*vmf->pte)))
+ ret = VM_FAULT_SIGBUS;
+ else
+ ret = VM_FAULT_NOPAGE;
+@@ -4708,7 +4700,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
+ * the pfn may be screwed if the read is non atomic.
+ */
+ spin_lock(vmf->ptl);
+- if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
++ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) {
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ goto out;
+ }
+@@ -4781,7 +4773,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
+ vmf->address, &vmf->ptl);
+ if (unlikely(!vmf->pte))
+ goto out;
+- if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
++ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) {
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ goto out;
+ }
+@@ -4939,7 +4931,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
+
+ spin_lock(vmf->ptl);
+ entry = vmf->orig_pte;
+- if (unlikely(!pte_same(ptep_get(vmf->pte), entry))) {
++ if (unlikely(!pte_same(*vmf->pte, entry))) {
+ update_mmu_tlb(vmf->vma, vmf->address, vmf->pte);
+ goto unlock;
+ }
+@@ -5425,7 +5417,7 @@ int follow_pte(struct mm_struct *mm, unsigned long address,
+ ptep = pte_offset_map_lock(mm, pmd, address, ptlp);
+ if (!ptep)
+ goto out;
+- if (!pte_present(ptep_get(ptep)))
++ if (!pte_present(*ptep))
+ goto unlock;
+ *ptepp = ptep;
+ return 0;
+@@ -5462,7 +5454,7 @@ int follow_pfn(struct vm_area_struct *vma, unsigned long address,
+ ret = follow_pte(vma->vm_mm, address, &ptep, &ptl);
+ if (ret)
+ return ret;
+- *pfn = pte_pfn(ptep_get(ptep));
++ *pfn = pte_pfn(*ptep);
+ pte_unmap_unlock(ptep, ptl);
+ return 0;
+ }
+@@ -5482,7 +5474,7 @@ int follow_phys(struct vm_area_struct *vma,
+
+ if (follow_pte(vma->vm_mm, address, &ptep, &ptl))
+ goto out;
+- pte = ptep_get(ptep);
++ pte = *ptep;
+
+ if ((flags & FOLL_WRITE) && !pte_write(pte))
+ goto unlock;
+@@ -5526,7 +5518,7 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
+ retry:
+ if (follow_pte(vma->vm_mm, addr, &ptep, &ptl))
+ return -EINVAL;
+- pte = ptep_get(ptep);
++ pte = *ptep;
+ pte_unmap_unlock(ptep, ptl);
+
+ prot = pgprot_val(pte_pgprot(pte));
+@@ -5542,7 +5534,7 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
+ if (follow_pte(vma->vm_mm, addr, &ptep, &ptl))
+ goto out_unmap;
+
+- if (!pte_same(pte, ptep_get(ptep))) {
++ if (!pte_same(pte, *ptep)) {
+ pte_unmap_unlock(ptep, ptl);
+ iounmap(maddr);
+
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index edc25195f5bd..0241bb64978b 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -508,7 +508,6 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr,
+ unsigned long flags = qp->flags;
+ bool has_unmovable = false;
+ pte_t *pte, *mapped_pte;
+- pte_t ptent;
+ spinlock_t *ptl;
+
+ ptl = pmd_trans_huge_lock(pmd, vma);
+@@ -521,10 +520,9 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr,
+ return 0;
+ }
+ for (; addr != end; pte++, addr += PAGE_SIZE) {
+- ptent = ptep_get(pte);
+- if (!pte_present(ptent))
++ if (!pte_present(*pte))
+ continue;
+- folio = vm_normal_folio(vma, addr, ptent);
++ folio = vm_normal_folio(vma, addr, *pte);
+ if (!folio || folio_is_zone_device(folio))
+ continue;
+ /*
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 24baad2571e3..d9e6b49b939e 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -187,7 +187,6 @@ static bool remove_migration_pte(struct folio *folio,
+
+ while (page_vma_mapped_walk(&pvmw)) {
+ rmap_t rmap_flags = RMAP_NONE;
+- pte_t old_pte;
+ pte_t pte;
+ swp_entry_t entry;
+ struct page *new;
+@@ -210,18 +209,17 @@ static bool remove_migration_pte(struct folio *folio,
+
+ folio_get(folio);
+ pte = mk_pte(new, READ_ONCE(vma->vm_page_prot));
+- old_pte = ptep_get(pvmw.pte);
+- if (pte_swp_soft_dirty(old_pte))
++ if (pte_swp_soft_dirty(*pvmw.pte))
+ pte = pte_mksoft_dirty(pte);
+
+- entry = pte_to_swp_entry(old_pte);
++ entry = pte_to_swp_entry(*pvmw.pte);
+ if (!is_migration_entry_young(entry))
+ pte = pte_mkold(pte);
+ if (folio_test_dirty(folio) && is_migration_entry_dirty(entry))
+ pte = pte_mkdirty(pte);
+ if (is_writable_migration_entry(entry))
+ pte = pte_mkwrite(pte);
+- else if (pte_swp_uffd_wp(old_pte))
++ else if (pte_swp_uffd_wp(*pvmw.pte))
+ pte = pte_mkuffd_wp(pte);
+
+ if (folio_test_anon(folio) && !is_readable_migration_entry(entry))
+@@ -235,9 +233,9 @@ static bool remove_migration_pte(struct folio *folio,
+ entry = make_readable_device_private_entry(
+ page_to_pfn(new));
+ pte = swp_entry_to_pte(entry);
+- if (pte_swp_soft_dirty(old_pte))
++ if (pte_swp_soft_dirty(*pvmw.pte))
+ pte = pte_swp_mksoft_dirty(pte);
+- if (pte_swp_uffd_wp(old_pte))
++ if (pte_swp_uffd_wp(*pvmw.pte))
+ pte = pte_swp_mkuffd_wp(pte);
+ }
+
+@@ -309,7 +307,7 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+ if (!ptep)
+ return;
+
+- pte = ptep_get(ptep);
++ pte = *ptep;
+ pte_unmap(ptep);
+
+ if (!is_swap_pte(pte))
+diff --git a/mm/migrate_device.c b/mm/migrate_device.c
+index 8365158460ed..67671bfef703 100644
+--- a/mm/migrate_device.c
++++ b/mm/migrate_device.c
+@@ -111,7 +111,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
+ swp_entry_t entry;
+ pte_t pte;
+
+- pte = ptep_get(ptep);
++ pte = *ptep;
+
+ if (pte_none(pte)) {
+ if (vma_is_anonymous(vma)) {
+@@ -194,7 +194,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
+ bool anon_exclusive;
+ pte_t swp_pte;
+
+- flush_cache_page(vma, addr, pte_pfn(pte));
++ flush_cache_page(vma, addr, pte_pfn(*ptep));
+ anon_exclusive = PageAnon(page) && PageAnonExclusive(page);
+ if (anon_exclusive) {
+ pte = ptep_clear_flush(vma, addr, ptep);
+@@ -573,7 +573,6 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+- pte_t orig_pte;
+
+ /* Only allow populating anonymous memory */
+ if (!vma_is_anonymous(vma))
+@@ -629,18 +628,16 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
+ ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl);
+ if (!ptep)
+ goto abort;
+- orig_pte = ptep_get(ptep);
+-
+ if (check_stable_address_space(mm))
+ goto unlock_abort;
+
+- if (pte_present(orig_pte)) {
+- unsigned long pfn = pte_pfn(orig_pte);
++ if (pte_present(*ptep)) {
++ unsigned long pfn = pte_pfn(*ptep);
+
+ if (!is_zero_pfn(pfn))
+ goto unlock_abort;
+ flush = true;
+- } else if (!pte_none(orig_pte))
++ } else if (!pte_none(*ptep))
+ goto unlock_abort;
+
+ /*
+@@ -657,7 +654,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
+ get_page(page);
+
+ if (flush) {
+- flush_cache_page(vma, addr, pte_pfn(orig_pte));
++ flush_cache_page(vma, addr, pte_pfn(*ptep));
+ ptep_clear_flush_notify(vma, addr, ptep);
+ set_pte_at_notify(mm, addr, ptep, entry);
+ update_mmu_cache(vma, addr, ptep);
+diff --git a/mm/mincore.c b/mm/mincore.c
+index b7f7a516b26c..f33f6a0b1ded 100644
+--- a/mm/mincore.c
++++ b/mm/mincore.c
+@@ -119,7 +119,7 @@ static int mincore_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
+ return 0;
+ }
+ for (; addr != end; ptep++, addr += PAGE_SIZE) {
+- pte_t pte = ptep_get(ptep);
++ pte_t pte = *ptep;
+
+ /* We need to do cache lookup too for pte markers */
+ if (pte_none_mostly(pte))
+diff --git a/mm/mlock.c b/mm/mlock.c
+index d7db94519884..9f2b1173b1b1 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -312,7 +312,6 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
+ struct vm_area_struct *vma = walk->vma;
+ spinlock_t *ptl;
+ pte_t *start_pte, *pte;
+- pte_t ptent;
+ struct folio *folio;
+
+ ptl = pmd_trans_huge_lock(pmd, vma);
+@@ -335,10 +334,9 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
+ return 0;
+ }
+ for (pte = start_pte; addr != end; pte++, addr += PAGE_SIZE) {
+- ptent = ptep_get(pte);
+- if (!pte_present(ptent))
++ if (!pte_present(*pte))
+ continue;
+- folio = vm_normal_folio(vma, addr, ptent);
++ folio = vm_normal_folio(vma, addr, *pte);
+ if (!folio || folio_is_zone_device(folio))
+ continue;
+ if (folio_test_large(folio))
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+index 6f658d483704..c697b9c0269f 100644
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -105,7 +105,7 @@ static long change_pte_range(struct mmu_gather *tlb,
+ flush_tlb_batched_pending(vma->vm_mm);
+ arch_enter_lazy_mmu_mode();
+ do {
+- oldpte = ptep_get(pte);
++ oldpte = *pte;
+ if (pte_present(oldpte)) {
+ pte_t ptent;
+
+@@ -544,8 +544,7 @@ long change_protection(struct mmu_gather *tlb,
+ static int prot_none_pte_entry(pte_t *pte, unsigned long addr,
+ unsigned long next, struct mm_walk *walk)
+ {
+- return pfn_modify_allowed(pte_pfn(ptep_get(pte)),
+- *(pgprot_t *)(walk->private)) ?
++ return pfn_modify_allowed(pte_pfn(*pte), *(pgprot_t *)(walk->private)) ?
+ 0 : -EACCES;
+ }
+
+@@ -553,8 +552,7 @@ static int prot_none_hugetlb_entry(pte_t *pte, unsigned long hmask,
+ unsigned long addr, unsigned long next,
+ struct mm_walk *walk)
+ {
+- return pfn_modify_allowed(pte_pfn(ptep_get(pte)),
+- *(pgprot_t *)(walk->private)) ?
++ return pfn_modify_allowed(pte_pfn(*pte), *(pgprot_t *)(walk->private)) ?
+ 0 : -EACCES;
+ }
+
+diff --git a/mm/mremap.c b/mm/mremap.c
+index fe6b722ae633..1be0b7ab2590 100644
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -188,7 +188,7 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+
+ for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
+ new_pte++, new_addr += PAGE_SIZE) {
+- if (pte_none(ptep_get(old_pte)))
++ if (pte_none(*old_pte))
+ continue;
+
+ pte = ptep_get_and_clear(mm, old_addr, old_pte);
+diff --git a/mm/page_table_check.c b/mm/page_table_check.c
+index 93ec7690a0d8..b743a2f6bce0 100644
+--- a/mm/page_table_check.c
++++ b/mm/page_table_check.c
+@@ -196,7 +196,7 @@ void __page_table_check_pte_set(struct mm_struct *mm, unsigned long addr,
+ if (&init_mm == mm)
+ return;
+
+- __page_table_check_pte_clear(mm, addr, ptep_get(ptep));
++ __page_table_check_pte_clear(mm, addr, *ptep);
+ if (pte_user_accessible_page(pte)) {
+ page_table_check_set(mm, addr, pte_pfn(pte),
+ PAGE_SIZE >> PAGE_SHIFT,
+@@ -249,7 +249,7 @@ void __page_table_check_pte_clear_range(struct mm_struct *mm,
+ if (WARN_ON(!ptep))
+ return;
+ for (i = 0; i < PTRS_PER_PTE; i++) {
+- __page_table_check_pte_clear(mm, addr, ptep_get(ptep));
++ __page_table_check_pte_clear(mm, addr, *ptep);
+ addr += PAGE_SIZE;
+ ptep++;
+ }
+diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
+index 49e0d28f0379..2af734274073 100644
+--- a/mm/page_vma_mapped.c
++++ b/mm/page_vma_mapped.c
+@@ -15,8 +15,6 @@ static inline bool not_found(struct page_vma_mapped_walk *pvmw)
+
+ static bool map_pte(struct page_vma_mapped_walk *pvmw, spinlock_t **ptlp)
+ {
+- pte_t ptent;
+-
+ if (pvmw->flags & PVMW_SYNC) {
+ /* Use the stricter lookup */
+ pvmw->pte = pte_offset_map_lock(pvmw->vma->vm_mm, pvmw->pmd,
+@@ -37,12 +35,10 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw, spinlock_t **ptlp)
+ if (!pvmw->pte)
+ return false;
+
+- ptent = ptep_get(pvmw->pte);
+-
+ if (pvmw->flags & PVMW_MIGRATION) {
+- if (!is_swap_pte(ptent))
++ if (!is_swap_pte(*pvmw->pte))
+ return false;
+- } else if (is_swap_pte(ptent)) {
++ } else if (is_swap_pte(*pvmw->pte)) {
+ swp_entry_t entry;
+ /*
+ * Handle un-addressable ZONE_DEVICE memory.
+@@ -60,11 +56,11 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw, spinlock_t **ptlp)
+ * For more details on device private memory see HMM
+ * (include/linux/hmm.h or mm/hmm.c).
+ */
+- entry = pte_to_swp_entry(ptent);
++ entry = pte_to_swp_entry(*pvmw->pte);
+ if (!is_device_private_entry(entry) &&
+ !is_device_exclusive_entry(entry))
+ return false;
+- } else if (!pte_present(ptent)) {
++ } else if (!pte_present(*pvmw->pte)) {
+ return false;
+ }
+ pvmw->ptl = *ptlp;
+@@ -94,34 +90,33 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw, spinlock_t **ptlp)
+ static bool check_pte(struct page_vma_mapped_walk *pvmw)
+ {
+ unsigned long pfn;
+- pte_t ptent = ptep_get(pvmw->pte);
+
+ if (pvmw->flags & PVMW_MIGRATION) {
+ swp_entry_t entry;
+- if (!is_swap_pte(ptent))
++ if (!is_swap_pte(*pvmw->pte))
+ return false;
+- entry = pte_to_swp_entry(ptent);
++ entry = pte_to_swp_entry(*pvmw->pte);
+
+ if (!is_migration_entry(entry) &&
+ !is_device_exclusive_entry(entry))
+ return false;
+
+ pfn = swp_offset_pfn(entry);
+- } else if (is_swap_pte(ptent)) {
++ } else if (is_swap_pte(*pvmw->pte)) {
+ swp_entry_t entry;
+
+ /* Handle un-addressable ZONE_DEVICE memory */
+- entry = pte_to_swp_entry(ptent);
++ entry = pte_to_swp_entry(*pvmw->pte);
+ if (!is_device_private_entry(entry) &&
+ !is_device_exclusive_entry(entry))
+ return false;
+
+ pfn = swp_offset_pfn(entry);
+ } else {
+- if (!pte_present(ptent))
++ if (!pte_present(*pvmw->pte))
+ return false;
+
+- pfn = pte_pfn(ptent);
++ pfn = pte_pfn(*pvmw->pte);
+ }
+
+ return (pfn - pvmw->pfn) < pvmw->nr_pages;
+@@ -299,7 +294,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
+ goto restart;
+ }
+ pvmw->pte++;
+- } while (pte_none(ptep_get(pvmw->pte)));
++ } while (pte_none(*pvmw->pte));
+
+ if (!pvmw->ptl) {
+ pvmw->ptl = ptl;
+diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
+index e6c582e659c9..d2fc52bffafc 100644
+--- a/mm/pgtable-generic.c
++++ b/mm/pgtable-generic.c
+@@ -66,7 +66,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep,
+ pte_t entry, int dirty)
+ {
+- int changed = !pte_same(ptep_get(ptep), entry);
++ int changed = !pte_same(*ptep, entry);
+ if (changed) {
+ set_pte_at(vma->vm_mm, address, ptep, entry);
+ flush_tlb_fix_spurious_fault(vma, address, ptep);
+diff --git a/mm/rmap.c b/mm/rmap.c
+index 0c0d8857dfce..cd918cb9a431 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -826,8 +826,7 @@ static bool folio_referenced_one(struct folio *folio,
+ }
+
+ if (pvmw.pte) {
+- if (lru_gen_enabled() &&
+- pte_young(ptep_get(pvmw.pte))) {
++ if (lru_gen_enabled() && pte_young(*pvmw.pte)) {
+ lru_gen_look_around(&pvmw);
+ referenced++;
+ }
+@@ -957,13 +956,13 @@ static int page_vma_mkclean_one(struct page_vma_mapped_walk *pvmw)
+
+ address = pvmw->address;
+ if (pvmw->pte) {
++ pte_t entry;
+ pte_t *pte = pvmw->pte;
+- pte_t entry = ptep_get(pte);
+
+- if (!pte_dirty(entry) && !pte_write(entry))
++ if (!pte_dirty(*pte) && !pte_write(*pte))
+ continue;
+
+- flush_cache_page(vma, address, pte_pfn(entry));
++ flush_cache_page(vma, address, pte_pfn(*pte));
+ entry = ptep_clear_flush(vma, address, pte);
+ entry = pte_wrprotect(entry);
+ entry = pte_mkclean(entry);
+@@ -1138,7 +1137,7 @@ void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma)
+ * @folio: Folio which contains page.
+ * @page: Page to add to rmap.
+ * @vma: VM area to add page to.
+- * @address: User virtual address of the mapping
++ * @address: User virtual address of the mapping
+ * @exclusive: the page is exclusively owned by the current process
+ */
+ static void __page_set_anon_rmap(struct folio *folio, struct page *page,
+@@ -1459,7 +1458,6 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
+ bool anon_exclusive, ret = true;
+ struct mmu_notifier_range range;
+ enum ttu_flags flags = (enum ttu_flags)(long)arg;
+- unsigned long pfn;
+
+ /*
+ * When racing against e.g. zap_pte_range() on another cpu,
+@@ -1510,8 +1508,8 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
+ break;
+ }
+
+- pfn = pte_pfn(ptep_get(pvmw.pte));
+- subpage = folio_page(folio, pfn - folio_pfn(folio));
++ subpage = folio_page(folio,
++ pte_pfn(*pvmw.pte) - folio_pfn(folio));
+ address = pvmw.address;
+ anon_exclusive = folio_test_anon(folio) &&
+ PageAnonExclusive(subpage);
+@@ -1573,7 +1571,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
+ }
+ pteval = huge_ptep_clear_flush(vma, address, pvmw.pte);
+ } else {
+- flush_cache_page(vma, address, pfn);
++ flush_cache_page(vma, address, pte_pfn(*pvmw.pte));
+ /* Nuke the page table entry. */
+ if (should_defer_flush(mm, flags)) {
+ /*
+@@ -1820,7 +1818,6 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
+ bool anon_exclusive, ret = true;
+ struct mmu_notifier_range range;
+ enum ttu_flags flags = (enum ttu_flags)(long)arg;
+- unsigned long pfn;
+
+ /*
+ * When racing against e.g. zap_pte_range() on another cpu,
+@@ -1880,8 +1877,6 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
+ /* Unexpected PMD-mapped THP? */
+ VM_BUG_ON_FOLIO(!pvmw.pte, folio);
+
+- pfn = pte_pfn(ptep_get(pvmw.pte));
+-
+ if (folio_is_zone_device(folio)) {
+ /*
+ * Our PTE is a non-present device exclusive entry and
+@@ -1896,7 +1891,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
+ VM_BUG_ON_FOLIO(folio_nr_pages(folio) > 1, folio);
+ subpage = &folio->page;
+ } else {
+- subpage = folio_page(folio, pfn - folio_pfn(folio));
++ subpage = folio_page(folio,
++ pte_pfn(*pvmw.pte) - folio_pfn(folio));
+ }
+ address = pvmw.address;
+ anon_exclusive = folio_test_anon(folio) &&
+@@ -1956,7 +1952,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
+ /* Nuke the hugetlb page table entry */
+ pteval = huge_ptep_clear_flush(vma, address, pvmw.pte);
+ } else {
+- flush_cache_page(vma, address, pfn);
++ flush_cache_page(vma, address, pte_pfn(*pvmw.pte));
+ /* Nuke the page table entry. */
+ if (should_defer_flush(mm, flags)) {
+ /*
+@@ -2191,7 +2187,6 @@ static bool page_make_device_exclusive_one(struct folio *folio,
+ struct mmu_notifier_range range;
+ swp_entry_t entry;
+ pte_t swp_pte;
+- pte_t ptent;
+
+ mmu_notifier_range_init_owner(&range, MMU_NOTIFY_EXCLUSIVE, 0,
+ vma->vm_mm, address, min(vma->vm_end,
+@@ -2203,19 +2198,18 @@ static bool page_make_device_exclusive_one(struct folio *folio,
+ /* Unexpected PMD-mapped THP? */
+ VM_BUG_ON_FOLIO(!pvmw.pte, folio);
+
+- ptent = ptep_get(pvmw.pte);
+- if (!pte_present(ptent)) {
++ if (!pte_present(*pvmw.pte)) {
+ ret = false;
+ page_vma_mapped_walk_done(&pvmw);
+ break;
+ }
+
+ subpage = folio_page(folio,
+- pte_pfn(ptent) - folio_pfn(folio));
++ pte_pfn(*pvmw.pte) - folio_pfn(folio));
+ address = pvmw.address;
+
+ /* Nuke the page table entry. */
+- flush_cache_page(vma, address, pte_pfn(ptent));
++ flush_cache_page(vma, address, pte_pfn(*pvmw.pte));
+ pteval = ptep_clear_flush(vma, address, pvmw.pte);
+
+ /* Set the dirty flag on the folio now the pte is gone. */
+diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
+index a044a130405b..10d73a0dfcec 100644
+--- a/mm/sparse-vmemmap.c
++++ b/mm/sparse-vmemmap.c
+@@ -133,7 +133,7 @@ static void * __meminit altmap_alloc_block_buf(unsigned long size,
+ void __meminit vmemmap_verify(pte_t *pte, int node,
+ unsigned long start, unsigned long end)
+ {
+- unsigned long pfn = pte_pfn(ptep_get(pte));
++ unsigned long pfn = pte_pfn(*pte);
+ int actual_node = early_pfn_to_nid(pfn);
+
+ if (node_distance(actual_node, node) > LOCAL_DISTANCE)
+@@ -146,7 +146,7 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node,
+ struct page *reuse)
+ {
+ pte_t *pte = pte_offset_kernel(pmd, addr);
+- if (pte_none(ptep_get(pte))) {
++ if (pte_none(*pte)) {
+ pte_t entry;
+ void *p;
+
+@@ -414,7 +414,7 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
+ * with just tail struct pages.
+ */
+ return vmemmap_populate_range(start, end, node, NULL,
+- pte_page(ptep_get(pte)));
++ pte_page(*pte));
+ }
+
+ size = min(end - start, pgmap_vmemmap_nr(pgmap) * sizeof(struct page));
+@@ -438,7 +438,7 @@ static int __meminit vmemmap_populate_compound_pages(unsigned long start_pfn,
+ */
+ next += PAGE_SIZE;
+ rc = vmemmap_populate_range(next, last, node, NULL,
+- pte_page(ptep_get(pte)));
++ pte_page(*pte));
+ if (rc)
+ return -ENOMEM;
+ }
+diff --git a/mm/swap_state.c b/mm/swap_state.c
+index f8ea7015bad4..f7d99f99a311 100644
+--- a/mm/swap_state.c
++++ b/mm/swap_state.c
+@@ -274,9 +274,9 @@ void clear_shadow_from_swap_cache(int type, unsigned long begin,
+ }
+ }
+
+-/*
+- * If we are the only user, then try to free up the swap cache.
+- *
++/*
++ * If we are the only user, then try to free up the swap cache.
++ *
+ * Its ok to check the swapcache flag without the folio lock
+ * here because we are going to recheck again inside
+ * folio_free_swap() _with_ the lock.
+@@ -293,7 +293,7 @@ void free_swap_cache(struct page *page)
+ }
+ }
+
+-/*
++/*
+ * Perform a free_page(), also freeing any swap cache associated with
+ * this page if it is the last user of the page.
+ */
+diff --git a/mm/swapfile.c b/mm/swapfile.c
+index 8e6dde68b389..211cf29fd2f4 100644
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -1745,7 +1745,7 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
+ struct page *page = folio_file_page(folio, swp_offset(entry));
+ struct page *swapcache;
+ spinlock_t *ptl;
+- pte_t *pte, new_pte, old_pte;
++ pte_t *pte, new_pte;
+ bool hwposioned = false;
+ int ret = 1;
+
+@@ -1757,14 +1757,11 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
+ hwposioned = true;
+
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+- if (unlikely(!pte || !pte_same_as_swp(ptep_get(pte),
+- swp_entry_to_pte(entry)))) {
++ if (unlikely(!pte || !pte_same_as_swp(*pte, swp_entry_to_pte(entry)))) {
+ ret = 0;
+ goto out;
+ }
+
+- old_pte = ptep_get(pte);
+-
+ if (unlikely(hwposioned || !PageUptodate(page))) {
+ swp_entry_t swp_entry;
+
+@@ -1796,7 +1793,7 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
+ * call and have the page locked.
+ */
+ VM_BUG_ON_PAGE(PageWriteback(page), page);
+- if (pte_swp_exclusive(old_pte))
++ if (pte_swp_exclusive(*pte))
+ rmap_flags |= RMAP_EXCLUSIVE;
+
+ page_add_anon_rmap(page, vma, addr, rmap_flags);
+@@ -1805,9 +1802,9 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
+ lru_cache_add_inactive_or_unevictable(page, vma);
+ }
+ new_pte = pte_mkold(mk_pte(page, vma->vm_page_prot));
+- if (pte_swp_soft_dirty(old_pte))
++ if (pte_swp_soft_dirty(*pte))
+ new_pte = pte_mksoft_dirty(new_pte);
+- if (pte_swp_uffd_wp(old_pte))
++ if (pte_swp_uffd_wp(*pte))
+ new_pte = pte_mkuffd_wp(new_pte);
+ setpte:
+ set_pte_at(vma->vm_mm, addr, pte, new_pte);
+@@ -1836,7 +1833,6 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ unsigned char swp_count;
+ swp_entry_t entry;
+ int ret;
+- pte_t ptent;
+
+ if (!pte++) {
+ pte = pte_offset_map(pmd, addr);
+@@ -1844,12 +1840,10 @@ static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ break;
+ }
+
+- ptent = ptep_get_lockless(pte);
+-
+- if (!is_swap_pte(ptent))
++ if (!is_swap_pte(*pte))
+ continue;
+
+- entry = pte_to_swp_entry(ptent);
++ entry = pte_to_swp_entry(*pte);
+ if (swp_type(entry) != type)
+ continue;
+
+diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
+index a2bf37ee276d..5fd787158c70 100644
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -97,7 +97,7 @@ int mfill_atomic_install_pte(pmd_t *dst_pmd,
+ * registered, we firstly wr-protect a none pte which has no page cache
+ * page backing it, then access the page.
+ */
+- if (!pte_none_mostly(ptep_get(dst_pte)))
++ if (!pte_none_mostly(*dst_pte))
+ goto out_unlock;
+
+ folio = page_folio(page);
+@@ -230,7 +230,7 @@ static int mfill_atomic_pte_zeropage(pmd_t *dst_pmd,
+ goto out_unlock;
+ }
+ ret = -EEXIST;
+- if (!pte_none(ptep_get(dst_pte)))
++ if (!pte_none(*dst_pte))
+ goto out_unlock;
+ set_pte_at(dst_vma->vm_mm, dst_addr, dst_pte, _dst_pte);
+ /* No need to invalidate - it was non-present before */
+diff --git a/mm/vmalloc.c b/mm/vmalloc.c
+index 93cf99aba335..41e490597159 100644
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -103,7 +103,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
+ if (!pte)
+ return -ENOMEM;
+ do {
+- BUG_ON(!pte_none(ptep_get(pte)));
++ BUG_ON(!pte_none(*pte));
+
+ #ifdef CONFIG_HUGETLB_PAGE
+ size = arch_vmap_pte_range_map_size(addr, end, pfn, max_page_shift);
+@@ -472,7 +472,7 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
+ do {
+ struct page *page = pages[*nr];
+
+- if (WARN_ON(!pte_none(ptep_get(pte))))
++ if (WARN_ON(!pte_none(*pte)))
+ return -EBUSY;
+ if (WARN_ON(!page))
+ return -ENOMEM;
+@@ -704,7 +704,7 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
+ return NULL;
+
+ ptep = pte_offset_kernel(pmd, addr);
+- pte = ptep_get(ptep);
++ pte = *ptep;
+ if (pte_present(pte))
+ page = pte_page(pte);
+
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 105807110c62..97acbdd2be20 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -4035,16 +4035,15 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
+ for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) {
+ unsigned long pfn;
+ struct folio *folio;
+- pte_t ptent = ptep_get(pte + i);
+
+ total++;
+ walk->mm_stats[MM_LEAF_TOTAL]++;
+
+- pfn = get_pte_pfn(ptent, args->vma, addr);
++ pfn = get_pte_pfn(pte[i], args->vma, addr);
+ if (pfn == -1)
+ continue;
+
+- if (!pte_young(ptent)) {
++ if (!pte_young(pte[i])) {
+ walk->mm_stats[MM_LEAF_OLD]++;
+ continue;
+ }
+@@ -4059,7 +4058,7 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
+ young++;
+ walk->mm_stats[MM_LEAF_YOUNG]++;
+
+- if (pte_dirty(ptent) && !folio_test_dirty(folio) &&
++ if (pte_dirty(pte[i]) && !folio_test_dirty(folio) &&
+ !(folio_test_anon(folio) && folio_test_swapbacked(folio) &&
+ !folio_test_swapcache(folio)))
+ folio_mark_dirty(folio);
+@@ -4702,13 +4701,12 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
+
+ for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
+ unsigned long pfn;
+- pte_t ptent = ptep_get(pte + i);
+
+- pfn = get_pte_pfn(ptent, pvmw->vma, addr);
++ pfn = get_pte_pfn(pte[i], pvmw->vma, addr);
+ if (pfn == -1)
+ continue;
+
+- if (!pte_young(ptent))
++ if (!pte_young(pte[i]))
+ continue;
+
+ folio = get_pfn_folio(pfn, memcg, pgdat, !walk || walk->can_swap);
+@@ -4720,7 +4718,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
+
+ young++;
+
+- if (pte_dirty(ptent) && !folio_test_dirty(folio) &&
++ if (pte_dirty(pte[i]) && !folio_test_dirty(folio) &&
+ !(folio_test_anon(folio) && folio_test_swapbacked(folio) &&
+ !folio_test_swapcache(folio)))
+ folio_mark_dirty(folio);
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 19f301ef23c9..b9f3c055af04 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -2596,7 +2596,6 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
+ {
+ kvm_pfn_t pfn;
+ pte_t *ptep;
+- pte_t pte;
+ spinlock_t *ptl;
+ int r;
+
+@@ -2620,16 +2619,14 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
+ return r;
+ }
+
+- pte = ptep_get(ptep);
+-
+- if (write_fault && !pte_write(pte)) {
++ if (write_fault && !pte_write(*ptep)) {
+ pfn = KVM_PFN_ERR_RO_FAULT;
+ goto out;
+ }
+
+ if (writable)
+- *writable = pte_write(pte);
+- pfn = pte_pfn(pte);
++ *writable = pte_write(*ptep);
++ pfn = pte_pfn(*ptep);
+
+ /*
+ * Get a reference here because callers of *hva_to_pfn* and
+@@ -2647,7 +2644,7 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
+ * tail pages of non-compound higher order allocations, which
+ * would then underflow the refcount when the caller does the
+ * required put_page. Don't allow those pages here.
+- */
++ */
+ if (!kvm_try_get_pfn(pfn))
+ r = -EFAULT;
+
+--
+2.25.1
+
diff --git a/patchsets/0003-Revert-mm-memory-handle_pte_fault-use-pte_offset_map.patch b/patchsets/0003-Revert-mm-memory-handle_pte_fault-use-pte_offset_map.patch
new file mode 100644
index 0000000..15a21b5
--- /dev/null
+++ b/patchsets/0003-Revert-mm-memory-handle_pte_fault-use-pte_offset_map.patch
@@ -0,0 +1,130 @@
+From 5d7d3cb6187d66212a8a55c88c3b68d8110bbb9a Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 16:02:12 +0800
+Subject: [PATCH 3/7] Revert "mm/memory: handle_pte_fault() use
+ pte_offset_map_nolock()"
+
+This reverts commit c7ad08804fae5baa7f71c0790038e8259e1066a5.
+---
+ mm/khugepaged.c | 6 ++----
+ mm/memory.c | 38 +++++++++++++++++++++++++-------------
+ 2 files changed, 27 insertions(+), 17 deletions(-)
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 4d085864f005..25aa8e29673f 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -999,7 +999,6 @@ static int __collapse_huge_page_swapin(struct mm_struct *mm,
+ unsigned long address, end = haddr + (HPAGE_PMD_NR * PAGE_SIZE);
+ int result;
+ pte_t *pte = NULL;
+- spinlock_t *ptl;
+
+ for (address = haddr; address < end; address += PAGE_SIZE) {
+ struct vm_fault vmf = {
+@@ -1011,7 +1010,7 @@ static int __collapse_huge_page_swapin(struct mm_struct *mm,
+ };
+
+ if (!pte++) {
+- pte = pte_offset_map_nolock(mm, pmd, address, &ptl);
++ pte = pte_offset_map(pmd, address);
+ if (!pte) {
+ mmap_read_unlock(mm);
+ result = SCAN_PMD_NULL;
+@@ -1019,12 +1018,11 @@ static int __collapse_huge_page_swapin(struct mm_struct *mm,
+ }
+ }
+
+- vmf.orig_pte = ptep_get_lockless(pte);
++ vmf.orig_pte = *pte;
+ if (!is_swap_pte(vmf.orig_pte))
+ continue;
+
+ vmf.pte = pte;
+- vmf.ptl = ptl;
+ ret = do_swap_page(&vmf);
+ /* Which unmaps pte (after perhaps re-checking the entry) */
+ pte = NULL;
+diff --git a/mm/memory.c b/mm/memory.c
+index dd51e4bea8c2..61534dbf7a6a 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2787,9 +2787,10 @@ static inline int pte_unmap_same(struct vm_fault *vmf)
+ int same = 1;
+ #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPTION)
+ if (sizeof(pte_t) > sizeof(unsigned long)) {
+- spin_lock(vmf->ptl);
++ spinlock_t *ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
++ spin_lock(ptl);
+ same = pte_same(*vmf->pte, vmf->orig_pte);
+- spin_unlock(vmf->ptl);
++ spin_unlock(ptl);
+ }
+ #endif
+ pte_unmap(vmf->pte);
+@@ -4699,6 +4700,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
+ * validation through pte_unmap_same(). It's of NUMA type but
+ * the pfn may be screwed if the read is non atomic.
+ */
++ vmf->ptl = pte_lockptr(vma->vm_mm, vmf->pmd);
+ spin_lock(vmf->ptl);
+ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) {
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+@@ -4769,10 +4771,8 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
+ flags |= TNF_MIGRATED;
+ } else {
+ flags |= TNF_MIGRATE_FAIL;
+- vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+- vmf->address, &vmf->ptl);
+- if (unlikely(!vmf->pte))
+- goto out;
++ vmf->pte = pte_offset_map(vmf->pmd, vmf->address);
++ spin_lock(vmf->ptl);
+ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte))) {
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ goto out;
+@@ -4902,15 +4902,26 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
+ vmf->flags &= ~FAULT_FLAG_ORIG_PTE_VALID;
+ } else {
+ /*
+- * A regular pmd is established and it can't morph into a huge
+- * pmd by anon khugepaged, since that takes mmap_lock in write
+- * mode; but shmem or file collapse to THP could still morph
+- * it into a huge pmd: just retry later if so.
++ * If a huge pmd materialized under us just retry later. Use
++ * pmd_trans_unstable() via pmd_devmap_trans_unstable() instead
++ * of pmd_trans_huge() to ensure the pmd didn't become
++ * pmd_trans_huge under us and then back to pmd_none, as a
++ * result of MADV_DONTNEED running immediately after a huge pmd
++ * fault in a different thread of this mm, in turn leading to a
++ * misleading pmd_trans_huge() retval. All we have to ensure is
++ * that it is a regular pmd that we can walk with
++ * pte_offset_map() and we can do that through an atomic read
++ * in C, which is what pmd_trans_unstable() provides.
+ */
+- vmf->pte = pte_offset_map_nolock(vmf->vma->vm_mm, vmf->pmd,
+- vmf->address, &vmf->ptl);
+- if (unlikely(!vmf->pte))
++ if (pmd_devmap_trans_unstable(vmf->pmd))
+ return 0;
++ /*
++ * A regular pmd is established and it can't morph into a huge
++ * pmd from under us anymore at this point because we hold the
++ * mmap_lock read mode and khugepaged takes it in write mode.
++ * So now it's safe to run pte_offset_map().
++ */
++ vmf->pte = pte_offset_map(vmf->pmd, vmf->address);
+ vmf->orig_pte = ptep_get_lockless(vmf->pte);
+ vmf->flags |= FAULT_FLAG_ORIG_PTE_VALID;
+
+@@ -4929,6 +4940,7 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
+ if (pte_protnone(vmf->orig_pte) && vma_is_accessible(vmf->vma))
+ return do_numa_page(vmf);
+
++ vmf->ptl = pte_lockptr(vmf->vma->vm_mm, vmf->pmd);
+ spin_lock(vmf->ptl);
+ entry = vmf->orig_pte;
+ if (unlikely(!pte_same(*vmf->pte, entry))) {
+--
+2.25.1
+
diff --git a/patchsets/0004-Revert-mm-memory-allow-pte_offset_map-_lock-to-fail.patch b/patchsets/0004-Revert-mm-memory-allow-pte_offset_map-_lock-to-fail.patch
new file mode 100644
index 0000000..d674b59
--- /dev/null
+++ b/patchsets/0004-Revert-mm-memory-allow-pte_offset_map-_lock-to-fail.patch
@@ -0,0 +1,422 @@
+From c2680e855c392d84cabb44bc99e7dd1ca236ffdf Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 16:02:23 +0800
+Subject: [PATCH 4/7] Revert "mm/memory: allow pte_offset_map[_lock]() to fail"
+
+This reverts commit 3db82b9374ca921b8b820a75e83809d5c4133d8f.
+---
+ mm/memory.c | 167 +++++++++++++++++++++++++++-------------------------
+ 1 file changed, 86 insertions(+), 81 deletions(-)
+
+diff --git a/mm/memory.c b/mm/memory.c
+index 61534dbf7a6a..6fab523e651d 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1013,25 +1013,13 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ progress = 0;
+ init_rss_vec(rss);
+
+- /*
+- * copy_pmd_range()'s prior pmd_none_or_clear_bad(src_pmd), and the
+- * error handling here, assume that exclusive mmap_lock on dst and src
+- * protects anon from unexpected THP transitions; with shmem and file
+- * protected by mmap_lock-less collapse skipping areas with anon_vma
+- * (whereas vma_needs_copy() skips areas without anon_vma). A rework
+- * can remove such assumptions later, but this is good enough for now.
+- */
+ dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
+ if (!dst_pte) {
+ ret = -ENOMEM;
+ goto out;
+ }
+- src_pte = pte_offset_map_nolock(src_mm, src_pmd, addr, &src_ptl);
+- if (!src_pte) {
+- pte_unmap_unlock(dst_pte, dst_ptl);
+- /* ret == 0 */
+- goto out;
+- }
++ src_pte = pte_offset_map(src_pmd, addr);
++ src_ptl = pte_lockptr(src_mm, src_pmd);
+ spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
+ orig_src_pte = src_pte;
+ orig_dst_pte = dst_pte;
+@@ -1096,7 +1084,8 @@ copy_pte_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ } while (dst_pte++, src_pte++, addr += PAGE_SIZE, addr != end);
+
+ arch_leave_lazy_mmu_mode();
+- pte_unmap_unlock(orig_src_pte, src_ptl);
++ spin_unlock(src_ptl);
++ pte_unmap(orig_src_pte);
+ add_mm_rss_vec(dst_mm, rss);
+ pte_unmap_unlock(orig_dst_pte, dst_ptl);
+ cond_resched();
+@@ -1400,11 +1389,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+ swp_entry_t entry;
+
+ tlb_change_page_size(tlb, PAGE_SIZE);
++again:
+ init_rss_vec(rss);
+- start_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+- if (!pte)
+- return addr;
+-
++ start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
++ pte = start_pte;
+ flush_tlb_batched_pending(mm);
+ arch_enter_lazy_mmu_mode();
+ do {
+@@ -1520,10 +1508,17 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+ * If we forced a TLB flush (either due to running out of
+ * batch buffers or because we needed to flush dirty TLB
+ * entries before releasing the ptl), free the batched
+- * memory too. Come back again if we didn't do everything.
++ * memory too. Restart if we didn't do everything.
+ */
+- if (force_flush)
++ if (force_flush) {
++ force_flush = 0;
+ tlb_flush_mmu(tlb);
++ }
++
++ if (addr != end) {
++ cond_resched();
++ goto again;
++ }
+
+ return addr;
+ }
+@@ -1542,10 +1537,8 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
+ if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
+ if (next - addr != HPAGE_PMD_SIZE)
+ __split_huge_pmd(vma, pmd, addr, false, NULL);
+- else if (zap_huge_pmd(tlb, vma, pmd, addr)) {
+- addr = next;
+- continue;
+- }
++ else if (zap_huge_pmd(tlb, vma, pmd, addr))
++ goto next;
+ /* fall through */
+ } else if (details && details->single_folio &&
+ folio_test_pmd_mappable(details->single_folio) &&
+@@ -1558,14 +1551,20 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
+ */
+ spin_unlock(ptl);
+ }
+- if (pmd_none(*pmd)) {
+- addr = next;
+- continue;
+- }
+- addr = zap_pte_range(tlb, vma, pmd, addr, next, details);
+- if (addr != next)
+- pmd--;
+- } while (pmd++, cond_resched(), addr != end);
++
++ /*
++ * Here there can be other concurrent MADV_DONTNEED or
++ * trans huge page faults running, and if the pmd is
++ * none or trans huge it can change under us. This is
++ * because MADV_DONTNEED holds the mmap_lock in read
++ * mode.
++ */
++ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
++ goto next;
++ next = zap_pte_range(tlb, vma, pmd, addr, next, details);
++next:
++ cond_resched();
++ } while (pmd++, addr = next, addr != end);
+
+ return addr;
+ }
+@@ -1907,10 +1906,6 @@ static int insert_pages(struct vm_area_struct *vma, unsigned long addr,
+ const int batch_size = min_t(int, pages_to_write_in_pmd, 8);
+
+ start_pte = pte_offset_map_lock(mm, pmd, addr, &pte_lock);
+- if (!start_pte) {
+- ret = -EFAULT;
+- goto out;
+- }
+ for (pte = start_pte; pte_idx < batch_size; ++pte, ++pte_idx) {
+ int err = insert_page_in_batch_locked(vma, pte,
+ addr, pages[curr_page_idx], prot);
+@@ -2578,10 +2573,10 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+ mapped_pte = pte = (mm == &init_mm) ?
+ pte_offset_kernel(pmd, addr) :
+ pte_offset_map_lock(mm, pmd, addr, &ptl);
+- if (!pte)
+- return -EINVAL;
+ }
+
++ BUG_ON(pmd_huge(*pmd));
++
+ arch_enter_lazy_mmu_mode();
+
+ if (fn) {
+@@ -2810,6 +2805,7 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
+ int ret;
+ void *kaddr;
+ void __user *uaddr;
++ bool locked = false;
+ struct vm_area_struct *vma = vmf->vma;
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long addr = vmf->address;
+@@ -2835,12 +2831,12 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
+ * On architectures with software "accessed" bits, we would
+ * take a double page fault, so mark it accessed here.
+ */
+- vmf->pte = NULL;
+ if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) {
+ pte_t entry;
+
+ vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
+- if (unlikely(!vmf->pte || !pte_same(*vmf->pte, vmf->orig_pte))) {
++ locked = true;
++ if (!likely(pte_same(*vmf->pte, vmf->orig_pte))) {
+ /*
+ * Other thread has already handled the fault
+ * and update local tlb only
+@@ -2863,12 +2859,13 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
+ * zeroes.
+ */
+ if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE)) {
+- if (vmf->pte)
++ if (locked)
+ goto warn;
+
+ /* Re-validate under PTL if the page is still mapped */
+ vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
+- if (unlikely(!vmf->pte || !pte_same(*vmf->pte, vmf->orig_pte))) {
++ locked = true;
++ if (!likely(pte_same(*vmf->pte, vmf->orig_pte))) {
+ /* The PTE changed under us, update local tlb */
+ if (vmf->pte)
+ update_mmu_tlb(vma, addr, vmf->pte);
+@@ -2894,7 +2891,7 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
+ ret = 0;
+
+ pte_unlock:
+- if (vmf->pte)
++ if (locked)
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ kunmap_atomic(kaddr);
+ flush_dcache_page(dst);
+@@ -3116,7 +3113,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
+ * Re-check the pte - we dropped the lock
+ */
+ vmf->pte = pte_offset_map_lock(mm, vmf->pmd, vmf->address, &vmf->ptl);
+- if (likely(vmf->pte && pte_same(*vmf->pte, vmf->orig_pte))) {
++ if (likely(pte_same(*vmf->pte, vmf->orig_pte))) {
+ if (old_folio) {
+ if (!folio_test_anon(old_folio)) {
+ dec_mm_counter(mm, mm_counter_file(&old_folio->page));
+@@ -3184,20 +3181,19 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
+ /* Free the old page.. */
+ new_folio = old_folio;
+ page_copied = 1;
+- pte_unmap_unlock(vmf->pte, vmf->ptl);
+- } else if (vmf->pte) {
++ } else {
+ update_mmu_tlb(vma, vmf->address, vmf->pte);
+- pte_unmap_unlock(vmf->pte, vmf->ptl);
+ }
+
++ if (new_folio)
++ folio_put(new_folio);
++
++ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ /*
+ * No need to double call mmu_notifier->invalidate_range() callback as
+ * the above ptep_clear_flush_notify() did already call it.
+ */
+ mmu_notifier_invalidate_range_only_end(&range);
+-
+- if (new_folio)
+- folio_put(new_folio);
+ if (old_folio) {
+ if (page_copied)
+ free_swap_cache(&old_folio->page);
+@@ -3237,8 +3233,6 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf)
+ WARN_ON_ONCE(!(vmf->vma->vm_flags & VM_SHARED));
+ vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd, vmf->address,
+ &vmf->ptl);
+- if (!vmf->pte)
+- return VM_FAULT_NOPAGE;
+ /*
+ * We might have raced with another page fault while we released the
+ * pte_offset_map_lock.
+@@ -3600,11 +3594,10 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)
+
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
+ &vmf->ptl);
+- if (likely(vmf->pte && pte_same(*vmf->pte, vmf->orig_pte)))
++ if (likely(pte_same(*vmf->pte, vmf->orig_pte)))
+ restore_exclusive_pte(vma, vmf->page, vmf->address, vmf->pte);
+
+- if (vmf->pte)
+- pte_unmap_unlock(vmf->pte, vmf->ptl);
++ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ folio_unlock(folio);
+ folio_put(folio);
+
+@@ -3635,8 +3628,6 @@ static vm_fault_t pte_marker_clear(struct vm_fault *vmf)
+ {
+ vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+- if (!vmf->pte)
+- return 0;
+ /*
+ * Be careful so that we will only recover a special uffd-wp pte into a
+ * none pte. Otherwise it means the pte could have changed, so retry.
+@@ -3740,8 +3731,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ vmf->page = pfn_swap_entry_to_page(entry);
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+- if (unlikely(!vmf->pte ||
+- !pte_same(*vmf->pte, vmf->orig_pte)))
++ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte)))
+ goto unlock;
+
+ /*
+@@ -3818,7 +3808,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ */
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+- if (likely(vmf->pte && pte_same(*vmf->pte, vmf->orig_pte)))
++ if (likely(pte_same(*vmf->pte, vmf->orig_pte)))
+ ret = VM_FAULT_OOM;
+ goto unlock;
+ }
+@@ -3888,7 +3878,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ */
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
+ &vmf->ptl);
+- if (unlikely(!vmf->pte || !pte_same(*vmf->pte, vmf->orig_pte)))
++ if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte)))
+ goto out_nomap;
+
+ if (unlikely(!folio_test_uptodate(folio))) {
+@@ -4014,15 +4004,13 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
+ /* No need to invalidate - it was non-present before */
+ update_mmu_cache(vma, vmf->address, vmf->pte);
+ unlock:
+- if (vmf->pte)
+- pte_unmap_unlock(vmf->pte, vmf->ptl);
++ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ out:
+ if (si)
+ put_swap_device(si);
+ return ret;
+ out_nomap:
+- if (vmf->pte)
+- pte_unmap_unlock(vmf->pte, vmf->ptl);
++ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ out_page:
+ folio_unlock(folio);
+ out_release:
+@@ -4054,12 +4042,22 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
+ return VM_FAULT_SIGBUS;
+
+ /*
+- * Use pte_alloc() instead of pte_alloc_map(), so that OOM can
+- * be distinguished from a transient failure of pte_offset_map().
++ * Use pte_alloc() instead of pte_alloc_map(). We can't run
++ * pte_offset_map() on pmds where a huge pmd might be created
++ * from a different thread.
++ *
++ * pte_alloc_map() is safe to use under mmap_write_lock(mm) or when
++ * parallel threads are excluded by other means.
++ *
++ * Here we only have mmap_read_lock(mm).
+ */
+ if (pte_alloc(vma->vm_mm, vmf->pmd))
+ return VM_FAULT_OOM;
+
++ /* See comment in handle_pte_fault() */
++ if (unlikely(pmd_trans_unstable(vmf->pmd)))
++ return 0;
++
+ /* Use the zero-page for reads */
+ if (!(vmf->flags & FAULT_FLAG_WRITE) &&
+ !mm_forbids_zeropage(vma->vm_mm)) {
+@@ -4067,8 +4065,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
+ vma->vm_page_prot));
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+- if (!vmf->pte)
+- goto unlock;
+ if (vmf_pte_changed(vmf)) {
+ update_mmu_tlb(vma, vmf->address, vmf->pte);
+ goto unlock;
+@@ -4109,8 +4105,6 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
+
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
+ &vmf->ptl);
+- if (!vmf->pte)
+- goto release;
+ if (vmf_pte_changed(vmf)) {
+ update_mmu_tlb(vma, vmf->address, vmf->pte);
+ goto release;
+@@ -4138,8 +4132,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
+ /* No need to invalidate - it was non-present before */
+ update_mmu_cache(vma, vmf->address, vmf->pte);
+ unlock:
+- if (vmf->pte)
+- pte_unmap_unlock(vmf->pte, vmf->ptl);
++ pte_unmap_unlock(vmf->pte, vmf->ptl);
+ return ret;
+ release:
+ folio_put(folio);
+@@ -4388,10 +4381,15 @@ vm_fault_t finish_fault(struct vm_fault *vmf)
+ return VM_FAULT_OOM;
+ }
+
++ /*
++ * See comment in handle_pte_fault() for how this scenario happens, we
++ * need to return NOPAGE so that we drop this page.
++ */
++ if (pmd_devmap_trans_unstable(vmf->pmd))
++ return VM_FAULT_NOPAGE;
++
+ vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
+ vmf->address, &vmf->ptl);
+- if (!vmf->pte)
+- return VM_FAULT_NOPAGE;
+
+ /* Re-check under ptl */
+ if (likely(!vmf_pte_changed(vmf))) {
+@@ -4633,11 +4631,17 @@ static vm_fault_t do_fault(struct vm_fault *vmf)
+ * The VMA was not fully populated on mmap() or missing VM_DONTEXPAND
+ */
+ if (!vma->vm_ops->fault) {
+- vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd,
+- vmf->address, &vmf->ptl);
+- if (unlikely(!vmf->pte))
++ /*
++ * If we find a migration pmd entry or a none pmd entry, which
++ * should never happen, return SIGBUS
++ */
++ if (unlikely(!pmd_present(*vmf->pmd)))
+ ret = VM_FAULT_SIGBUS;
+ else {
++ vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm,
++ vmf->pmd,
++ vmf->address,
++ &vmf->ptl);
+ /*
+ * Make sure this is not a temporary clearing of pte
+ * by holding ptl and checking again. A R/M/W update
+@@ -5426,9 +5430,10 @@ int follow_pte(struct mm_struct *mm, unsigned long address,
+ pmd = pmd_offset(pud, address);
+ VM_BUG_ON(pmd_trans_huge(*pmd));
+
+- ptep = pte_offset_map_lock(mm, pmd, address, ptlp);
+- if (!ptep)
++ if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+ goto out;
++
++ ptep = pte_offset_map_lock(mm, pmd, address, ptlp);
+ if (!pte_present(*ptep))
+ goto unlock;
+ *ptepp = ptep;
+--
+2.25.1
+
diff --git a/patchsets/0005-Revert-mm-pgtable-delete-pmd_trans_unstable-and-frie.patch b/patchsets/0005-Revert-mm-pgtable-delete-pmd_trans_unstable-and-frie.patch
new file mode 100644
index 0000000..fec5bdb
--- /dev/null
+++ b/patchsets/0005-Revert-mm-pgtable-delete-pmd_trans_unstable-and-frie.patch
@@ -0,0 +1,163 @@
+From c1f1ff783aa2af26e026d6fe4bfab19974bcec12 Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 16:06:46 +0800
+Subject: [PATCH 5/7] Revert "mm/pgtable: delete pmd_trans_unstable() and
+ friends"
+
+This reverts commit feda5c393a6c843c7bf1fc49e1381e2d3822b564.
+---
+ include/linux/pgtable.h | 103 +++++++++++++++++++++++++++++++++++++---
+ mm/khugepaged.c | 4 ++
+ 2 files changed, 100 insertions(+), 7 deletions(-)
+
+diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
+index 8a79afab07cc..c36c453807ea 100644
+--- a/include/linux/pgtable.h
++++ b/include/linux/pgtable.h
+@@ -591,10 +591,6 @@ extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
+ extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
+ #endif
+
+-#ifndef arch_needs_pgtable_deposit
+-#define arch_needs_pgtable_deposit() (false)
+-#endif
+-
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ /*
+ * This is an implementation of pmdp_establish() that is only suitable for an
+@@ -1296,10 +1292,9 @@ static inline int pud_trans_huge(pud_t pud)
+ }
+ #endif
+
+-static inline int pud_trans_unstable(pud_t *pud)
++/* See pmd_none_or_trans_huge_or_clear_bad for discussion. */
++static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud)
+ {
+-#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
+- defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
+ pud_t pudval = READ_ONCE(*pud);
+
+ if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval))
+@@ -1308,10 +1303,104 @@ static inline int pud_trans_unstable(pud_t *pud)
+ pud_clear_bad(pud);
+ return 1;
+ }
++ return 0;
++}
++
++/* See pmd_trans_unstable for discussion. */
++static inline int pud_trans_unstable(pud_t *pud)
++{
++#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
++ defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
++ return pud_none_or_trans_huge_or_dev_or_clear_bad(pud);
++#else
++ return 0;
+ #endif
++}
++
++#ifndef arch_needs_pgtable_deposit
++#define arch_needs_pgtable_deposit() (false)
++#endif
++/*
++ * This function is meant to be used by sites walking pagetables with
++ * the mmap_lock held in read mode to protect against MADV_DONTNEED and
++ * transhuge page faults. MADV_DONTNEED can convert a transhuge pmd
++ * into a null pmd and the transhuge page fault can convert a null pmd
++ * into an hugepmd or into a regular pmd (if the hugepage allocation
++ * fails). While holding the mmap_lock in read mode the pmd becomes
++ * stable and stops changing under us only if it's not null and not a
++ * transhuge pmd. When those races occurs and this function makes a
++ * difference vs the standard pmd_none_or_clear_bad, the result is
++ * undefined so behaving like if the pmd was none is safe (because it
++ * can return none anyway). The compiler level barrier() is critically
++ * important to compute the two checks atomically on the same pmdval.
++ *
++ * For 32bit kernels with a 64bit large pmd_t this automatically takes
++ * care of reading the pmd atomically to avoid SMP race conditions
++ * against pmd_populate() when the mmap_lock is hold for reading by the
++ * caller (a special atomic read not done by "gcc" as in the generic
++ * version above, is also needed when THP is disabled because the page
++ * fault can populate the pmd from under us).
++ */
++static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
++{
++ pmd_t pmdval = pmdp_get_lockless(pmd);
++ /*
++ * !pmd_present() checks for pmd migration entries
++ *
++ * The complete check uses is_pmd_migration_entry() in linux/swapops.h
++ * But using that requires moving current function and pmd_trans_unstable()
++ * to linux/swapops.h to resolve dependency, which is too much code move.
++ *
++ * !pmd_present() is equivalent to is_pmd_migration_entry() currently,
++ * because !pmd_present() pages can only be under migration not swapped
++ * out.
++ *
++ * pmd_none() is preserved for future condition checks on pmd migration
++ * entries and not confusing with this function name, although it is
++ * redundant with !pmd_present().
++ */
++ if (pmd_none(pmdval) || pmd_trans_huge(pmdval) ||
++ (IS_ENABLED(CONFIG_ARCH_ENABLE_THP_MIGRATION) && !pmd_present(pmdval)))
++ return 1;
++ if (unlikely(pmd_bad(pmdval))) {
++ pmd_clear_bad(pmd);
++ return 1;
++ }
+ return 0;
+ }
+
++/*
++ * This is a noop if Transparent Hugepage Support is not built into
++ * the kernel. Otherwise it is equivalent to
++ * pmd_none_or_trans_huge_or_clear_bad(), and shall only be called in
++ * places that already verified the pmd is not none and they want to
++ * walk ptes while holding the mmap sem in read mode (write mode don't
++ * need this). If THP is not enabled, the pmd can't go away under the
++ * code even if MADV_DONTNEED runs, but if THP is enabled we need to
++ * run a pmd_trans_unstable before walking the ptes after
++ * split_huge_pmd returns (because it may have run when the pmd become
++ * null, but then a page fault can map in a THP and not a regular page).
++ */
++static inline int pmd_trans_unstable(pmd_t *pmd)
++{
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++ return pmd_none_or_trans_huge_or_clear_bad(pmd);
++#else
++ return 0;
++#endif
++}
++
++/*
++ * the ordering of these checks is important for pmds with _page_devmap set.
++ * if we check pmd_trans_unstable() first we will trip the bad_pmd() check
++ * inside of pmd_none_or_trans_huge_or_clear_bad(). this will end up correctly
++ * returning 1 but not before it spams dmesg with the pmd_clear_bad() output.
++ */
++static inline int pmd_devmap_trans_unstable(pmd_t *pmd)
++{
++ return pmd_devmap(*pmd) || pmd_trans_unstable(pmd);
++}
++
+ #ifndef CONFIG_NUMA_BALANCING
+ /*
+ * Technically a PTE can be PROTNONE even when not doing NUMA balancing but
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 25aa8e29673f..6c601fddd892 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -944,6 +944,10 @@ static int hugepage_vma_revalidate(struct mm_struct *mm, unsigned long address,
+ return SCAN_SUCCEED;
+ }
+
++/*
++ * See pmd_trans_unstable() for how the result may change out from
++ * underneath us, even if we hold mmap_lock in read.
++ */
+ static int find_pmd_or_thp_or_none(struct mm_struct *mm,
+ unsigned long address,
+ pmd_t **pmd)
+--
+2.25.1
+
diff --git a/patchsets/0006-Revert-mm-mremap-retry-if-either-pte_offset_map_-loc.patch b/patchsets/0006-Revert-mm-mremap-retry-if-either-pte_offset_map_-loc.patch
new file mode 100644
index 0000000..27a702b
--- /dev/null
+++ b/patchsets/0006-Revert-mm-mremap-retry-if-either-pte_offset_map_-loc.patch
@@ -0,0 +1,117 @@
+From 6c57d0d0576a8c2778f4659a0b852271cd0e029a Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 16:14:55 +0800
+Subject: [PATCH 6/7] Revert "mm/mremap: retry if either pte_offset_map_*lock()
+ fails"
+
+This reverts commit a5be621ee2925b6ee2db455c45c2af2d8a195b0c.
+---
+ mm/huge_memory.c | 5 ++---
+ mm/mremap.c | 28 ++++++++--------------------
+ 2 files changed, 10 insertions(+), 23 deletions(-)
+
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index a37e86c09c5e..b36e62a4fb75 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -1760,10 +1760,9 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
+
+ /*
+ * The destination pmd shouldn't be established, free_pgtables()
+- * should have released it; but move_page_tables() might have already
+- * inserted a page table, if racing against shmem/file collapse.
++ * should have release it.
+ */
+- if (!pmd_none(*new_pmd)) {
++ if (WARN_ON(!pmd_none(*new_pmd))) {
+ VM_BUG_ON(pmd_trans_huge(*new_pmd));
+ return false;
+ }
+diff --git a/mm/mremap.c b/mm/mremap.c
+index 1be0b7ab2590..75a3db3913e4 100644
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -133,7 +133,7 @@ static pte_t move_soft_dirty_pte(pte_t pte)
+ return pte;
+ }
+
+-static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
++static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+ unsigned long old_addr, unsigned long old_end,
+ struct vm_area_struct *new_vma, pmd_t *new_pmd,
+ unsigned long new_addr, bool need_rmap_locks)
+@@ -143,7 +143,6 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+ spinlock_t *old_ptl, *new_ptl;
+ bool force_flush = false;
+ unsigned long len = old_end - old_addr;
+- int err = 0;
+
+ /*
+ * When need_rmap_locks is true, we take the i_mmap_rwsem and anon_vma
+@@ -171,16 +170,8 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+ * pte locks because exclusive mmap_lock prevents deadlock.
+ */
+ old_pte = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl);
+- if (!old_pte) {
+- err = -EAGAIN;
+- goto out;
+- }
+- new_pte = pte_offset_map_nolock(mm, new_pmd, new_addr, &new_ptl);
+- if (!new_pte) {
+- pte_unmap_unlock(old_pte, old_ptl);
+- err = -EAGAIN;
+- goto out;
+- }
++ new_pte = pte_offset_map(new_pmd, new_addr);
++ new_ptl = pte_lockptr(mm, new_pmd);
+ if (new_ptl != old_ptl)
+ spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+ flush_tlb_batched_pending(vma->vm_mm);
+@@ -217,10 +208,8 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
+ spin_unlock(new_ptl);
+ pte_unmap(new_pte - 1);
+ pte_unmap_unlock(old_pte - 1, old_ptl);
+-out:
+ if (need_rmap_locks)
+ drop_rmap_locks(vma);
+- return err;
+ }
+
+ #ifndef arch_supports_page_table_move
+@@ -548,7 +537,6 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
+ new_pmd = alloc_new_pmd(vma->vm_mm, vma, new_addr);
+ if (!new_pmd)
+ break;
+-again:
+ if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd) ||
+ pmd_devmap(*old_pmd)) {
+ if (extent == HPAGE_PMD_SIZE &&
+@@ -556,6 +544,8 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
+ old_pmd, new_pmd, need_rmap_locks))
+ continue;
+ split_huge_pmd(vma, old_pmd, old_addr);
++ if (pmd_trans_unstable(old_pmd))
++ continue;
+ } else if (IS_ENABLED(CONFIG_HAVE_MOVE_PMD) &&
+ extent == PMD_SIZE) {
+ /*
+@@ -566,13 +556,11 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
+ old_pmd, new_pmd, true))
+ continue;
+ }
+- if (pmd_none(*old_pmd))
+- continue;
++
+ if (pte_alloc(new_vma->vm_mm, new_pmd))
+ break;
+- if (move_ptes(vma, old_pmd, old_addr, old_addr + extent,
+- new_vma, new_pmd, new_addr, need_rmap_locks) < 0)
+- goto again;
++ move_ptes(vma, old_pmd, old_addr, old_addr + extent, new_vma,
++ new_pmd, new_addr, need_rmap_locks);
+ }
+
+ mmu_notifier_invalidate_range_end(&range);
+--
+2.25.1
+
diff --git a/patchsets/0007-Revert-mm-page_vma_mapped-pte_offset_map_nolock-not-.patch b/patchsets/0007-Revert-mm-page_vma_mapped-pte_offset_map_nolock-not-.patch
new file mode 100644
index 0000000..cfd6821
--- /dev/null
+++ b/patchsets/0007-Revert-mm-page_vma_mapped-pte_offset_map_nolock-not-.patch
@@ -0,0 +1,89 @@
+From 95a3215e077990da16d780d60d1987bd2269e3f4 Mon Sep 17 00:00:00 2001
+From: Yongqin Liu <yongqin.liu@linaro.org>
+Date: Fri, 28 Jul 2023 16:24:29 +0800
+Subject: [PATCH 7/7] Revert "mm/page_vma_mapped: pte_offset_map_nolock() not
+ pte_lockptr()"
+
+This reverts commit 2798bbe75b9c2752b46d292e5c2a49f49da36418.
+---
+ mm/page_vma_mapped.c | 28 ++++++----------------------
+ 1 file changed, 6 insertions(+), 22 deletions(-)
+
+diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
+index 2af734274073..947dc7491815 100644
+--- a/mm/page_vma_mapped.c
++++ b/mm/page_vma_mapped.c
+@@ -13,28 +13,16 @@ static inline bool not_found(struct page_vma_mapped_walk *pvmw)
+ return false;
+ }
+
+-static bool map_pte(struct page_vma_mapped_walk *pvmw, spinlock_t **ptlp)
++static bool map_pte(struct page_vma_mapped_walk *pvmw)
+ {
+ if (pvmw->flags & PVMW_SYNC) {
+ /* Use the stricter lookup */
+ pvmw->pte = pte_offset_map_lock(pvmw->vma->vm_mm, pvmw->pmd,
+ pvmw->address, &pvmw->ptl);
+- *ptlp = pvmw->ptl;
+- return !!pvmw->pte;
++ return true;
+ }
+
+- /*
+- * It is important to return the ptl corresponding to pte,
+- * in case *pvmw->pmd changes underneath us; so we need to
+- * return it even when choosing not to lock, in case caller
+- * proceeds to loop over next ptes, and finds a match later.
+- * Though, in most cases, page lock already protects this.
+- */
+- pvmw->pte = pte_offset_map_nolock(pvmw->vma->vm_mm, pvmw->pmd,
+- pvmw->address, ptlp);
+- if (!pvmw->pte)
+- return false;
+-
++ pvmw->pte = pte_offset_map(pvmw->pmd, pvmw->address);
+ if (pvmw->flags & PVMW_MIGRATION) {
+ if (!is_swap_pte(*pvmw->pte))
+ return false;
+@@ -63,7 +51,7 @@ static bool map_pte(struct page_vma_mapped_walk *pvmw, spinlock_t **ptlp)
+ } else if (!pte_present(*pvmw->pte)) {
+ return false;
+ }
+- pvmw->ptl = *ptlp;
++ pvmw->ptl = pte_lockptr(pvmw->vma->vm_mm, pvmw->pmd);
+ spin_lock(pvmw->ptl);
+ return true;
+ }
+@@ -168,7 +156,6 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
+ struct vm_area_struct *vma = pvmw->vma;
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long end;
+- spinlock_t *ptl;
+ pgd_t *pgd;
+ p4d_t *p4d;
+ pud_t *pud;
+@@ -270,11 +257,8 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
+ step_forward(pvmw, PMD_SIZE);
+ continue;
+ }
+- if (!map_pte(pvmw, &ptl)) {
+- if (!pvmw->pte)
+- goto restart;
++ if (!map_pte(pvmw))
+ goto next_pte;
+- }
+ this_pte:
+ if (check_pte(pvmw))
+ return true;
+@@ -297,7 +281,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
+ } while (pte_none(*pvmw->pte));
+
+ if (!pvmw->ptl) {
+- pvmw->ptl = ptl;
++ pvmw->ptl = pte_lockptr(mm, pvmw->pmd);
+ spin_lock(pvmw->ptl);
+ }
+ goto this_pte;
+--
+2.25.1
+
diff --git a/patchsets/apply.sh b/patchsets/apply.sh
index 954ed42..45becfd 100755
--- a/patchsets/apply.sh
+++ b/patchsets/apply.sh
@@ -45,3 +45,16 @@ fi
## drm/omapdrm: Implement fbdev emulation as in-kernel client
## https://patchwork.freedesktop.org/patch/530540/
git am "${dir_parent}/0001-Revert-drm-omapdrm-Implement-fbdev-emulation-as-in-k.patch"
+
+## ERROR: modpost: "__pte_offset_map_lock" [../omap-modules/android-mainline/pvr/pvrsrvkm.ko] undefined!
+## https://lore.kernel.org/all/2929bfd-9893-a374-e463-4c3127ff9b9d@google.com/T/#m8e8ebe5939450e276bb4a5ad6e41c2cad01a8ccc
+git am "${dir_parent}/0001-Revert-mm-pgtable-allow-pte_offset_map-_lock-to-fail.patch"
+git am "${dir_parent}/0002-Revert-mm-ptep_get-conversion.patch"
+git am "${dir_parent}/0003-Revert-mm-memory-handle_pte_fault-use-pte_offset_map.patch"
+git am "${dir_parent}/0004-Revert-mm-memory-allow-pte_offset_map-_lock-to-fail.patch"
+git am "${dir_parent}/0005-Revert-mm-pgtable-delete-pmd_trans_unstable-and-frie.patch"
+git am "${dir_parent}/0006-Revert-mm-mremap-retry-if-either-pte_offset_map_-loc.patch"
+git am "${dir_parent}/0007-Revert-mm-page_vma_mapped-pte_offset_map_nolock-not-.patch"
+
+
+