backends/hostmem: Report error when memory size is unaligned
If memory-backend-{file,ram} has a size that's not aligned to underlying page size it is not only wasteful, but also may lead to hard to debug behaviour. For instance, in case memory-backend-file and hugepages, madvise() and mbind() fail. Rightfully so, page is the smallest unit they can work with. And even though an error is reported, the root cause it not very clear: qemu-system-x86_64: Couldn't set property 'dump' on 'memory-backend-file': Invalid argument After this commit: qemu-system-x86_64: backend 'memory-backend-file' memory size must be multiple of 2 MiB Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Tested-by: Mario Casquero <mcasquer@redhat.com> Message-ID: <b5b9f9c6bba07879fb43f3c6f496c69867ae3716.1717584048.git.mprivozn@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
210b7b2b3c
commit
5d9a9a6170
@ -36,6 +36,7 @@ sgx_epc_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend->aligned = true;
|
||||||
name = object_get_canonical_path(OBJECT(backend));
|
name = object_get_canonical_path(OBJECT(backend));
|
||||||
ram_flags = (backend->share ? RAM_SHARED : 0) | RAM_PROTECTED;
|
ram_flags = (backend->share ? RAM_SHARED : 0) | RAM_PROTECTED;
|
||||||
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
||||||
|
@ -80,6 +80,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend->aligned = true;
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
ram_flags = backend->share ? RAM_SHARED : 0;
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
|
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
|
||||||
|
@ -52,6 +52,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend->aligned = true;
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
ram_flags = backend->share ? RAM_SHARED : 0;
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "qemu/mmap-alloc.h"
|
#include "qemu/mmap-alloc.h"
|
||||||
#include "qemu/madvise.h"
|
#include "qemu/madvise.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
#include "hw/qdev-core.h"
|
#include "hw/qdev-core.h"
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
@ -325,6 +326,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
|
|||||||
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
|
HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc);
|
||||||
void *ptr;
|
void *ptr;
|
||||||
uint64_t sz;
|
uint64_t sz;
|
||||||
|
size_t pagesize;
|
||||||
bool async = !phase_check(PHASE_LATE_BACKENDS_CREATED);
|
bool async = !phase_check(PHASE_LATE_BACKENDS_CREATED);
|
||||||
|
|
||||||
if (!bc->alloc) {
|
if (!bc->alloc) {
|
||||||
@ -336,6 +338,14 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
|
|||||||
|
|
||||||
ptr = memory_region_get_ram_ptr(&backend->mr);
|
ptr = memory_region_get_ram_ptr(&backend->mr);
|
||||||
sz = memory_region_size(&backend->mr);
|
sz = memory_region_size(&backend->mr);
|
||||||
|
pagesize = qemu_ram_pagesize(backend->mr.ram_block);
|
||||||
|
|
||||||
|
if (backend->aligned && !QEMU_IS_ALIGNED(sz, pagesize)) {
|
||||||
|
g_autofree char *pagesize_str = size_to_str(pagesize);
|
||||||
|
error_setg(errp, "backend '%s' memory size must be multiple of %s",
|
||||||
|
object_get_typename(OBJECT(uc)), pagesize_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend->merge) {
|
if (backend->merge) {
|
||||||
qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
|
qemu_madvise(ptr, sz, QEMU_MADV_MERGEABLE);
|
||||||
|
@ -74,7 +74,7 @@ struct HostMemoryBackend {
|
|||||||
uint64_t size;
|
uint64_t size;
|
||||||
bool merge, dump, use_canonical_path;
|
bool merge, dump, use_canonical_path;
|
||||||
bool prealloc, is_mapped, share, reserve;
|
bool prealloc, is_mapped, share, reserve;
|
||||||
bool guest_memfd;
|
bool guest_memfd, aligned;
|
||||||
uint32_t prealloc_threads;
|
uint32_t prealloc_threads;
|
||||||
ThreadContext *prealloc_context;
|
ThreadContext *prealloc_context;
|
||||||
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
|
DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user