aboutsummaryrefslogtreecommitdiff
path: root/backends/hostmem-file.c
diff options
context:
space:
mode:
authorHaozhong Zhang <haozhong.zhang@intel.com>2017-12-11 15:28:04 +0800
committerEduardo Habkost <ehabkost@redhat.com>2018-01-19 11:18:51 -0200
commit983768431676f9ab8599a0b4813e1ca17af70838 (patch)
tree4923d3621cf664db0fe10092321df708f718c84f /backends/hostmem-file.c
parent1e2bdd2e20844f6bc343232ea1bb6f64c54a95ce (diff)
hostmem-file: add "align" option
When mmap(2) the backend files, QEMU uses the host page size (getpagesize(2)) by default as the alignment of mapping address. However, some backends may require alignments different than the page size. For example, mmap a device DAX (e.g., /dev/dax0.0) on Linux kernel 4.13 to an address, which is 4K-aligned but not 2M-aligned, fails with a kernel message like [617494.969768] dax dax0.0: qemu-system-x86: dax_mmap: fail, unaligned vma (0x7fa37c579000 - 0x7fa43c579000, 0x1fffff) Because there is no common approach to get such alignment requirement, we add the 'align' option to 'memory-backend-file', so that users or management utils, which have enough knowledge about the backend, can specify a proper alignment via this option. Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com> Message-Id: <20171211072806.2812-2-haozhong.zhang@intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> [ehabkost: fixed typo, fixed error_setg() format string] Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Diffstat (limited to 'backends/hostmem-file.c')
-rw-r--r--backends/hostmem-file.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e44c319915..e319ec1ad8 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -34,6 +34,7 @@ struct HostMemoryBackendFile {
bool share;
bool discard_data;
char *mem_path;
+ uint64_t align;
};
static void
@@ -58,7 +59,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
path = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
path,
- backend->size, fb->share,
+ backend->size, fb->align, fb->share,
fb->mem_path, errp);
g_free(path);
}
@@ -115,6 +116,40 @@ static void file_memory_backend_set_discard_data(Object *o, bool value,
MEMORY_BACKEND_FILE(o)->discard_data = value;
}
+static void file_memory_backend_get_align(Object *o, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+ uint64_t val = fb->align;
+
+ visit_type_size(v, name, &val, errp);
+}
+
+static void file_memory_backend_set_align(Object *o, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ HostMemoryBackend *backend = MEMORY_BACKEND(o);
+ HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
+ Error *local_err = NULL;
+ uint64_t val;
+
+ if (host_memory_backend_mr_inited(backend)) {
+ error_setg(&local_err, "cannot change property value");
+ goto out;
+ }
+
+ visit_type_size(v, name, &val, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ fb->align = val;
+
+ out:
+ error_propagate(errp, local_err);
+}
+
static void file_backend_unparent(Object *obj)
{
HostMemoryBackend *backend = MEMORY_BACKEND(obj);
@@ -145,6 +180,10 @@ file_backend_class_init(ObjectClass *oc, void *data)
object_class_property_add_str(oc, "mem-path",
get_mem_path, set_mem_path,
&error_abort);
+ object_class_property_add(oc, "align", "int",
+ file_memory_backend_get_align,
+ file_memory_backend_set_align,
+ NULL, NULL, &error_abort);
}
static void file_backend_instance_finalize(Object *o)