Le 27/02/2023 à 23:29, Rick Edgecombe a écrit : > The x86 Control-flow Enforcement Technology (CET) feature includes a new > type of memory called shadow stack. This shadow stack memory has some > unusual properties, which requires some core mm changes to function > properly. > > One of these unusual properties is that shadow stack memory is writable, > but only in limited ways. These limits are applied via a specific PTE > bit combination. Nevertheless, the memory is writable, and core mm code > will need to apply the writable permissions in the typical paths that > call pte_mkwrite(). > > In addition to VM_WRITE, the shadow stack VMA's will have a flag denoting > that they are special shadow stack flavor of writable memory. So make > pte_mkwrite() take a VMA, so that the x86 implementation of it can know to > create regular writable memory or shadow stack memory. > > Apply the same changes for pmd_mkwrite() and huge_pte_mkwrite(). I'm not sure it is a good idea to add a second argument to pte_mkwrite(). All pte_mkxxxx() only take a pte and nothing else. I think you should do the same as commit d9ed9faac283 ("mm: add new arch_make_huge_pte() method for tile support") Christophe > > No functional change. > > Cc: linux-doc@xxxxxxxxxxxxxxx > Cc: linux-kernel@xxxxxxxxxxxxxxx > Cc: linux-alpha@xxxxxxxxxxxxxxx > Cc: linux-snps-arc@xxxxxxxxxxxxxxxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > Cc: linux-csky@xxxxxxxxxxxxxxx > Cc: linux-hexagon@xxxxxxxxxxxxxxx > Cc: linux-ia64@xxxxxxxxxxxxxxx > Cc: loongarch@xxxxxxxxxxxxxxx > Cc: linux-m68k@xxxxxxxxxxxxxxxxxxxx > Cc: Michal Simek <monstr@xxxxxxxxx> > Cc: Dinh Nguyen <dinguyen@xxxxxxxxxx> > Cc: linux-mips@xxxxxxxxxxxxxxx > Cc: linux-openrisc@xxxxxxxxxxxxxxx > Cc: linux-parisc@xxxxxxxxxxxxxxx > Cc: linuxppc-dev@xxxxxxxxxxxxxxxx > Cc: linux-riscv@xxxxxxxxxxxxxxxxxxx > Cc: linux-s390@xxxxxxxxxxxxxxx > Cc: linux-sh@xxxxxxxxxxxxxxx > Cc: sparclinux@xxxxxxxxxxxxxxx > Cc: linux-um@xxxxxxxxxxxxxxxxxxx > Cc: xen-devel@xxxxxxxxxxxxxxxxxxxx > Cc: linux-arch@xxxxxxxxxxxxxxx > Cc: linux-mm@xxxxxxxxx > Tested-by: Pengfei Xu <pengfei.xu@xxxxxxxxx> > Tested-by: John Allen <john.allen@xxxxxxx> > Tested-by: Kees Cook <keescook@xxxxxxxxxxxx> > Acked-by: Mike Rapoport (IBM) <rppt@xxxxxxxxxx> > Acked-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx> > Acked-by: David Hildenbrand <david@xxxxxxxxxx> > Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> > Suggested-by: David Hildenbrand <david@xxxxxxxxxx> > Signed-off-by: Rick Edgecombe <rick.p.edgecombe@xxxxxxxxx> > > --- > Hi Non-x86 Arch’s, > > x86 has a feature that allows for the creation of a special type of > writable memory (shadow stack) that is only writable in limited specific > ways. Previously, changes were proposed to core MM code to teach it to > decide when to create normally writable memory or the special shadow stack > writable memory, but David Hildenbrand suggested[0] to change > pXX_mkwrite() to take a VMA, so awareness of shadow stack memory can be > moved into x86 code. > > Since pXX_mkwrite() is defined in every arch, it requires some tree-wide > changes. So that is why you are seeing some patches out of a big x86 > series pop up in your arch mailing list. There is no functional change. > After this refactor, the shadow stack series goes on to use the arch > helpers to push shadow stack memory details inside arch/x86. > > Testing was just 0-day build testing. > > Hopefully that is enough context. Thanks! > > [0] https://lore.kernel.org/lkml/0e29a2d0-08d8-bcd6-ff26-4bea0e4037b0@xxxxxxxxxx/#t > > v6: > - New patch > --- > Documentation/mm/arch_pgtable_helpers.rst | 9 ++++++--- > arch/alpha/include/asm/pgtable.h | 6 +++++- > arch/arc/include/asm/hugepage.h | 2 +- > arch/arc/include/asm/pgtable-bits-arcv2.h | 7 ++++++- > arch/arm/include/asm/pgtable-3level.h | 7 ++++++- > arch/arm/include/asm/pgtable.h | 2 +- > arch/arm64/include/asm/pgtable.h | 4 ++-- > arch/csky/include/asm/pgtable.h | 2 +- > arch/hexagon/include/asm/pgtable.h | 2 +- > arch/ia64/include/asm/pgtable.h | 2 +- > arch/loongarch/include/asm/pgtable.h | 4 ++-- > arch/m68k/include/asm/mcf_pgtable.h | 2 +- > arch/m68k/include/asm/motorola_pgtable.h | 6 +++++- > arch/m68k/include/asm/sun3_pgtable.h | 6 +++++- > arch/microblaze/include/asm/pgtable.h | 2 +- > arch/mips/include/asm/pgtable.h | 6 +++--- > arch/nios2/include/asm/pgtable.h | 2 +- > arch/openrisc/include/asm/pgtable.h | 2 +- > arch/parisc/include/asm/pgtable.h | 6 +++++- > arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- > arch/powerpc/include/asm/book3s/64/pgtable.h | 4 ++-- > arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +- > arch/powerpc/include/asm/nohash/32/pte-8xx.h | 2 +- > arch/powerpc/include/asm/nohash/64/pgtable.h | 2 +- > arch/riscv/include/asm/pgtable.h | 6 +++--- > arch/s390/include/asm/hugetlb.h | 4 ++-- > arch/s390/include/asm/pgtable.h | 4 ++-- > arch/sh/include/asm/pgtable_32.h | 10 ++++++++-- > arch/sparc/include/asm/pgtable_32.h | 2 +- > arch/sparc/include/asm/pgtable_64.h | 6 +++--- > arch/um/include/asm/pgtable.h | 2 +- > arch/x86/include/asm/pgtable.h | 6 ++++-- > arch/xtensa/include/asm/pgtable.h | 2 +- > include/asm-generic/hugetlb.h | 4 ++-- > include/linux/mm.h | 2 +- > mm/debug_vm_pgtable.c | 16 ++++++++-------- > mm/huge_memory.c | 6 +++--- > mm/hugetlb.c | 4 ++-- > mm/memory.c | 4 ++-- > mm/migrate_device.c | 2 +- > mm/mprotect.c | 2 +- > mm/userfaultfd.c | 2 +- > 42 files changed, 106 insertions(+), 69 deletions(-) > > diff --git a/Documentation/mm/arch_pgtable_helpers.rst b/Documentation/mm/arch_pgtable_helpers.rst > index 30d9a09f01f4..78ac3ff2fe1d 100644 > --- a/Documentation/mm/arch_pgtable_helpers.rst > +++ b/Documentation/mm/arch_pgtable_helpers.rst > @@ -46,7 +46,8 @@ PTE Page Table Helpers > +---------------------------+--------------------------------------------------+ > | pte_mkclean | Creates a clean PTE | > +---------------------------+--------------------------------------------------+ > -| pte_mkwrite | Creates a writable PTE | > +| pte_mkwrite | Creates a writable PTE of the type specified by | > +| | the VMA. | > +---------------------------+--------------------------------------------------+ > | pte_wrprotect | Creates a write protected PTE | > +---------------------------+--------------------------------------------------+ > @@ -118,7 +119,8 @@ PMD Page Table Helpers > +---------------------------+--------------------------------------------------+ > | pmd_mkclean | Creates a clean PMD | > +---------------------------+--------------------------------------------------+ > -| pmd_mkwrite | Creates a writable PMD | > +| pmd_mkwrite | Creates a writable PMD of the type specified by | > +| | the VMA. | > +---------------------------+--------------------------------------------------+ > | pmd_wrprotect | Creates a write protected PMD | > +---------------------------+--------------------------------------------------+ > @@ -222,7 +224,8 @@ HugeTLB Page Table Helpers > +---------------------------+--------------------------------------------------+ > | huge_pte_mkdirty | Creates a dirty HugeTLB | > +---------------------------+--------------------------------------------------+ > -| huge_pte_mkwrite | Creates a writable HugeTLB | > +| huge_pte_mkwrite | Creates a writable HugeTLB of the type specified | > +| | by the VMA. | > +---------------------------+--------------------------------------------------+ > | huge_pte_wrprotect | Creates a write protected HugeTLB | > +---------------------------+--------------------------------------------------+ > diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h > index ba43cb841d19..fb5d207c2a89 100644 > --- a/arch/alpha/include/asm/pgtable.h > +++ b/arch/alpha/include/asm/pgtable.h > @@ -256,9 +256,13 @@ extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; > extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_FOW; return pte; } > extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(__DIRTY_BITS); return pte; } > extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(__ACCESS_BITS); return pte; } > -extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_FOW; return pte; } > extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; return pte; } > extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } > +extern inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > +{ > + pte_val(pte) &= ~_PAGE_FOW; > + return pte; > +} > > /* > * The smp_rmb() in the following functions are required to order the load of > diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h > index 5001b796fb8d..223a96967188 100644 > --- a/arch/arc/include/asm/hugepage.h > +++ b/arch/arc/include/asm/hugepage.h > @@ -21,7 +21,7 @@ static inline pmd_t pte_pmd(pte_t pte) > } > > #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) > -#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) > +#define pmd_mkwrite(pmd, vma) pte_pmd(pte_mkwrite(pmd_pte(pmd), (vma))) > #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) > #define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) > #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) > diff --git a/arch/arc/include/asm/pgtable-bits-arcv2.h b/arch/arc/include/asm/pgtable-bits-arcv2.h > index 6e9f8ca6d6a1..a5b8bc955015 100644 > --- a/arch/arc/include/asm/pgtable-bits-arcv2.h > +++ b/arch/arc/include/asm/pgtable-bits-arcv2.h > @@ -87,7 +87,6 @@ > > PTE_BIT_FUNC(mknotpresent, &= ~(_PAGE_PRESENT)); > PTE_BIT_FUNC(wrprotect, &= ~(_PAGE_WRITE)); > -PTE_BIT_FUNC(mkwrite, |= (_PAGE_WRITE)); > PTE_BIT_FUNC(mkclean, &= ~(_PAGE_DIRTY)); > PTE_BIT_FUNC(mkdirty, |= (_PAGE_DIRTY)); > PTE_BIT_FUNC(mkold, &= ~(_PAGE_ACCESSED)); > @@ -95,6 +94,12 @@ PTE_BIT_FUNC(mkyoung, |= (_PAGE_ACCESSED)); > PTE_BIT_FUNC(mkspecial, |= (_PAGE_SPECIAL)); > PTE_BIT_FUNC(mkhuge, |= (_PAGE_HW_SZ)); > > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > +{ > + pte_val(pte) |= (_PAGE_WRITE); > + return pte; > +} > + > static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) > { > return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); > diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h > index 106049791500..df071a807610 100644 > --- a/arch/arm/include/asm/pgtable-3level.h > +++ b/arch/arm/include/asm/pgtable-3level.h > @@ -202,11 +202,16 @@ static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; } > > PMD_BIT_FUNC(wrprotect, |= L_PMD_SECT_RDONLY); > PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF); > -PMD_BIT_FUNC(mkwrite, &= ~L_PMD_SECT_RDONLY); > PMD_BIT_FUNC(mkdirty, |= L_PMD_SECT_DIRTY); > PMD_BIT_FUNC(mkclean, &= ~L_PMD_SECT_DIRTY); > PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF); > > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > +{ > + pmd_val(pmd) |= L_PMD_SECT_RDONLY; > + return pmd; > +} > + > #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT)) > > #define pmd_pfn(pmd) (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT) > diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h > index a58ccbb406ad..39ad1ae1308d 100644 > --- a/arch/arm/include/asm/pgtable.h > +++ b/arch/arm/include/asm/pgtable.h > @@ -227,7 +227,7 @@ static inline pte_t pte_wrprotect(pte_t pte) > return set_pte_bit(pte, __pgprot(L_PTE_RDONLY)); > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return clear_pte_bit(pte, __pgprot(L_PTE_RDONLY)); > } > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h > index cccf8885792e..913bf370f74a 100644 > --- a/arch/arm64/include/asm/pgtable.h > +++ b/arch/arm64/include/asm/pgtable.h > @@ -187,7 +187,7 @@ static inline pte_t pte_mkwrite_kernel(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return pte_mkwrite_kernel(pte); > } > @@ -492,7 +492,7 @@ static inline int pmd_trans_huge(pmd_t pmd) > #define pmd_cont(pmd) pte_cont(pmd_pte(pmd)) > #define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd))) > #define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd))) > -#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) > +#define pmd_mkwrite(pmd, vma) pte_pmd(pte_mkwrite(pmd_pte(pmd), (vma))) > #define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd))) > #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) > #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) > diff --git a/arch/csky/include/asm/pgtable.h b/arch/csky/include/asm/pgtable.h > index d4042495febc..c2f92c991e37 100644 > --- a/arch/csky/include/asm/pgtable.h > +++ b/arch/csky/include/asm/pgtable.h > @@ -176,7 +176,7 @@ static inline pte_t pte_mkold(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= _PAGE_WRITE; > if (pte_val(pte) & _PAGE_MODIFIED) > diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h > index 59393613d086..14ab9c789c0e 100644 > --- a/arch/hexagon/include/asm/pgtable.h > +++ b/arch/hexagon/include/asm/pgtable.h > @@ -300,7 +300,7 @@ static inline pte_t pte_wrprotect(pte_t pte) > } > > /* pte_mkwrite - mark page as writable */ > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= _PAGE_WRITE; > return pte; > diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h > index 21c97e31a28a..f879dd626da6 100644 > --- a/arch/ia64/include/asm/pgtable.h > +++ b/arch/ia64/include/asm/pgtable.h > @@ -268,7 +268,7 @@ ia64_phys_addr_valid (unsigned long addr) > * access rights: > */ > #define pte_wrprotect(pte) (__pte(pte_val(pte) & ~_PAGE_AR_RW)) > -#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_AR_RW)) > +#define pte_mkwrite(pte, vma) (__pte(pte_val(pte) | _PAGE_AR_RW)) > #define pte_mkold(pte) (__pte(pte_val(pte) & ~_PAGE_A)) > #define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_A)) > #define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D)) > diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h > index d28fb9dbec59..ebf645f40298 100644 > --- a/arch/loongarch/include/asm/pgtable.h > +++ b/arch/loongarch/include/asm/pgtable.h > @@ -390,7 +390,7 @@ static inline pte_t pte_mkdirty(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= _PAGE_WRITE; > if (pte_val(pte) & _PAGE_MODIFIED) > @@ -490,7 +490,7 @@ static inline int pmd_write(pmd_t pmd) > return !!(pmd_val(pmd) & _PAGE_WRITE); > } > > -static inline pmd_t pmd_mkwrite(pmd_t pmd) > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > pmd_val(pmd) |= _PAGE_WRITE; > if (pmd_val(pmd) & _PAGE_MODIFIED) > diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h > index 13741c1245e1..37d77e055016 100644 > --- a/arch/m68k/include/asm/mcf_pgtable.h > +++ b/arch/m68k/include/asm/mcf_pgtable.h > @@ -211,7 +211,7 @@ static inline pte_t pte_mkold(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= CF_PAGE_WRITABLE; > return pte; > diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h > index ec0dc19ab834..c4e8eb76286d 100644 > --- a/arch/m68k/include/asm/motorola_pgtable.h > +++ b/arch/m68k/include/asm/motorola_pgtable.h > @@ -155,7 +155,6 @@ static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; > static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; } > static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } > static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } > -static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) &= ~_PAGE_RONLY; return pte; } > static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } > static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } > static inline pte_t pte_mknocache(pte_t pte) > @@ -168,6 +167,11 @@ static inline pte_t pte_mkcache(pte_t pte) > pte_val(pte) = (pte_val(pte) & _CACHEMASK040) | m68k_supervisor_cachemode; > return pte; > } > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > +{ > + pte_val(pte) &= ~_PAGE_RONLY; > + return pte; > +} > > #define swapper_pg_dir kernel_pg_dir > extern pgd_t kernel_pg_dir[128]; > diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h > index e582b0484a55..2a06bea51a1e 100644 > --- a/arch/m68k/include/asm/sun3_pgtable.h > +++ b/arch/m68k/include/asm/sun3_pgtable.h > @@ -143,10 +143,14 @@ static inline int pte_young(pte_t pte) { return pte_val(pte) & SUN3_PAGE_ACCESS > static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_WRITEABLE; return pte; } > static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_MODIFIED; return pte; } > static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~SUN3_PAGE_ACCESSED; return pte; } > -static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= SUN3_PAGE_WRITEABLE; return pte; } > static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= SUN3_PAGE_MODIFIED; return pte; } > static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= SUN3_PAGE_ACCESSED; return pte; } > static inline pte_t pte_mknocache(pte_t pte) { pte_val(pte) |= SUN3_PAGE_NOCACHE; return pte; } > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > +{ > + pte_val(pte) |= SUN3_PAGE_WRITEABLE; > + return pte; > +} > // use this version when caches work... > //static inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) &= SUN3_PAGE_NOCACHE; return pte; } > // until then, use: > diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h > index d1b8272abcd9..5b83e82f8d7e 100644 > --- a/arch/microblaze/include/asm/pgtable.h > +++ b/arch/microblaze/include/asm/pgtable.h > @@ -266,7 +266,7 @@ static inline pte_t pte_mkread(pte_t pte) \ > { pte_val(pte) |= _PAGE_USER; return pte; } > static inline pte_t pte_mkexec(pte_t pte) \ > { pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; } > -static inline pte_t pte_mkwrite(pte_t pte) \ > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) \ > { pte_val(pte) |= _PAGE_RW; return pte; } > static inline pte_t pte_mkdirty(pte_t pte) \ > { pte_val(pte) |= _PAGE_DIRTY; return pte; } > diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h > index 791389bf3c12..06efd567144a 100644 > --- a/arch/mips/include/asm/pgtable.h > +++ b/arch/mips/include/asm/pgtable.h > @@ -309,7 +309,7 @@ static inline pte_t pte_mkold(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte.pte_low |= _PAGE_WRITE; > if (pte.pte_low & _PAGE_MODIFIED) { > @@ -364,7 +364,7 @@ static inline pte_t pte_mkold(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= _PAGE_WRITE; > if (pte_val(pte) & _PAGE_MODIFIED) > @@ -626,7 +626,7 @@ static inline pmd_t pmd_wrprotect(pmd_t pmd) > return pmd; > } > > -static inline pmd_t pmd_mkwrite(pmd_t pmd) > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > pmd_val(pmd) |= _PAGE_WRITE; > if (pmd_val(pmd) & _PAGE_MODIFIED) > diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h > index 0f5c2564e9f5..edd458518e0e 100644 > --- a/arch/nios2/include/asm/pgtable.h > +++ b/arch/nios2/include/asm/pgtable.h > @@ -129,7 +129,7 @@ static inline pte_t pte_mkold(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= _PAGE_WRITE; > return pte; > diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h > index 3eb9b9555d0d..fd40aec189d1 100644 > --- a/arch/openrisc/include/asm/pgtable.h > +++ b/arch/openrisc/include/asm/pgtable.h > @@ -250,7 +250,7 @@ static inline pte_t pte_mkold(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > pte_val(pte) |= _PAGE_WRITE; > return pte; > diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h > index e2950f5db7c9..89f62137e67f 100644 > --- a/arch/parisc/include/asm/pgtable.h > +++ b/arch/parisc/include/asm/pgtable.h > @@ -331,8 +331,12 @@ static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; retu > static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; return pte; } > static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } > static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } > -static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; } > static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; return pte; } > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > +{ > + pte_val(pte) |= _PAGE_WRITE; > + return pte; > +} > > /* > * Huge pte definitions. > diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h > index 7bf1fe7297c6..10d9a1d2aca9 100644 > --- a/arch/powerpc/include/asm/book3s/32/pgtable.h > +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h > @@ -498,7 +498,7 @@ static inline pte_t pte_mkpte(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return __pte(pte_val(pte) | _PAGE_RW); > } > diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h > index 4acc9690f599..be0636522d36 100644 > --- a/arch/powerpc/include/asm/book3s/64/pgtable.h > +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h > @@ -600,7 +600,7 @@ static inline pte_t pte_mkexec(pte_t pte) > return __pte_raw(pte_raw(pte) | cpu_to_be64(_PAGE_EXEC)); > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > /* > * write implies read, hence set both > @@ -1071,7 +1071,7 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd) > #define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd))) > #define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd))) > #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) > -#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd))) > +#define pmd_mkwrite(pmd, vma) pte_pmd(pte_mkwrite(pmd_pte(pmd), (vma))) > > #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY > #define pmd_soft_dirty(pmd) pte_soft_dirty(pmd_pte(pmd)) > diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h > index fec56d965f00..7bfbcb9ba55b 100644 > --- a/arch/powerpc/include/asm/nohash/32/pgtable.h > +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h > @@ -171,7 +171,7 @@ void unmap_kernel_page(unsigned long va); > do { pte_update(mm, addr, ptep, ~0, 0, 0); } while (0) > > #ifndef pte_mkwrite > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return __pte(pte_val(pte) | _PAGE_RW); > } > diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h > index 1a89ebdc3acc..f32450eb270a 100644 > --- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h > +++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h > @@ -101,7 +101,7 @@ static inline int pte_write(pte_t pte) > > #define pte_write pte_write > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return __pte(pte_val(pte) & ~_PAGE_RO); > } > diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h > index 287e25864ffa..589009555877 100644 > --- a/arch/powerpc/include/asm/nohash/64/pgtable.h > +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h > @@ -85,7 +85,7 @@ > #ifndef __ASSEMBLY__ > /* pte_clear moved to later in this file */ > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return __pte(pte_val(pte) | _PAGE_RW); > } > diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h > index d8d8de0ded99..fed1b81fbe07 100644 > --- a/arch/riscv/include/asm/pgtable.h > +++ b/arch/riscv/include/asm/pgtable.h > @@ -338,7 +338,7 @@ static inline pte_t pte_wrprotect(pte_t pte) > > /* static inline pte_t pte_mkread(pte_t pte) */ > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return __pte(pte_val(pte) | _PAGE_WRITE); > } > @@ -624,9 +624,9 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) > return pte_pmd(pte_mkyoung(pmd_pte(pmd))); > } > > -static inline pmd_t pmd_mkwrite(pmd_t pmd) > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > - return pte_pmd(pte_mkwrite(pmd_pte(pmd))); > + return pte_pmd(pte_mkwrite(pmd_pte(pmd), vma)); > } > > static inline pmd_t pmd_wrprotect(pmd_t pmd) > diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h > index ccdbccfde148..558f7eef9c4d 100644 > --- a/arch/s390/include/asm/hugetlb.h > +++ b/arch/s390/include/asm/hugetlb.h > @@ -102,9 +102,9 @@ static inline int huge_pte_dirty(pte_t pte) > return pte_dirty(pte); > } > > -static inline pte_t huge_pte_mkwrite(pte_t pte) > +static inline pte_t huge_pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > - return pte_mkwrite(pte); > + return pte_mkwrite(pte, vma); > } > > static inline pte_t huge_pte_mkdirty(pte_t pte) > diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h > index deeb918cae1d..8f2c743da0eb 100644 > --- a/arch/s390/include/asm/pgtable.h > +++ b/arch/s390/include/asm/pgtable.h > @@ -1013,7 +1013,7 @@ static inline pte_t pte_mkwrite_kernel(pte_t pte) > return pte; > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return pte_mkwrite_kernel(pte); > } > @@ -1499,7 +1499,7 @@ static inline pmd_t pmd_mkwrite_kernel(pmd_t pmd) > return pmd; > } > > -static inline pmd_t pmd_mkwrite(pmd_t pmd) > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > return pmd_mkwrite_kernel(pmd); > } > diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h > index 21952b094650..9f2dcb9eafc8 100644 > --- a/arch/sh/include/asm/pgtable_32.h > +++ b/arch/sh/include/asm/pgtable_32.h > @@ -351,6 +351,12 @@ static inline void set_pte(pte_t *ptep, pte_t pte) > > #define PTE_BIT_FUNC(h,fn,op) \ > static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; } > +#define PTE_BIT_FUNC_VMA(h,fn,op) \ > +static inline pte_t pte_##fn(pte_t pte, struct vm_area_struct *vma) \ > +{ \ > + pte.pte_##h op; \ > + return pte; \ > +} > > #ifdef CONFIG_X2TLB > /* > @@ -359,11 +365,11 @@ static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; } > * kernel permissions), we attempt to couple them a bit more sanely here. > */ > PTE_BIT_FUNC(high, wrprotect, &= ~(_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE)); > -PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE); > +PTE_BIT_FUNC_VMA(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE); > PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE); > #else > PTE_BIT_FUNC(low, wrprotect, &= ~_PAGE_RW); > -PTE_BIT_FUNC(low, mkwrite, |= _PAGE_RW); > +PTE_BIT_FUNC_VMA(low, mkwrite, |= _PAGE_RW); > PTE_BIT_FUNC(low, mkhuge, |= _PAGE_SZHUGE); > #endif > > diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h > index d4330e3c57a6..3e8836179456 100644 > --- a/arch/sparc/include/asm/pgtable_32.h > +++ b/arch/sparc/include/asm/pgtable_32.h > @@ -241,7 +241,7 @@ static inline pte_t pte_mkold(pte_t pte) > return __pte(pte_val(pte) & ~SRMMU_REF); > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return __pte(pte_val(pte) | SRMMU_WRITE); > } > diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h > index 2dc8d4641734..c5cd5c03f557 100644 > --- a/arch/sparc/include/asm/pgtable_64.h > +++ b/arch/sparc/include/asm/pgtable_64.h > @@ -466,7 +466,7 @@ static inline pte_t pte_mkclean(pte_t pte) > return __pte(val); > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > unsigned long val = pte_val(pte), mask; > > @@ -756,11 +756,11 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) > return __pmd(pte_val(pte)); > } > > -static inline pmd_t pmd_mkwrite(pmd_t pmd) > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > pte_t pte = __pte(pmd_val(pmd)); > > - pte = pte_mkwrite(pte); > + pte = pte_mkwrite(pte, vma); > > return __pmd(pte_val(pte)); > } > diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h > index a70d1618eb35..963479c133b7 100644 > --- a/arch/um/include/asm/pgtable.h > +++ b/arch/um/include/asm/pgtable.h > @@ -207,7 +207,7 @@ static inline pte_t pte_mkyoung(pte_t pte) > return(pte); > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > if (unlikely(pte_get_bits(pte, _PAGE_RW))) > return pte; > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > index 3607f2572f9e..66c514808276 100644 > --- a/arch/x86/include/asm/pgtable.h > +++ b/arch/x86/include/asm/pgtable.h > @@ -369,7 +369,9 @@ static inline pte_t pte_mkwrite_kernel(pte_t pte) > return pte_set_flags(pte, _PAGE_RW); > } > > -static inline pte_t pte_mkwrite(pte_t pte) > +struct vm_area_struct; > + > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > return pte_mkwrite_kernel(pte); > } > @@ -470,7 +472,7 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) > return pmd_set_flags(pmd, _PAGE_ACCESSED); > } > > -static inline pmd_t pmd_mkwrite(pmd_t pmd) > +static inline pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > return pmd_set_flags(pmd, _PAGE_RW); > } > diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h > index fc7a14884c6c..d72632d9c53c 100644 > --- a/arch/xtensa/include/asm/pgtable.h > +++ b/arch/xtensa/include/asm/pgtable.h > @@ -262,7 +262,7 @@ static inline pte_t pte_mkdirty(pte_t pte) > { pte_val(pte) |= _PAGE_DIRTY; return pte; } > static inline pte_t pte_mkyoung(pte_t pte) > { pte_val(pte) |= _PAGE_ACCESSED; return pte; } > -static inline pte_t pte_mkwrite(pte_t pte) > +static inline pte_t pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { pte_val(pte) |= _PAGE_WRITABLE; return pte; } > > #define pgprot_noncached(prot) \ > diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h > index d7f6335d3999..e86c830728de 100644 > --- a/include/asm-generic/hugetlb.h > +++ b/include/asm-generic/hugetlb.h > @@ -20,9 +20,9 @@ static inline unsigned long huge_pte_dirty(pte_t pte) > return pte_dirty(pte); > } > > -static inline pte_t huge_pte_mkwrite(pte_t pte) > +static inline pte_t huge_pte_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > - return pte_mkwrite(pte); > + return pte_mkwrite(pte, vma); > } > > #ifndef __HAVE_ARCH_HUGE_PTE_WRPROTECT > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 1f79667824eb..af652444fbba 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1163,7 +1163,7 @@ void free_compound_page(struct page *page); > static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) > { > if (likely(vma->vm_flags & VM_WRITE)) > - pte = pte_mkwrite(pte); > + pte = pte_mkwrite(pte, vma); > return pte; > } > > diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c > index af59cc7bd307..7bc5592900bc 100644 > --- a/mm/debug_vm_pgtable.c > +++ b/mm/debug_vm_pgtable.c > @@ -109,10 +109,10 @@ static void __init pte_basic_tests(struct pgtable_debug_args *args, int idx) > WARN_ON(!pte_same(pte, pte)); > WARN_ON(!pte_young(pte_mkyoung(pte_mkold(pte)))); > WARN_ON(!pte_dirty(pte_mkdirty(pte_mkclean(pte)))); > - WARN_ON(!pte_write(pte_mkwrite(pte_wrprotect(pte)))); > + WARN_ON(!pte_write(pte_mkwrite(pte_wrprotect(pte), args->vma))); > WARN_ON(pte_young(pte_mkold(pte_mkyoung(pte)))); > WARN_ON(pte_dirty(pte_mkclean(pte_mkdirty(pte)))); > - WARN_ON(pte_write(pte_wrprotect(pte_mkwrite(pte)))); > + WARN_ON(pte_write(pte_wrprotect(pte_mkwrite(pte, args->vma)))); > WARN_ON(pte_dirty(pte_wrprotect(pte_mkclean(pte)))); > WARN_ON(!pte_dirty(pte_wrprotect(pte_mkdirty(pte)))); > } > @@ -153,7 +153,7 @@ static void __init pte_advanced_tests(struct pgtable_debug_args *args) > pte = pte_mkclean(pte); > set_pte_at(args->mm, args->vaddr, args->ptep, pte); > flush_dcache_page(page); > - pte = pte_mkwrite(pte); > + pte = pte_mkwrite(pte, args->vma); > pte = pte_mkdirty(pte); > ptep_set_access_flags(args->vma, args->vaddr, args->ptep, pte, 1); > pte = ptep_get(args->ptep); > @@ -199,10 +199,10 @@ static void __init pmd_basic_tests(struct pgtable_debug_args *args, int idx) > WARN_ON(!pmd_same(pmd, pmd)); > WARN_ON(!pmd_young(pmd_mkyoung(pmd_mkold(pmd)))); > WARN_ON(!pmd_dirty(pmd_mkdirty(pmd_mkclean(pmd)))); > - WARN_ON(!pmd_write(pmd_mkwrite(pmd_wrprotect(pmd)))); > + WARN_ON(!pmd_write(pmd_mkwrite(pmd_wrprotect(pmd), args->vma))); > WARN_ON(pmd_young(pmd_mkold(pmd_mkyoung(pmd)))); > WARN_ON(pmd_dirty(pmd_mkclean(pmd_mkdirty(pmd)))); > - WARN_ON(pmd_write(pmd_wrprotect(pmd_mkwrite(pmd)))); > + WARN_ON(pmd_write(pmd_wrprotect(pmd_mkwrite(pmd, args->vma)))); > WARN_ON(pmd_dirty(pmd_wrprotect(pmd_mkclean(pmd)))); > WARN_ON(!pmd_dirty(pmd_wrprotect(pmd_mkdirty(pmd)))); > /* > @@ -253,7 +253,7 @@ static void __init pmd_advanced_tests(struct pgtable_debug_args *args) > pmd = pmd_mkclean(pmd); > set_pmd_at(args->mm, vaddr, args->pmdp, pmd); > flush_dcache_page(page); > - pmd = pmd_mkwrite(pmd); > + pmd = pmd_mkwrite(pmd, args->vma); > pmd = pmd_mkdirty(pmd); > pmdp_set_access_flags(args->vma, vaddr, args->pmdp, pmd, 1); > pmd = READ_ONCE(*args->pmdp); > @@ -928,8 +928,8 @@ static void __init hugetlb_basic_tests(struct pgtable_debug_args *args) > pte = mk_huge_pte(page, args->page_prot); > > WARN_ON(!huge_pte_dirty(huge_pte_mkdirty(pte))); > - WARN_ON(!huge_pte_write(huge_pte_mkwrite(huge_pte_wrprotect(pte)))); > - WARN_ON(huge_pte_write(huge_pte_wrprotect(huge_pte_mkwrite(pte)))); > + WARN_ON(!huge_pte_write(huge_pte_mkwrite(huge_pte_wrprotect(pte), args->vma))); > + WARN_ON(huge_pte_write(huge_pte_wrprotect(huge_pte_mkwrite(pte, args->vma)))); > > #ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB > pte = pfn_pte(args->fixed_pmd_pfn, args->page_prot); > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 4fc43859e59a..aaf815838144 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -555,7 +555,7 @@ __setup("transparent_hugepage=", setup_transparent_hugepage); > pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) > { > if (likely(vma->vm_flags & VM_WRITE)) > - pmd = pmd_mkwrite(pmd); > + pmd = pmd_mkwrite(pmd, vma); > return pmd; > } > > @@ -1580,7 +1580,7 @@ vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf) > pmd = pmd_modify(oldpmd, vma->vm_page_prot); > pmd = pmd_mkyoung(pmd); > if (writable) > - pmd = pmd_mkwrite(pmd); > + pmd = pmd_mkwrite(pmd, vma); > set_pmd_at(vma->vm_mm, haddr, vmf->pmd, pmd); > update_mmu_cache_pmd(vma, vmf->address, vmf->pmd); > spin_unlock(vmf->ptl); > @@ -1926,7 +1926,7 @@ int change_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, > /* See change_pte_range(). */ > if ((cp_flags & MM_CP_TRY_CHANGE_WRITABLE) && !pmd_write(entry) && > can_change_pmd_writable(vma, addr, entry)) > - entry = pmd_mkwrite(entry); > + entry = pmd_mkwrite(entry, vma); > > ret = HPAGE_PMD_NR; > set_pmd_at(mm, addr, pmd, entry); > diff --git a/mm/hugetlb.c b/mm/hugetlb.c > index 07abcb6eb203..6af471bdcff8 100644 > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -4900,7 +4900,7 @@ static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, > > if (writable) { > entry = huge_pte_mkwrite(huge_pte_mkdirty(mk_huge_pte(page, > - vma->vm_page_prot))); > + vma->vm_page_prot)), vma); > } else { > entry = huge_pte_wrprotect(mk_huge_pte(page, > vma->vm_page_prot)); > @@ -4916,7 +4916,7 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma, > { > pte_t entry; > > - entry = huge_pte_mkwrite(huge_pte_mkdirty(huge_ptep_get(ptep))); > + entry = huge_pte_mkwrite(huge_pte_mkdirty(huge_ptep_get(ptep)), vma); > if (huge_ptep_set_access_flags(vma, address, ptep, entry, 1)) > update_mmu_cache(vma, address, ptep); > } > diff --git a/mm/memory.c b/mm/memory.c > index f456f3b5049c..d0972d2d6f36 100644 > --- a/mm/memory.c > +++ b/mm/memory.c > @@ -4067,7 +4067,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) > entry = mk_pte(&folio->page, vma->vm_page_prot); > entry = pte_sw_mkyoung(entry); > if (vma->vm_flags & VM_WRITE) > - entry = pte_mkwrite(pte_mkdirty(entry)); > + entry = pte_mkwrite(pte_mkdirty(entry), vma); > > vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address, > &vmf->ptl); > @@ -4755,7 +4755,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf) > pte = pte_modify(old_pte, vma->vm_page_prot); > pte = pte_mkyoung(pte); > if (writable) > - pte = pte_mkwrite(pte); > + pte = pte_mkwrite(pte, vma); > ptep_modify_prot_commit(vma, vmf->address, vmf->pte, old_pte, pte); > update_mmu_cache(vma, vmf->address, vmf->pte); > pte_unmap_unlock(vmf->pte, vmf->ptl); > diff --git a/mm/migrate_device.c b/mm/migrate_device.c > index d30c9de60b0d..df3f5e9d5f76 100644 > --- a/mm/migrate_device.c > +++ b/mm/migrate_device.c > @@ -646,7 +646,7 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate, > } > entry = mk_pte(page, vma->vm_page_prot); > if (vma->vm_flags & VM_WRITE) > - entry = pte_mkwrite(pte_mkdirty(entry)); > + entry = pte_mkwrite(pte_mkdirty(entry), vma); > } > > ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); > diff --git a/mm/mprotect.c b/mm/mprotect.c > index 1d4843c97c2a..381163a41e88 100644 > --- a/mm/mprotect.c > +++ b/mm/mprotect.c > @@ -198,7 +198,7 @@ static long change_pte_range(struct mmu_gather *tlb, > if ((cp_flags & MM_CP_TRY_CHANGE_WRITABLE) && > !pte_write(ptent) && > can_change_pte_writable(vma, addr, ptent)) > - ptent = pte_mkwrite(ptent); > + ptent = pte_mkwrite(ptent, vma); > > ptep_modify_prot_commit(vma, addr, pte, oldpte, ptent); > if (pte_needs_flush(oldpte, ptent)) > diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c > index 53c3d916ff66..3db6f87c0aca 100644 > --- a/mm/userfaultfd.c > +++ b/mm/userfaultfd.c > @@ -75,7 +75,7 @@ int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd, > if (page_in_cache && !vm_shared) > writable = false; > if (writable) > - _dst_pte = pte_mkwrite(_dst_pte); > + _dst_pte = pte_mkwrite(_dst_pte, dst_vma); > if (wp_copy) > _dst_pte = pte_mkuffd_wp(_dst_pte); >