mm: ptep_clear() page table helper
authorPasha Tatashin <pasha.tatashin@soleen.com>
Fri, 14 Jan 2022 22:06:33 +0000 (14:06 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 15 Jan 2022 14:30:28 +0000 (16:30 +0200)
We have ptep_get_and_clear() and ptep_get_and_clear_full() helpers to
clear PTE from user page tables, but there is no variant for simple
clear of a present PTE from user page tables without using a low level
pte_clear() which can be either native or para-virtualised.

Add a new ptep_clear() that can be used in common code to clear PTEs
from page table.  We will need this call later in order to add a hook
for page table check.

Link: https://lkml.kernel.org/r/20211221154650.1047963-3-pasha.tatashin@soleen.com
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Greg Thelen <gthelen@google.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Slaby <jirislaby@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <keescook@chromium.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Muchun Song <songmuchun@bytedance.com>
Cc: Paul Turner <pjt@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sami Tolvanen <samitolvanen@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Wei Xu <weixugc@google.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/vm/arch_pgtable_helpers.rst
include/linux/pgtable.h
mm/debug_vm_pgtable.c
mm/khugepaged.c

index b3166c33db393229b8caed0a241c6ffcdd257946..f8b225fc919047a998e920fa52fca434b8b10878 100644 (file)
@@ -66,9 +66,11 @@ PTE Page Table Helpers
 +---------------------------+--------------------------------------------------+
 | pte_mknotpresent          | Invalidates a mapped PTE                         |
 +---------------------------+--------------------------------------------------+
-| ptep_get_and_clear        | Clears a PTE                                     |
+| ptep_clear                | Clears a PTE                                     |
 +---------------------------+--------------------------------------------------+
-| ptep_get_and_clear_full   | Clears a PTE                                     |
+| ptep_get_and_clear        | Clears and returns PTE                           |
++---------------------------+--------------------------------------------------+
+| ptep_get_and_clear_full   | Clears and returns PTE (batched PTE unmap)       |
 +---------------------------+--------------------------------------------------+
 | ptep_test_and_clear_young | Clears young from a PTE                          |
 +---------------------------+--------------------------------------------------+
index e24d2c992b1129f3f2b01a8a8ddc5071abe1551c..bc8713a76e0343ac3760eb76ce9dc5bbdd5b36d6 100644 (file)
@@ -258,6 +258,14 @@ static inline int pmdp_clear_flush_young(struct vm_area_struct *vma,
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
+#ifndef __HAVE_ARCH_PTEP_CLEAR
+static inline void ptep_clear(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep)
+{
+       pte_clear(mm, addr, ptep);
+}
+#endif
+
 #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
                                       unsigned long address,
index 2a2b24e87877d10de68f15017ce0c56da319fe28..a7ac97c76762c449f60f6009c3926bc29f93f41e 100644 (file)
@@ -652,7 +652,7 @@ static void __init pte_clear_tests(struct pgtable_debug_args *args)
        set_pte_at(args->mm, args->vaddr, args->ptep, pte);
        flush_dcache_page(page);
        barrier();
-       pte_clear(args->mm, args->vaddr, args->ptep);
+       ptep_clear(args->mm, args->vaddr, args->ptep);
        pte = ptep_get(args->ptep);
        WARN_ON(!pte_none(pte));
 }
index e99101162f1abf62be1249d01867e7b31c9e2bc8..9d40dd8890e581dde2cb17ac2d7f7b1c1280be8f 100644 (file)
@@ -756,11 +756,7 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page,
                                 * ptl mostly unnecessary.
                                 */
                                spin_lock(ptl);
-                               /*
-                                * paravirt calls inside pte_clear here are
-                                * superfluous.
-                                */
-                               pte_clear(vma->vm_mm, address, _pte);
+                               ptep_clear(vma->vm_mm, address, _pte);
                                spin_unlock(ptl);
                        }
                } else {
@@ -774,11 +770,7 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page,
                         * inside page_remove_rmap().
                         */
                        spin_lock(ptl);
-                       /*
-                        * paravirt calls inside pte_clear here are
-                        * superfluous.
-                        */
-                       pte_clear(vma->vm_mm, address, _pte);
+                       ptep_clear(vma->vm_mm, address, _pte);
                        page_remove_rmap(src_page, false);
                        spin_unlock(ptl);
                        free_page_and_swap_cache(src_page);