We want to populate memory within a reserved memory region. Let's factor that out.
Cc: "Michael S. Tsirkin" <m...@redhat.com> Cc: Greg Kurz <gr...@kaod.org> Cc: Murilo Opsfelder Araujo <muri...@linux.ibm.com> Cc: Eduardo Habkost <ehabk...@redhat.com> Cc: "Dr. David Alan Gilbert" <dgilb...@redhat.com> Signed-off-by: David Hildenbrand <da...@redhat.com> --- util/mmap-alloc.c | 89 +++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 43a26f38a8..f043ccb0ab 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -114,6 +114,50 @@ static void *mmap_reserve(size_t size, int fd) return mmap(0, size, PROT_NONE, flags, fd, 0); } +/* + * Populate memory in a reserved region from the given fd (if any). + */ +static void *mmap_populate(void *ptr, size_t size, int fd, bool shared, + bool is_pmem) +{ + int map_sync_flags = 0; + int flags = MAP_FIXED; + void *new_ptr; + + flags |= fd == -1 ? MAP_ANONYMOUS : 0; + flags |= shared ? MAP_SHARED : MAP_PRIVATE; + if (shared && is_pmem) { + map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE; + } + + new_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags | map_sync_flags, + fd, 0); + if (new_ptr == MAP_FAILED && map_sync_flags) { + if (errno == ENOTSUP) { + char *proc_link = g_strdup_printf("/proc/self/fd/%d", fd); + char *file_name = g_malloc0(PATH_MAX); + int len = readlink(proc_link, file_name, PATH_MAX - 1); + + if (len < 0) { + len = 0; + } + file_name[len] = '\0'; + fprintf(stderr, "Warning: requesting persistence across crashes " + "for backend file %s failed. Proceeding without " + "persistence, data might become corrupted in case of host " + "crash.\n", file_name); + g_free(proc_link); + g_free(file_name); + } + /* + * If mmap failed with MAP_SHARED_VALIDATE | MAP_SYNC, we will try + * again without these flags to handle backwards compatibility. + */ + new_ptr = mmap(ptr, size, PROT_READ | PROT_WRITE, flags, fd, 0); + } + return new_ptr; +} + static inline size_t mmap_pagesize(int fd) { #if defined(__powerpc64__) && defined(__linux__) @@ -131,12 +175,8 @@ void *qemu_ram_mmap(int fd, bool is_pmem) { const size_t pagesize = mmap_pagesize(fd); - int flags; - int map_sync_flags = 0; - size_t offset; - size_t total; - void *guardptr; - void *ptr; + size_t offset, total; + void *ptr, *guardptr; /* * Note: this always allocates at least one extra page of virtual address @@ -153,44 +193,9 @@ void *qemu_ram_mmap(int fd, /* Always align to host page size */ assert(align >= pagesize); - flags = MAP_FIXED; - flags |= fd == -1 ? MAP_ANONYMOUS : 0; - flags |= shared ? MAP_SHARED : MAP_PRIVATE; - if (shared && is_pmem) { - map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE; - } - offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr; - ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags | map_sync_flags, fd, 0); - - if (ptr == MAP_FAILED && map_sync_flags) { - if (errno == ENOTSUP) { - char *proc_link, *file_name; - int len; - proc_link = g_strdup_printf("/proc/self/fd/%d", fd); - file_name = g_malloc0(PATH_MAX); - len = readlink(proc_link, file_name, PATH_MAX - 1); - if (len < 0) { - len = 0; - } - file_name[len] = '\0'; - fprintf(stderr, "Warning: requesting persistence across crashes " - "for backend file %s failed. Proceeding without " - "persistence, data might become corrupted in case of host " - "crash.\n", file_name); - g_free(proc_link); - g_free(file_name); - } - /* - * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC, - * we will remove these flags to handle compatibility. - */ - ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags, fd, 0); - } - + ptr = mmap_populate(guardptr + offset, size, fd, shared, is_pmem); if (ptr == MAP_FAILED) { munmap(guardptr, total); return MAP_FAILED; -- 2.24.1