memory_region_init_ram_guest_memfd_private() is called in some cases (legacy BIOS regions / IGVM regions) to allocate a new RAM region with a guest_memfd FD under the covers to handle private memory since the GPA range can be converted between shared/private guest RAM.
When in-place conversion is enabled, the conversions happen with the guest_memfd inode itself, so the same inode must be used for both shared and private memory. Handle this accordingly when convert-in-place=true. Signed-off-by: Michael Roth <[email protected]> --- system/memory.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/system/memory.c b/system/memory.c index b3b678617b..ba3ef27b58 100644 --- a/system/memory.c +++ b/system/memory.c @@ -3623,10 +3623,27 @@ bool memory_region_init_ram_guest_memfd_private(MemoryRegion *mr, uint64_t size, Error **errp) { - if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, size, - RAM_GUEST_MEMFD_PRIVATE, errp)) { - return false; + if (machine_require_guest_memfd_convert_in_place(current_machine)) { + int fd = kvm_create_guest_memfd(size, errp); + if (fd < 0) { + return false; + } + + if (!memory_region_init_ram_from_fd(mr, owner, name, size, + RAM_SHARED | + RAM_GUEST_MEMFD_PRIVATE | + RAM_GUEST_MEMFD_SHARED, + fd, 0, errp)) { + close(fd); + return false; + } + } else { + if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, size, + RAM_GUEST_MEMFD_PRIVATE, errp)) { + return false; + } } + memory_region_register_ram(mr, owner); return true; } -- 2.43.0
