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


Reply via email to