memory_region_init_ram_guest_memfd() 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 | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/system/memory.c b/system/memory.c index 739ba11da6..f6c695fd23 100644 --- a/system/memory.c +++ b/system/memory.c @@ -35,6 +35,7 @@ #include "hw/core/boards.h" #include "migration/vmstate.h" #include "system/address-spaces.h" +#include "system/confidential-guest-support.h" #include "memory-internal.h" @@ -3674,10 +3675,25 @@ bool memory_region_init_ram_guest_memfd(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, errp)) { - return false; + if (current_machine->cgs && current_machine->cgs->convert_in_place) { + int fd = kvm_create_guest_memfd_shared(size, errp); + if (fd < 0) { + return false; + } + + if (!memory_region_init_ram_from_fd(mr, owner, name, size, + RAM_SHARED | RAM_GUEST_MEMFD | + RAM_GUEST_MEMFD_SHARED, + fd, 0, errp)) { + return false; + } + } else { + if (!memory_region_init_ram_flags_nomigrate(mr, owner, name, size, + RAM_GUEST_MEMFD, errp)) { + return false; + } } + memory_region_register_ram(mr, owner); return true; } -- 2.43.0
