From: Sean Christopherson <seanjc@google.com>
To: Pankaj Gupta <pankaj.gupta@amd.com>
Cc: "David Hildenbrand (Arm)" <david@kernel.org>,
pbonzini@redhat.com, tglx@kernel.org, mingo@redhat.com,
dave.hansen@linux.intel.com, bp@alien8.de, x86@kernel.org,
thomas.lendacky@amd.com, hpa@zytor.com, yangge1116@126.com,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org,
"Lorenzo Stoakes (Oracle)" <ljs@kernel.org>
Subject: Re: [PATCH] KVM: SEV: drop FOLL_LONGTERM for encrypted region registration
Date: Tue, 7 Jul 2026 06:59:53 -0700 [thread overview]
Message-ID: <ak0GWRue6-S-BQEu@google.com> (raw)
In-Reply-To: <2bd89e95-9c15-4a3a-916d-0d71a92d8b02@amd.com>
On Tue, Jul 07, 2026, Pankaj Gupta wrote:
> > > > IIRC, fsdax cannot tolerate unbounded pins. Is that the case we are running into?
> > > Host side backend is regular file backed memory (no fsdax).
> > Okay, so we'll end up mapping an ordinary file into VM memory, and expose that
> > to the VM as part of virtio-pmem device.
> >
> > That also means that vfio etc. won't be able to longterm-pin such device memory.
> > So this is not a problem isolated to SEV.
The problem that _is_ "isolated" to SEV though, is that this used to work :-/
> > Forbidding to longterm pin is actually the right thing to do if the filesystem
> > relies on writenotify, as spelled out by Lorenzo's commit:
> >
> > "
> > Writing to file-backed mappings which require folio dirty tracking using
> > GUP is a fundamentally broken operation, as kernel write access to GUP
> > mappings do not adhere to the semantics expected by a file system.
> >
> > A GUP caller uses the direct mapping to access the folio, which does not
> > cause write notify to trigger, nor does it enforce that the caller marks
> > the folio dirty.
> >
> > The problem arises when, after an initial write to the folio, writeback
> > results in the folio being cleaned and then the caller, via the GUP
> > interface, writes to the folio again.
> > "
> >
> > Hmmm
>
> Yes. For file based mapping we don't allow long term pinning.
>
> If we take into account the fragmentation concerns for MIGRATE_CMA and
> ZONE_MOVABLE allocations
>
> solvable with FOLL_LONGTERM, I can think of two options(tested) to allow
> file based mappings as well:
>
> 1. Fallback on FOLL_WRITE when FOLL_LONGTERM fails as suggested by Sean.
>
> 2. Explicitly restrict long-term pinning for file-backed mappings with a
> change like the patch below [1].
>
> David, Sean,
>
> Do you have a preference between these two approaches? I am leaning toward
> towards option 2.
Option 1. Option 2 has a TOCTOU bug (the VMA could be changed after dropping
mmap_lock), and I'd rather not bleed any more mm/ details into KVM than is
required: falling back to a non-FOLL_LONGTERM acknowledges that there are mapping
types that don't support WRITE+LONGTERM, but checking vma_is_anonymous() takes
things a few steps further by forcing KVM to know what types of mappings are
problematic.
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 6c6a6d663e29..c4b53700f69e 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -2743,6 +2743,29 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user
> *argp)
> return r;
> }
>
> +static unsigned int sev_region_gup_flags(unsigned long uaddr, unsigned long
> ulen)
> +{
> + struct mm_struct *mm = current->mm;
> + unsigned long end = uaddr + ulen;
> + struct vm_area_struct *vma;
> + unsigned int flags = FOLL_WRITE | FOLL_LONGTERM;
> + VMA_ITERATOR(vmi, mm, uaddr);
> +
> + if (ulen == 0 || end < uaddr)
> + return FOLL_WRITE;
> +
> + mmap_read_lock(mm);
> + for_each_vma_range(vmi, vma, end) {
> + if (!vma_is_anonymous(vma)) {
> + flags = FOLL_WRITE;
> + break;
> + }
> + }
> + mmap_read_unlock(mm);
> +
> + return flags;
> +}
> +
> int sev_mem_enc_register_region(struct kvm *kvm,
> struct kvm_enc_region *range)
> {
> @@ -2764,7 +2787,7 @@ int sev_mem_enc_register_region(struct kvm *kvm,
> return -ENOMEM;
>
> region->pages = sev_pin_memory(kvm, range->addr, range->size,
> ®ion->npages,
> - FOLL_WRITE | FOLL_LONGTERM);
> + sev_region_gup_flags(range->addr, range->size));
> if (IS_ERR(region->pages)) {
> ret = PTR_ERR(region->pages);
> goto e_free;
> (END)
> --
>
>
>
>
next prev parent reply other threads:[~2026-07-07 13:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 14:45 [PATCH] KVM: SEV: drop FOLL_LONGTERM for encrypted region registration Pankaj Gupta
2026-07-01 14:58 ` sashiko-bot
2026-07-01 16:25 ` David Hildenbrand (Arm)
2026-07-01 16:30 ` Sean Christopherson
2026-07-01 16:39 ` David Hildenbrand (Arm)
2026-07-01 16:56 ` Sean Christopherson
2026-07-06 12:03 ` Gupta, Pankaj
2026-07-07 10:04 ` David Hildenbrand (Arm)
2026-07-07 13:45 ` Gupta, Pankaj
2026-07-07 13:59 ` Sean Christopherson [this message]
2026-07-07 14:58 ` David Hildenbrand (Arm)
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=ak0GWRue6-S-BQEu@google.com \
--to=seanjc@google.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mingo@redhat.com \
--cc=pankaj.gupta@amd.com \
--cc=pbonzini@redhat.com \
--cc=stable@vger.kernel.org \
--cc=tglx@kernel.org \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
--cc=yangge1116@126.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.