From: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>
To: linux-coco@lists.linux.dev
Cc: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org>,
Ackerley Tng <ackerleytng@google.com>,
Alex Williamson <alex@shazbot.org>,
David Woodhouse <dwmw2@infradead.org>,
David Hildenbrand <david@kernel.org>,
Jason Gunthorpe <jgg@nvidia.com>,
"Joerg Roedel (AMD)" <joro@8bytes.org>,
Kevin Tian <kevin.tian@intel.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Robin Murphy <robin.murphy@arm.com>,
Sean Christopherson <seanjc@google.com>,
Alexey Kardashevskiy <aik@amd.com>,
Xu Yilun <yilun.xu@linux.intel.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Steven Price <steven.price@arm.com>,
Fred Griffoul <griffoul@gmail.com>,
iommu@lists.linux.dev, kvm@vger.kernel.org,
patches@lists.linux.dev
Subject: [RFC PATCH v4 03/25] KVM: guest_memfd: Let providers coordinate mapping changes
Date: Wed, 4 Nov 2026 20:33:00 +0530 [thread overview]
Message-ID: <20261104150322.3516320-4-aneesh.kumar@kernel.org> (raw)
In-Reply-To: <20261104150322.3516320-1-aneesh.kumar@kernel.org>
Resource providers may need to serialize host access with guest
invalidation, architecture conversion and publication of new attributes.
Add optional paired lock() and unlock() callbacks without exposing KVM
memslots or architecture requests through the provider interface. Reject
providers that supply only one callback.
Call gmem_provider_lock() with inode->i_mapping->invalidate_lock held
for write, after prepare_attributes() and before guest invalidation
starts. It invokes the provider's optional lock() callback. Call
gmem_provider_unlock() after invalidation ends, regardless of whether
conversion succeeds. Publish attributes before unlocking only when
conversion succeeds.
Subsequent revocation, memslot unbind and final file cleanup use the
same pair without changing attributes.
Existing providers omit both callbacks and retain their current behavior.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: kvm@vger.kernel.org
Cc: patches@lists.linux.dev
Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
include/linux/guest_memfd.h | 11 +++++++++++
virt/kvm/guest_memfd.c | 37 ++++++++++++++++++++++++++++---------
2 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/include/linux/guest_memfd.h b/include/linux/guest_memfd.h
index 17407504307b..9fc04f1188c1 100644
--- a/include/linux/guest_memfd.h
+++ b/include/linux/guest_memfd.h
@@ -20,6 +20,15 @@ struct mempolicy;
* Offset and size are in bytes. The flags contain only
* KVM_MEM_LOG_DIRTY_PAGES and KVM_MEM_READONLY bits.
* Return 0 on success or a negative error code.
+ * @lock: Optional provider exclusion for mapping and attribute changes. Called
+ * with the inode invalidate lock held for write, before guest
+ * invalidation starts. May sleep and must return with exclusion held.
+ * Supply both lock and unlock, or neither.
+ * @unlock: Release exclusion acquired by lock(). Called after guest
+ * invalidation ends and any successful attribute publication, with
+ * the inode invalidate lock still held. The pair also covers range
+ * revocation, memslot unbind and final file cleanup; those operations
+ * do not change attributes.
* @alloc_folio: Allocate an uninserted folio for a given index and NUMA policy.
* Must return a pointer to a struct folio on success, or an
* ERR_PTR() error code on failure. Must never return NULL.
@@ -52,6 +61,8 @@ struct guest_memfd_provider_operations {
void (*release)(void *provider);
int (*prepare_memory_region)(void *provider, u64 offset, u64 size,
u32 flags);
+ void (*lock)(void *provider);
+ void (*unlock)(void *provider);
struct folio *(*alloc_folio)(void *provider, pgoff_t index,
struct mempolicy *mpol);
void (*invalidate_folio)(void *provider, struct folio *folio);
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 3cb1523ad74e..20c72693c210 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -33,19 +33,20 @@ struct gmem_file {
struct kvm_gmem_backing_ops {
/*
- * Validate the transition before guest invalidation and conversion.
- * Caller holds inode->i_mapping->invalidate_lock for write. May revoke
- * host mappings and check outstanding references. On failure, return an
- * error and set err_index to the failing offset; it defaults to the range
- * start.
+ * Validate the transition before gmem_provider_lock(), guest invalidation
+ * and conversion. Caller holds inode->i_mapping->invalidate_lock for write.
+ * May revoke host mappings and check outstanding references. On failure,
+ * return an error and set err_index to the failing offset; it defaults to
+ * the range start.
*/
int (*prepare_attributes)(struct inode *inode, pgoff_t start,
size_t nr_pages, u64 attrs, pgoff_t *err_index);
/*
* Complete range conversion after guest invalidation starts and before
* attributes are published. Caller holds inode->i_mapping->invalidate_lock
- * for write. Shared memory must be safe for host access when the
- * attributes become visible; host faults bypass prepare_pfn().
+ * for write and calls this between gmem_provider_lock() and
+ * gmem_provider_unlock(). Shared memory must be safe for host access when
+ * the attributes become visible; host faults bypass prepare_pfn().
* NULL means no additional conversion is needed at this phase.
*/
int (*convert_attributes)(struct inode *inode, pgoff_t start, pgoff_t end,
@@ -125,6 +126,9 @@ static bool gmem_provider_ops_valid(struct gmem_inode *gi,
if (!ops || !ops->attach)
return false;
+ if (!!ops->lock != !!ops->unlock)
+ return false;
+
if (kvm_gmem_is_pfn_mode(gi))
return ops->get_pfn && ops->lookup_pfn_range;
@@ -226,6 +230,18 @@ static void gmem_provider_put_pfn_range(struct gmem_inode *gi, pgoff_t index,
gi->provider_ops->put_pfn_range(gi->provider, index, nr_pages);
}
+static void gmem_provider_lock(struct gmem_inode *gi)
+{
+ if (gi->provider_ops && gi->provider_ops->lock)
+ gi->provider_ops->lock(gi->provider);
+}
+
+static void gmem_provider_unlock(struct gmem_inode *gi)
+{
+ if (gi->provider_ops && gi->provider_ops->unlock)
+ gi->provider_ops->unlock(gi->provider);
+}
+
static void gmem_provider_release(struct gmem_inode *gi)
{
if (gi->provider_ops && gi->provider_ops->release)
@@ -1121,8 +1137,7 @@ static int kvm_gmem_convert_attributes(struct inode *inode, pgoff_t start,
}
static int __kvm_gmem_set_attributes(struct inode *inode, pgoff_t start,
- size_t nr_pages, uint64_t attrs,
- pgoff_t *err_index)
+ size_t nr_pages, u64 attrs, pgoff_t *err_index)
{
bool to_private = attrs & KVM_MEMORY_ATTRIBUTE_PRIVATE;
struct address_space *mapping = inode->i_mapping;
@@ -1148,6 +1163,9 @@ static int __kvm_gmem_set_attributes(struct inode *inode, pgoff_t start,
if (r)
goto destroy;
+ /* Call the provider's lock() before invalidation as well as conversion. */
+ gmem_provider_lock(gi);
+
filter = to_private ? KVM_FILTER_SHARED : KVM_FILTER_PRIVATE;
kvm_gmem_invalidate_start(inode, start, end, filter);
@@ -1158,6 +1176,7 @@ static int __kvm_gmem_set_attributes(struct inode *inode, pgoff_t start,
if (r)
mas_destroy(&mas);
kvm_gmem_invalidate_end(inode, start, end);
+ gmem_provider_unlock(gi);
goto out;
destroy:
--
2.43.0
next prev parent reply other threads:[~2026-11-04 15:03 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 15:02 [RFC PATCH v4 00/25] KVM/VFIO: Add guest_memfd support for device MMIO Aneesh Kumar K.V (Arm)
2026-11-04 15:02 ` [RFC PATCH v4 01/25] KVM: guest_memfd: Let providers prepare memory regions Aneesh Kumar K.V (Arm)
2026-11-04 15:02 ` [RFC PATCH v4 02/25] KVM: guest_memfd: Dispatch conversion through backing operations Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` Aneesh Kumar K.V (Arm) [this message]
2026-11-04 15:03 ` [RFC PATCH v4 04/25] KVM: guest_memfd: Dispatch revocation " Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 05/25] KVM: guest_memfd: Split population by backing type Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 06/25] KVM: guest_memfd: Support device-backed PFN providers Aneesh Kumar K.V (Arm)
2026-11-04 18:37 ` Fred Griffoul
2026-11-04 15:03 ` [RFC PATCH v4 07/25] KVM: guest_memfd: Support private/shared conversion of device memory Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 08/25] KVM: guest_memfd: Track private device ranges after attribute updates Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 09/25] KVM: guest_memfd: Support range revocation of device mappings Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 10/25] KVM: guest_memfd: Add shared device mmap through PFN providers Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 11/25] KVM: guest_memfd: Clear private device state on final close Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 12/25] KVM: guest_memfd: Invalidate mappings before memslot unbind Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 13/25] vfio: Track device use by guest_memfd Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 14/25] vfio/pci: Add helpers to check and serialize BAR state changes Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 15/25] vfio/pci: Check command enable changes before updating device state Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 16/25] vfio/pci: Check whether BAR state changes are allowed before reset Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 17/25] vfio/pci: Check low-power requests before updating device state Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 18/25] vfio/pci: Track userspace BAR mappings Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 19/25] vfio/pci: Restrict host BAR access for guest_memfd providers Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 20/25] vfio: Dispatch guest_memfd provider operations through the device file Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 21/25] vfio: Serialize guest_memfd attachment with device file operations Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 22/25] vfio/pci: Require D0 before providing guest_memfd BAR backing Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 23/25] iommufd: Support MMIO provider attachment to vDEVICEs Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 24/25] vfio/pci: Add a guest_memfd resource provider for MMIO BARs Aneesh Kumar K.V (Arm)
2026-11-04 15:03 ` [RFC PATCH v4 25/25] KVM: Document device-backed guest_memfd and VFIO usage Aneesh Kumar K.V (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=20261104150322.3516320-4-aneesh.kumar@kernel.org \
--to=aneesh.kumar@kernel.org \
--cc=ackerleytng@google.com \
--cc=aik@amd.com \
--cc=alex@shazbot.org \
--cc=catalin.marinas@arm.com \
--cc=david@kernel.org \
--cc=dwmw2@infradead.org \
--cc=griffoul@gmail.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=patches@lists.linux.dev \
--cc=pbonzini@redhat.com \
--cc=robin.murphy@arm.com \
--cc=seanjc@google.com \
--cc=steven.price@arm.com \
--cc=suzuki.poulose@arm.com \
--cc=yilun.xu@linux.intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox