aboutsummaryrefslogtreecommitdiff
path: root/util/cutils.c
diff options
context:
space:
mode:
authorBeata Michalska <beata.michalska@linaro.org>2019-11-21 00:08:41 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-12-16 10:46:35 +0000
commit61c490e25e081af39ff40556f6c1229b8b011585 (patch)
treea05523934595b80768e7060a982fbc89041bfa08 /util/cutils.c
parent9e70492b4389d4355ae9c9ee2ba6286cfdadc257 (diff)
Memory: Enable writeback for given memory region
Add an option to trigger memory writeback to sync given memory region with the corresponding backing store, case one is available. This extends the support for persistent memory, allowing syncing on-demand. Signed-off-by: Beata Michalska <beata.michalska@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20191121000843.24844-3-beata.michalska@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/cutils.c')
-rw-r--r--util/cutils.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/util/cutils.c b/util/cutils.c
index 77acadc70a..2380165230 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -164,6 +164,44 @@ int qemu_fdatasync(int fd)
#endif
}
+/**
+ * Sync changes made to the memory mapped file back to the backing
+ * storage. For POSIX compliant systems this will fallback
+ * to regular msync call. Otherwise it will trigger whole file sync
+ * (including the metadata case there is no support to skip that otherwise)
+ *
+ * @addr - start of the memory area to be synced
+ * @length - length of the are to be synced
+ * @fd - file descriptor for the file to be synced
+ * (mandatory only for POSIX non-compliant systems)
+ */
+int qemu_msync(void *addr, size_t length, int fd)
+{
+#ifdef CONFIG_POSIX
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
+
+ /**
+ * There are no strict reqs as per the length of mapping
+ * to be synced. Still the length needs to follow the address
+ * alignment changes. Additionally - round the size to the multiple
+ * of PAGE_SIZE
+ */
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
+ length = (length + ~align_mask) & align_mask;
+
+ addr = (void *)((uintptr_t)addr & align_mask);
+
+ return msync(addr, length, MS_SYNC);
+#else /* CONFIG_POSIX */
+ /**
+ * Perform the sync based on the file descriptor
+ * The sync range will most probably be wider than the one
+ * requested - but it will still get the job done
+ */
+ return qemu_fdatasync(fd);
+#endif /* CONFIG_POSIX */
+}
+
#ifndef _WIN32
/* Sets a specific flag */
int fcntl_setfl(int fd, int flag)