diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-02-04 10:33:40 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-02-04 10:33:40 +0000 |
commit | a61faa3d02159d24d4fa984733dbc0c905508752 (patch) | |
tree | a21a48ecf9d9f7bee7a085b5f6a945b2e48c9de7 /util/mmap-alloc.c | |
parent | b3fc0af1ff5e922d4dd7c875394dbd26dc7313b4 (diff) | |
parent | 53adb9d43e1abba187387a51f238e878e934c647 (diff) |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.0-20190204' into staging
ppc patch queue 2019-02-04
Here's the next batch of ppc target and spapr related changes.
Highlights are:
* A number of endianness handling cleanups from Mark Cave-Ayland
* Updated Mac VGA driver
* Updated SLOF image
* Some XIVE cleanups and small fixes
* ppc4xx cleanups and fixes from BALATON Zoltan
There are a few chances not technically in the ppc target code:
* Several MAINTAINERS updates
* Fixes for unmapping of hugepages on power hosts
The latter is included because it's primarily of interest for ppc KVM setups.
# gpg: Signature made Mon 04 Feb 2019 07:52:26 GMT
# gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392
* remotes/dgibson/tags/ppc-for-4.0-20190204: (37 commits)
mmap-alloc: fix hugetlbfs misaligned length in ppc64
mmap-alloc: unfold qemu_ram_mmap()
hw/ppc: Don't include m48t59.h if it is not necessary
spapr_pci: Fix endianness in assigned-addresses property
target/ppc: remove various HOST_WORDS_BIGENDIAN hacks in int_helper.c
target/ppc: remove ROTRu32 and ROTRu64 macros from int_helper.c
target/ppc: simplify VEXT_SIGNED macro in int_helper.c
target/ppc: eliminate use of EL_IDX macros from int_helper.c
target/ppc: eliminate use of HI_IDX and LO_IDX macros from int_helper.c
target/ppc: rework vmul{e,o}{s,u}{b,h,w} instructions to use Vsr* macros
target/ppc: rework vmrg{l,h}{b,h,w} instructions to use Vsr* macros
hw/ppc/spapr: Add support for "-vga cirrus"
QemuMacDrivers: update qemu_vga.ndrv to 90c488d built from submodule
MAINTAINERS: add myself as maintainer for Mac Old World and New World machines
spapr: Drop unused parameters from fdt building helper
MAINTAINERS: Merge the two e500 sections
MAINTAINERS: XIVE is an interrupt controller, not a machine
hw/ppc: Move ppc40x_*reset() functions from ppc405_uc.c to ppc.c
ppc: remove the interrupt presenters from under PowerPCCPU
target/ppc: implement complete set of Vsr* macros
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/mmap-alloc.c')
-rw-r--r-- | util/mmap-alloc.c | 73 |
1 files changed, 49 insertions, 24 deletions
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index fd329eccd8..8565885420 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -77,11 +77,20 @@ size_t qemu_mempath_getpagesize(const char *mem_path) void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) { + int flags; + int guardfd; + size_t offset; + size_t pagesize; + size_t total; + void *guardptr; + void *ptr; + /* * Note: this always allocates at least one extra page of virtual address * space, even if size is already aligned. */ - size_t total = size + align; + total = size + align; + #if defined(__powerpc64__) && defined(__linux__) /* On ppc64 mappings in the same segment (aka slice) must share the same * page size. Since we will be re-allocating part of this segment @@ -91,36 +100,45 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) * We do this unless we are using the system page size, in which case * anonymous memory is OK. */ - int anonfd = fd == -1 || qemu_fd_getpagesize(fd) == getpagesize() ? -1 : fd; - int flags = anonfd == -1 ? MAP_ANONYMOUS : MAP_NORESERVE; - void *ptr = mmap(0, total, PROT_NONE, flags | MAP_PRIVATE, anonfd, 0); + flags = MAP_PRIVATE; + pagesize = qemu_fd_getpagesize(fd); + if (fd == -1 || pagesize == getpagesize()) { + guardfd = -1; + flags |= MAP_ANONYMOUS; + } else { + guardfd = fd; + flags |= MAP_NORESERVE; + } #else - void *ptr = mmap(0, total, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + guardfd = -1; + pagesize = getpagesize(); + flags = MAP_PRIVATE | MAP_ANONYMOUS; #endif - size_t offset; - void *ptr1; - if (ptr == MAP_FAILED) { + guardptr = mmap(0, total, PROT_NONE, flags, guardfd, 0); + + if (guardptr == MAP_FAILED) { return MAP_FAILED; } assert(is_power_of_2(align)); /* Always align to host page size */ - assert(align >= getpagesize()); - - offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr; - ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE, - MAP_FIXED | - (fd == -1 ? MAP_ANONYMOUS : 0) | - (shared ? MAP_SHARED : MAP_PRIVATE), - fd, 0); - if (ptr1 == MAP_FAILED) { - munmap(ptr, total); + assert(align >= pagesize); + + flags = MAP_FIXED; + flags |= fd == -1 ? MAP_ANONYMOUS : 0; + flags |= shared ? MAP_SHARED : MAP_PRIVATE; + offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr; + + ptr = mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, flags, fd, 0); + + if (ptr == MAP_FAILED) { + munmap(guardptr, total); return MAP_FAILED; } if (offset > 0) { - munmap(ptr, offset); + munmap(guardptr, offset); } /* @@ -128,17 +146,24 @@ void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared) * a guard page guarding against potential buffer overflows. */ total -= offset; - if (total > size + getpagesize()) { - munmap(ptr1 + size + getpagesize(), total - size - getpagesize()); + if (total > size + pagesize) { + munmap(ptr + size + pagesize, total - size - pagesize); } - return ptr1; + return ptr; } -void qemu_ram_munmap(void *ptr, size_t size) +void qemu_ram_munmap(int fd, void *ptr, size_t size) { + size_t pagesize; + if (ptr) { /* Unmap both the RAM block and the guard page */ - munmap(ptr, size + getpagesize()); +#if defined(__powerpc64__) && defined(__linux__) + pagesize = qemu_fd_getpagesize(fd); +#else + pagesize = getpagesize(); +#endif + munmap(ptr, size + pagesize); } } |