All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends
@ 2026-09-08 13:30 Michael Roth
  2026-09-08 13:30 ` [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
                   ` (12 more replies)
  0 siblings, 13 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david

v1: https://lore.kernel.org/r/20251023185913.2923322-1-peterx@redhat.com
v2: https://lore.kernel.org/r/20251119172913.577392-1-peterx@redhat.com
v3: https://lore.kernel.org/r/20251215205203.1185099-1-peterx@redhat.com/
v4: https://lore.kernel.org/qemu-devel/20260812201938.198915-1-michael.roth@amd.com/
v5:
- Fix error handling for 'hugetlb' when guest-memfd=on (Daniel, Peter)
- Default to 'seal' option being allowed/on for guest-memfd=on since
  it already satisfies the documented semantics (Peter)
- Don't explicitly set a placeholder URI for qtest/migration-test
  as the code now relies on NULL for this path (Peter)
- Clarify rationale for checking for kvm_enabled() in 
  kvm_create_guest_memfd() (Philippe, Peter)

This patchset is also available at:

  https://github.com/amdese/qemu/commits/gmem-shared-mem-v5

and is based on top of qemu master (99e54ab5e7)


OVERVIEW
========

(cover letter shamelessly adapted from Peter's prior postings)

Recent kernels allow guest_memfd to be initialized with an 'init-shared'
flag that will default to allocating normal/non-private memory that can be
used to back non-confidential VMs.

This allows QEMU to make use of these init-shared guest_memfd instances via
a common memory backend that's usable for either provide a common memory
backend.

On the QEMU side, before this series, guest_memfd was only used for private
guest memory (and thus only applied to confidential VMs), and the guest_memfd
FDs would be created implicitly whenever a confidential environment was
detected/specified.

With this series, users can now explicitly configure QEMU to use guest_memfd
for non-private memory; thus, it can be used for non-confidential
VMs. It also has implications for confidential VMs, since with this series an
init-shared guest_memfd instance can now be specified for the shared memory
while the internally-allocated guest_memfd continues to be used for private
memory. This same infrastructure will also be used as the base for enabling
in-place conversion for confidential VMs, where these separate shared/private
paths will be modified to act on the same underlying guest_memfd instance and
use a unified pool of shared/private memory.


IMPLEMENTATION
==============

In the current patchset, I reused the memory-backend-memfd object, rather
than creating a new type of object.  After all, guest-memfd (at least from
userspace POV) works similarly like a memfd, except that it was tailored
for VM's use case. While there is potential that new guest_memfd features
may eventually necessitate introducing a dedicated guest_memfd memory
backend object, for now the memory-backend-memfd object is a good fit for
the current feature set.

This will also make it easier when in-place conversion comes around, since
confidential VMs typically already use memory-backend-memfd for their shared
memory, so by also making using that approach to specify the guest_memfd
backend for in-place conversion the command-line syntax remains similar, and
even allow choosing between memfd vs. guest_memfd to be handled automatically
based on whether or not we're dealing with a Confidential VM with in-place
conversion enabled.

Now, instead of using a normal memfd backend using:

  -object memory-backend-memfd,id=ID,size=SIZE,share=on

One can also boot a VM with guest-memfd:

  -object memory-backend-memfd,id=ID,size=SIZE,share=on,guest-memfd=on

The init-shared guest-memfd relies on a recent kernel (6.18+). When run it on
an older qemu, you'll see errors like:

  qemu-system-x86_64: KVM does not support guest_memfd

One thing to mention is live migration is by default supported, however
postcopy is still currently not supported.  The postcopy support will have
some kernel dependency work to be merged in Linux first.


Thanks,

Mike


Peter Xu (11):
      kvm: Detect guest-memfd flags supported
      kvm: Provide explicit error for kvm_create_guest_memfd()
      ramblock: Rename guest_memfd to guest_memfd_private
      memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE
      memory: Rename memory_region_has_guest_memfd() to *_private()
      hostmem: Rename guest_memfd to guest_memfd_private
      hostmem: Support fully shared guest memfd to back a VM
      machine: Rename machine_require_guest_memfd() to *_private()
      memory: Rename memory_region_init_ram_guest_memfd() to *_private()
      tests/migration-test: Support guest-memfd init shared mem type
      tests/migration-test: Add a precopy test for guest-memfd

Xiaoyao Li (1):
      kvm: Decouple memory attribute check from kvm_guest_memfd_supported

 accel/kvm/kvm-all.c                   | 38 ++++++++++++++++++----
 accel/stubs/kvm-stub.c                |  6 ++++
 backends/hostmem-file.c               |  2 +-
 backends/hostmem-memfd.c              | 60 +++++++++++++++++++++++++++++++----
 backends/hostmem-ram.c                |  2 +-
 backends/hostmem-shm.c                |  2 +-
 backends/hostmem.c                    |  2 +-
 backends/igvm.c                       |  4 +--
 hw/core/machine.c                     |  2 +-
 hw/i386/pc.c                          |  6 ++--
 hw/i386/pc_sysfw.c                    |  8 ++---
 hw/i386/x86-common.c                  |  8 ++---
 include/hw/core/boards.h              |  2 +-
 include/system/hostmem.h              |  2 +-
 include/system/kvm.h                  |  1 +
 include/system/memory.h               | 27 ++++++++--------
 include/system/ramblock.h             |  9 ++++--
 qapi/qom.json                         |  6 +++-
 system/memory.c                       | 14 ++++----
 system/physmem.c                      | 51 +++++++++++++++++------------
 target/i386/kvm/kvm.c                 |  3 +-
 tests/qtest/migration/framework.c     | 60 +++++++++++++++++++++++++++++++++++
 tests/qtest/migration/framework.h     |  4 +++
 tests/qtest/migration/precopy-tests.c |  9 ++++++
 24 files changed, 252 insertions(+), 76 deletions(-)



^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:47   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 02/12] kvm: Detect guest-memfd flags supported Michael Roth
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

From: Xiaoyao Li <xiaoyao.li@intel.com>

With the mmap support of guest memfd, KVM allows userspace to create
guest memfd serving as normal non-private memory for X86 DEFAULT VM.
However, KVM doesn't support private memory attribute for X86 DEFAULT
VM.

Make kvm_guest_memfd_supported not rely on KVM_MEMORY_ATTRIBUTE_PRIVATE
and check KVM_MEMORY_ATTRIBUTE_PRIVATE separately when the machine
requires guest_memfd to serve as private memory.

This allows QEMU to create guest memfd with mmap to serve as the memory
backend for X86 DEFAULT VM.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 accel/kvm/kvm-all.c    | 8 ++++++--
 accel/stubs/kvm-stub.c | 5 +++++
 include/system/kvm.h   | 1 +
 system/physmem.c       | 8 ++++++++
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 83cbd120a8..cdc7554082 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1627,6 +1627,11 @@ int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size)
     return kvm_set_memory_attributes(start, size, 0);
 }
 
+bool kvm_private_memory_attribute_supported(void)
+{
+    return !!(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
+}
+
 /* Called with KVMMemoryListener.slots_lock held */
 static void kvm_set_phys_mem(KVMMemoryListener *kml,
                              MemoryRegionSection *section, bool add)
@@ -3058,8 +3063,7 @@ static int kvm_init(AccelState *as, MachineState *ms)
     kvm_supported_memory_attributes = kvm_vm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
     kvm_guest_memfd_supported =
         kvm_vm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
-        kvm_vm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
-        (kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
+        kvm_vm_check_extension(s, KVM_CAP_USER_MEMORY2);
     kvm_pre_fault_memory_supported = kvm_vm_check_extension(s, KVM_CAP_PRE_FAULT_MEMORY);
 
     if (s->kernel_irqchip_split == ON_OFF_AUTO_AUTO) {
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index 32b4b07403..3d34e3b99d 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -143,3 +143,8 @@ int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
 {
     return -ENOSYS;
 }
+
+bool kvm_private_memory_attribute_supported(void)
+{
+    return false;
+}
diff --git a/include/system/kvm.h b/include/system/kvm.h
index 714b8c7b01..d29624034c 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -551,6 +551,7 @@ int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp);
 
 int kvm_set_memory_attributes_private(hwaddr start, uint64_t size);
 int kvm_set_memory_attributes_shared(hwaddr start, uint64_t size);
+bool kvm_private_memory_attribute_supported(void);
 
 int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private);
 
diff --git a/system/physmem.c b/system/physmem.c
index a4a6a4710c..b665cd3c33 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2190,6 +2190,14 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
                        object_get_typename(OBJECT(current_machine->cgs)));
             goto out_free;
         }
+
+        if (!kvm_private_memory_attribute_supported()) {
+            error_setg(errp, "cannot set up private guest memory for %s: "
+                       "KVM does not support private memory attribute",
+                       object_get_typename(OBJECT(current_machine->cgs)));
+            goto out_free;
+        }
+
         assert(new_block->guest_memfd < 0);
 
         ret = ram_block_coordinated_discard_require(true);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 02/12] kvm: Detect guest-memfd flags supported
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
  2026-09-08 13:30 ` [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-08 13:30 ` [PATCH v5 03/12] kvm: Provide explicit error for kvm_create_guest_memfd() Michael Roth
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

From: Peter Xu <peterx@redhat.com>

Detect supported guest-memfd flags by the current kernel, and reject
creations of guest-memfd using invalid flags.  When the cap isn't
available, then no flag is supported.

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 accel/kvm/kvm-all.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index cdc7554082..120cab1e22 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -107,6 +107,7 @@ bool kvm_pre_fault_memory_supported;
 static bool kvm_immediate_exit;
 static uint64_t kvm_supported_memory_attributes;
 static bool kvm_guest_memfd_supported;
+static uint64_t kvm_guest_memfd_flags_supported;
 static hwaddr kvm_max_slot_size = ~0;
 
 static const KVMCapabilityInfo kvm_required_capabilities[] = {
@@ -3065,6 +3066,8 @@ static int kvm_init(AccelState *as, MachineState *ms)
         kvm_vm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
         kvm_vm_check_extension(s, KVM_CAP_USER_MEMORY2);
     kvm_pre_fault_memory_supported = kvm_vm_check_extension(s, KVM_CAP_PRE_FAULT_MEMORY);
+    kvm_guest_memfd_flags_supported =
+        kvm_vm_check_extension(s, KVM_CAP_GUEST_MEMFD_FLAGS);
 
     if (s->kernel_irqchip_split == ON_OFF_AUTO_AUTO) {
         s->kernel_irqchip_split = mc->default_kernel_irqchip_split ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
@@ -4760,6 +4763,13 @@ int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
         return -1;
     }
 
+    if (flags & ~kvm_guest_memfd_flags_supported) {
+        error_setg(errp, "Current KVM instance does not support "
+                   "guest-memfd flag: 0x%"PRIx64,
+                   flags & ~kvm_guest_memfd_flags_supported);
+        return -1;
+    }
+
     fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_GUEST_MEMFD, &guest_memfd);
     if (fd < 0) {
         error_setg_errno(errp, errno, "Error creating KVM guest_memfd");
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 03/12] kvm: Provide explicit error for kvm_create_guest_memfd()
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
  2026-09-08 13:30 ` [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
  2026-09-08 13:30 ` [PATCH v5 02/12] kvm: Detect guest-memfd flags supported Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:48   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 04/12] ramblock: Rename guest_memfd to guest_memfd_private Michael Roth
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

From: Peter Xu <peterx@redhat.com>

So that there will be a verbal string returned when kvm not enabled, or
kvm not compiled.

Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 accel/kvm/kvm-all.c    | 12 ++++++++++++
 accel/stubs/kvm-stub.c |  1 +
 2 files changed, 13 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 120cab1e22..a851b8f628 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -4758,6 +4758,18 @@ int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
         .flags = flags,
     };
 
+    /*
+     * kvm_create_guest_memfd() can be invoked from generic hostmem code
+     * where KVM might be compiled but not necessarily enabled. Because
+     * of this, check for KVM support explictly before continuing with
+     * any KVM-specific checks.
+     *
+     */
+    if (!kvm_enabled()) {
+        error_setg(errp, "guest-memfd requires KVM accelerator");
+        return -1;
+    }
+
     if (!kvm_guest_memfd_supported) {
         error_setg(errp, "KVM does not support guest_memfd");
         return -1;
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index 3d34e3b99d..acbd0785e0 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -141,6 +141,7 @@ bool kvm_hwpoisoned_mem(void)
 
 int kvm_create_guest_memfd(uint64_t size, uint64_t flags, Error **errp)
 {
+    error_setg(errp, "KVM is not enabled");
     return -ENOSYS;
 }
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 04/12] ramblock: Rename guest_memfd to guest_memfd_private
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (2 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 03/12] kvm: Provide explicit error for kvm_create_guest_memfd() Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:49   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE Michael Roth
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

Rename the field to reflect the fact that the guest_memfd in this case only
backs private portion of the ramblock rather than all of it.

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 accel/kvm/kvm-all.c       |  2 +-
 include/system/memory.h   |  7 ++++---
 include/system/ramblock.h |  7 ++++++-
 system/memory.c           |  2 +-
 system/physmem.c          | 33 +++++++++++++++++----------------
 5 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index a851b8f628..6f3f619b8c 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1729,7 +1729,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
         mem->ram_start_offset = ram_start_offset;
         mem->ram = ram;
         mem->flags = kvm_mem_flags(mr);
-        mem->guest_memfd = mr->ram_block->guest_memfd;
+        mem->guest_memfd = mr->ram_block->guest_memfd_private;
         mem->guest_memfd_offset = mem->guest_memfd >= 0 ?
                                   (uint8_t*)ram - mr->ram_block->host : 0;
 
diff --git a/include/system/memory.h b/include/system/memory.h
index a7e03fc3e7..aef555af80 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -1507,10 +1507,11 @@ bool memory_region_skip_iommu_map(const MemoryRegion *mr);
 void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip);
 
 /**
- * memory_region_has_guest_memfd: check whether a memory region has guest_memfd
- *     associated
+ * memory_region_has_guest_memfd: check whether a memory region has
+ *     guest_memfd_private associated
  *
- * Returns %true if a memory region's ram_block has valid guest_memfd assigned.
+ * Returns %true if a memory region's ram_block has valid guest_memfd_private
+ * assigned.
  *
  * @mr: the memory region being queried
  */
diff --git a/include/system/ramblock.h b/include/system/ramblock.h
index 84624aca2c..0388d6cc6b 100644
--- a/include/system/ramblock.h
+++ b/include/system/ramblock.h
@@ -40,7 +40,12 @@ struct RAMBlock {
     Error *cpr_blocker;
     int fd;
     uint64_t fd_offset;
-    int guest_memfd;
+    /*
+     * When RAM_GUEST_MEMFD_PRIVATE flag is set, this ramblock can have
+     * private pages backed by guest_memfd_private specified, while shared
+     * pages are backed by the ramblock on its own.
+     */
+    int guest_memfd_private;
     RamBlockAttributes *attributes;
     size_t page_size;
     /* dirty bitmap used during migration */
diff --git a/system/memory.c b/system/memory.c
index 9760721e45..bd9e22ab7e 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1805,7 +1805,7 @@ void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip)
 
 bool memory_region_has_guest_memfd(const MemoryRegion *mr)
 {
-    return mr->ram_block && mr->ram_block->guest_memfd >= 0;
+    return mr->ram_block && mr->ram_block->guest_memfd_private >= 0;
 }
 
 uint8_t memory_region_get_dirty_log_mask(const MemoryRegion *mr)
diff --git a/system/physmem.c b/system/physmem.c
index b665cd3c33..305a3febca 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2198,7 +2198,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
             goto out_free;
         }
 
-        assert(new_block->guest_memfd < 0);
+        assert(new_block->guest_memfd_private < 0);
 
         ret = ram_block_coordinated_discard_require(true);
         if (ret < 0) {
@@ -2208,9 +2208,9 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
             goto out_free;
         }
 
-        new_block->guest_memfd = kvm_create_guest_memfd(new_block->max_length,
-                                                        0, errp);
-        if (new_block->guest_memfd < 0) {
+        new_block->guest_memfd_private =
+            kvm_create_guest_memfd(new_block->max_length, 0, errp);
+        if (new_block->guest_memfd_private < 0) {
             qemu_mutex_unlock_ramlist();
             goto out_free;
         }
@@ -2227,7 +2227,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
         new_block->attributes = ram_block_attributes_create(new_block);
         if (!new_block->attributes) {
             error_setg(errp, "Failed to create ram block attribute");
-            close(new_block->guest_memfd);
+            close(new_block->guest_memfd_private);
             ram_block_coordinated_discard_require(false);
             qemu_mutex_unlock_ramlist();
             goto out_free;
@@ -2363,7 +2363,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, ram_addr_t max_size,
     new_block->max_length = max_size;
     new_block->resized = resized;
     new_block->flags = ram_flags;
-    new_block->guest_memfd = -1;
+    new_block->guest_memfd_private = -1;
     new_block->host = file_ram_alloc(new_block, max_size, fd,
                                      file_size < offset + max_size,
                                      offset, errp);
@@ -2536,7 +2536,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
     new_block->used_length = size;
     new_block->max_length = max_size;
     new_block->fd = -1;
-    new_block->guest_memfd = -1;
+    new_block->guest_memfd_private = -1;
     new_block->page_size = qemu_real_host_page_size();
     new_block->host = host;
     new_block->flags = ram_flags;
@@ -2587,8 +2587,8 @@ static void reclaim_ramblock(RAMBlock *block)
         qemu_anon_ram_free(block->host, block->max_length);
     }
 
-    if (block->guest_memfd >= 0) {
-        close(block->guest_memfd);
+    if (block->guest_memfd_private >= 0) {
+        close(block->guest_memfd_private);
         ram_block_coordinated_discard_require(false);
     }
 
@@ -2836,12 +2836,12 @@ int ram_block_rebind(Error **errp)
 
     RAMBLOCK_FOREACH(block) {
         if (block->flags & RAM_GUEST_MEMFD) {
-            if (block->guest_memfd >= 0) {
-                close(block->guest_memfd);
+            if (block->guest_memfd_private >= 0) {
+                close(block->guest_memfd_private);
             }
-            block->guest_memfd = kvm_create_guest_memfd(block->max_length,
-                                                        0, errp);
-            if (block->guest_memfd < 0) {
+            block->guest_memfd_private = kvm_create_guest_memfd(
+                block->max_length, 0, errp);
+            if (block->guest_memfd_private < 0) {
                 qemu_mutex_unlock_ramlist();
                 return -1;
             }
@@ -4269,7 +4269,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t offset, size_t length)
         return ret;
     }
 
-    if (rb->guest_memfd >= 0) {
+    if (rb->guest_memfd_private >= 0) {
         ret = ram_block_discard_guest_memfd_range(rb, offset, length);
     }
 
@@ -4283,7 +4283,8 @@ int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t offset,
 
 #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
     /* ignore fd_offset with guest_memfd */
-    ret = fallocate(rb->guest_memfd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+    ret = fallocate(rb->guest_memfd_private,
+                    FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
                     offset, length);
 
     if (ret) {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (3 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 04/12] ramblock: Rename guest_memfd to guest_memfd_private Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:50   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 06/12] memory: Rename memory_region_has_guest_memfd() to *_private() Michael Roth
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

This name is too generic, and can conflict with support for using
guest-memfd for shared memory. Add a _PRIVATE suffix to show what it
really means: it is using guest_memfd specifically for private memory;
whether or not guest_memfd is being used for shared memory is something
to be configured/determined separately.

This also paves way for in-place guest-memfd, which means we can have a
ramblock that allocates pages completely from guest-memfd (private or
shared).

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 backends/hostmem-file.c   |  2 +-
 backends/hostmem-memfd.c  |  2 +-
 backends/hostmem-ram.c    |  2 +-
 backends/hostmem-shm.c    |  2 +-
 include/system/memory.h   |  8 ++++----
 include/system/ramblock.h |  2 +-
 system/memory.c           |  2 +-
 system/physmem.c          | 10 +++++-----
 8 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 8e3219c061..1f20cd8fd6 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -86,7 +86,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
     ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
+    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
     ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
     ram_flags |= RAM_NAMED_FILE;
     return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 923239f9cf..3f3e485709 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -60,7 +60,7 @@ have_fd:
     backend->aligned = true;
     ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
+    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
     return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
                                           backend->size, ram_flags, fd, 0, errp);
 }
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index 062b1abb11..96ad29112d 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -30,7 +30,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     name = host_memory_backend_get_name(backend);
     ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
+    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
     return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend),
                                                   name, backend->size,
                                                   ram_flags, errp);
diff --git a/backends/hostmem-shm.c b/backends/hostmem-shm.c
index 806e2670e0..e86fb2e0aa 100644
--- a/backends/hostmem-shm.c
+++ b/backends/hostmem-shm.c
@@ -54,7 +54,7 @@ have_fd:
     /* Let's do the same as memory-backend-ram,share=on would do. */
     ram_flags = RAM_SHARED;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
+    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
 
     return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
                                               backend_name, backend->size,
diff --git a/include/system/memory.h b/include/system/memory.h
index aef555af80..932072c631 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -262,7 +262,7 @@ typedef struct IOMMUTLBEvent {
 #define RAM_READONLY_FD (1 << 11)
 
 /* RAM can be private that has kvm guest memfd backend */
-#define RAM_GUEST_MEMFD   (1 << 12)
+#define RAM_GUEST_MEMFD_PRIVATE   (1 << 12)
 
 /*
  * In RAMBlock creation functions, if MAP_SHARED is 0 in the flags parameter,
@@ -1119,7 +1119,7 @@ void memory_region_init_io(MemoryRegion *mr,
  *        must be unique within any device
  * @size: size of the region.
  * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE,
- *             RAM_GUEST_MEMFD.
+ *             RAM_GUEST_MEMFD_PRIVATE.
  * @errp: pointer to Error*, to store an error if it happens.
  *
  * Note that this function does not do anything to cause the data in the
@@ -1181,7 +1181,7 @@ bool memory_region_init_resizeable_ram(MemoryRegion *mr,
  *         (getpagesize()) will be used.
  * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
  *             RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
- *             RAM_READONLY_FD, RAM_GUEST_MEMFD
+ *             RAM_READONLY_FD, RAM_GUEST_MEMFD_PRIVATE
  * @path: the path in which to allocate the RAM.
  * @offset: offset within the file referenced by path
  * @errp: pointer to Error*, to store an error if it happens.
@@ -1212,7 +1212,7 @@ bool memory_region_init_ram_from_file(MemoryRegion *mr,
  * @size: size of the region.
  * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
  *             RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
- *             RAM_READONLY_FD, RAM_GUEST_MEMFD
+ *             RAM_READONLY_FD, RAM_GUEST_MEMFD_PRIVATE
  * @fd: the fd to mmap.
  * @offset: offset within the file referenced by fd
  * @errp: pointer to Error*, to store an error if it happens.
diff --git a/include/system/ramblock.h b/include/system/ramblock.h
index 0388d6cc6b..1352ec1603 100644
--- a/include/system/ramblock.h
+++ b/include/system/ramblock.h
@@ -257,7 +257,7 @@ static inline unsigned long int ramblock_recv_bitmap_offset(void *host_addr,
  *  @resized: callback after calls to qemu_ram_resize
  *  @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
  *              RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
- *              RAM_READONLY_FD, RAM_GUEST_MEMFD
+ *              RAM_READONLY_FD, RAM_GUEST_MEMFD_PRIVATE
  *  @mem_path or @fd: specify the backing file or device
  *  @offset: Offset into target file
  *  @grow: extend file if necessary (but an empty file is always extended).
diff --git a/system/memory.c b/system/memory.c
index bd9e22ab7e..e2f0bd6928 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -3622,7 +3622,7 @@ bool memory_region_init_ram_guest_memfd(MemoryRegion *mr, Object *owner,
                                         Error **errp)
 {
     if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, size,
-                                                RAM_GUEST_MEMFD, errp)) {
+                                                RAM_GUEST_MEMFD_PRIVATE, errp)) {
         return false;
     }
     memory_region_register_ram(mr, owner);
diff --git a/system/physmem.c b/system/physmem.c
index 305a3febca..f6dff18bbb 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2182,7 +2182,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
         }
     }
 
-    if (new_block->flags & RAM_GUEST_MEMFD) {
+    if (new_block->flags & RAM_GUEST_MEMFD_PRIVATE) {
         int ret;
 
         if (!kvm_enabled()) {
@@ -2319,7 +2319,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, ram_addr_t max_size,
     /* Just support these ram flags by now. */
     assert((ram_flags & ~(RAM_SHARED | RAM_PMEM | RAM_NORESERVE |
                           RAM_PROTECTED | RAM_NAMED_FILE | RAM_READONLY |
-                          RAM_READONLY_FD | RAM_GUEST_MEMFD |
+                          RAM_READONLY_FD | RAM_GUEST_MEMFD_PRIVATE |
                           RAM_RESIZEABLE)) == 0);
     assert(max_size >= size);
 
@@ -2476,7 +2476,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
     ram_flags &= ~RAM_PRIVATE;
 
     assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC |
-                          RAM_NORESERVE | RAM_GUEST_MEMFD)) == 0);
+                          RAM_NORESERVE | RAM_GUEST_MEMFD_PRIVATE)) == 0);
     assert(!host ^ (ram_flags & RAM_PREALLOC));
     assert(max_size >= size);
 
@@ -2559,7 +2559,7 @@ RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
 RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags,
                          MemoryRegion *mr, Error **errp)
 {
-    assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE | RAM_GUEST_MEMFD |
+    assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE | RAM_GUEST_MEMFD_PRIVATE |
                           RAM_PRIVATE)) == 0);
     return qemu_ram_alloc_internal(size, size, NULL, NULL, ram_flags, mr, errp);
 }
@@ -2835,7 +2835,7 @@ int ram_block_rebind(Error **errp)
     qemu_mutex_lock_ramlist();
 
     RAMBLOCK_FOREACH(block) {
-        if (block->flags & RAM_GUEST_MEMFD) {
+        if (block->flags & RAM_GUEST_MEMFD_PRIVATE) {
             if (block->guest_memfd_private >= 0) {
                 close(block->guest_memfd_private);
             }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 06/12] memory: Rename memory_region_has_guest_memfd() to *_private()
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (4 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:50   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 07/12] hostmem: Rename guest_memfd to guest_memfd_private Michael Roth
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

Rename the function with "_private" suffix, to show that it returns true
only if it has an internal guest-memfd to back private pages (rather than
fully shared guest-memfd).

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 accel/kvm/kvm-all.c     | 6 +++---
 include/system/memory.h | 4 ++--
 system/memory.c         | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 6f3f619b8c..70605a8d10 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -792,7 +792,7 @@ static int kvm_mem_flags(MemoryRegion *mr)
     if (readonly && kvm_readonly_mem_allowed) {
         flags |= KVM_MEM_READONLY;
     }
-    if (memory_region_has_guest_memfd(mr)) {
+    if (memory_region_has_guest_memfd_private(mr)) {
         assert(kvm_guest_memfd_supported);
         flags |= KVM_MEM_GUEST_MEMFD;
     }
@@ -1741,7 +1741,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
             abort();
         }
 
-        if (memory_region_has_guest_memfd(mr)) {
+        if (memory_region_has_guest_memfd_private(mr)) {
             err = kvm_set_memory_attributes_private(start_addr, slot_size);
             if (err) {
                 error_report("%s: failed to set memory attribute private: %s",
@@ -3372,7 +3372,7 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
         return ret;
     }
 
-    if (!memory_region_has_guest_memfd(mr)) {
+    if (!memory_region_has_guest_memfd_private(mr)) {
         /*
          * Because vMMIO region must be shared, guest TD may convert vMMIO
          * region to shared explicitly.  Don't complain such case.  See
diff --git a/include/system/memory.h b/include/system/memory.h
index 932072c631..96ab920e7d 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -1507,7 +1507,7 @@ bool memory_region_skip_iommu_map(const MemoryRegion *mr);
 void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip);
 
 /**
- * memory_region_has_guest_memfd: check whether a memory region has
+ * memory_region_has_guest_memfd_private: check whether a memory region has
  *     guest_memfd_private associated
  *
  * Returns %true if a memory region's ram_block has valid guest_memfd_private
@@ -1515,7 +1515,7 @@ void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip);
  *
  * @mr: the memory region being queried
  */
-bool memory_region_has_guest_memfd(const MemoryRegion *mr);
+bool memory_region_has_guest_memfd_private(const MemoryRegion *mr);
 
 /**
  * memory_region_get_iommu: check whether a memory region is an iommu
diff --git a/system/memory.c b/system/memory.c
index e2f0bd6928..b520cca1a0 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1803,7 +1803,7 @@ void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip)
     mr->ram_device_skip_iommu_map = skip;
 }
 
-bool memory_region_has_guest_memfd(const MemoryRegion *mr)
+bool memory_region_has_guest_memfd_private(const MemoryRegion *mr)
 {
     return mr->ram_block && mr->ram_block->guest_memfd_private >= 0;
 }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 07/12] hostmem: Rename guest_memfd to guest_memfd_private
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (5 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 06/12] memory: Rename memory_region_has_guest_memfd() to *_private() Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:51   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

Rename the HostMemoryBackend.guest_memfd field to reflect what it really
means: whether it needs guest_memfd to back its private guest memory.
This will help avoid conflicts when we introduce supported for using
guest_memfd for shared guest memory via hostmem.

Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 backends/hostmem-file.c  | 2 +-
 backends/hostmem-memfd.c | 2 +-
 backends/hostmem-ram.c   | 2 +-
 backends/hostmem-shm.c   | 2 +-
 backends/hostmem.c       | 2 +-
 include/system/hostmem.h | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 1f20cd8fd6..0e4cfd6dc6 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -86,7 +86,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
     ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
+    ram_flags |= backend->guest_memfd_private ? RAM_GUEST_MEMFD_PRIVATE : 0;
     ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
     ram_flags |= RAM_NAMED_FILE;
     return memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 3f3e485709..ea93f034e4 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -60,7 +60,7 @@ have_fd:
     backend->aligned = true;
     ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
+    ram_flags |= backend->guest_memfd_private ? RAM_GUEST_MEMFD_PRIVATE : 0;
     return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
                                           backend->size, ram_flags, fd, 0, errp);
 }
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index 96ad29112d..6a507fad77 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -30,7 +30,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     name = host_memory_backend_get_name(backend);
     ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
+    ram_flags |= backend->guest_memfd_private ? RAM_GUEST_MEMFD_PRIVATE : 0;
     return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend),
                                                   name, backend->size,
                                                   ram_flags, errp);
diff --git a/backends/hostmem-shm.c b/backends/hostmem-shm.c
index e86fb2e0aa..4766db6aad 100644
--- a/backends/hostmem-shm.c
+++ b/backends/hostmem-shm.c
@@ -54,7 +54,7 @@ have_fd:
     /* Let's do the same as memory-backend-ram,share=on would do. */
     ram_flags = RAM_SHARED;
     ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
-    ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD_PRIVATE : 0;
+    ram_flags |= backend->guest_memfd_private ? RAM_GUEST_MEMFD_PRIVATE : 0;
 
     return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
                                               backend_name, backend->size,
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 5dd5fb155c..d54d9091c3 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -290,7 +290,7 @@ static void host_memory_backend_init(Object *obj)
     /* TODO: convert access to globals to compat properties */
     backend->merge = machine_mem_merge(machine);
     backend->dump = machine_dump_guest_core(machine);
-    backend->guest_memfd = machine_require_guest_memfd(machine);
+    backend->guest_memfd_private = machine_require_guest_memfd(machine);
     backend->reserve = true;
     backend->prealloc_threads = machine->smp.cpus;
 }
diff --git a/include/system/hostmem.h b/include/system/hostmem.h
index 88fa791ac7..dcbf81aeae 100644
--- a/include/system/hostmem.h
+++ b/include/system/hostmem.h
@@ -76,7 +76,7 @@ struct HostMemoryBackend {
     uint64_t size;
     bool merge, dump, use_canonical_path;
     bool prealloc, is_mapped, share, reserve;
-    bool guest_memfd, aligned;
+    bool guest_memfd_private, aligned;
     uint32_t prealloc_threads;
     ThreadContext *prealloc_context;
     DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (6 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 07/12] hostmem: Rename guest_memfd to guest_memfd_private Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-08 14:03   ` Markus Armbruster
  2026-09-10  8:54   ` David Hildenbrand
  2026-09-08 13:30 ` [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private() Michael Roth
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

From: Peter Xu <peterx@redhat.com>

Host backends supports guest-memfd now by detecting whether it's a
confidential VM.  There's no way to choose it yet from the memory level to
use it fully shared.  If we use guest-memfd, it so far always implies we
need two layers of memory backends, while the guest-memfd only provides the
private set of pages.

This patch introduces a way so that QEMU can consume guest memfd as the
only source of memory to back the object (aka, fully shared).

To use the fully shared guest-memfd, one can add a memfd object with:

  -object memory-backend-memfd,guest-memfd=on,share=on

Note that share=on is required with fully shared guest_memfd.

PS: there's a trivial touch-up on fd<0 check, because the stub to create
guest-memfd may return negative but not -1.

Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 backends/hostmem-memfd.c | 58 ++++++++++++++++++++++++++++++++++++----
 qapi/qom.json            |  6 ++++-
 2 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index ea93f034e4..6576331441 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -18,6 +18,8 @@
 #include "qapi/error.h"
 #include "qom/object.h"
 #include "migration/cpr.h"
+#include "system/kvm.h"
+#include <linux/kvm.h>
 
 OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendMemfd, MEMORY_BACKEND_MEMFD)
 
@@ -28,6 +30,13 @@ struct HostMemoryBackendMemfd {
     bool hugetlb;
     uint64_t hugetlbsize;
     bool seal;
+    /*
+     * NOTE: this differs from HostMemoryBackend's guest_memfd_private,
+     * which represents an internally private guest-memfd that only backs
+     * private pages.  Instead, this flag marks the memory backend will
+     * 100% use the guest-memfd pages in-place.
+     */
+    bool guest_memfd;
 };
 
 static bool
@@ -47,11 +56,31 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
         goto have_fd;
     }
 
-    fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
-                           m->hugetlb, m->hugetlbsize, m->seal ?
-                           F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
-                           errp);
-    if (fd == -1) {
+    if (m->guest_memfd) {
+        /*
+         * NOTE: guest-memfd ignores seal=on/off because it always
+         * implicitly seals the FD by definition.
+         */
+        if (!backend->share) {
+            error_setg(errp, "guest-memfd=on must be used with share=on");
+            return false;
+        } else if (m->hugetlb) {
+            error_setg(errp, "guest-memfd=on doesn't support hugetlb=on yet");
+            return false;
+        }
+
+        fd = kvm_create_guest_memfd(backend->size,
+                                    GUEST_MEMFD_FLAG_MMAP |
+                                    GUEST_MEMFD_FLAG_INIT_SHARED,
+                                    errp);
+    } else {
+        fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
+                               m->hugetlb, m->hugetlbsize, m->seal ?
+                               F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
+                               errp);
+    }
+
+    if (fd < 0) {
         return false;
     }
     cpr_save_fd(name, 0, fd);
@@ -65,6 +94,18 @@ have_fd:
                                           backend->size, ram_flags, fd, 0, errp);
 }
 
+static bool
+memfd_backend_get_guest_memfd(Object *o, Error **errp)
+{
+    return MEMORY_BACKEND_MEMFD(o)->guest_memfd;
+}
+
+static void
+memfd_backend_set_guest_memfd(Object *o, bool value, Error **errp)
+{
+    MEMORY_BACKEND_MEMFD(o)->guest_memfd = value;
+}
+
 static bool
 memfd_backend_get_hugetlb(Object *o, Error **errp)
 {
@@ -152,6 +193,13 @@ memfd_backend_class_init(ObjectClass *oc, const void *data)
         object_class_property_set_description(oc, "hugetlbsize",
                                               "Huge pages size (ex: 2M, 1G)");
     }
+
+    object_class_property_add_bool(oc, "guest-memfd",
+                                   memfd_backend_get_guest_memfd,
+                                   memfd_backend_set_guest_memfd);
+    object_class_property_set_description(oc, "guest-memfd",
+                                          "Use guest memfd");
+
     object_class_property_add_bool(oc, "seal",
                                    memfd_backend_get_seal,
                                    memfd_backend_set_seal);
diff --git a/qapi/qom.json b/qapi/qom.json
index 4a9b7f9088..909add4299 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -771,13 +771,17 @@
 # @seal: if true, create a sealed-file, which will block further
 #     resizing of the memory (default: true)
 #
+# @guest-memfd: if true, use guest-memfd to back the memory region.
+#     (default: false, since: 11.2)
+#
 # Since: 2.12
 ##
 { 'struct': 'MemoryBackendMemfdProperties',
   'base': 'MemoryBackendProperties',
   'data': { '*hugetlb': 'bool',
             '*hugetlbsize': 'size',
-            '*seal': 'bool' },
+            '*seal': 'bool',
+            '*guest-memfd': 'bool' },
   'if': 'CONFIG_LINUX' }
 
 ##
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private()
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (7 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
@ 2026-09-08 13:30 ` Michael Roth
  2026-09-10  8:55   ` David Hildenbrand
  2026-09-08 13:31 ` [PATCH v5 10/12] memory: Rename memory_region_init_ram_guest_memfd() " Michael Roth
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:30 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

Differenciate it from fully shared guest-memfd use cases.

When at it, add proper brackets in kvm_handle_hc_map_gpa_range() otherwise
checkpatch may complain.

Suggested-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 backends/hostmem.c       | 2 +-
 hw/core/machine.c        | 2 +-
 hw/i386/pc.c             | 2 +-
 hw/i386/pc_sysfw.c       | 4 ++--
 hw/i386/x86-common.c     | 4 ++--
 include/hw/core/boards.h | 2 +-
 target/i386/kvm/kvm.c    | 3 ++-
 7 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index d54d9091c3..0cc5adcd38 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -290,7 +290,7 @@ static void host_memory_backend_init(Object *obj)
     /* TODO: convert access to globals to compat properties */
     backend->merge = machine_mem_merge(machine);
     backend->dump = machine_dump_guest_core(machine);
-    backend->guest_memfd_private = machine_require_guest_memfd(machine);
+    backend->guest_memfd_private = machine_require_guest_memfd_private(machine);
     backend->reserve = true;
     backend->prealloc_threads = machine->smp.cpus;
 }
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 8939ae1666..469033d6b3 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1337,7 +1337,7 @@ bool machine_mem_merge(MachineState *machine)
     return machine->mem_merge;
 }
 
-bool machine_require_guest_memfd(MachineState *machine)
+bool machine_require_guest_memfd_private(MachineState *machine)
 {
     return machine->cgs && machine->cgs->require_guest_memfd;
 }
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e9e4fc262b..9c2d77e494 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -873,7 +873,7 @@ void pc_memory_init(PCMachineState *pcms,
 
     if (!is_tdx_vm()) {
         option_rom_mr = g_malloc(sizeof(*option_rom_mr));
-        if (machine_require_guest_memfd(machine)) {
+        if (machine_require_guest_memfd_private(machine)) {
             memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom",
                                             PC_ROM_SIZE, &error_fatal);
         } else {
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 1a41a5972b..4a7694c131 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -51,7 +51,7 @@ static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios,
 
     /* map the last 128KB of the BIOS in ISA space */
     isa_bios_size = MIN(flash_size, 128 * KiB);
-    if (machine_require_guest_memfd(MACHINE(pcms))) {
+    if (machine_require_guest_memfd_private(MACHINE(pcms))) {
         memory_region_init_ram_guest_memfd(isa_bios, NULL, "isa-bios",
                                            isa_bios_size, &error_fatal);
     } else {
@@ -70,7 +70,7 @@ static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios,
            ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
            isa_bios_size);
 
-    if (!machine_require_guest_memfd(current_machine)) {
+    if (!machine_require_guest_memfd_private(current_machine)) {
         memory_region_set_readonly(isa_bios, true);
     }
 }
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 8f9419e7d3..dd526c561c 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -1036,7 +1036,7 @@ static void load_bios_from_file(X86MachineState *x86ms, const char *bios_name,
     ssize_t ret;
 
     /* BIOS load */
-    if (machine_require_guest_memfd(MACHINE(x86ms))) {
+    if (machine_require_guest_memfd_private(MACHINE(x86ms))) {
         memory_region_init_ram_guest_memfd(&x86ms->bios, NULL, "pc.bios",
                                            bios_size, &error_fatal);
         if (is_tdx_vm()) {
@@ -1106,7 +1106,7 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
     bios_size = get_bios_size(x86ms, bios_name, filename);
     load_bios_from_file(x86ms, bios_name, filename, bios_size, isapc_ram_fw);
 
-    if (!machine_require_guest_memfd(MACHINE(x86ms))) {
+    if (!machine_require_guest_memfd_private(MACHINE(x86ms))) {
         /* map the last 128KB of the BIOS in ISA space */
         x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios,
                           !isapc_ram_fw);
diff --git a/include/hw/core/boards.h b/include/hw/core/boards.h
index a436d48c8e..7925f0451a 100644
--- a/include/hw/core/boards.h
+++ b/include/hw/core/boards.h
@@ -43,7 +43,7 @@ bool machine_usb(MachineState *machine);
 int machine_phandle_start(MachineState *machine);
 bool machine_dump_guest_core(MachineState *machine);
 bool machine_mem_merge(MachineState *machine);
-bool machine_require_guest_memfd(MachineState *machine);
+bool machine_require_guest_memfd_private(MachineState *machine);
 HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
 void machine_set_cpu_numa_node(MachineState *machine,
                                const CpuInstanceProperties *props,
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 1eeadb99ad..a72b6e6b74 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -6488,8 +6488,9 @@ static int kvm_handle_hc_map_gpa_range(X86CPU *cpu, struct kvm_run *run)
     uint64_t gpa, size, attributes;
     int ret;
 
-    if (!machine_require_guest_memfd(current_machine))
+    if (!machine_require_guest_memfd_private(current_machine)) {
         return -EINVAL;
+    }
 
     gpa = run->hypercall.args[0];
     size = run->hypercall.args[1] * TARGET_PAGE_SIZE;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 10/12] memory: Rename memory_region_init_ram_guest_memfd() to *_private()
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (8 preceding siblings ...)
  2026-09-08 13:30 ` [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private() Michael Roth
@ 2026-09-08 13:31 ` Michael Roth
  2026-09-10  8:56   ` David Hildenbrand
  2026-09-08 13:31 ` [PATCH v5 11/12] tests/migration-test: Support guest-memfd init shared mem type Michael Roth
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

Differenciate it from fully shared guest-memfd use cases.

Suggested-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 backends/igvm.c         |  4 ++--
 hw/i386/pc.c            |  4 ++--
 hw/i386/pc_sysfw.c      |  4 ++--
 hw/i386/x86-common.c    |  4 ++--
 include/system/memory.h | 10 +++++-----
 system/memory.c         |  8 +++++---
 6 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/backends/igvm.c b/backends/igvm.c
index 7b7bdc72b7..228d332f42 100644
--- a/backends/igvm.c
+++ b/backends/igvm.c
@@ -259,8 +259,8 @@ static void *qigvm_prepare_memory(QIgvm *ctx, uint64_t addr, uint64_t size,
         imr->mr = g_new0(MemoryRegion, 1);
         if (ctx->machine_state->cgs &&
             ctx->machine_state->cgs->require_guest_memfd) {
-            if (!memory_region_init_ram_guest_memfd(imr->mr, NULL,
-                                                    region_name, size, errp)) {
+            if (!memory_region_init_ram_guest_memfd_private(
+                    imr->mr, NULL, region_name, size, errp)) {
                 g_free(imr->mr);
                 g_free(imr);
                 return NULL;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 9c2d77e494..1e5b23d7aa 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -874,8 +874,8 @@ void pc_memory_init(PCMachineState *pcms,
     if (!is_tdx_vm()) {
         option_rom_mr = g_malloc(sizeof(*option_rom_mr));
         if (machine_require_guest_memfd_private(machine)) {
-            memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom",
-                                            PC_ROM_SIZE, &error_fatal);
+            memory_region_init_ram_guest_memfd_private(
+                option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, &error_fatal);
         } else {
             memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
                                 &error_fatal);
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 4a7694c131..3e0b9e1d28 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -52,8 +52,8 @@ static void pc_isa_bios_init(PCMachineState *pcms, MemoryRegion *isa_bios,
     /* map the last 128KB of the BIOS in ISA space */
     isa_bios_size = MIN(flash_size, 128 * KiB);
     if (machine_require_guest_memfd_private(MACHINE(pcms))) {
-        memory_region_init_ram_guest_memfd(isa_bios, NULL, "isa-bios",
-                                           isa_bios_size, &error_fatal);
+        memory_region_init_ram_guest_memfd_private(
+            isa_bios, NULL, "isa-bios", isa_bios_size, &error_fatal);
     } else {
         memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
                                &error_fatal);
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index dd526c561c..ffe9cc90b6 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -1037,8 +1037,8 @@ static void load_bios_from_file(X86MachineState *x86ms, const char *bios_name,
 
     /* BIOS load */
     if (machine_require_guest_memfd_private(MACHINE(x86ms))) {
-        memory_region_init_ram_guest_memfd(&x86ms->bios, NULL, "pc.bios",
-                                           bios_size, &error_fatal);
+        memory_region_init_ram_guest_memfd_private(
+            &x86ms->bios, NULL, "pc.bios", bios_size, &error_fatal);
         if (is_tdx_vm()) {
             tdx_set_tdvf_region(&x86ms->bios);
         }
diff --git a/include/system/memory.h b/include/system/memory.h
index 96ab920e7d..027ca81bd2 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -1358,11 +1358,11 @@ bool memory_region_init_ram(MemoryRegion *mr,
                             uint64_t size,
                             Error **errp);
 
-bool memory_region_init_ram_guest_memfd(MemoryRegion *mr,
-                                        Object *owner,
-                                        const char *name,
-                                        uint64_t size,
-                                        Error **errp);
+bool memory_region_init_ram_guest_memfd_private(MemoryRegion *mr,
+                                                Object *owner,
+                                                const char *name,
+                                                uint64_t size,
+                                                Error **errp);
 
 /**
  * memory_region_init_rom: Initialize a ROM memory region.
diff --git a/system/memory.c b/system/memory.c
index b520cca1a0..b3b678617b 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -3617,9 +3617,11 @@ bool memory_region_init_ram(MemoryRegion *mr, Object *owner,
     return true;
 }
 
-bool memory_region_init_ram_guest_memfd(MemoryRegion *mr, Object *owner,
-                                        const char *name, uint64_t size,
-                                        Error **errp)
+bool memory_region_init_ram_guest_memfd_private(MemoryRegion *mr,
+                                                Object *owner,
+                                                const char *name,
+                                                uint64_t size,
+                                                Error **errp)
 {
     if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, size,
                                                 RAM_GUEST_MEMFD_PRIVATE, errp)) {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 11/12] tests/migration-test: Support guest-memfd init shared mem type
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (9 preceding siblings ...)
  2026-09-08 13:31 ` [PATCH v5 10/12] memory: Rename memory_region_init_ram_guest_memfd() " Michael Roth
@ 2026-09-08 13:31 ` Michael Roth
  2026-09-08 13:31 ` [PATCH v5 12/12] tests/migration-test: Add a precopy test for guest-memfd Michael Roth
  2026-09-10  8:45 ` [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends David Hildenbrand
  12 siblings, 0 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu

From: Peter Xu <peterx@redhat.com>

Support the guest-memfd type when the fd has init share enabled.  It means
the gmemfd can be used similarly to memfd.

Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 tests/qtest/migration/framework.c | 60 +++++++++++++++++++++++++++++++
 tests/qtest/migration/framework.h |  4 +++
 2 files changed, 64 insertions(+)

diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index a830b96f41..b7aef6b21c 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -26,6 +26,10 @@
 #include "qemu/range.h"
 #include "qemu/sockets.h"
 
+#ifdef CONFIG_LINUX
+#include <linux/kvm.h>
+#include <sys/ioctl.h>
+#endif
 
 #define QEMU_VM_FILE_MAGIC 0x5145564d
 #define QEMU_ENV_SRC "QTEST_QEMU_BINARY_SRC"
@@ -296,6 +300,9 @@ static char *migrate_mem_type_get_opts(MemType type, const char *memory_size)
     case MEM_TYPE_MEMFD:
         backend = g_strdup("-object memory-backend-memfd");
         break;
+    case MEM_TYPE_GUEST_MEMFD:
+        backend = g_strdup("-object memory-backend-memfd,guest-memfd=on");
+        break;
     default:
         g_assert_not_reached();
         break;
@@ -444,8 +451,55 @@ int migrate_args(char **from, char **to, MigrateStart *args)
     return 0;
 }
 
+static bool kvm_guest_memfd_init_shared_supported(const char **reason)
+{
+    assert(*reason == NULL);
+
+#ifdef CONFIG_LINUX
+    int ret, fd = -1;
+
+    if (!migration_get_env()->has_kvm) {
+        *reason = "KVM is not enabled in the current QEMU build";
+        goto out;
+    }
+
+    fd = open("/dev/kvm", O_RDWR);
+    if (fd < 0) {
+        *reason = "KVM module isn't available or missing permission";
+        goto out;
+    }
+
+    ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_GUEST_MEMFD);
+    if (!ret) {
+        *reason = "KVM module doesn't support guest-memfd";
+        goto out;
+    }
+
+    ret = ioctl(fd, KVM_CHECK_EXTENSION, KVM_CAP_GUEST_MEMFD_FLAGS);
+    if (ret < 0) {
+        *reason = "KVM doesn't support KVM_CAP_GUEST_MEMFD_FLAGS";
+        goto out;
+    }
+
+    if (!(ret & GUEST_MEMFD_FLAG_INIT_SHARED)) {
+        *reason = "KVM doesn't support GUEST_MEMFD_FLAG_INIT_SHARED";
+        goto out;
+    }
+out:
+    if (fd >= 0) {
+        close(fd);
+    }
+#else
+    *reason = "KVM not supported on non-Linux OS";
+#endif
+
+    return !*reason;
+}
+
 static bool migrate_mem_type_prepare(MemType type)
 {
+    const char *reason = NULL;
+
     switch (type) {
     case MEM_TYPE_SHMEM:
         if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
@@ -453,6 +507,12 @@ static bool migrate_mem_type_prepare(MemType type)
             return false;
         }
         break;
+    case MEM_TYPE_GUEST_MEMFD:
+        if (!kvm_guest_memfd_init_shared_supported(&reason)) {
+            g_test_skip(reason);
+            return false;
+        }
+        break;
     default:
         break;
     }
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
index 941cbd7102..10761f6e28 100644
--- a/tests/qtest/migration/framework.h
+++ b/tests/qtest/migration/framework.h
@@ -34,6 +34,10 @@ typedef enum {
      * but only anonymously allocated.
      */
     MEM_TYPE_MEMFD,
+    /*
+     * Use guest-memfd, shared mappings.
+     */
+    MEM_TYPE_GUEST_MEMFD,
     MEM_TYPE_NUM,
 } MemType;
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH v5 12/12] tests/migration-test: Add a precopy test for guest-memfd
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (10 preceding siblings ...)
  2026-09-08 13:31 ` [PATCH v5 11/12] tests/migration-test: Support guest-memfd init shared mem type Michael Roth
@ 2026-09-08 13:31 ` Michael Roth
  2026-09-10  8:45 ` [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends David Hildenbrand
  12 siblings, 0 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-08 13:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

From: Peter Xu <peterx@redhat.com>

Add a plain tcp test for guest-memfd.  Note that the test will be
automatically skipped whenever not supported (e.g. qemu compiled without
KVM, or host kernel doesn't support kvm, or old kernels, etc.).

Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 tests/qtest/migration/precopy-tests.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c
index a23d51126b..d57ffcac23 100644
--- a/tests/qtest/migration/precopy-tests.c
+++ b/tests/qtest/migration/precopy-tests.c
@@ -182,6 +182,13 @@ static void test_precopy_tcp_plain(char *name, MigrateCommon *args)
     test_precopy_common(args);
 }
 
+static void test_precopy_tcp_plain_gmemfd(char *name, MigrateCommon *args)
+{
+    args->start.mem_type = MEM_TYPE_GUEST_MEMFD;
+
+    test_precopy_common(args);
+}
+
 static void test_precopy_tcp_switchover_ack(char *name, MigrateCommon *args)
 {
     /*
@@ -1108,6 +1115,8 @@ void migration_test_add_precopy(MigrationTestEnv *env)
         return;
     }
 
+    migration_test_add("/migration/precopy/tcp/plain/guest-memfd",
+                       test_precopy_tcp_plain_gmemfd);
     migration_test_add("/migration/precopy/tcp/plain/switchover-ack",
                        test_precopy_tcp_switchover_ack);
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-08 13:30 ` [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
@ 2026-09-08 14:03   ` Markus Armbruster
  2026-09-10 22:58     ` Michael Roth
  2026-09-10  8:54   ` David Hildenbrand
  1 sibling, 1 reply; 33+ messages in thread
From: Markus Armbruster @ 2026-09-08 14:03 UTC (permalink / raw)
  To: Michael Roth
  Cc: qemu-devel, pbonzini, berrange, armbru, pankaj.gupta,
	isaku.yamahata, xiaoyao.li, chao.p.peng, david, Peter Xu,
	Fabiano Rosas

Michael Roth <michael.roth@amd.com> writes:

> From: Peter Xu <peterx@redhat.com>
>
> Host backends supports guest-memfd now by detecting whether it's a
> confidential VM.  There's no way to choose it yet from the memory level to
> use it fully shared.  If we use guest-memfd, it so far always implies we
> need two layers of memory backends, while the guest-memfd only provides the
> private set of pages.
>
> This patch introduces a way so that QEMU can consume guest memfd as the
> only source of memory to back the object (aka, fully shared).
>
> To use the fully shared guest-memfd, one can add a memfd object with:
>
>   -object memory-backend-memfd,guest-memfd=on,share=on
>
> Note that share=on is required with fully shared guest_memfd.
>
> PS: there's a trivial touch-up on fd<0 check, because the stub to create
> guest-memfd may return negative but not -1.
>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Signed-off-by: Michael Roth <michael.roth@amd.com>

[...]

> diff --git a/qapi/qom.json b/qapi/qom.json
> index 4a9b7f9088..909add4299 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -771,13 +771,17 @@
>  # @seal: if true, create a sealed-file, which will block further
>  #     resizing of the memory (default: true)
>  #
> +# @guest-memfd: if true, use guest-memfd to back the memory region.
> +#     (default: false, since: 11.2)

What's guest-memfd and why would I want to use it?

> +#
>  # Since: 2.12
>  ##
>  { 'struct': 'MemoryBackendMemfdProperties',
>    'base': 'MemoryBackendProperties',
>    'data': { '*hugetlb': 'bool',
>              '*hugetlbsize': 'size',
> -            '*seal': 'bool' },
> +            '*seal': 'bool',
> +            '*guest-memfd': 'bool' },
>    'if': 'CONFIG_LINUX' }
>  
>  ##



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends
  2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
                   ` (11 preceding siblings ...)
  2026-09-08 13:31 ` [PATCH v5 12/12] tests/migration-test: Add a precopy test for guest-memfd Michael Roth
@ 2026-09-10  8:45 ` David Hildenbrand
  12 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:45 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng

On 9/8/26 15:30, Michael Roth wrote:
> v1: https://lore.kernel.org/r/20251023185913.2923322-1-peterx@redhat.com
> v2: https://lore.kernel.org/r/20251119172913.577392-1-peterx@redhat.com
> v3: https://lore.kernel.org/r/20251215205203.1185099-1-peterx@redhat.com/
> v4: https://lore.kernel.org/qemu-devel/20260812201938.198915-1-michael.roth@amd.com/
> v5:
> - Fix error handling for 'hugetlb' when guest-memfd=on (Daniel, Peter)
> - Default to 'seal' option being allowed/on for guest-memfd=on since
>   it already satisfies the documented semantics (Peter)
> - Don't explicitly set a placeholder URI for qtest/migration-test
>   as the code now relies on NULL for this path (Peter)
> - Clarify rationale for checking for kvm_enabled() in 
>   kvm_create_guest_memfd() (Philippe, Peter)
> 
> This patchset is also available at:
> 
>   https://github.com/amdese/qemu/commits/gmem-shared-mem-v5
> 
> and is based on top of qemu master (99e54ab5e7)
> 
> 
> OVERVIEW
> ========
> 
> (cover letter shamelessly adapted from Peter's prior postings)
> 
> Recent kernels allow guest_memfd to be initialized with an 'init-shared'
> flag that will default to allocating normal/non-private memory that can be
> used to back non-confidential VMs.
> 
> This allows QEMU to make use of these init-shared guest_memfd instances via
> a common memory backend that's usable for either provide a common memory
> backend.
> 
> On the QEMU side, before this series, guest_memfd was only used for private
> guest memory (and thus only applied to confidential VMs), and the guest_memfd
> FDs would be created implicitly whenever a confidential environment was
> detected/specified.
> 
> With this series, users can now explicitly configure QEMU to use guest_memfd
> for non-private memory; thus, it can be used for non-confidential
> VMs. It also has implications for confidential VMs, since with this series an
> init-shared guest_memfd instance can now be specified for the shared memory
> while the internally-allocated guest_memfd continues to be used for private
> memory. This same infrastructure will also be used as the base for enabling
> in-place conversion for confidential VMs, where these separate shared/private
> paths will be modified to act on the same underlying guest_memfd instance and
> use a unified pool of shared/private memory.
> 
> 
> IMPLEMENTATION
> ==============
> 
> In the current patchset, I reused the memory-backend-memfd object, rather
> than creating a new type of object.  After all, guest-memfd (at least from
> userspace POV) works similarly like a memfd, except that it was tailored
> for VM's use case. While there is potential that new guest_memfd features
> may eventually necessitate introducing a dedicated guest_memfd memory
> backend object, for now the memory-backend-memfd object is a good fit for
> the current feature set.
> 
> This will also make it easier when in-place conversion comes around, since
> confidential VMs typically already use memory-backend-memfd for their shared
> memory, so by also making using that approach to specify the guest_memfd
> backend for in-place conversion the command-line syntax remains similar, and
> even allow choosing between memfd vs. guest_memfd to be handled automatically
> based on whether or not we're dealing with a Confidential VM with in-place
> conversion enabled.
> 
> Now, instead of using a normal memfd backend using:
> 
>   -object memory-backend-memfd,id=ID,size=SIZE,share=on
> 
> One can also boot a VM with guest-memfd:
> 
>   -object memory-backend-memfd,id=ID,size=SIZE,share=on,guest-memfd=on
> 
> The init-shared guest-memfd relies on a recent kernel (6.18+). When run it on
> an older qemu, you'll see errors like:
> 
>   qemu-system-x86_64: KVM does not support guest_memfd
> 
> One thing to mention is live migration is by default supported, however
> postcopy is still currently not supported.  The postcopy support will have
> some kernel dependency work to be merged in Linux first.

All makes sense to me!
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported
  2026-09-08 13:30 ` [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
@ 2026-09-10  8:47   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:47 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu, Fabiano Rosas

On 9/8/26 15:30, Michael Roth wrote:
> From: Xiaoyao Li <xiaoyao.li@intel.com>
> 
> With the mmap support of guest memfd, KVM allows userspace to create
> guest memfd serving as normal non-private memory for X86 DEFAULT VM.
> However, KVM doesn't support private memory attribute for X86 DEFAULT
> VM.
> 
> Make kvm_guest_memfd_supported not rely on KVM_MEMORY_ATTRIBUTE_PRIVATE
> and check KVM_MEMORY_ATTRIBUTE_PRIVATE separately when the machine
> requires guest_memfd to serve as private memory.
> 
> This allows QEMU to create guest memfd with mmap to serve as the memory
> backend for X86 DEFAULT VM.
> 
> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Reviewed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---
Reviewed-by: David Hildenbrand <david@kernel.org>

-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 03/12] kvm: Provide explicit error for kvm_create_guest_memfd()
  2026-09-08 13:30 ` [PATCH v5 03/12] kvm: Provide explicit error for kvm_create_guest_memfd() Michael Roth
@ 2026-09-10  8:48   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:48 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu, Fabiano Rosas

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> So that there will be a verbal string returned when kvm not enabled, or
> kvm not compiled.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Reviewed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 04/12] ramblock: Rename guest_memfd to guest_memfd_private
  2026-09-08 13:30 ` [PATCH v5 04/12] ramblock: Rename guest_memfd to guest_memfd_private Michael Roth
@ 2026-09-10  8:49   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:49 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> Rename the field to reflect the fact that the guest_memfd in this case only
> backs private portion of the ramblock rather than all of it.
> 
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE
  2026-09-08 13:30 ` [PATCH v5 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE Michael Roth
@ 2026-09-10  8:50   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:50 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> This name is too generic, and can conflict with support for using
> guest-memfd for shared memory. Add a _PRIVATE suffix to show what it
> really means: it is using guest_memfd specifically for private memory;
> whether or not guest_memfd is being used for shared memory is something
> to be configured/determined separately.
> 
> This also paves way for in-place guest-memfd, which means we can have a
> ramblock that allocates pages completely from guest-memfd (private or
> shared).
> 
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 06/12] memory: Rename memory_region_has_guest_memfd() to *_private()
  2026-09-08 13:30 ` [PATCH v5 06/12] memory: Rename memory_region_has_guest_memfd() to *_private() Michael Roth
@ 2026-09-10  8:50   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:50 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> Rename the function with "_private" suffix, to show that it returns true
> only if it has an internal guest-memfd to back private pages (rather than
> fully shared guest-memfd).
> 
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 07/12] hostmem: Rename guest_memfd to guest_memfd_private
  2026-09-08 13:30 ` [PATCH v5 07/12] hostmem: Rename guest_memfd to guest_memfd_private Michael Roth
@ 2026-09-10  8:51   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:51 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> Rename the HostMemoryBackend.guest_memfd field to reflect what it really
> means: whether it needs guest_memfd to back its private guest memory.
> This will help avoid conflicts when we introduce supported for using
> guest_memfd for shared guest memory via hostmem.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Reviewed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-08 13:30 ` [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
  2026-09-08 14:03   ` Markus Armbruster
@ 2026-09-10  8:54   ` David Hildenbrand
  2026-09-10 23:00     ` Michael Roth
  1 sibling, 1 reply; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:54 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu, Fabiano Rosas

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> Host backends supports guest-memfd now by detecting whether it's a
> confidential VM.  There's no way to choose it yet from the memory level to
> use it fully shared.  If we use guest-memfd, it so far always implies we
> need two layers of memory backends, while the guest-memfd only provides the
> private set of pages.
> 
> This patch introduces a way so that QEMU can consume guest memfd as the
> only source of memory to back the object (aka, fully shared).
> 
> To use the fully shared guest-memfd, one can add a memfd object with:
> 
>   -object memory-backend-memfd,guest-memfd=on,share=on
> 
> Note that share=on is required with fully shared guest_memfd.
> 
> PS: there's a trivial touch-up on fd<0 check, because the stub to create
> guest-memfd may return negative but not -1.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---

[...]

>  static bool
> @@ -47,11 +56,31 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
>          goto have_fd;
>      }
>  
> -    fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
> -                           m->hugetlb, m->hugetlbsize, m->seal ?
> -                           F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
> -                           errp);
> -    if (fd == -1) {
> +    if (m->guest_memfd) {
> +        /*
> +         * NOTE: guest-memfd ignores seal=on/off because it always
> +         * implicitly seals the FD by definition.
> +         */
> +        if (!backend->share) {
> +            error_setg(errp, "guest-memfd=on must be used with share=on");
> +            return false;
> +        } else if (m->hugetlb) {
> +            error_setg(errp, "guest-memfd=on doesn't support hugetlb=on yet");

There is a lot of uncertainty how guest_memfd would consume huge pages. So best
to drop the "yet" that implies how it would be consumed (and that it would be
called "hugetlb").


Apart from that LGTM

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private()
  2026-09-08 13:30 ` [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private() Michael Roth
@ 2026-09-10  8:55   ` David Hildenbrand
  2026-09-10 23:08     ` Michael Roth
  0 siblings, 1 reply; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:55 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu

On 9/8/26 15:30, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> Differenciate it from fully shared guest-memfd use cases.

s/Differenciate/Differentiate/

> 
> When at it, add proper brackets in kvm_handle_hc_map_gpa_range() otherwise
> checkpatch may complain.

Why is this patch not moved further up, where we rename other stuff?

Reviewed-by: David Hildenbrand <david@kernel.org>
-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 10/12] memory: Rename memory_region_init_ram_guest_memfd() to *_private()
  2026-09-08 13:31 ` [PATCH v5 10/12] memory: Rename memory_region_init_ram_guest_memfd() " Michael Roth
@ 2026-09-10  8:56   ` David Hildenbrand
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand @ 2026-09-10  8:56 UTC (permalink / raw)
  To: Michael Roth, qemu-devel
  Cc: pbonzini, berrange, armbru, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, Peter Xu

On 9/8/26 15:31, Michael Roth wrote:
> From: Peter Xu <peterx@redhat.com>
> 
> Differenciate it from fully shared guest-memfd use cases.

s/Differenciate/Differentiate/

Same question regarding patch ordering.

Reviewed-by: David Hildenbrand <david@kernel.org>

-- 
Cheers,

David



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-08 14:03   ` Markus Armbruster
@ 2026-09-10 22:58     ` Michael Roth
  2026-09-11  5:56       ` Markus Armbruster
  0 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-10 22:58 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, pbonzini, berrange, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

On Tue, Sep 08, 2026 at 04:03:28PM +0200, Markus Armbruster wrote:
> Michael Roth <michael.roth@amd.com> writes:
> 
> > From: Peter Xu <peterx@redhat.com>
> >
> > Host backends supports guest-memfd now by detecting whether it's a
> > confidential VM.  There's no way to choose it yet from the memory level to
> > use it fully shared.  If we use guest-memfd, it so far always implies we
> > need two layers of memory backends, while the guest-memfd only provides the
> > private set of pages.
> >
> > This patch introduces a way so that QEMU can consume guest memfd as the
> > only source of memory to back the object (aka, fully shared).
> >
> > To use the fully shared guest-memfd, one can add a memfd object with:
> >
> >   -object memory-backend-memfd,guest-memfd=on,share=on
> >
> > Note that share=on is required with fully shared guest_memfd.
> >
> > PS: there's a trivial touch-up on fd<0 check, because the stub to create
> > guest-memfd may return negative but not -1.
> >
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> > Reviewed-by: Fabiano Rosas <farosas@suse.de>
> > Signed-off-by: Michael Roth <michael.roth@amd.com>
> 
> [...]
> 
> > diff --git a/qapi/qom.json b/qapi/qom.json
> > index 4a9b7f9088..909add4299 100644
> > --- a/qapi/qom.json
> > +++ b/qapi/qom.json
> > @@ -771,13 +771,17 @@
> >  # @seal: if true, create a sealed-file, which will block further
> >  #     resizing of the memory (default: true)
> >  #
> > +# @guest-memfd: if true, use guest-memfd to back the memory region.
> > +#     (default: false, since: 11.2)
> 
> What's guest-memfd and why would I want to use it?

I'm planning to squash the below documentation patch into this commit so
it can be referenced in the schema documentation for the @guest-memfd
option.

I think it explains the "what", but the "why" is a bit awkward at this
stage because we anticipate a lot of use-cases, and potentially it
becoming the general default for backing guest memory that doesn't
specifically need any functionality provided by the other
memory-backend-* implementations, but admittedly at this stage it would
be primarily for experimentation and getting infrastructure in place
because there are feature gaps like hugepage/THP support that would
prevent it from being a drop in replacement for memfd users.

The first 'real' use-case will come when either one of the features
mentioned in the documentation below (or something else) goes upstream,
or (more likely at this point) the in-place conversion patches land and
the @guest-memfd=on functionality becomes a requirement for Confidential
VMs that want to run in that mode (which does have immediately tangible
benefits like not needing to reallocate memory after every
shared<->private conversion and will likely deprecate the existing
out-of-place conversion mode currently used by SNP/TDX fairly quickly)).
I plan to add that use-case to the document as well, but it seems more
appropriate to do so in the context of the in-place conversion series
where I can talk about it in a non-theoretical context.

But hopefully the below documentation is enough to at least let people
know who should/shouldn't care about this option in the context of this
series though. If that seems acceptable I can it into this patch for v6
to compliment the schema documentation.

Thanks,

Mike


From: Michael Roth <michael.roth@amd.com>
Date: Thu, 10 Sep 2026 17:03:20 -0500
Subject: [PATCH] docs/system: Add documentation on support for guest_memfd

Document how guest_memfd is used in QEMU for both Confidential VMs as
well as normal VMs.

Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 docs/system/guest-memfd.rst | 49 +++++++++++++++++++++++++++++++++++++
 docs/system/index.rst       |  1 +
 2 files changed, 50 insertions(+)
 create mode 100644 docs/system/guest-memfd.rst

diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst
new file mode 100644
index 0000000000..9fc4ffb015
--- /dev/null
+++ b/docs/system/guest-memfd.rst
@@ -0,0 +1,49 @@
+.. _guest-memfd:
+
+guest-memfd support
+===================
+
+Recent kernels allow for the creation of a guest-memfd file descriptor, which
+can be used to back VMs in a similar manner as a memfd file descriptor, but is
+intended specifically for this purpose and allows for closer coordination
+between KVM and the management of this memory to enable more
+advanced/VM-specific use-cases.
+
+Initially this additional functionality centered around providing a
+common/centralized place for managing kernel-side memory handing requirements
+for various Confidential Computing architectures, but it has since evolved to
+become a more general-purpose way to allocate/manage guest memory and
+potentially allow for things like providing additional memory isolation within
+the kernel[1] and support for persisting a VM's state across kexec to allow for
+live-updating the host kernel with minimal VM downtime[2].
+
+Usage
+-----
+
+For Confidential VMs, guest-memfd is currently utilized internally by QEMU to
+handle private guest memory, independently of whatever memory backend the user
+has configured for normal/non-private/shared guest memory. To avoid doubling
+memory, QEMU discards memory in response to the guest converting GPA ranges
+between shared/private. (e.g. if GPA X is converted from private to shared, the
+guest-memfd FD offset corresponding to GPA x will be truncated since the memory
+will be provided by the memory backend the user configured for shared memory,
+and vice-versa). This is handled automatically/internally for Confidential VMs
+that rely on this handling and is not directly exposed by QEMU command-line
+options.
+
+For non-Confidential VMs, guest-memfd can be used in a manner that is somewhat
+interchangeable with a normal memfd. Currently, this is handled by using the
+same memory-backend implementation as memfd, but with an additional
+'guest-memfd=on' option. E.g.::
+
+    qemu ... \
+      -object memory-backend-memfd,id=ID,size=SIZE,share=on,guest-memfd=on
+
+(Note that the share=on option is required for guest-memfd, since it does not
+support anonymous memory allocations or COW-like semantics.)
+
+References
+----------
+
+- `[1] directmap removal <https://lore.kernel.org/kvm/20260317141031.514-1-kalyazin@amazon.com/>`__
+- `[2] LUO <https://lore.kernel.org/kvm/20260728121138.1103610-1-tarunsahu@google.com/>`__
diff --git a/docs/system/index.rst b/docs/system/index.rst
index 4509630fa4..060850a739 100644
--- a/docs/system/index.rst
+++ b/docs/system/index.rst
@@ -44,3 +44,4 @@ or Hypervisor.Framework.
    vm-templating
    sriov
    qemu-colo
+   guest-memfd


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-10  8:54   ` David Hildenbrand
@ 2026-09-10 23:00     ` Michael Roth
  2026-09-11 12:06       ` Peter Xu
  0 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-10 23:00 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, pbonzini, berrange, armbru, pankaj.gupta,
	isaku.yamahata, xiaoyao.li, chao.p.peng, Peter Xu, Fabiano Rosas

On Thu, Sep 10, 2026 at 10:54:09AM +0200, David Hildenbrand wrote:
> On 9/8/26 15:30, Michael Roth wrote:
> > From: Peter Xu <peterx@redhat.com>
> > 
> > Host backends supports guest-memfd now by detecting whether it's a
> > confidential VM.  There's no way to choose it yet from the memory level to
> > use it fully shared.  If we use guest-memfd, it so far always implies we
> > need two layers of memory backends, while the guest-memfd only provides the
> > private set of pages.
> > 
> > This patch introduces a way so that QEMU can consume guest memfd as the
> > only source of memory to back the object (aka, fully shared).
> > 
> > To use the fully shared guest-memfd, one can add a memfd object with:
> > 
> >   -object memory-backend-memfd,guest-memfd=on,share=on
> > 
> > Note that share=on is required with fully shared guest_memfd.
> > 
> > PS: there's a trivial touch-up on fd<0 check, because the stub to create
> > guest-memfd may return negative but not -1.
> > 
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> > Reviewed-by: Fabiano Rosas <farosas@suse.de>
> > Signed-off-by: Michael Roth <michael.roth@amd.com>
> > ---
> 
> [...]
> 
> >  static bool
> > @@ -47,11 +56,31 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
> >          goto have_fd;
> >      }
> >  
> > -    fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
> > -                           m->hugetlb, m->hugetlbsize, m->seal ?
> > -                           F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
> > -                           errp);
> > -    if (fd == -1) {
> > +    if (m->guest_memfd) {
> > +        /*
> > +         * NOTE: guest-memfd ignores seal=on/off because it always
> > +         * implicitly seals the FD by definition.
> > +         */
> > +        if (!backend->share) {
> > +            error_setg(errp, "guest-memfd=on must be used with share=on");
> > +            return false;
> > +        } else if (m->hugetlb) {
> > +            error_setg(errp, "guest-memfd=on doesn't support hugetlb=on yet");
> 
> There is a lot of uncertainty how guest_memfd would consume huge pages. So best
> to drop the "yet" that implies how it would be consumed (and that it would be
> called "hugetlb").

Makes sense, will change this as suggested for v6

Thanks,

Mike

> 
> 
> Apart from that LGTM
> 
> Reviewed-by: David Hildenbrand <david@kernel.org>
> -- 
> Cheers,
> 
> David
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private()
  2026-09-10  8:55   ` David Hildenbrand
@ 2026-09-10 23:08     ` Michael Roth
  2026-09-11 10:48       ` David Hildenbrand (Arm)
  0 siblings, 1 reply; 33+ messages in thread
From: Michael Roth @ 2026-09-10 23:08 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, pbonzini, berrange, armbru, pankaj.gupta,
	isaku.yamahata, xiaoyao.li, chao.p.peng, Peter Xu

On Thu, Sep 10, 2026 at 10:55:09AM +0200, David Hildenbrand wrote:
> On 9/8/26 15:30, Michael Roth wrote:
> > From: Peter Xu <peterx@redhat.com>
> > 
> > Differenciate it from fully shared guest-memfd use cases.
> 
> s/Differenciate/Differentiate/

I prefer the other spelling, but I guess the ship has sailed on that
discussion :)

> 
> > 
> > When at it, add proper brackets in kvm_handle_hc_map_gpa_range() otherwise
> > checkpatch may complain.
> 
> Why is this patch not moved further up, where we rename other stuff?

Hmm... I'm not sure. Technically they are not dependencies of this patch,
but that's also true for some of the other renamings, so I'll plan to move
this to the end of the series for v6 unless Peter has any objections.

Thanks,

Mike

> 
> Reviewed-by: David Hildenbrand <david@kernel.org>
> -- 
> Cheers,
> 
> David
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-10 22:58     ` Michael Roth
@ 2026-09-11  5:56       ` Markus Armbruster
  2026-09-11 19:22         ` Michael Roth
  0 siblings, 1 reply; 33+ messages in thread
From: Markus Armbruster @ 2026-09-11  5:56 UTC (permalink / raw)
  To: Michael Roth
  Cc: qemu-devel, pbonzini, berrange, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

Michael Roth <michael.roth@amd.com> writes:

> On Tue, Sep 08, 2026 at 04:03:28PM +0200, Markus Armbruster wrote:
>> Michael Roth <michael.roth@amd.com> writes:
>> 
>> > From: Peter Xu <peterx@redhat.com>
>> >
>> > Host backends supports guest-memfd now by detecting whether it's a
>> > confidential VM.  There's no way to choose it yet from the memory level to
>> > use it fully shared.  If we use guest-memfd, it so far always implies we
>> > need two layers of memory backends, while the guest-memfd only provides the
>> > private set of pages.
>> >
>> > This patch introduces a way so that QEMU can consume guest memfd as the
>> > only source of memory to back the object (aka, fully shared).
>> >
>> > To use the fully shared guest-memfd, one can add a memfd object with:
>> >
>> >   -object memory-backend-memfd,guest-memfd=on,share=on
>> >
>> > Note that share=on is required with fully shared guest_memfd.
>> >
>> > PS: there's a trivial touch-up on fd<0 check, because the stub to create
>> > guest-memfd may return negative but not -1.
>> >
>> > Signed-off-by: Peter Xu <peterx@redhat.com>
>> > Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
>> > Reviewed-by: Fabiano Rosas <farosas@suse.de>
>> > Signed-off-by: Michael Roth <michael.roth@amd.com>
>> 
>> [...]
>> 
>> > diff --git a/qapi/qom.json b/qapi/qom.json
>> > index 4a9b7f9088..909add4299 100644
>> > --- a/qapi/qom.json
>> > +++ b/qapi/qom.json
>> > @@ -771,13 +771,17 @@
>> >  # @seal: if true, create a sealed-file, which will block further
>> >  #     resizing of the memory (default: true)
>> >  #
>> > +# @guest-memfd: if true, use guest-memfd to back the memory region.
>> > +#     (default: false, since: 11.2)
>> 
>> What's guest-memfd and why would I want to use it?
>
> I'm planning to squash the below documentation patch into this commit so
> it can be referenced in the schema documentation for the @guest-memfd
> option.
>
> I think it explains the "what", but the "why" is a bit awkward at this
> stage because we anticipate a lot of use-cases, and potentially it
> becoming the general default for backing guest memory that doesn't
> specifically need any functionality provided by the other
> memory-backend-* implementations, but admittedly at this stage it would
> be primarily for experimentation and getting infrastructure in place
> because there are feature gaps like hugepage/THP support that would
> prevent it from being a drop in replacement for memfd users.
>
> The first 'real' use-case will come when either one of the features
> mentioned in the documentation below (or something else) goes upstream,
> or (more likely at this point) the in-place conversion patches land and
> the @guest-memfd=on functionality becomes a requirement for Confidential
> VMs that want to run in that mode (which does have immediately tangible
> benefits like not needing to reallocate memory after every
> shared<->private conversion and will likely deprecate the existing
> out-of-place conversion mode currently used by SNP/TDX fairly quickly)).
> I plan to add that use-case to the document as well, but it seems more
> appropriate to do so in the context of the in-place conversion series
> where I can talk about it in a non-theoretical context.

Would it make sense to mark it experimental until then?  Also makes me
more willing to accept documentation gaps, and could serve as a reminder
to fill them.

I've come to ask "why would I want to use this?" more and more.  QEMU
has so many knobs to push and turn, and we provide so little guidance on
what to use them for.  Users' need for guidance is easy to miss when you
don't feel it yourself, because you're deep into the feature.

> But hopefully the below documentation is enough to at least let people
> know who should/shouldn't care about this option in the context of this
> series though. If that seems acceptable I can it into this patch for v6
> to compliment the schema documentation.

Yes, please.  Consider wrapping lines around column 70 to make it easier
to read.

[...]



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private()
  2026-09-10 23:08     ` Michael Roth
@ 2026-09-11 10:48       ` David Hildenbrand (Arm)
  2026-09-11 19:27         ` Michael Roth
  0 siblings, 1 reply; 33+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-11 10:48 UTC (permalink / raw)
  To: Michael Roth
  Cc: qemu-devel, pbonzini, berrange, armbru, pankaj.gupta,
	isaku.yamahata, xiaoyao.li, chao.p.peng, Peter Xu

On 9/11/26 01:08, Michael Roth wrote:
> On Thu, Sep 10, 2026 at 10:55:09AM +0200, David Hildenbrand wrote:
>> On 9/8/26 15:30, Michael Roth wrote:
>>> From: Peter Xu <peterx@redhat.com>
>>>
>>> Differenciate it from fully shared guest-memfd use cases.
>>
>> s/Differenciate/Differentiate/
> 
> I prefer the other spelling, but I guess the ship has sailed on that
> discussion :)

Heh, my spellcheck flags it (and it looks odd). If it's valid, please keep it :)

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-10 23:00     ` Michael Roth
@ 2026-09-11 12:06       ` Peter Xu
  2026-09-11 16:00         ` David Hildenbrand (Arm)
  0 siblings, 1 reply; 33+ messages in thread
From: Peter Xu @ 2026-09-11 12:06 UTC (permalink / raw)
  To: Michael Roth
  Cc: David Hildenbrand, qemu-devel, pbonzini, berrange, armbru,
	pankaj.gupta, isaku.yamahata, xiaoyao.li, chao.p.peng,
	Fabiano Rosas

On Thu, Sep 10, 2026 at 06:00:11PM -0500, Michael Roth wrote:
> On Thu, Sep 10, 2026 at 10:54:09AM +0200, David Hildenbrand wrote:
> > On 9/8/26 15:30, Michael Roth wrote:
> > > From: Peter Xu <peterx@redhat.com>
> > > 
> > > Host backends supports guest-memfd now by detecting whether it's a
> > > confidential VM.  There's no way to choose it yet from the memory level to
> > > use it fully shared.  If we use guest-memfd, it so far always implies we
> > > need two layers of memory backends, while the guest-memfd only provides the
> > > private set of pages.
> > > 
> > > This patch introduces a way so that QEMU can consume guest memfd as the
> > > only source of memory to back the object (aka, fully shared).
> > > 
> > > To use the fully shared guest-memfd, one can add a memfd object with:
> > > 
> > >   -object memory-backend-memfd,guest-memfd=on,share=on
> > > 
> > > Note that share=on is required with fully shared guest_memfd.
> > > 
> > > PS: there's a trivial touch-up on fd<0 check, because the stub to create
> > > guest-memfd may return negative but not -1.
> > > 
> > > Signed-off-by: Peter Xu <peterx@redhat.com>
> > > Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> > > Reviewed-by: Fabiano Rosas <farosas@suse.de>
> > > Signed-off-by: Michael Roth <michael.roth@amd.com>
> > > ---
> > 
> > [...]
> > 
> > >  static bool
> > > @@ -47,11 +56,31 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
> > >          goto have_fd;
> > >      }
> > >  
> > > -    fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
> > > -                           m->hugetlb, m->hugetlbsize, m->seal ?
> > > -                           F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
> > > -                           errp);
> > > -    if (fd == -1) {
> > > +    if (m->guest_memfd) {
> > > +        /*
> > > +         * NOTE: guest-memfd ignores seal=on/off because it always
> > > +         * implicitly seals the FD by definition.
> > > +         */
> > > +        if (!backend->share) {
> > > +            error_setg(errp, "guest-memfd=on must be used with share=on");
> > > +            return false;
> > > +        } else if (m->hugetlb) {
> > > +            error_setg(errp, "guest-memfd=on doesn't support hugetlb=on yet");
> > 
> > There is a lot of uncertainty how guest_memfd would consume huge pages. So best
> > to drop the "yet" that implies how it would be consumed (and that it would be
> > called "hugetlb").
> 
> Makes sense, will change this as suggested for v6

I'm just curious, any more info on this part?  Any link to existing work
would help.

At least from our side, we look for hugetlb-alike support on gmem.  I want
to make sure what I understand still is valid, and it is still open to
solve the postcopy problem.

Thanks,

-- 
Peter Xu



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-11 12:06       ` Peter Xu
@ 2026-09-11 16:00         ` David Hildenbrand (Arm)
  0 siblings, 0 replies; 33+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-11 16:00 UTC (permalink / raw)
  To: Peter Xu, Michael Roth
  Cc: qemu-devel, pbonzini, berrange, armbru, pankaj.gupta,
	isaku.yamahata, xiaoyao.li, chao.p.peng, Fabiano Rosas

On 9/11/26 14:06, Peter Xu wrote:
> On Thu, Sep 10, 2026 at 06:00:11PM -0500, Michael Roth wrote:
>> On Thu, Sep 10, 2026 at 10:54:09AM +0200, David Hildenbrand wrote:
>>>
>>> [...]
>>>
>>>
>>> There is a lot of uncertainty how guest_memfd would consume huge pages. So best
>>> to drop the "yet" that implies how it would be consumed (and that it would be
>>> called "hugetlb").
>>
>> Makes sense, will change this as suggested for v6
> 
> I'm just curious, any more info on this part?  Any link to existing work
> would help.

Ackerley has been mostly busy doing the in-place conversion, the hugetlb-related
patches he sent are a bit dated.

He's been recently looking into how to abstract memory providers for
guest_memfd, I think there were some upstream discussions related to that in
related context:

https://lore.kernel.org/r/CAEvNRgHbfx470HUBJhEUVKPKqsV0LnhX+wkD1TE-61fZy3jjUw@mail.gmail.com


> 
> At least from our side, we look for hugetlb-alike support on gmem.  I want
> to make sure what I understand still is valid, and it is still open to
> solve the postcopy problem.

Right, something like that will come. And I am not saying that we won't model it
as "guest memfd hugetlb" support in QEMU, but I wouldn't start documenting that
it will be modeled like that.

hugetlb will initially be used as a memory provider for hugetlb to allocate
larger pages, and guest_memfd will essentially strip these pages from hugetlb
details, turning them into simple large guest_memfd pages.

One idea is to support other pools, where also hugetlb could take pages from
these pools.

So it's just a matter of "we don't know how we will model it, and we don't know
whether it will be called hugetlb".

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM
  2026-09-11  5:56       ` Markus Armbruster
@ 2026-09-11 19:22         ` Michael Roth
  0 siblings, 0 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-11 19:22 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, pbonzini, berrange, pankaj.gupta, isaku.yamahata,
	xiaoyao.li, chao.p.peng, david, Peter Xu, Fabiano Rosas

On Fri, Sep 11, 2026 at 07:56:11AM +0200, Markus Armbruster wrote:
> Michael Roth <michael.roth@amd.com> writes:
> 
> > On Tue, Sep 08, 2026 at 04:03:28PM +0200, Markus Armbruster wrote:
> >> Michael Roth <michael.roth@amd.com> writes:
> >> 
> >> > From: Peter Xu <peterx@redhat.com>
> >> >
> >> > Host backends supports guest-memfd now by detecting whether it's a
> >> > confidential VM.  There's no way to choose it yet from the memory level to
> >> > use it fully shared.  If we use guest-memfd, it so far always implies we
> >> > need two layers of memory backends, while the guest-memfd only provides the
> >> > private set of pages.
> >> >
> >> > This patch introduces a way so that QEMU can consume guest memfd as the
> >> > only source of memory to back the object (aka, fully shared).
> >> >
> >> > To use the fully shared guest-memfd, one can add a memfd object with:
> >> >
> >> >   -object memory-backend-memfd,guest-memfd=on,share=on
> >> >
> >> > Note that share=on is required with fully shared guest_memfd.
> >> >
> >> > PS: there's a trivial touch-up on fd<0 check, because the stub to create
> >> > guest-memfd may return negative but not -1.
> >> >
> >> > Signed-off-by: Peter Xu <peterx@redhat.com>
> >> > Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> >> > Reviewed-by: Fabiano Rosas <farosas@suse.de>
> >> > Signed-off-by: Michael Roth <michael.roth@amd.com>
> >> 
> >> [...]
> >> 
> >> > diff --git a/qapi/qom.json b/qapi/qom.json
> >> > index 4a9b7f9088..909add4299 100644
> >> > --- a/qapi/qom.json
> >> > +++ b/qapi/qom.json
> >> > @@ -771,13 +771,17 @@
> >> >  # @seal: if true, create a sealed-file, which will block further
> >> >  #     resizing of the memory (default: true)
> >> >  #
> >> > +# @guest-memfd: if true, use guest-memfd to back the memory region.
> >> > +#     (default: false, since: 11.2)
> >> 
> >> What's guest-memfd and why would I want to use it?
> >
> > I'm planning to squash the below documentation patch into this commit so
> > it can be referenced in the schema documentation for the @guest-memfd
> > option.
> >
> > I think it explains the "what", but the "why" is a bit awkward at this
> > stage because we anticipate a lot of use-cases, and potentially it
> > becoming the general default for backing guest memory that doesn't
> > specifically need any functionality provided by the other
> > memory-backend-* implementations, but admittedly at this stage it would
> > be primarily for experimentation and getting infrastructure in place
> > because there are feature gaps like hugepage/THP support that would
> > prevent it from being a drop in replacement for memfd users.
> >
> > The first 'real' use-case will come when either one of the features
> > mentioned in the documentation below (or something else) goes upstream,
> > or (more likely at this point) the in-place conversion patches land and
> > the @guest-memfd=on functionality becomes a requirement for Confidential
> > VMs that want to run in that mode (which does have immediately tangible
> > benefits like not needing to reallocate memory after every
> > shared<->private conversion and will likely deprecate the existing
> > out-of-place conversion mode currently used by SNP/TDX fairly quickly)).
> > I plan to add that use-case to the document as well, but it seems more
> > appropriate to do so in the context of the in-place conversion series
> > where I can talk about it in a non-theoretical context.
> 
> Would it make sense to mark it experimental until then?  Also makes me
> more willing to accept documentation gaps, and could serve as a reminder
> to fill them.

I wouldn't have any objections to that. Though once the in-place
conversion support lands and comes to rely on it, we'd probably want to
drop the experimental tag at that point. But that all seems fine to me.

Unless there are any objections. Peter, does that work on your end?

> 
> I've come to ask "why would I want to use this?" more and more.  QEMU
> has so many knobs to push and turn, and we provide so little guidance on
> what to use them for.  Users' need for guidance is easy to miss when you
> don't feel it yourself, because you're deep into the feature.
> 
> > But hopefully the below documentation is enough to at least let people
> > know who should/shouldn't care about this option in the context of this
> > series though. If that seems acceptable I can it into this patch for v6
> > to compliment the schema documentation.
> 
> Yes, please.  Consider wrapping lines around column 70 to make it easier
> to read.

Will do.

Thanks,

Mike

> 
> [...]
> 


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private()
  2026-09-11 10:48       ` David Hildenbrand (Arm)
@ 2026-09-11 19:27         ` Michael Roth
  0 siblings, 0 replies; 33+ messages in thread
From: Michael Roth @ 2026-09-11 19:27 UTC (permalink / raw)
  To: David Hildenbrand (Arm)
  Cc: qemu-devel, pbonzini, berrange, armbru, pankaj.gupta,
	isaku.yamahata, xiaoyao.li, chao.p.peng, Peter Xu

On Fri, Sep 11, 2026 at 12:48:10PM +0200, David Hildenbrand (Arm) wrote:
> On 9/11/26 01:08, Michael Roth wrote:
> > On Thu, Sep 10, 2026 at 10:55:09AM +0200, David Hildenbrand wrote:
> >> On 9/8/26 15:30, Michael Roth wrote:
> >>> From: Peter Xu <peterx@redhat.com>
> >>>
> >>> Differenciate it from fully shared guest-memfd use cases.
> >>
> >> s/Differenciate/Differentiate/
> > 
> > I prefer the other spelling, but I guess the ship has sailed on that
> > discussion :)
> 
> Heh, my spellcheck flags it (and it looks odd). If it's valid, please keep it :)

No your spellcheck is correct, I just couldn't resist the opportunity to
complain about the inconsistencies of the English language :)

Thanks,

Mike

> 
> -- 
> Cheers,
> 
> David


^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2026-09-11 19:28 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-08 13:30 [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
2026-09-08 13:30 ` [PATCH v5 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
2026-09-10  8:47   ` David Hildenbrand
2026-09-08 13:30 ` [PATCH v5 02/12] kvm: Detect guest-memfd flags supported Michael Roth
2026-09-08 13:30 ` [PATCH v5 03/12] kvm: Provide explicit error for kvm_create_guest_memfd() Michael Roth
2026-09-10  8:48   ` David Hildenbrand
2026-09-08 13:30 ` [PATCH v5 04/12] ramblock: Rename guest_memfd to guest_memfd_private Michael Roth
2026-09-10  8:49   ` David Hildenbrand
2026-09-08 13:30 ` [PATCH v5 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE Michael Roth
2026-09-10  8:50   ` David Hildenbrand
2026-09-08 13:30 ` [PATCH v5 06/12] memory: Rename memory_region_has_guest_memfd() to *_private() Michael Roth
2026-09-10  8:50   ` David Hildenbrand
2026-09-08 13:30 ` [PATCH v5 07/12] hostmem: Rename guest_memfd to guest_memfd_private Michael Roth
2026-09-10  8:51   ` David Hildenbrand
2026-09-08 13:30 ` [PATCH v5 08/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
2026-09-08 14:03   ` Markus Armbruster
2026-09-10 22:58     ` Michael Roth
2026-09-11  5:56       ` Markus Armbruster
2026-09-11 19:22         ` Michael Roth
2026-09-10  8:54   ` David Hildenbrand
2026-09-10 23:00     ` Michael Roth
2026-09-11 12:06       ` Peter Xu
2026-09-11 16:00         ` David Hildenbrand (Arm)
2026-09-08 13:30 ` [PATCH v5 09/12] machine: Rename machine_require_guest_memfd() to *_private() Michael Roth
2026-09-10  8:55   ` David Hildenbrand
2026-09-10 23:08     ` Michael Roth
2026-09-11 10:48       ` David Hildenbrand (Arm)
2026-09-11 19:27         ` Michael Roth
2026-09-08 13:31 ` [PATCH v5 10/12] memory: Rename memory_region_init_ram_guest_memfd() " Michael Roth
2026-09-10  8:56   ` David Hildenbrand
2026-09-08 13:31 ` [PATCH v5 11/12] tests/migration-test: Support guest-memfd init shared mem type Michael Roth
2026-09-08 13:31 ` [PATCH v5 12/12] tests/migration-test: Add a precopy test for guest-memfd Michael Roth
2026-09-10  8:45 ` [PATCH v5 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends David Hildenbrand

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.