Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- osdep.h | 10 ++++++++++ oslib-posix.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ oslib-win32.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+)
diff --git a/osdep.h b/osdep.h index 87d3b9c..fb7f72c 100644 --- a/osdep.h +++ b/osdep.h @@ -134,6 +134,16 @@ void qemu_vfree(void *ptr); #endif +typedef struct QEMUMmapArea { + int fd; + void *mem; + size_t size; +} QEMUMmapArea; + +int qemu_mmap_alloc(QEMUMmapArea *mm, const char *path, size_t size); +int qemu_mmap_flush(QEMUMmapArea *mm); +void qemu_mmap_free(QEMUMmapArea *mm); + int qemu_madvise(void *addr, size_t len, int advice); int qemu_open(const char *name, int flags, ...); diff --git a/oslib-posix.c b/oslib-posix.c index 9db9c3d..f230f61 100644 --- a/oslib-posix.c +++ b/oslib-posix.c @@ -61,6 +61,7 @@ static int running_on_valgrind = -1; #ifdef CONFIG_LINUX #include <sys/syscall.h> #endif +#include <sys/mman.h> int qemu_get_thread_id(void) { @@ -226,3 +227,49 @@ int qemu_utimens(const char *path, const struct timespec *times) return utimes(path, &tv[0]); } + +int qemu_mmap_alloc(QEMUMmapArea *mm, const char *path, size_t size) +{ + int fd = -1; + char *mem = NULL; + int save_errno; + + fd = qemu_open(path, O_RDWR | O_CREAT, 0666); + if (fd < 0) { + goto fail; + } + + if (ftruncate(fd, size) < 0) { + goto fail; + } + + mem = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (!mem) { + goto fail; + } + + mm->fd = fd; + mm->mem = mem; + mm->size = size; + return 0; + +fail: + save_errno = errno; + if (fd >= 0) { + close(fd); + unlink(path); + } + return -save_errno; +} + +int qemu_mmap_flush(QEMUMmapArea *mm) +{ + int rc = msync(mm->mem, mm->size, MS_SYNC); + return rc < 0 ? -errno : 0; +} + +void qemu_mmap_free(QEMUMmapArea *mm) +{ + munmap(mm->mem, mm->size); + close(mm->fd); +} diff --git a/oslib-win32.c b/oslib-win32.c index 51b33e8..3885a31 100644 --- a/oslib-win32.c +++ b/oslib-win32.c @@ -150,3 +150,62 @@ int qemu_get_thread_id(void) { return GetCurrentThreadId(); } + +int qemu_mmap_alloc(QEMUMmapArea *mm, const char *path, size_t size) +{ + int fd = -1; + char *mem = NULL; + + HANDLE hFile, hMapping; + int save_errno; + + fd = qemu_open(path, O_RDWR | O_CREAT, 0666); + if (fd < 0) { + goto fail; + } + + hFile = (HANDLE)_get_osfhandle(fd); + if (ftruncate(fd, size) < 0) { + goto fail; + } + + hMapping = CreateFileMapping(hFile, NULL, PAGE_EXECUTE_READWRITE, + 0, 0, NULL); + if (!hMapping) { + goto fail; + } + + mem = MapViewOfFileEx(hMapping, FILE_MAP_WRITE, 0, 0, size, NULL); + CloseHandle(hMapping); + if (mem) { + goto fail; + } + + mm->fd = fd; + mm->mem = mem; + mm->size = size; + return 0; + +fail: + save_errno = errno; + if (fd >= 0) { + close(fd); + unlink(path); + } + return -save_errno; +} + +int qemu_mmap_flush(QEMUMmapArea *mm) +{ + int rc; + + FlushViewOfFile(mm->mem, mm->size); + rc = qemu_fdatasync(mm->fd); + return rc < 0 ? -errno : 0; +} + +void qemu_mmap_free(QEMUMmapArea *mm) +{ + UnmapViewOfFile(mm->mem); + close(mm->fd); +} -- 1.8.0.1