Commit dbcb8981 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Michael S. Tsirkin
Browse files

hostmem: add property to map memory with MAP_SHARED



A new "share" property can be used with the "memory-file" backend to
map memory with MAP_SHARED instead of MAP_PRIVATE.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarHu Tao <hutao@cn.fujitsu.com>
Acked-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent a35ba7be
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile;

struct HostMemoryBackendFile {
    HostMemoryBackend parent_obj;

    bool share;
    char *mem_path;
};

@@ -51,7 +53,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
        backend->force_prealloc = mem_prealloc;
        memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
                                 object_get_canonical_path(OBJECT(backend)),
                                 backend->size,
                                 backend->size, fb->share,
                                 fb->mem_path, errp);
    }
#endif
@@ -87,9 +89,31 @@ static void set_mem_path(Object *o, const char *str, Error **errp)
    fb->mem_path = g_strdup(str);
}

static bool file_memory_backend_get_share(Object *o, Error **errp)
{
    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);

    return fb->share;
}

static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
{
    HostMemoryBackend *backend = MEMORY_BACKEND(o);
    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);

    if (memory_region_size(&backend->mr)) {
        error_setg(errp, "cannot change property value");
        return;
    }
    fb->share = value;
}

static void
file_backend_instance_init(Object *o)
{
    object_property_add_bool(o, "share",
                        file_memory_backend_get_share,
                        file_memory_backend_set_share, NULL);
    object_property_add_str(o, "mem-path", get_mem_path,
                            set_mem_path, NULL);
}
+10 −8
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ static MemoryRegion io_mem_unassigned;
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC   (1 << 0)

/* RAM is mmap-ed with MAP_SHARED */
#define RAM_SHARED     (1 << 1)

#endif

struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -1074,7 +1077,9 @@ static void *file_ram_alloc(RAMBlock *block,
        perror("ftruncate");
    }

    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
    area = mmap(0, memory, PROT_READ | PROT_WRITE,
                (block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE),
                fd, 0);
    if (area == MAP_FAILED) {
        error_setg_errno(errp, errno,
                         "unable to map backing store for hugepages");
@@ -1286,7 +1291,7 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)

#ifdef __linux__
ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
                                    const char *mem_path,
                                    bool share, const char *mem_path,
                                    Error **errp)
{
    RAMBlock *new_block;
@@ -1311,6 +1316,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
    new_block = g_malloc0(sizeof(*new_block));
    new_block->mr = mr;
    new_block->length = size;
    new_block->flags = share ? RAM_SHARED : 0;
    new_block->host = file_ram_alloc(new_block, size,
                                     mem_path, errp);
    if (!new_block->host) {
@@ -1413,12 +1419,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
                flags = MAP_FIXED;
                munmap(vaddr, length);
                if (block->fd >= 0) {
#ifdef MAP_POPULATE
                    flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
                        MAP_PRIVATE;
#else
                    flags |= MAP_PRIVATE;
#endif
                    flags |= (block->flags & RAM_SHARED ?
                              MAP_SHARED : MAP_PRIVATE);
                    area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                flags, block->fd, offset);
                } else {
+2 −0
Original line number Diff line number Diff line
@@ -321,6 +321,7 @@ void memory_region_init_ram(MemoryRegion *mr,
 * @owner: the object that tracks the region's reference count
 * @name: the name of the region.
 * @size: size of the region.
 * @share: %true if memory must be mmaped with the MAP_SHARED flag
 * @path: the path in which to allocate the RAM.
 * @errp: pointer to Error*, to store an error if it happens.
 */
@@ -328,6 +329,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
                                      struct Object *owner,
                                      const char *name,
                                      uint64_t size,
                                      bool share,
                                      const char *path,
                                      Error **errp);
#endif
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
#include "hw/xen/xen.h"

ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
                                    const char *mem_path, Error **errp);
                                    bool share, const char *mem_path,
                                    Error **errp);
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                   MemoryRegion *mr);
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
+2 −1
Original line number Diff line number Diff line
@@ -1038,6 +1038,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
                                      struct Object *owner,
                                      const char *name,
                                      uint64_t size,
                                      bool share,
                                      const char *path,
                                      Error **errp)
{
@@ -1045,7 +1046,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
    mr->ram = true;
    mr->terminates = true;
    mr->destructor = memory_region_destructor_ram;
    mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp);
    mr->ram_addr = qemu_ram_alloc_from_file(size, mr, share, path, errp);
}
#endif

Loading