When in-place conversion is enabled, both the shared memory and private memory must come from the same guest_memfd instance. Thus, the memory-backend-memfd options must in turn correspond to a guest_memfd instance, e.g. guest-memfd=on must be specified. Since there is no use-case for enabling in-place conversion without setting guest-memfd=on, just set it automatically if in-place conversion is enabled (unless guest-memfd has been explicitly set to 'off', in which case generate an informative error message).
Also update the 'guest-memfd' documentation to note this behavior. Signed-off-by: Michael Roth <[email protected]> --- backends/hostmem-memfd.c | 13 ++++++++++++- docs/system/guest-memfd.rst | 21 +++++++++++++++++++++ qapi/qom.json | 5 +++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c index d3b17232f0..11873b4e0e 100644 --- a/backends/hostmem-memfd.c +++ b/backends/hostmem-memfd.c @@ -21,6 +21,8 @@ #include "system/kvm.h" #include <linux/kvm.h> #include "qapi/qapi-visit-common.h" +#include "hw/core/boards.h" +#include "hw/core/qdev.h" OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendMemfd, MEMORY_BACKEND_MEMFD) @@ -45,6 +47,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) { HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend); g_autofree char *name = host_memory_backend_get_name(backend); + MachineState *machine = MACHINE(qdev_get_machine()); int fd = cpr_find_fd(name, 0); uint32_t ram_flags; @@ -57,7 +60,9 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) goto have_fd; } - if (m->guest_memfd == ON_OFF_AUTO_ON) { + if (m->guest_memfd == ON_OFF_AUTO_ON || + (m->guest_memfd == ON_OFF_AUTO_AUTO && + machine_require_guest_memfd_convert_in_place(machine))) { /* * NOTE: guest-memfd ignores seal=on/off because it always * implicitly seals the FD by definition. @@ -72,6 +77,12 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) fd = kvm_create_guest_memfd(backend->size, errp); } else { + if (machine_require_guest_memfd_convert_in_place(machine)) { + error_setg(errp, "the current machine requires in-place conversion," + " which is not compatible with setting" + " guest-memfd=off"); + return false; + } 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, diff --git a/docs/system/guest-memfd.rst b/docs/system/guest-memfd.rst index d62a214a91..4477756424 100644 --- a/docs/system/guest-memfd.rst +++ b/docs/system/guest-memfd.rst @@ -53,6 +53,27 @@ 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 +In-place conversion +------------------- + +Newer kernels now support using a guest-memfd instance for both +private and shared memory at the same time by re-using the same +physical backing pages if a guest converts a GPA range between +shared and private. This is known as "in-place conversion". + +For some confidential computing architectures, like SEV-SNP and +TDX, this mode offers better performance due to not needing to +deallocate/reallocate between 2 separate pools of shared vs. private +memory every time the guest converts memory between shared/private. +For other architectures, this is the only supported mode of +operation. + +When in-place conversion is enabled, it is necessary to use the +memory-backend-memfd backend with guest-memfd=on as shown in the +"Usage" section. Because of this, guest-memfd=auto (which is the +default) will result in the parameter being automatically enabled +if the confidential guest type enables in-place conversion. + References ---------- diff --git a/qapi/qom.json b/qapi/qom.json index 84166c2457..5d66e67087 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -756,8 +756,9 @@ # @guest-memfd: if 'on', use guest-memfd to back the memory region. # See the :doc:`/system/guest-memfd` documentation for more # details. If 'auto', the option will default to 'off' -# currently, but in the future it may result in the option being -# set to 'on' for QEMU configurations that explicitly require it. +# unless the QEMU configuration explicitly requires it to be set, +# e.g. if in-place conversion is enabled for confidential guest +# types like sev-snp-guest. # (default: auto, since: 11.2) # # Features: -- 2.43.0
