14e647fa0SStefano Garzarella /* 24e647fa0SStefano Garzarella * QEMU host POSIX shared memory object backend 34e647fa0SStefano Garzarella * 44e647fa0SStefano Garzarella * Copyright (C) 2024 Red Hat Inc 54e647fa0SStefano Garzarella * 64e647fa0SStefano Garzarella * Authors: 74e647fa0SStefano Garzarella * Stefano Garzarella <sgarzare@redhat.com> 84e647fa0SStefano Garzarella * 94e647fa0SStefano Garzarella * This work is licensed under the terms of the GNU GPL, version 2 or later. 104e647fa0SStefano Garzarella * See the COPYING file in the top-level directory. 114e647fa0SStefano Garzarella */ 124e647fa0SStefano Garzarella 134e647fa0SStefano Garzarella #include "qemu/osdep.h" 1432cad1ffSPhilippe Mathieu-Daudé #include "system/hostmem.h" 154e647fa0SStefano Garzarella #include "qapi/error.h" 162ef12168SSteve Sistare #include "migration/cpr.h" 174e647fa0SStefano Garzarella 184e647fa0SStefano Garzarella #define TYPE_MEMORY_BACKEND_SHM "memory-backend-shm" 194e647fa0SStefano Garzarella 204e647fa0SStefano Garzarella OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendShm, MEMORY_BACKEND_SHM) 214e647fa0SStefano Garzarella 224e647fa0SStefano Garzarella struct HostMemoryBackendShm { 234e647fa0SStefano Garzarella HostMemoryBackend parent_obj; 244e647fa0SStefano Garzarella }; 254e647fa0SStefano Garzarella 264e647fa0SStefano Garzarella static bool 274e647fa0SStefano Garzarella shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) 284e647fa0SStefano Garzarella { 292ef12168SSteve Sistare g_autofree char *backend_name = host_memory_backend_get_name(backend); 304e647fa0SStefano Garzarella uint32_t ram_flags; 312ef12168SSteve Sistare int fd = cpr_find_fd(backend_name, 0); 324e647fa0SStefano Garzarella 334e647fa0SStefano Garzarella if (!backend->size) { 344e647fa0SStefano Garzarella error_setg(errp, "can't create shm backend with size 0"); 354e647fa0SStefano Garzarella return false; 364e647fa0SStefano Garzarella } 374e647fa0SStefano Garzarella 384e647fa0SStefano Garzarella if (!backend->share) { 394e647fa0SStefano Garzarella error_setg(errp, "can't create shm backend with `share=off`"); 404e647fa0SStefano Garzarella return false; 414e647fa0SStefano Garzarella } 424e647fa0SStefano Garzarella 432ef12168SSteve Sistare if (fd >= 0) { 442ef12168SSteve Sistare goto have_fd; 452ef12168SSteve Sistare } 462ef12168SSteve Sistare 4757ad6ab8SSteve Sistare fd = qemu_shm_alloc(backend->size, errp); 484e647fa0SStefano Garzarella if (fd < 0) { 494e647fa0SStefano Garzarella return false; 504e647fa0SStefano Garzarella } 512ef12168SSteve Sistare cpr_save_fd(backend_name, 0, fd); 524e647fa0SStefano Garzarella 532ef12168SSteve Sistare have_fd: 5457ad6ab8SSteve Sistare /* Let's do the same as memory-backend-ram,share=on would do. */ 554e647fa0SStefano Garzarella ram_flags = RAM_SHARED; 564e647fa0SStefano Garzarella ram_flags |= backend->reserve ? 0 : RAM_NORESERVE; 574e647fa0SStefano Garzarella 584e647fa0SStefano Garzarella return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), 594e647fa0SStefano Garzarella backend_name, backend->size, 604e647fa0SStefano Garzarella ram_flags, fd, 0, errp); 614e647fa0SStefano Garzarella } 624e647fa0SStefano Garzarella 634e647fa0SStefano Garzarella static void 644e647fa0SStefano Garzarella shm_backend_instance_init(Object *obj) 654e647fa0SStefano Garzarella { 664e647fa0SStefano Garzarella HostMemoryBackendShm *m = MEMORY_BACKEND_SHM(obj); 674e647fa0SStefano Garzarella 684e647fa0SStefano Garzarella MEMORY_BACKEND(m)->share = true; 694e647fa0SStefano Garzarella } 704e647fa0SStefano Garzarella 714e647fa0SStefano Garzarella static void 72*12d1a768SPhilippe Mathieu-Daudé shm_backend_class_init(ObjectClass *oc, const void *data) 734e647fa0SStefano Garzarella { 744e647fa0SStefano Garzarella HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc); 754e647fa0SStefano Garzarella 764e647fa0SStefano Garzarella bc->alloc = shm_backend_memory_alloc; 774e647fa0SStefano Garzarella } 784e647fa0SStefano Garzarella 794e647fa0SStefano Garzarella static const TypeInfo shm_backend_info = { 804e647fa0SStefano Garzarella .name = TYPE_MEMORY_BACKEND_SHM, 814e647fa0SStefano Garzarella .parent = TYPE_MEMORY_BACKEND, 824e647fa0SStefano Garzarella .instance_init = shm_backend_instance_init, 834e647fa0SStefano Garzarella .class_init = shm_backend_class_init, 844e647fa0SStefano Garzarella .instance_size = sizeof(HostMemoryBackendShm), 854e647fa0SStefano Garzarella }; 864e647fa0SStefano Garzarella 874e647fa0SStefano Garzarella static void register_types(void) 884e647fa0SStefano Garzarella { 894e647fa0SStefano Garzarella type_register_static(&shm_backend_info); 904e647fa0SStefano Garzarella } 914e647fa0SStefano Garzarella 924e647fa0SStefano Garzarella type_init(register_types); 93