exec.c: Ensure right alignment also for file backed ram

While in the anonymous ram case we already take care of the right alignment
such an alignment gurantee does not exist for file backed ram allocation.

Instead, pagesize is used for alignment. On s390 this is not enough for gmap,
as we need to satisfy an alignment up to segments.

Reported-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>

Message-Id: <1461585338-45863-1-git-send-email-dingel@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Dominik Dingel 2016-04-25 13:55:38 +02:00 committed by Paolo Bonzini
parent e081c24d30
commit d2f39add72
3 changed files with 16 additions and 15 deletions

5
exec.c
View File

@ -1299,7 +1299,7 @@ static void *file_ram_alloc(RAMBlock *block,
} }
page_size = qemu_fd_getpagesize(fd); page_size = qemu_fd_getpagesize(fd);
block->mr->align = page_size; block->mr->align = MAX(page_size, QEMU_VMALLOC_ALIGN);
if (memory < page_size) { if (memory < page_size) {
error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to " error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
@ -1320,7 +1320,8 @@ static void *file_ram_alloc(RAMBlock *block,
perror("ftruncate"); perror("ftruncate");
} }
area = qemu_ram_mmap(fd, memory, page_size, block->flags & RAM_SHARED); area = qemu_ram_mmap(fd, memory, block->mr->align,
block->flags & RAM_SHARED);
if (area == MAP_FAILED) { if (area == MAP_FAILED) {
error_setg_errno(errp, errno, error_setg_errno(errp, errno,
"unable to map backing store for guest RAM"); "unable to map backing store for guest RAM");

View File

@ -263,6 +263,19 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#endif #endif
#if defined(__linux__) && \
(defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
/* Use 2 MiB alignment so transparent hugepages can be used by KVM.
Valgrind does not support alignments larger than 1 MiB,
therefore we need special code which handles running on Valgrind. */
# define QEMU_VMALLOC_ALIGN (512 * 4096)
#elif defined(__linux__) && defined(__s390x__)
/* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
# define QEMU_VMALLOC_ALIGN (256 * 4096)
#else
# define QEMU_VMALLOC_ALIGN getpagesize()
#endif
int qemu_madvise(void *addr, size_t len, int advice); int qemu_madvise(void *addr, size_t len, int advice);
int qemu_open(const char *name, int flags, ...); int qemu_open(const char *name, int flags, ...);

View File

@ -26,19 +26,6 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#if defined(__linux__) && \
(defined(__x86_64__) || defined(__arm__) || defined(__aarch64__))
/* Use 2 MiB alignment so transparent hugepages can be used by KVM.
Valgrind does not support alignments larger than 1 MiB,
therefore we need special code which handles running on Valgrind. */
# define QEMU_VMALLOC_ALIGN (512 * 4096)
#elif defined(__linux__) && defined(__s390x__)
/* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */
# define QEMU_VMALLOC_ALIGN (256 * 4096)
#else
# define QEMU_VMALLOC_ALIGN getpagesize()
#endif
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include <termios.h> #include <termios.h>
#include <termios.h> #include <termios.h>