1 /* 2 * QEMU host POSIX shared memory object backend 3 * 4 * Copyright (C) 2024 Red Hat Inc 5 * 6 * Authors: 7 * Stefano Garzarella <sgarzare@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "system/hostmem.h" 15 #include "qapi/error.h" 16 17 #define TYPE_MEMORY_BACKEND_SHM "memory-backend-shm" 18 19 OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendShm, MEMORY_BACKEND_SHM) 20 21 struct HostMemoryBackendShm { 22 HostMemoryBackend parent_obj; 23 }; 24 25 static bool 26 shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) 27 { 28 g_autofree char *backend_name = NULL; 29 uint32_t ram_flags; 30 int fd; 31 32 if (!backend->size) { 33 error_setg(errp, "can't create shm backend with size 0"); 34 return false; 35 } 36 37 if (!backend->share) { 38 error_setg(errp, "can't create shm backend with `share=off`"); 39 return false; 40 } 41 42 fd = qemu_shm_alloc(backend->size, errp); 43 if (fd < 0) { 44 return false; 45 } 46 47 /* Let's do the same as memory-backend-ram,share=on would do. */ 48 backend_name = host_memory_backend_get_name(backend); 49 ram_flags = RAM_SHARED; 50 ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; 51 52 return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), 53 backend_name, backend->size, 54 ram_flags, fd, 0, errp); 55 } 56 57 static void 58 shm_backend_instance_init(Object *obj) 59 { 60 HostMemoryBackendShm *m = MEMORY_BACKEND_SHM(obj); 61 62 MEMORY_BACKEND(m)->share = true; 63 } 64 65 static void 66 shm_backend_class_init(ObjectClass *oc, void *data) 67 { 68 HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc); 69 70 bc->alloc = shm_backend_memory_alloc; 71 } 72 73 static const TypeInfo shm_backend_info = { 74 .name = TYPE_MEMORY_BACKEND_SHM, 75 .parent = TYPE_MEMORY_BACKEND, 76 .instance_init = shm_backend_instance_init, 77 .class_init = shm_backend_class_init, 78 .instance_size = sizeof(HostMemoryBackendShm), 79 }; 80 81 static void register_types(void) 82 { 83 type_register_static(&shm_backend_info); 84 } 85 86 type_init(register_types); 87