mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Carlos López" <clopez@suse.de>
To: kvm@vger.kernel.org, linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org,
	linux-riscv@lists.infradead.org, seanjc@google.com,
	pbonzini@redhat.com, akpm@linux-foundation.org, david@kernel.org,
	peterx@redhat.com, ljs@kernel.org, imbrenda@linux.ibm.com,
	borntraeger@linux.ibm.com, frankja@linux.ibm.com,
	"Carlos López" <clopez@suse.de>,
	"Liam R. Howlett" <liam@infradead.org>,
	"Vlastimil Babka" <vbabka@kernel.org>,
	"Jann Horn" <jannh@google.com>,
	"Pedro Falcato" <pfalcato@suse.de>,
	"Peter Feiner" <pfeiner@google.com>
Subject: [PATCH v2 1/9] mm: fix eager write-bit restore for write-notified shared mappings
Date: Thu,  5 Nov 2026 17:49:58 +0100	[thread overview]
Message-ID: <20261105165004.2663799-5-clopez@suse.de> (raw)
In-Reply-To: <20261105165004.2663799-4-clopez@suse.de>

change_protection() applies vma->vm_page_prot, which lacks
the write bit for CoW and write-notified mappings. To avoid
needless write faults, callers set MM_CP_TRY_CHANGE_WRITABLE when
vma_wants_manual_pte_write_upgrade() returns true, so that entries that
can be written without a fault, such as dirty PTEs in a shared mapping,
are made writable right away.

For shared mappings, that function passes vma->vm_page_prot to
vma_wants_writenotify(). Once writenotify is enabled, this protection
lacks the write bit, while the vma_pgprot_modify() result it is compared
against adds it back. The two never match, so vma_wants_writenotify()
returns false before checking for soft-dirty, uffd-wp and writeback.

As a result, write-notified shmem mappings never get
MM_CP_TRY_CHANGE_WRITABLE, and their dirty PTEs stay read-only after a
protection change. For example, commit 931298e103c2 ("mm/userfaultfd:
rely on vma->vm_page_prot in uffd_wp_range()") made uffd-wp unprotect
set MM_CP_TRY_CHANGE_WRITABLE so that dirty shmem PTEs become writable
again, but this never takes effect. Unprotecting N dirty shmem pages
still leads to N faults that only set the write bit.

This dates back to the commit in the Fixes tag, which moved the
equivalent check in mprotect_fixup() before vma_set_page_prot().

Fix this by passing the protection recomputed from the VMA flags, as
vma_set_page_prot() does. Note that this is a performance-only fix, as
the write bit is restored on the next page fault anyway.

Fixes: 64e455079e1b ("mm: softdirty: enable write notifications on VMAs after VM_SOFTDIRTY cleared")
Signed-off-by: Carlos López <clopez@suse.de>
---
 mm/vma.h | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/mm/vma.h b/mm/vma.h
index 3fc3b47a954b..e83700e248e4 100644
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -589,6 +589,14 @@ int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
 	      unsigned long addr, int new_below);
 #endif
 
+#ifdef CONFIG_MMU
+static inline pgprot_t vma_pgprot_modify(pgprot_t oldprot, vma_flags_t vma_flags)
+{
+	const pgprot_t prot = vma_flags_to_page_prot(vma_flags);
+
+	return pgprot_modify(oldprot, prot);
+}
+
 static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma)
 {
 	/*
@@ -596,19 +604,16 @@ static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma
 	 * if we can't do that automatically for all PTEs in a mapping. For
 	 * private mappings, that's always the case when we have write
 	 * permissions as we properly have to handle COW.
+	 *
+	 * vma->vm_page_prot lacks the write bit if writenotify is already
+	 * enabled, so pass it with the bits restored, as vma_set_page_prot()
+	 * does.
 	 */
 	if (vma->vm_flags & VM_SHARED)
-		return vma_wants_writenotify(vma, vma->vm_page_prot);
+		return vma_wants_writenotify(vma,
+		       vma_pgprot_modify(vma->vm_page_prot, vma->flags));
 	return !!(vma->vm_flags & VM_WRITE);
 }
-
-#ifdef CONFIG_MMU
-static inline pgprot_t vma_pgprot_modify(pgprot_t oldprot, vma_flags_t vma_flags)
-{
-	const pgprot_t prot = vma_flags_to_page_prot(vma_flags);
-
-	return pgprot_modify(oldprot, prot);
-}
 #endif
 
 static inline struct vm_area_struct *vma_prev_limit(struct vma_iterator *vmi,
-- 
2.51.0


  reply	other threads:[~2026-11-05 17:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 16:49 [PATCH v2 0/9] KVM: don't zap secondary MMU on permission upgrade Carlos López
2026-11-05 16:49 ` Carlos López [this message]
2026-11-05 16:49 ` [PATCH v2 2/9] riscv: mm: add pud_soft_dirty() Carlos López
2026-11-05 16:50 ` [PATCH v2 3/9] mm/huge_memory: honor MM_CP_TRY_CHANGE_WRITABLE in change_huge_pud() Carlos López
2026-11-05 16:50 ` [PATCH v2 4/9] mm/mprotect: add MM_CP_PERM_UPGRADE Carlos López
2026-11-05 16:50 ` [PATCH v2 5/9] mm/mprotect: keep writable entries writable on permission upgrades Carlos López
2026-11-05 17:06   ` David Hildenbrand (Arm)
2026-11-05 16:50 ` [PATCH v2 6/9] mm/mmu_notifier: add MMU_NOTIFIER_RANGE_PERM_UPGRADE Carlos López
2026-11-05 16:50 ` [PATCH v2 7/9] KVM: pass the mmu_notifier event and flags to kvm_gfn_range Carlos López
2026-11-05 16:50 ` [PATCH v2 8/9] KVM: x86/mmu: don't zap secondary MMU on permission upgrade Carlos López
2026-11-05 16:50 ` [PATCH v2 9/9] KVM: s390: don't unmap the gmap " Carlos López

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261105165004.2663799-5-clopez@suse.de \
    --to=clopez@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=borntraeger@linux.ibm.com \
    --cc=david@kernel.org \
    --cc=frankja@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=jannh@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=pfalcato@suse.de \
    --cc=pfeiner@google.com \
    --cc=seanjc@google.com \
    --cc=vbabka@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®