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 <peterx@redhat.com>
> ---
> 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 <xiaoyao.li@intel.com>
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 <xiaoyao.li@intel.com>
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);