* [PATCH v6 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 02/12] kvm: Detect guest-memfd flags supported Michael Roth
` (11 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng, 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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 | 9 +++++++++
4 files changed, 21 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 bd5f41cb02..1b3f327ed5 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2192,6 +2192,15 @@ 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)));
+ qemu_mutex_unlock_ramlist();
+ 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] 17+ messages in thread* [PATCH v6 02/12] kvm: Detect guest-memfd flags supported
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
2026-09-25 1:43 ` [PATCH v6 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 03/12] kvm: Provide explicit error for kvm_create_guest_memfd() Michael Roth
` (10 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng, 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] 17+ messages in thread* [PATCH v6 03/12] kvm: Provide explicit error for kvm_create_guest_memfd()
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
2026-09-25 1:43 ` [PATCH v6 01/12] kvm: Decouple memory attribute check from kvm_guest_memfd_supported Michael Roth
2026-09-25 1:43 ` [PATCH v6 02/12] kvm: Detect guest-memfd flags supported Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 04/12] ramblock: Rename guest_memfd to guest_memfd_private Michael Roth
` (9 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng, 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>
Reviewed-by: David Hildenbrand <david@kernel.org>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
accel/kvm/kvm-all.c | 11 +++++++++++
accel/stubs/kvm-stub.c | 1 +
2 files changed, 12 insertions(+)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 120cab1e22..0b1407e4ea 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -4758,6 +4758,17 @@ 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 explicitly 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] 17+ messages in thread* [PATCH v6 04/12] ramblock: Rename guest_memfd to guest_memfd_private
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (2 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 03/12] kvm: Provide explicit error for kvm_create_guest_memfd() Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE Michael Roth
` (8 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 0b1407e4ea..a29b1d7a3c 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 264dc90c0a..b07d5dc542 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1780,7 +1780,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 1b3f327ed5..156853c8db 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2201,7 +2201,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) {
@@ -2211,9 +2211,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;
}
@@ -2230,7 +2230,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;
@@ -2366,7 +2366,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);
@@ -2539,7 +2539,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;
@@ -2590,8 +2590,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);
}
@@ -2839,12 +2839,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;
}
@@ -4272,7 +4272,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);
}
@@ -4286,7 +4286,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] 17+ messages in thread* [PATCH v6 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (3 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 04/12] ramblock: Rename guest_memfd to guest_memfd_private Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 06/12] memory: Rename memory_region_has_guest_memfd() to *_private() Michael Roth
` (7 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 8cf27ad67e..bb7323d2bf 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 e21c5a3f2e..d917a94d73 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 b07d5dc542..96e42beb2e 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -3597,7 +3597,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 156853c8db..db3dda563d 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2184,7 +2184,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()) {
@@ -2322,7 +2322,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);
@@ -2479,7 +2479,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);
@@ -2562,7 +2562,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);
}
@@ -2838,7 +2838,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] 17+ messages in thread* [PATCH v6 06/12] memory: Rename memory_region_has_guest_memfd() to *_private()
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (4 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 05/12] memory: Rename RAM_GUEST_MEMFD to RAM_GUEST_MEMFD_PRIVATE Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 07/12] hostmem: Rename guest_memfd to guest_memfd_private Michael Roth
` (6 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 a29b1d7a3c..db52bb9ffb 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 96e42beb2e..fa0a2cf563 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1778,7 +1778,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] 17+ messages in thread* [PATCH v6 07/12] hostmem: Rename guest_memfd to guest_memfd_private
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (5 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 06/12] memory: Rename memory_region_has_guest_memfd() to *_private() Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 08/12] machine: Rename machine_require_guest_memfd() to *_private() Michael Roth
` (5 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 bb7323d2bf..7efecf71f5 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 d917a94d73..7a7855aaab 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 02846b597d..a41540d50d 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] 17+ messages in thread* [PATCH v6 08/12] machine: Rename machine_require_guest_memfd() to *_private()
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (6 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 07/12] hostmem: Rename guest_memfd to guest_memfd_private Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 09/12] memory: Rename memory_region_init_ram_guest_memfd() " Michael Roth
` (4 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
From: Peter Xu <peterx@redhat.com>
Differentiate 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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 a41540d50d..8782c8b1ea 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 92f7be52a1..438624ece3 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 b649f184de..2fd90fa739 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 441e777191..b6a56ef1fd 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 ae58352760..59e92b1a1b 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 3b86724cf0..d0e4ad9820 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] 17+ messages in thread* [PATCH v6 09/12] memory: Rename memory_region_init_ram_guest_memfd() to *_private()
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (7 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 08/12] machine: Rename machine_require_guest_memfd() to *_private() Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 10/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
` (3 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
From: Peter Xu <peterx@redhat.com>
Differentiate 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>
Reviewed-by: David Hildenbrand <david@kernel.org>
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 ec7bee428b..58f3097e85 100644
--- a/backends/igvm.c
+++ b/backends/igvm.c
@@ -291,8 +291,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 2fd90fa739..1ae0c4f614 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 b6a56ef1fd..6ff0b9baae 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 59e92b1a1b..fa18bf1aec 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 fa0a2cf563..f1910af8a0 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -3592,9 +3592,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] 17+ messages in thread* [PATCH v6 10/12] hostmem: Support fully shared guest memfd to back a VM
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (8 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 09/12] memory: Rename memory_region_init_ram_guest_memfd() " Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-28 6:03 ` Markus Armbruster
2026-09-25 1:43 ` [PATCH v6 11/12] tests/migration-test: Support guest-memfd init shared mem type Michael Roth
` (2 subsequent siblings)
12 siblings, 1 reply; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng, 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,x-guest-memfd=on,share=on
Note that share=on is required with fully shared guest_memfd.
Since guest-memfd is not yet a drop-in replacement for memfd (e.g. lack
of hugepage support), the option is tagged as experimental for now so
that it can be made available for early enablement/testing without
causing any surprises for other users.
PS: there's a trivial touch-up on fd<0 check, because the stub to create
guest-memfd may return negative but not -1.
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: David Hildenbrand <david@kernel.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
[mdr: add accompanying guest-memfd doc, mark as experimental]
Co-developed-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
backends/hostmem-memfd.c | 67 ++++++++++++++++++++--
docs/system/confidential-guest-support.rst | 2 +
docs/system/guest-memfd.rst | 60 +++++++++++++++++++
docs/system/index.rst | 1 +
qapi/qom.json | 7 ++-
5 files changed, 131 insertions(+), 6 deletions(-)
create mode 100644 docs/system/guest-memfd.rst
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 7a7855aaab..a164bb659f 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -18,6 +18,9 @@
#include "qapi/error.h"
#include "qom/object.h"
#include "migration/cpr.h"
+#include "system/kvm.h"
+#include <linux/kvm.h>
+#include "qapi/qapi-visit-common.h"
OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendMemfd, MEMORY_BACKEND_MEMFD)
@@ -28,6 +31,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.
+ */
+ OnOffAuto guest_memfd;
};
static bool
@@ -47,11 +57,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 == ON_OFF_AUTO_ON) {
+ /*
+ * NOTE: x-guest-memfd ignores seal=on/off because it always
+ * implicitly seals the FD by definition.
+ */
+ if (!backend->share) {
+ error_setg(errp, "x-guest-memfd=on must be used with share=on");
+ return false;
+ } else if (m->hugetlb) {
+ error_setg(errp, "x-guest-memfd=on doesn't support hugetlb=on");
+ 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 +95,26 @@ have_fd:
backend->size, ram_flags, fd, 0, errp);
}
+static void
+memfd_backend_get_guest_memfd(Object *o, Visitor *v,
+ const char *value, void *opaque,
+ Error **errp)
+{
+ HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(o);
+
+ visit_type_OnOffAuto(v, value, &m->guest_memfd, errp);
+}
+
+static void
+memfd_backend_set_guest_memfd(Object *o, Visitor *v,
+ const char *value, void *opaque,
+ Error **errp)
+{
+ HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(o);
+
+ visit_type_OnOffAuto(v, value, &m->guest_memfd, errp);
+}
+
static bool
memfd_backend_get_hugetlb(Object *o, Error **errp)
{
@@ -152,6 +202,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(oc, "x-guest-memfd", "OnOffAuto",
+ memfd_backend_get_guest_memfd,
+ memfd_backend_set_guest_memfd, NULL, NULL);
+ object_class_property_set_description(oc, "x-guest-memfd",
+ "Use guest memfd");
+
object_class_property_add_bool(oc, "seal",
memfd_backend_get_seal,
memfd_backend_set_seal);
diff --git a/docs/system/confidential-guest-support.rst b/docs/system/confidential-guest-support.rst
index 562a7c3c28..58732d658f 100644
--- a/docs/system/confidential-guest-support.rst
+++ b/docs/system/confidential-guest-support.rst
@@ -1,3 +1,5 @@
+.. _confidential-guest-support:
+
Confidential Guest Support
==========================
diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst
new file mode 100644
index 0000000000..f7cef19283
--- /dev/null
+++ b/docs/system/guest-memfd.rst
@@ -0,0 +1,60 @@
+.. _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 Guest architectures. (For more
+on Confidential Guests, see :ref:`confidential-guest-support`).
+
+guest_memfd 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 guest's state across kexec to allow for live-updating
+the host kernel with minimal guest downtime[2].
+
+Usage
+-----
+
+For Confidential Guests, 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 Guests that rely on this handling and is not directly
+exposed by QEMU command-line options.
+
+For non-Confidential guests, 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 'x-guest-memfd=on' option. E.g.::
+
+ qemu ... \
+ -object memory-backend-memfd,id=ID,size=SIZE,share=on,x-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.
+
+Also note that there are a couple of limitations in using guest_memfd
+in this way compared to a normal memfd, which is why the option is
+exposed as an experimental for the time being:
+
+ * guest_memfd does not currently support the hugetlb=on option
+ * guest_memfd does not currently support Transparent Huge Pages
+
+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
diff --git a/qapi/qom.json b/qapi/qom.json
index 5895c97750..602b17ad83 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -780,13 +780,18 @@
# @seal: if true, create a sealed-file, which will block further
# resizing of the memory (default: true)
#
+# @x-guest-memfd: if 'on', use guest-memfd to back the memory region.
+# See the "guest-memfd" QEMU documentation for more details.
+# (default: auto, since: 11.2)
+#
# Since: 2.12
##
{ 'struct': 'MemoryBackendMemfdProperties',
'base': 'MemoryBackendProperties',
'data': { '*hugetlb': 'bool',
'*hugetlbsize': 'size',
- '*seal': 'bool' },
+ '*seal': 'bool',
+ '*x-guest-memfd': 'OnOffAuto' },
'if': 'CONFIG_LINUX' }
##
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v6 10/12] hostmem: Support fully shared guest memfd to back a VM
2026-09-25 1:43 ` [PATCH v6 10/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
@ 2026-09-28 6:03 ` Markus Armbruster
2026-09-29 23:48 ` Michael Roth
0 siblings, 1 reply; 17+ messages in thread
From: Markus Armbruster @ 2026-09-28 6:03 UTC (permalink / raw)
To: Michael Roth
Cc: qemu-devel, david, pbonzini, peterx, xiaoyao.li, berrange,
pankaj.gupta, chao.p.peng, 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,x-guest-memfd=on,share=on
>
> Note that share=on is required with fully shared guest_memfd.
>
> Since guest-memfd is not yet a drop-in replacement for memfd (e.g. lack
> of hugepage support), the option is tagged as experimental for now so
> that it can be made available for early enablement/testing without
> causing any surprises for other users.
>
> PS: there's a trivial touch-up on fd<0 check, because the stub to create
> guest-memfd may return negative but not -1.
>
> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Reviewed-by: David Hildenbrand <david@kernel.org>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> [mdr: add accompanying guest-memfd doc, mark as experimental]
> Co-developed-by: Michael Roth <michael.roth@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
[...]
> diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst
> new file mode 100644
> index 0000000000..f7cef19283
> --- /dev/null
> +++ b/docs/system/guest-memfd.rst
> @@ -0,0 +1,60 @@
> +.. _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 Guest architectures. (For more
> +on Confidential Guests, see :ref:`confidential-guest-support`).
> +
> +guest_memfd 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 guest's state across kexec to allow for live-updating
> +the host kernel with minimal guest downtime[2].
> +
> +Usage
> +-----
> +
> +For Confidential Guests, 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 Guests that rely on this handling and is not directly
> +exposed by QEMU command-line options.
> +
> +For non-Confidential guests, 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 'x-guest-memfd=on' option. E.g.::
> +
> + qemu ... \
> + -object memory-backend-memfd,id=ID,size=SIZE,share=on,x-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.
> +
> +Also note that there are a couple of limitations in using guest_memfd
> +in this way compared to a normal memfd, which is why the option is
> +exposed as an experimental for the time being:
> +
> + * guest_memfd does not currently support the hugetlb=on option
> + * guest_memfd does not currently support Transparent Huge Pages
> +
> +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/>`__
This is helpful, thanks.
> 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
> diff --git a/qapi/qom.json b/qapi/qom.json
> index 5895c97750..602b17ad83 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -780,13 +780,18 @@
> # @seal: if true, create a sealed-file, which will block further
> # resizing of the memory (default: true)
> #
> +# @x-guest-memfd: if 'on', use guest-memfd to back the memory region.
> +# See the "guest-memfd" QEMU documentation for more details.
Can you make this a link? Try :doc:`/system/guest-memfd`.
> +# (default: auto, since: 11.2)
What does 'auto' mean?
> +#
> # Since: 2.12
> ##
> { 'struct': 'MemoryBackendMemfdProperties',
> 'base': 'MemoryBackendProperties',
> 'data': { '*hugetlb': 'bool',
> '*hugetlbsize': 'size',
> - '*seal': 'bool' },
> + '*seal': 'bool',
> + '*x-guest-memfd': 'OnOffAuto' },
You forgot to mark the member unstable. Use
{ 'name': 'x-guest-memfd', 'features': [ 'unstable' ] }
This will make the generator demand documentation. Add this
# Features:
#
# @unstable: Member @x-guest-memfd is experimental.
between the member descriptions and "Since:".
The 'x-' name prefix is fine, but not required; the feature is the sole
source of truth. The prefix can serve as an additional signal to human
users. Drawback: you have to rename when the member becomes stable. Up
to you.
> 'if': 'CONFIG_LINUX' }
>
> ##
^ permalink raw reply [flat|nested] 17+ messages in thread* Re: [PATCH v6 10/12] hostmem: Support fully shared guest memfd to back a VM
2026-09-28 6:03 ` Markus Armbruster
@ 2026-09-29 23:48 ` Michael Roth
0 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-29 23:48 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, david, pbonzini, peterx, xiaoyao.li, berrange,
pankaj.gupta, chao.p.peng, Fabiano Rosas
On Mon, Sep 28, 2026 at 08:03:42AM +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,x-guest-memfd=on,share=on
> >
> > Note that share=on is required with fully shared guest_memfd.
> >
> > Since guest-memfd is not yet a drop-in replacement for memfd (e.g. lack
> > of hugepage support), the option is tagged as experimental for now so
> > that it can be made available for early enablement/testing without
> > causing any surprises for other users.
> >
> > PS: there's a trivial touch-up on fd<0 check, because the stub to create
> > guest-memfd may return negative but not -1.
> >
> > Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
> > Reviewed-by: Fabiano Rosas <farosas@suse.de>
> > Reviewed-by: David Hildenbrand <david@kernel.org>
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > [mdr: add accompanying guest-memfd doc, mark as experimental]
> > Co-developed-by: Michael Roth <michael.roth@amd.com>
> > Signed-off-by: Michael Roth <michael.roth@amd.com>
>
> [...]
>
> > diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst
> > new file mode 100644
> > index 0000000000..f7cef19283
> > --- /dev/null
> > +++ b/docs/system/guest-memfd.rst
> > @@ -0,0 +1,60 @@
> > +.. _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 Guest architectures. (For more
> > +on Confidential Guests, see :ref:`confidential-guest-support`).
> > +
> > +guest_memfd 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 guest's state across kexec to allow for live-updating
> > +the host kernel with minimal guest downtime[2].
> > +
> > +Usage
> > +-----
> > +
> > +For Confidential Guests, 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 Guests that rely on this handling and is not directly
> > +exposed by QEMU command-line options.
> > +
> > +For non-Confidential guests, 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 'x-guest-memfd=on' option. E.g.::
> > +
> > + qemu ... \
> > + -object memory-backend-memfd,id=ID,size=SIZE,share=on,x-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.
> > +
> > +Also note that there are a couple of limitations in using guest_memfd
> > +in this way compared to a normal memfd, which is why the option is
> > +exposed as an experimental for the time being:
> > +
> > + * guest_memfd does not currently support the hugetlb=on option
> > + * guest_memfd does not currently support Transparent Huge Pages
> > +
> > +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/>`__
>
> This is helpful, thanks.
>
> > 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
> > diff --git a/qapi/qom.json b/qapi/qom.json
> > index 5895c97750..602b17ad83 100644
> > --- a/qapi/qom.json
> > +++ b/qapi/qom.json
> > @@ -780,13 +780,18 @@
> > # @seal: if true, create a sealed-file, which will block further
> > # resizing of the memory (default: true)
> > #
> > +# @x-guest-memfd: if 'on', use guest-memfd to back the memory region.
> > +# See the "guest-memfd" QEMU documentation for more details.
>
> Can you make this a link? Try :doc:`/system/guest-memfd`.
That works, thanks.
>
> > +# (default: auto, since: 11.2)
>
> What does 'auto' mean?
I've added some documentation for this in v7.
>
> > +#
> > # Since: 2.12
> > ##
> > { 'struct': 'MemoryBackendMemfdProperties',
> > 'base': 'MemoryBackendProperties',
> > 'data': { '*hugetlb': 'bool',
> > '*hugetlbsize': 'size',
> > - '*seal': 'bool' },
> > + '*seal': 'bool',
> > + '*x-guest-memfd': 'OnOffAuto' },
>
> You forgot to mark the member unstable. Use
>
> { 'name': 'x-guest-memfd', 'features': [ 'unstable' ] }
>
> This will make the generator demand documentation. Add this
>
> # Features:
> #
> # @unstable: Member @x-guest-memfd is experimental.
>
> between the member descriptions and "Since:".
>
> The 'x-' name prefix is fine, but not required; the feature is the sole
> source of truth. The prefix can serve as an additional signal to human
> users. Drawback: you have to rename when the member becomes stable. Up
> to you.
Thanks, I'd somehow missed that 'unstable' features deprecated the old school
"x-" stuff. Hopefully I got it right in v7 :) Based on Peter's recommendation
I went with 'guest-memfd'.
Thanks,
Mike
>
> > 'if': 'CONFIG_LINUX' }
> >
> > ##
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v6 11/12] tests/migration-test: Support guest-memfd init shared mem type
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (9 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 10/12] hostmem: Support fully shared guest memfd to back a VM Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 1:43 ` [PATCH v6 12/12] tests/migration-test: Add a precopy test for guest-memfd Michael Roth
2026-09-25 13:04 ` [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Peter Xu
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
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..93225e3720 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,x-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] 17+ messages in thread* [PATCH v6 12/12] tests/migration-test: Add a precopy test for guest-memfd
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (10 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 11/12] tests/migration-test: Support guest-memfd init shared mem type Michael Roth
@ 2026-09-25 1:43 ` Michael Roth
2026-09-25 13:04 ` [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Peter Xu
12 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-25 1:43 UTC (permalink / raw)
To: qemu-devel
Cc: david, pbonzini, peterx, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng, 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] 17+ messages in thread* Re: [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends
2026-09-25 1:43 [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Michael Roth
` (11 preceding siblings ...)
2026-09-25 1:43 ` [PATCH v6 12/12] tests/migration-test: Add a precopy test for guest-memfd Michael Roth
@ 2026-09-25 13:04 ` Peter Xu
2026-09-29 23:44 ` Michael Roth
12 siblings, 1 reply; 17+ messages in thread
From: Peter Xu @ 2026-09-25 13:04 UTC (permalink / raw)
To: Michael Roth
Cc: qemu-devel, david, pbonzini, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
On Thu, Sep 24, 2026 at 08:43:06PM -0500, 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: https://lore.kernel.org/qemu-devel/20260908133151.836685-1-michael.roth@amd.com/
> v6:
> - Rename the hostmem property to 'x-guest-memfd' since initial users
> are expected to be developers or early enablers (Markus)
> - Introduce accompanying 'guest-memfd' RST doc and reference it in
> the QAPI schema documentation for x-guest-memfd (Markus)
> - Move all renaming patches toward beginning of the series for
> consistency (David)
> - Fix mispellings in commit messages (David)
> - Drop ramlist lock in new ram_block_add() error path
> - Collect Reviewed-by's
> - Rebase on QEMU master
Michael,
Sorry, I missed your very last discussion with Markus.. only notice until
I saw the repost. I agree we can mark it experimental, but just to mention
we should have moved to use "unstable" rather than prefix "x-", then we
don't need to bother with the ABI change, see:
commit a3c45b3e62962f99338716b1347cfb0d427cea44
Author: Markus Armbruster <armbru@redhat.com>
Date: Thu Oct 28 12:25:12 2021 +0200
qapi: New special feature flag "unstable"
No need for another repost, I can manage that with two fixups when queue,
please shoot if there's any objections. Attached at the end.
Thanks,
===8<===
From 94884f136d9d42044e3f4cfcf440df8016ad3e99 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Fri, 25 Sep 2026 08:51:13 -0400
Subject: [PATCH 1/2] fixup! hostmem: Support fully shared guest memfd to back
a VM
Signed-off-by: Peter Xu <peterx@redhat.com>
---
docs/system/guest-memfd.rst | 4 ++--
qapi/qom.json | 9 +++++++--
backends/hostmem-memfd.c | 10 +++++-----
3 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst
index f7cef19283..d62a214a91 100644
--- a/docs/system/guest-memfd.rst
+++ b/docs/system/guest-memfd.rst
@@ -38,10 +38,10 @@ exposed by QEMU command-line options.
For non-Confidential guests, 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 'x-guest-memfd=on' option. E.g.::
+with an additional 'guest-memfd=on' option. E.g.::
qemu ... \
- -object memory-backend-memfd,id=ID,size=SIZE,share=on,x-guest-memfd=on
+ -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.
diff --git a/qapi/qom.json b/qapi/qom.json
index 602b17ad83..7423acea8f 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -780,10 +780,14 @@
# @seal: if true, create a sealed-file, which will block further
# resizing of the memory (default: true)
#
-# @x-guest-memfd: if 'on', use guest-memfd to back the memory region.
+# @guest-memfd: if 'on', use guest-memfd to back the memory region.
# See the "guest-memfd" QEMU documentation for more details.
# (default: auto, since: 11.2)
#
+# Features:
+#
+# @unstable: Member @guest-memfd is experimental.
+#
# Since: 2.12
##
{ 'struct': 'MemoryBackendMemfdProperties',
@@ -791,7 +795,8 @@
'data': { '*hugetlb': 'bool',
'*hugetlbsize': 'size',
'*seal': 'bool',
- '*x-guest-memfd': 'OnOffAuto' },
+ '*guest-memfd': { 'type': 'OnOffAuto',
+ 'features': [ 'unstable' ] } },
'if': 'CONFIG_LINUX' }
##
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index a164bb659f..666593ff6c 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -59,14 +59,14 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
if (m->guest_memfd == ON_OFF_AUTO_ON) {
/*
- * NOTE: x-guest-memfd ignores seal=on/off because it always
+ * NOTE: guest-memfd ignores seal=on/off because it always
* implicitly seals the FD by definition.
*/
if (!backend->share) {
- error_setg(errp, "x-guest-memfd=on must be used with share=on");
+ error_setg(errp, "guest-memfd=on must be used with share=on");
return false;
} else if (m->hugetlb) {
- error_setg(errp, "x-guest-memfd=on doesn't support hugetlb=on");
+ error_setg(errp, "guest-memfd=on doesn't support hugetlb=on");
return false;
}
@@ -203,10 +203,10 @@ memfd_backend_class_init(ObjectClass *oc, const void *data)
"Huge pages size (ex: 2M, 1G)");
}
- object_class_property_add(oc, "x-guest-memfd", "OnOffAuto",
+ object_class_property_add(oc, "guest-memfd", "OnOffAuto",
memfd_backend_get_guest_memfd,
memfd_backend_set_guest_memfd, NULL, NULL);
- object_class_property_set_description(oc, "x-guest-memfd",
+ object_class_property_set_description(oc, "guest-memfd",
"Use guest memfd");
object_class_property_add_bool(oc, "seal",
--
2.55.0
From efb5a9d33373e0dcedbfec3dce28844164ccb8c8 Mon Sep 17 00:00:00 2001
From: Peter Xu <peterx@redhat.com>
Date: Fri, 25 Sep 2026 08:51:26 -0400
Subject: [PATCH 2/2] fixup! tests/migration-test: Support guest-memfd init
shared mem type
Signed-off-by: Peter Xu <peterx@redhat.com>
---
tests/qtest/migration/framework.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index 93225e3720..b7aef6b21c 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -301,7 +301,7 @@ static char *migrate_mem_type_get_opts(MemType type, const char *memory_size)
backend = g_strdup("-object memory-backend-memfd");
break;
case MEM_TYPE_GUEST_MEMFD:
- backend = g_strdup("-object memory-backend-memfd,x-guest-memfd=on");
+ backend = g_strdup("-object memory-backend-memfd,guest-memfd=on");
break;
default:
g_assert_not_reached();
--
2.55.0
--
Peter Xu
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends
2026-09-25 13:04 ` [PATCH v6 00/12] KVM/hostmem: Support init-shared guest-memfd as VM backends Peter Xu
@ 2026-09-29 23:44 ` Michael Roth
0 siblings, 0 replies; 17+ messages in thread
From: Michael Roth @ 2026-09-29 23:44 UTC (permalink / raw)
To: Peter Xu
Cc: qemu-devel, david, pbonzini, xiaoyao.li, berrange, armbru,
pankaj.gupta, chao.p.peng
On Fri, Sep 25, 2026 at 09:04:14AM -0400, Peter Xu wrote:
> On Thu, Sep 24, 2026 at 08:43:06PM -0500, 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: https://lore.kernel.org/qemu-devel/20260908133151.836685-1-michael.roth@amd.com/
> > v6:
> > - Rename the hostmem property to 'x-guest-memfd' since initial users
> > are expected to be developers or early enablers (Markus)
> > - Introduce accompanying 'guest-memfd' RST doc and reference it in
> > the QAPI schema documentation for x-guest-memfd (Markus)
> > - Move all renaming patches toward beginning of the series for
> > consistency (David)
> > - Fix mispellings in commit messages (David)
> > - Drop ramlist lock in new ram_block_add() error path
> > - Collect Reviewed-by's
> > - Rebase on QEMU master
>
> Michael,
>
> Sorry, I missed your very last discussion with Markus.. only notice until
> I saw the repost. I agree we can mark it experimental, but just to mention
> we should have moved to use "unstable" rather than prefix "x-", then we
> don't need to bother with the ABI change, see:
>
> commit a3c45b3e62962f99338716b1347cfb0d427cea44
> Author: Markus Armbruster <armbru@redhat.com>
> Date: Thu Oct 28 12:25:12 2021 +0200
>
> qapi: New special feature flag "unstable"
>
> No need for another repost, I can manage that with two fixups when queue,
> please shoot if there's any objections. Attached at the end.
Thanks Peter, the fixups look good. Since Markus pointed out a couple
other things to fix up I went ahead and squashed these into v7 which
will go out shortly.
Thanks,
Mike
>
> Thanks,
>
> ===8<===
> From 94884f136d9d42044e3f4cfcf440df8016ad3e99 Mon Sep 17 00:00:00 2001
> From: Peter Xu <peterx@redhat.com>
> Date: Fri, 25 Sep 2026 08:51:13 -0400
> Subject: [PATCH 1/2] fixup! hostmem: Support fully shared guest memfd to back
> a VM
>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
> docs/system/guest-memfd.rst | 4 ++--
> qapi/qom.json | 9 +++++++--
> backends/hostmem-memfd.c | 10 +++++-----
> 3 files changed, 14 insertions(+), 9 deletions(-)
>
> diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst
> index f7cef19283..d62a214a91 100644
> --- a/docs/system/guest-memfd.rst
> +++ b/docs/system/guest-memfd.rst
> @@ -38,10 +38,10 @@ exposed by QEMU command-line options.
> For non-Confidential guests, 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 'x-guest-memfd=on' option. E.g.::
> +with an additional 'guest-memfd=on' option. E.g.::
>
> qemu ... \
> - -object memory-backend-memfd,id=ID,size=SIZE,share=on,x-guest-memfd=on
> + -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.
> diff --git a/qapi/qom.json b/qapi/qom.json
> index 602b17ad83..7423acea8f 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -780,10 +780,14 @@
> # @seal: if true, create a sealed-file, which will block further
> # resizing of the memory (default: true)
> #
> -# @x-guest-memfd: if 'on', use guest-memfd to back the memory region.
> +# @guest-memfd: if 'on', use guest-memfd to back the memory region.
> # See the "guest-memfd" QEMU documentation for more details.
> # (default: auto, since: 11.2)
> #
> +# Features:
> +#
> +# @unstable: Member @guest-memfd is experimental.
> +#
> # Since: 2.12
> ##
> { 'struct': 'MemoryBackendMemfdProperties',
> @@ -791,7 +795,8 @@
> 'data': { '*hugetlb': 'bool',
> '*hugetlbsize': 'size',
> '*seal': 'bool',
> - '*x-guest-memfd': 'OnOffAuto' },
> + '*guest-memfd': { 'type': 'OnOffAuto',
> + 'features': [ 'unstable' ] } },
> 'if': 'CONFIG_LINUX' }
>
> ##
> diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
> index a164bb659f..666593ff6c 100644
> --- a/backends/hostmem-memfd.c
> +++ b/backends/hostmem-memfd.c
> @@ -59,14 +59,14 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
>
> if (m->guest_memfd == ON_OFF_AUTO_ON) {
> /*
> - * NOTE: x-guest-memfd ignores seal=on/off because it always
> + * NOTE: guest-memfd ignores seal=on/off because it always
> * implicitly seals the FD by definition.
> */
> if (!backend->share) {
> - error_setg(errp, "x-guest-memfd=on must be used with share=on");
> + error_setg(errp, "guest-memfd=on must be used with share=on");
> return false;
> } else if (m->hugetlb) {
> - error_setg(errp, "x-guest-memfd=on doesn't support hugetlb=on");
> + error_setg(errp, "guest-memfd=on doesn't support hugetlb=on");
> return false;
> }
>
> @@ -203,10 +203,10 @@ memfd_backend_class_init(ObjectClass *oc, const void *data)
> "Huge pages size (ex: 2M, 1G)");
> }
>
> - object_class_property_add(oc, "x-guest-memfd", "OnOffAuto",
> + object_class_property_add(oc, "guest-memfd", "OnOffAuto",
> memfd_backend_get_guest_memfd,
> memfd_backend_set_guest_memfd, NULL, NULL);
> - object_class_property_set_description(oc, "x-guest-memfd",
> + object_class_property_set_description(oc, "guest-memfd",
> "Use guest memfd");
>
> object_class_property_add_bool(oc, "seal",
> --
> 2.55.0
>
>
> From efb5a9d33373e0dcedbfec3dce28844164ccb8c8 Mon Sep 17 00:00:00 2001
> From: Peter Xu <peterx@redhat.com>
> Date: Fri, 25 Sep 2026 08:51:26 -0400
> Subject: [PATCH 2/2] fixup! tests/migration-test: Support guest-memfd init
> shared mem type
>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
> tests/qtest/migration/framework.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
> index 93225e3720..b7aef6b21c 100644
> --- a/tests/qtest/migration/framework.c
> +++ b/tests/qtest/migration/framework.c
> @@ -301,7 +301,7 @@ static char *migrate_mem_type_get_opts(MemType type, const char *memory_size)
> backend = g_strdup("-object memory-backend-memfd");
> break;
> case MEM_TYPE_GUEST_MEMFD:
> - backend = g_strdup("-object memory-backend-memfd,x-guest-memfd=on");
> + backend = g_strdup("-object memory-backend-memfd,guest-memfd=on");
> break;
> default:
> g_assert_not_reached();
> --
> 2.55.0
>
>
>
> --
> Peter Xu
>
^ permalink raw reply [flat|nested] 17+ messages in thread