mirror of https://github.com/xemu-project/xemu.git
util/mmap-alloc: Factor out activating of memory to mmap_activate()
We want to activate memory within a reserved memory region, to make it accessible. Let's factor that out. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Acked-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com> Reviewed-by: Peter Xu <peterx@redhat.com> Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20210510114328.21835-4-david@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
01c26ad6af
commit
d01cbf82ce
|
@ -114,6 +114,52 @@ static void *mmap_reserve(size_t size, int fd)
|
|||
return mmap(0, size, PROT_NONE, flags, fd, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Activate memory in a reserved region from the given fd (if any), to make
|
||||
* it accessible.
|
||||
*/
|
||||
static void *mmap_activate(void *ptr, size_t size, int fd, bool readonly,
|
||||
bool shared, bool is_pmem, off_t map_offset)
|
||||
{
|
||||
const int prot = PROT_READ | (readonly ? 0 : PROT_WRITE);
|
||||
int map_sync_flags = 0;
|
||||
int flags = MAP_FIXED;
|
||||
void *activated_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;
|
||||
}
|
||||
|
||||
activated_ptr = mmap(ptr, size, prot, flags | map_sync_flags, fd,
|
||||
map_offset);
|
||||
if (activated_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.
|
||||
*/
|
||||
activated_ptr = mmap(ptr, size, prot, flags, fd, map_offset);
|
||||
}
|
||||
return activated_ptr;
|
||||
}
|
||||
|
||||
static inline size_t mmap_guard_pagesize(int fd)
|
||||
{
|
||||
#if defined(__powerpc64__) && defined(__linux__)
|
||||
|
@ -133,13 +179,8 @@ void *qemu_ram_mmap(int fd,
|
|||
off_t map_offset)
|
||||
{
|
||||
const size_t guard_pagesize = mmap_guard_pagesize(fd);
|
||||
int prot;
|
||||
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
|
||||
|
@ -156,45 +197,10 @@ void *qemu_ram_mmap(int fd,
|
|||
/* Always align to host page size */
|
||||
assert(align >= guard_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;
|
||||
|
||||
prot = PROT_READ | (readonly ? 0 : PROT_WRITE);
|
||||
|
||||
ptr = mmap(guardptr + offset, size, prot,
|
||||
flags | map_sync_flags, fd, map_offset);
|
||||
|
||||
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, flags, fd, map_offset);
|
||||
}
|
||||
|
||||
ptr = mmap_activate(guardptr + offset, size, fd, readonly, shared, is_pmem,
|
||||
map_offset);
|
||||
if (ptr == MAP_FAILED) {
|
||||
munmap(guardptr, total);
|
||||
return MAP_FAILED;
|
||||
|
|
Loading…
Reference in New Issue