diff options
Diffstat (limited to 'meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch')
-rw-r--r-- | meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch b/meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch new file mode 100644 index 0000000000..cc53b1eedd --- /dev/null +++ b/meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch @@ -0,0 +1,282 @@ +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 */ |