|
@@ -1,282 +0,0 @@
|
|
|
-From fa9bcabe2387bb230ef82d62827ad6f93b8a1e61 Mon Sep 17 00:00:00 2001
|
|
|
-From: Frederic Konrad <fkonrad@amd.com>
|
|
|
-Date: Wed, 17 Jan 2024 18:15:06 +0000
|
|
|
-Subject: [PATCH 1/2] linux-user/*: workaround for missing MAP_FIXED_NOREPLACE
|
|
|
-
|
|
|
-QEMU v8.1.0 recently requires MAP_FIXED_NOREPLACE flags implementation for mmap.
|
|
|
-
|
|
|
-This is missing from ubuntu 18.04, thus this patch catches the mmap calls which
|
|
|
-could use that new flag and forwards them to mmap when MAP_FIXED_NOREPLACE
|
|
|
-flag isn't set or emulates them by checking the returned address w.r.t the
|
|
|
-requested address.
|
|
|
-
|
|
|
-Signed-off-by: Frederic Konrad <fkonrad@amd.com>
|
|
|
-Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
|
|
|
-
|
|
|
-Upstream-Status: Inappropriate [OE specific]
|
|
|
-
|
|
|
-The upstream only supports the last two major releases of an OS. The ones
|
|
|
-they have declared all have kernel 4.17 or newer.
|
|
|
-
|
|
|
-See:
|
|
|
-https://xilinx.slack.com/archives/D04G2647CTV/p1705074697942019
|
|
|
-
|
|
|
-https://www.qemu.org/docs/master/about/build-platforms.html
|
|
|
-
|
|
|
- The project aims to support the most recent major version at all times for up
|
|
|
- to five years after its initial release. Support for the previous major
|
|
|
- version will be dropped 2 years after the new major version is released or
|
|
|
- when the vendor itself drops support, whichever comes first.
|
|
|
-
|
|
|
-Signed-off-by: Mark Hatle <mark.hatle@amd.com>
|
|
|
----
|
|
|
- linux-user/elfload.c | 7 +++--
|
|
|
- linux-user/meson.build | 1 +
|
|
|
- linux-user/mmap-fixed.c | 63 +++++++++++++++++++++++++++++++++++++++++
|
|
|
- linux-user/mmap-fixed.h | 39 +++++++++++++++++++++++++
|
|
|
- linux-user/mmap.c | 31 +++++++++++---------
|
|
|
- linux-user/syscall.c | 1 +
|
|
|
- 6 files changed, 125 insertions(+), 17 deletions(-)
|
|
|
- create mode 100644 linux-user/mmap-fixed.c
|
|
|
- create mode 100644 linux-user/mmap-fixed.h
|
|
|
-
|
|
|
-Index: qemu-8.2.1/linux-user/elfload.c
|
|
|
-===================================================================
|
|
|
---- qemu-8.2.1.orig/linux-user/elfload.c
|
|
|
-+++ qemu-8.2.1/linux-user/elfload.c
|
|
|
-@@ -22,6 +22,7 @@
|
|
|
- #include "qemu/error-report.h"
|
|
|
- #include "target_signal.h"
|
|
|
- #include "accel/tcg/debuginfo.h"
|
|
|
-+#include "mmap-fixed.h"
|
|
|
-
|
|
|
- #ifdef TARGET_ARM
|
|
|
- #include "target/arm/cpu-features.h"
|
|
|
-@@ -2765,9 +2766,9 @@ static abi_ulong create_elf_tables(abi_u
|
|
|
- static int pgb_try_mmap(uintptr_t addr, uintptr_t addr_last, bool keep)
|
|
|
- {
|
|
|
- size_t size = addr_last - addr + 1;
|
|
|
-- void *p = mmap((void *)addr, size, PROT_NONE,
|
|
|
-- MAP_ANONYMOUS | MAP_PRIVATE |
|
|
|
-- MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0);
|
|
|
-+ void *p = mmap_fixed_noreplace((void *)addr, size, PROT_NONE,
|
|
|
-+ MAP_ANONYMOUS | MAP_PRIVATE |
|
|
|
-+ MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0);
|
|
|
- int ret;
|
|
|
-
|
|
|
- if (p == MAP_FAILED) {
|
|
|
-Index: qemu-8.2.1/linux-user/meson.build
|
|
|
-===================================================================
|
|
|
---- qemu-8.2.1.orig/linux-user/meson.build
|
|
|
-+++ qemu-8.2.1/linux-user/meson.build
|
|
|
-@@ -14,6 +14,7 @@ linux_user_ss.add(files(
|
|
|
- 'linuxload.c',
|
|
|
- 'main.c',
|
|
|
- 'mmap.c',
|
|
|
-+ 'mmap-fixed.c',
|
|
|
- 'signal.c',
|
|
|
- 'strace.c',
|
|
|
- 'syscall.c',
|
|
|
-Index: qemu-8.2.1/linux-user/mmap-fixed.c
|
|
|
-===================================================================
|
|
|
---- /dev/null
|
|
|
-+++ qemu-8.2.1/linux-user/mmap-fixed.c
|
|
|
-@@ -0,0 +1,63 @@
|
|
|
-+/*
|
|
|
-+ * Workaround for MAP_FIXED_NOREPLACE
|
|
|
-+ *
|
|
|
-+ * Copyright (c) 2024, Advanced Micro Devices, Inc.
|
|
|
-+ * Developed by Fred Konrad <fkonrad@amd.com>
|
|
|
-+ *
|
|
|
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
-+ * of this software and associated documentation files (the "Software"), to deal
|
|
|
-+ * in the Software without restriction, including without limitation the rights
|
|
|
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
-+ * copies of the Software, and to permit persons to whom the Software is
|
|
|
-+ * furnished to do so, subject to the following conditions:
|
|
|
-+ *
|
|
|
-+ * The above copyright notice and this permission notice shall be included in
|
|
|
-+ * all copies or substantial portions of the Software.
|
|
|
-+ *
|
|
|
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
-+ * THE SOFTWARE.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#include <sys/mman.h>
|
|
|
-+#include <errno.h>
|
|
|
-+
|
|
|
-+#ifndef MAP_FIXED_NOREPLACE
|
|
|
-+#include "mmap-fixed.h"
|
|
|
-+
|
|
|
-+void *mmap_fixed_noreplace(void *addr, size_t len, int prot, int flags,
|
|
|
-+ int fd, off_t offset)
|
|
|
-+{
|
|
|
-+ void *retaddr;
|
|
|
-+
|
|
|
-+ if (!(flags & MAP_FIXED_NOREPLACE)) {
|
|
|
-+ /* General case, use the regular mmap. */
|
|
|
-+ return mmap(addr, len, prot, flags, fd, offset);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /* Since MAP_FIXED_NOREPLACE is not implemented, try to emulate it. */
|
|
|
-+ flags = flags & ~(MAP_FIXED_NOREPLACE | MAP_FIXED);
|
|
|
-+ retaddr = mmap(addr, len, prot, flags, fd, offset);
|
|
|
-+ if ((retaddr == addr) || (retaddr == MAP_FAILED)) {
|
|
|
-+ /*
|
|
|
-+ * Either the map worked and we get the good address so it can be
|
|
|
-+ * returned, or it failed and would have failed the same with
|
|
|
-+ * MAP_FIXED*, in which case return MAP_FAILED.
|
|
|
-+ */
|
|
|
-+ return retaddr;
|
|
|
-+ } else {
|
|
|
-+ /*
|
|
|
-+ * Page has been mapped but not at the requested address.. unmap it and
|
|
|
-+ * return EEXIST.
|
|
|
-+ */
|
|
|
-+ munmap(retaddr, len);
|
|
|
-+ errno = EEXIST;
|
|
|
-+ return MAP_FAILED;
|
|
|
-+ }
|
|
|
-+}
|
|
|
-+
|
|
|
-+#endif
|
|
|
-Index: qemu-8.2.1/linux-user/mmap-fixed.h
|
|
|
-===================================================================
|
|
|
---- /dev/null
|
|
|
-+++ qemu-8.2.1/linux-user/mmap-fixed.h
|
|
|
-@@ -0,0 +1,39 @@
|
|
|
-+/*
|
|
|
-+ * Workaround for MAP_FIXED_NOREPLACE
|
|
|
-+ *
|
|
|
-+ * Copyright (c) 2024, Advanced Micro Devices, Inc.
|
|
|
-+ * Developed by Fred Konrad <fkonrad@amd.com>
|
|
|
-+ *
|
|
|
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
-+ * of this software and associated documentation files (the "Software"), to deal
|
|
|
-+ * in the Software without restriction, including without limitation the rights
|
|
|
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
-+ * copies of the Software, and to permit persons to whom the Software is
|
|
|
-+ * furnished to do so, subject to the following conditions:
|
|
|
-+ *
|
|
|
-+ * The above copyright notice and this permission notice shall be included in
|
|
|
-+ * all copies or substantial portions of the Software.
|
|
|
-+ *
|
|
|
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
-+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
-+ * THE SOFTWARE.
|
|
|
-+ */
|
|
|
-+
|
|
|
-+#ifndef MMAP_FIXED_H
|
|
|
-+#define MMAP_FIXED_H
|
|
|
-+
|
|
|
-+#ifndef MAP_FIXED_NOREPLACE
|
|
|
-+#define MAP_FIXED_NOREPLACE 0x100000
|
|
|
-+
|
|
|
-+void *mmap_fixed_noreplace(void *addr, size_t len, int prot, int flags,
|
|
|
-+ int fd, off_t offset);
|
|
|
-+
|
|
|
-+#else /* MAP_FIXED_NOREPLACE */
|
|
|
-+#define mmap_fixed_noreplace mmap
|
|
|
-+#endif /* MAP_FIXED_NOREPLACE */
|
|
|
-+
|
|
|
-+#endif /* MMAP_FIXED_H */
|
|
|
-Index: qemu-8.2.1/linux-user/mmap.c
|
|
|
-===================================================================
|
|
|
---- qemu-8.2.1.orig/linux-user/mmap.c
|
|
|
-+++ qemu-8.2.1/linux-user/mmap.c
|
|
|
-@@ -25,6 +25,7 @@
|
|
|
- #include "user-mmap.h"
|
|
|
- #include "target_mman.h"
|
|
|
- #include "qemu/interval-tree.h"
|
|
|
-+#include "mmap-fixed.h"
|
|
|
-
|
|
|
- #ifdef TARGET_ARM
|
|
|
- #include "target/arm/cpu-features.h"
|
|
|
-@@ -273,7 +274,7 @@ int target_mprotect(abi_ulong start, abi
|
|
|
- static int do_munmap(void *addr, size_t len)
|
|
|
- {
|
|
|
- if (reserved_va) {
|
|
|
-- void *ptr = mmap(addr, len, PROT_NONE,
|
|
|
-+ void *ptr = mmap_fixed_noreplace(addr, len, PROT_NONE,
|
|
|
- MAP_FIXED | MAP_ANONYMOUS
|
|
|
- | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
|
|
|
- return ptr == addr ? 0 : -1;
|
|
|
-@@ -319,9 +320,9 @@ static bool mmap_frag(abi_ulong real_sta
|
|
|
- * outside of the fragment we need to map. Allocate a new host
|
|
|
- * page to cover, discarding whatever else may have been present.
|
|
|
- */
|
|
|
-- void *p = mmap(host_start, qemu_host_page_size,
|
|
|
-- target_to_host_prot(prot),
|
|
|
-- flags | MAP_ANONYMOUS, -1, 0);
|
|
|
-+ void *p = mmap_fixed_noreplace(host_start, qemu_host_page_size,
|
|
|
-+ target_to_host_prot(prot),
|
|
|
-+ flags | MAP_ANONYMOUS, -1, 0);
|
|
|
- if (p != host_start) {
|
|
|
- if (p != MAP_FAILED) {
|
|
|
- munmap(p, qemu_host_page_size);
|
|
|
-@@ -420,8 +421,9 @@ abi_ulong mmap_find_vma(abi_ulong start,
|
|
|
- * - mremap() with MREMAP_FIXED flag
|
|
|
- * - shmat() with SHM_REMAP flag
|
|
|
- */
|
|
|
-- ptr = mmap(g2h_untagged(addr), size, PROT_NONE,
|
|
|
-- MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
|
|
|
-+ ptr = mmap_fixed_noreplace(g2h_untagged(addr), size, PROT_NONE,
|
|
|
-+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE,
|
|
|
-+ -1, 0);
|
|
|
-
|
|
|
- /* ENOMEM, if host address space has no memory */
|
|
|
- if (ptr == MAP_FAILED) {
|
|
|
-@@ -615,16 +617,16 @@ abi_long target_mmap(abi_ulong start, ab
|
|
|
- * especially important if qemu_host_page_size >
|
|
|
- * qemu_real_host_page_size.
|
|
|
- */
|
|
|
-- p = mmap(g2h_untagged(start), host_len, host_prot,
|
|
|
-- flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
|
|
|
-+ p = mmap_fixed_noreplace(g2h_untagged(start), host_len, host_prot,
|
|
|
-+ flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
|
|
|
- if (p == MAP_FAILED) {
|
|
|
- goto fail;
|
|
|
- }
|
|
|
- /* update start so that it points to the file position at 'offset' */
|
|
|
- host_start = (uintptr_t)p;
|
|
|
- if (!(flags & MAP_ANONYMOUS)) {
|
|
|
-- p = mmap(g2h_untagged(start), len, host_prot,
|
|
|
-- flags | MAP_FIXED, fd, host_offset);
|
|
|
-+ p = mmap_fixed_noreplace(g2h_untagged(start), len, host_prot,
|
|
|
-+ flags | MAP_FIXED, fd, host_offset);
|
|
|
- if (p == MAP_FAILED) {
|
|
|
- munmap(g2h_untagged(start), host_len);
|
|
|
- goto fail;
|
|
|
-@@ -749,8 +751,9 @@ abi_long target_mmap(abi_ulong start, ab
|
|
|
- len1 = real_last - real_start + 1;
|
|
|
- want_p = g2h_untagged(real_start);
|
|
|
-
|
|
|
-- p = mmap(want_p, len1, target_to_host_prot(target_prot),
|
|
|
-- flags, fd, offset1);
|
|
|
-+ p = mmap_fixed_noreplace(want_p, len1,
|
|
|
-+ target_to_host_prot(target_prot),
|
|
|
-+ flags, fd, offset1);
|
|
|
- if (p != want_p) {
|
|
|
- if (p != MAP_FAILED) {
|
|
|
- munmap(p, len1);
|
|
|
-Index: qemu-8.2.1/linux-user/syscall.c
|
|
|
-===================================================================
|
|
|
---- qemu-8.2.1.orig/linux-user/syscall.c
|
|
|
-+++ qemu-8.2.1/linux-user/syscall.c
|
|
|
-@@ -145,6 +145,7 @@
|
|
|
- #include "qapi/error.h"
|
|
|
- #include "fd-trans.h"
|
|
|
- #include "cpu_loop-common.h"
|
|
|
-+#include "mmap-fixed.h"
|
|
|
-
|
|
|
- #ifndef CLONE_IO
|
|
|
- #define CLONE_IO 0x80000000 /* Clone io context */
|