mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Zi Yan" <ziy@nvidia.com>
To: "Jason Gunthorpe" <jgg@ziepe.ca>
Cc: "Leon Romanovsky" <leon@kernel.org>, <linux-mm@kvack.org>,
	"Lorenzo Stoakes" <ljs@kernel.org>,
	"Lance Yang" <lance.yang@linux.dev>,
	"Kiryl Shutsemau" <kas@kernel.org>,
	"David Hildenbrand (Arm)" <david@kernel.org>,
	<linux-rdma@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] RDMA/uverbs: Don't return the shared zero page from rdma_umap_fault()
Date: Mon, 26 Oct 2026 11:41:54 -0400	[thread overview]
Message-ID: <DMEVUFVL2D1Z.3AOCMD4UUMT4V@nvidia.com> (raw)
In-Reply-To: <20261026114955.GP3977851@ziepe.ca>

On Mon Oct 26, 2026 at 7:49 AM EDT, Jason Gunthorpe wrote:
> On Sun, Oct 25, 2026 at 10:04:42PM -0400, Zi Yan wrote:
>> After disassociation, rdma_umap_fault() returns the shared zero page from
>> ->fault for VMAs without VM_WRITE and VM_MAYWRITE. Such VMAs come from
>> rdma_user_mmap_io() in drivers that clear VM_MAYWRITE and they are shared
>> VM_PFNMAP. A page returned from ->fault is mapped as a normal page and goes
>> through rmap code. Two issues:
>> 
>> 1. shared zero page causes VM_WARN_ONs in rmap code,
>> 
>> 2. normal pages in shared VM_PFNMAP VMAs cause accounting leak on arch
>>    without pte_special(), namely the page refcount, mapcount, and vm stats
>>    are never dropped.
>> 
>> Map ufile->disassociate_page for VMAs without VM_WRITE and VM_MAYWRITE,
>> with vmf_insert_pfn(). The page lives until ib_uverbs_release_file(), which
>> cannot run while a VMA holds a reference to the file.
>> 
>> Writable VMAs keep returning disassociate_page in vmf->page, thus its
>> accounting leak on arch without pte_special() needs a separate fix.
>> 
>> Userspace can see two differences after the patch. A mapping without
>> VM_WRITE and VM_MAYWRITE now reads what was written through writable
>> mappings of the same uverbs file instead of zeroes; after disassociation
>> both are dummy data. The first fault now allocates the page and fails with
>> VM_FAULT_SIGBUS if the allocation fails, as a write fault already does.
>> 
>> Fixes: 67f269b37f9b ("RDMA/ucontext: Fix regression with disassociate")
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> ---
>> The issue was discovered during PG_folio development when making sure only
>> rmappable folios can enter rmap code path.
>> 
>> Alternative: map the zero page with vmf_insert_pfn_prot()
>> ===
>> 
>> Read-only mappings could keep reading zeroes if rdma_umap_fault()
>> installed the zero page itself as a special PTE:
>> 
>> return vmf_insert_pfn_prot(vmf->vma, vmf->address, zero_pfn(vmf->address));
>> 
>> It does not work today. Commit 7b466529307be ("mm: disallow raw PFN
>> mappings of huge/shared zeropage") makes vmf_insert_pfn_prot() return
>> VM_FAULT_SIGBUS for the zero pfn. vmf_insert_mixed() does not support
>> VM_PFNMAP, since vm_mixed_zeropage_allowed() warns on VM_PFNMAP.
>> 
>> The first version of that patch [1] did not change vmf_insert_pfn_prot().
>> Due to no in-kernel user at that time and complication it can cause,
>> vmf_insert_pfn_prot() rejects zero pages now.
>> 
>> Fix to writable VMA path
>> ===
>> A new vmf_insert_pfn_mkwrite() is needed, since vmf_insert_pfn() has a
>> narrow failing scenario. When a process mapping the disassociated page has
>> soft-dirty tracking enabled, vm_page_prot becomes read-only;
>> vmf_insert_pfn() then uses a read-only PTE instead of a writable one;
>> fixup_user_fault() is used to write to the page (e.g., KVM with the uverbs
>> mapping as guest memory) and fails, because it does not take the second
>> fault to upgrade the read-only PTE to a writable one.
>> 
>> LLM was used for investigation and code development.
>
> Is that why all of the above was so hard to read?

LLM drafted the original long and full of details commit message and
cover letter, I trimmed down as much as I can but kept the necessary details.
Let me know which part is hard to read.

I provided the details because:

1. the original code returns a page on VM_PFNMAP VMAs instead of a
   proper vm_insert*()
2. vmf_insert_pfn_prot() is the proper fix but it has been changed to
   block zero_page, so I would like to know it is worth the effort to
   add complication for this single user.
3. the writable path needs a separate fix, which also requires
   additional MM fixes, a new vmf_insert_pfn_mkwrite() function.

Probably I should have sent it as a RFC instead.

>
> The zero page was used because things like the clock page really need
> to be zero. Reflecting back random things from the disassociate page
> is not going to work out.

Got it. I did not realize that each ufile has only one disassociate page and
the read-only page and writable page can be used in a single ufile.

>
> I don't think rdma supports any architectures without the special bit
> so I'm not sure this is a real issue in practice.

Sounds good.

>
> I guess using vmf_insert_pfn_prot() consistently is the right answer
> since these VMAs are not supposed to be mixed maps.

It requires nontrivial MM changes[1] plus rdma_umap_fault() needs to
handle when mm_forbids_zeropage() is true. Basically, it needs to get a
zero page itself when that happens.

Maybe it is better to add a dedicated zero_disassociate_page for it, to
avoid the fallback handling.

In terms of allowing vmf_insert_pfn_prot() to accept zero_page, I would
like to get inputs from David and Kiril. Or the rule can be no zero_page
for PFNMAP and device needs to manage its own zero page and do the
vm_insert*().


[1] https://lore.kernel.org/all/c0979ad4-9fec-49f1-8442-d90061b79504@kernel.org/

-- 
Best Regards,
Yan, Zi


  reply	other threads:[~2026-10-26 15:44 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26  2:04 Zi Yan
2026-10-26  8:55 ` Jose A. Perez de Azpillaga
2026-10-26 11:49 ` Jason Gunthorpe
2026-10-26 15:41   ` Zi Yan [this message]
2026-10-26 12:20 ` David Hildenbrand (Arm)
2026-10-26 15:48   ` Zi Yan

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=DMEVUFVL2D1Z.3AOCMD4UUMT4V@nvidia.com \
    --to=ziy@nvidia.com \
    --cc=david@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=kas@kernel.org \
    --cc=lance.yang@linux.dev \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=ljs@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®