summary refs log tree commit diff stats
path: root/util/memfd.c
diff options
context:
space:
mode:
authorSteve Sistare <steven.sistare@oracle.com>2025-01-15 11:00:30 -0800
committerFabiano Rosas <farosas@suse.de>2025-01-29 11:43:04 -0300
commit9fb40bb9621df9acb88a8128bee2e0f68631b245 (patch)
tree5ec0edbb677304929c05d749e7bad1f7c207c624 /util/memfd.c
parent3ec02148160a8147187fce211d1251af2c4cf9f1 (diff)
downloadfocaccia-qemu-9fb40bb9621df9acb88a8128bee2e0f68631b245.tar.gz
focaccia-qemu-9fb40bb9621df9acb88a8128bee2e0f68631b245.zip
physmem: fd-based shared memory
Create MAP_SHARED RAMBlocks by mmap'ing a file descriptor rather than using
MAP_ANON, so the memory can be accessed in another process by passing and
mmap'ing the fd.  This will allow CPR to support memory-backend-ram and
memory-backend-shm objects, provided the user creates them with share=on.

Use memfd_create if available because it has no constraints.  If not, use
POSIX shm_open.  However, allocation on the opened fd may fail if the shm
mount size is too small, even if the system has free memory, so for backwards
compatibility fall back to qemu_anon_ram_alloc/MAP_ANON on failure.

For backwards compatibility on Windows, always use MAP_ANON.  share=on has
no purpose there, but the syntax is accepted, and must continue to work.

Lastly, quietly fall back to MAP_ANON if the system does not support
qemu_ram_alloc_from_fd.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/r/1736967650-129648-5-git-send-email-steven.sistare@oracle.com
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Diffstat (limited to 'util/memfd.c')
-rw-r--r--util/memfd.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/util/memfd.c b/util/memfd.c
index 8a2e906962..07beab174d 100644
--- a/util/memfd.c
+++ b/util/memfd.c
@@ -194,17 +194,27 @@ bool qemu_memfd_alloc_check(void)
 /**
  * qemu_memfd_check():
  *
- * Check if host supports memfd.
+ * Check if host supports memfd.  Cache the answer for the common case flags=0.
  */
 bool qemu_memfd_check(unsigned int flags)
 {
 #ifdef CONFIG_LINUX
-    int mfd = memfd_create("test", flags | MFD_CLOEXEC);
+    int mfd;
+    static int memfd_check = MEMFD_TODO;
+
+    if (!flags && memfd_check != MEMFD_TODO) {
+        return memfd_check;
+    }
 
+    mfd = memfd_create("test", flags | MFD_CLOEXEC);
     if (mfd >= 0) {
         close(mfd);
-        return true;
     }
+    if (!flags) {
+        memfd_check = (mfd >= 0) ? MEMFD_OK : MEMFD_KO;
+    }
+    return (mfd >= 0);
+
 #endif
 
     return false;