]> Git Repo - linux.git/commitdiff
mm/hugetlb: add prot_modify_start/commit sequence for hugetlb update
authorAneesh Kumar K.V <[email protected]>
Tue, 5 Mar 2019 23:46:37 +0000 (15:46 -0800)
committerLinus Torvalds <[email protected]>
Wed, 6 Mar 2019 05:07:18 +0000 (21:07 -0800)
Architectures like ppc64 require to do a conditional tlb flush based on
the old and new value of pte.  Follow the regular pte change protection
sequence for hugetlb too.  This allows the architectures to override the
update sequence.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Aneesh Kumar K.V <[email protected]>
Reviewed-by: Michael Ellerman <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Nicholas Piggin <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
include/linux/hugetlb.h
mm/hugetlb.c

index 4cc3871b65fca7264870bbefa463893756483153..54c317c8355fc5ee329baaed4216da808adf3c34 100644 (file)
@@ -580,6 +580,26 @@ static inline void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr
        set_huge_pte_at(mm, addr, ptep, pte);
 }
 #endif
+
+#ifndef huge_ptep_modify_prot_start
+#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
+static inline pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
+                                               unsigned long addr, pte_t *ptep)
+{
+       return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
+}
+#endif
+
+#ifndef huge_ptep_modify_prot_commit
+#define huge_ptep_modify_prot_commit huge_ptep_modify_prot_commit
+static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
+                                               unsigned long addr, pte_t *ptep,
+                                               pte_t old_pte, pte_t pte)
+{
+       set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+}
+#endif
+
 #else  /* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page(v, a, r) NULL
index 2fb3062a3595715e6559349d41254f7a6931abe2..0c7848fccf9393f4e7202df0e4ba1e2da2ccde6f 100644 (file)
@@ -4399,10 +4399,12 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
                        continue;
                }
                if (!huge_pte_none(pte)) {
-                       pte = huge_ptep_get_and_clear(mm, address, ptep);
-                       pte = pte_mkhuge(huge_pte_modify(pte, newprot));
+                       pte_t old_pte;
+
+                       old_pte = huge_ptep_modify_prot_start(vma, address, ptep);
+                       pte = pte_mkhuge(huge_pte_modify(old_pte, newprot));
                        pte = arch_make_huge_pte(pte, vma, NULL, 0);
-                       set_huge_pte_at(mm, address, ptep, pte);
+                       huge_ptep_modify_prot_commit(vma, address, ptep, old_pte, pte);
                        pages++;
                }
                spin_unlock(ptl);
This page took 0.0641 seconds and 4 git commands to generate.