On 10/24/2025 2:59 AM, Peter Xu wrote:
Guest-memfd is not 100% attached to private, it's a VM-specific memory
provider.  Allow it to be created even without private attributes, for
example, when the VM can use the guest-memfd memory completely shared.

Signed-off-by: Peter Xu <[email protected]>
---
  accel/kvm/kvm-all.c | 6 ++----
  1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f9254ae654..1425dfd8b3 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2779,10 +2779,8 @@ 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_guest_memfd_supported = 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);
if (s->kernel_irqchip_split == ON_OFF_AUTO_AUTO) {


The check on KVM_MEMORY_ATTRIBUTE_PRIVATE is dropped silently. But using guest memfd to serve as private memory does requires the support of KVM_MEMORY_ATTRIBUTE_PRIVATE.

My version of the patch was


Author: Xiaoyao Li <[email protected]>
Date:   Sat Jul 19 00:56:57 2025 +0800

    kvm: Decouple memory attribute check from kvm_guest_memfd_supported

    With the mmap support of guest memfd, KVM allows usersapce to create
    guest memfd serving as normal non-private memory for X86 DEFEAULT VM.
    However, KVM doesn't support private memory attriute 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 QMEU to create guest memfd with mmap to serve as the memory
    backend for X86 DEFAULT VM.

    Signed-off-by: Xiaoyao Li <[email protected]>

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f9254ae65466..96c194ce54cd 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1501,6 +1501,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)
@@ -2781,8 +2786,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 68cd33ba9735..73f04eb589ef 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -125,3 +125,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 8f9eecf044c2..b5811c90f1cc 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -561,6 +561,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 a340ca3e6166..7704572a5745 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2211,6 +2211,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);

Reply via email to