summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@amd.com>2024-01-25 15:03:54 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-02-02 10:38:28 +0000
commit069d2dfd86e8ba6cc6bcf21d908d87319ac1fcde (patch)
tree242313a9c58d11c76ddd406ad71cf73ca504beed
parent2608d399a2d5e12910c0625e87e7caf6db7f1fab (diff)
downloadpoky-069d2dfd86e8ba6cc6bcf21d908d87319ac1fcde.tar.gz
qemu: Allow native and nativesdk versions on Linux older then 4.17
Linux kernel 4.17 introduced two new mmap flags, MAP_FIXED_NOREPLACE and MAP_SHARED_VALIDATE. Starting with QEMU 8.1, these flags are now used and required for proper system operation. In order to build and run on a system older then 4.17, we need to emulate this new behavior. Not having a newer kernel could result in the mmap memory being allocated in a way that will cause failures without QEMU checking for these conditions. Note, memory allocation issues are rare in my experience so this is more of a 'just-in-case' behavior. SDK_OLDEST_KERNEL is currently set to 3.2.0, the only way this can claim that qemu works in an SDK is by checking the return values to emulate the expected behavior. (From OE-Core rev: 4eb0a83c7851e2eb6d7890a130dfe50f37ff8ac9) Signed-off-by: Mark Hatle <mark.hatle@amd.com> Signed-off-by: Mark Hatle <mark.hatle@kernel.crashing.org> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/qemu/qemu.inc12
-rw-r--r--meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch286
-rw-r--r--meta/recipes-devtools/qemu/qemu/0012-linux-user-workaround-for-missing-MAP_SHARED_VALIDAT.patch51
3 files changed, 349 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index bc6ce0bb38..14b975db30 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -40,6 +40,18 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
40 " 40 "
41UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar" 41UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
42 42
43# SDK_OLDEST_KERNEL is set below 4.17, which is the minimum version required by QEMU >= 8.1
44# This is due to two MMAP flags being used at certain points
45SRC_URI:append:class-nativesdk = " \
46 file://0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch \
47 file://0012-linux-user-workaround-for-missing-MAP_SHARED_VALIDAT.patch \
48 "
49
50# Support building and using native version on pre 4.17 kernels
51SRC_URI:append:class-native = " \
52 file://0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch \
53 file://0012-linux-user-workaround-for-missing-MAP_SHARED_VALIDAT.patch \
54 "
43 55
44SRC_URI[sha256sum] = "bf00d2fa12010df8b0ade93371def58e632cb32a6bfdc5f5a0ff8e6a1fb1bf32" 56SRC_URI[sha256sum] = "bf00d2fa12010df8b0ade93371def58e632cb32a6bfdc5f5a0ff8e6a1fb1bf32"
45 57
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..672d5458cd
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/0011-linux-user-workaround-for-missing-MAP_FIXED_NOREPLAC.patch
@@ -0,0 +1,286 @@
1From fa9bcabe2387bb230ef82d62827ad6f93b8a1e61 Mon Sep 17 00:00:00 2001
2From: Frederic Konrad <fkonrad@amd.com>
3Date: Wed, 17 Jan 2024 18:15:06 +0000
4Subject: [PATCH 1/2] linux-user/*: workaround for missing MAP_FIXED_NOREPLACE
5
6QEMU v8.1.0 recently requires MAP_FIXED_NOREPLACE flags implementation for mmap.
7
8This is missing from ubuntu 18.04, thus this patch catches the mmap calls which
9could use that new flag and forwards them to mmap when MAP_FIXED_NOREPLACE
10flag isn't set or emulates them by checking the returned address w.r.t the
11requested address.
12
13Signed-off-by: Frederic Konrad <fkonrad@amd.com>
14Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
15
16Upstream-Status: Inappropriate [OE specific]
17
18The upstream only supports the last two major releases of an OS. The ones
19they have declared all have kernel 4.17 or newer.
20
21See:
22https://xilinx.slack.com/archives/D04G2647CTV/p1705074697942019
23
24https://www.qemu.org/docs/master/about/build-platforms.html
25
26 The project aims to support the most recent major version at all times for up
27 to five years after its initial release. Support for the previous major
28 version will be dropped 2 years after the new major version is released or
29 when the vendor itself drops support, whichever comes first.
30
31Signed-off-by: Mark Hatle <mark.hatle@amd.com>
32---
33 linux-user/elfload.c | 7 +++--
34 linux-user/meson.build | 1 +
35 linux-user/mmap-fixed.c | 63 +++++++++++++++++++++++++++++++++++++++++
36 linux-user/mmap-fixed.h | 39 +++++++++++++++++++++++++
37 linux-user/mmap.c | 31 +++++++++++---------
38 linux-user/syscall.c | 1 +
39 6 files changed, 125 insertions(+), 17 deletions(-)
40 create mode 100644 linux-user/mmap-fixed.c
41 create mode 100644 linux-user/mmap-fixed.h
42
43Index: qemu-8.2.0/linux-user/elfload.c
44===================================================================
45--- qemu-8.2.0.orig/linux-user/elfload.c
46+++ qemu-8.2.0/linux-user/elfload.c
47@@ -22,6 +22,7 @@
48 #include "qemu/error-report.h"
49 #include "target_signal.h"
50 #include "accel/tcg/debuginfo.h"
51+#include "mmap-fixed.h"
52
53 #ifdef TARGET_ARM
54 #include "target/arm/cpu-features.h"
55@@ -2765,9 +2766,9 @@ static abi_ulong create_elf_tables(abi_u
56 static int pgb_try_mmap(uintptr_t addr, uintptr_t addr_last, bool keep)
57 {
58 size_t size = addr_last - addr + 1;
59- void *p = mmap((void *)addr, size, PROT_NONE,
60- MAP_ANONYMOUS | MAP_PRIVATE |
61- MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0);
62+ void *p = mmap_fixed_noreplace((void *)addr, size, PROT_NONE,
63+ MAP_ANONYMOUS | MAP_PRIVATE |
64+ MAP_NORESERVE | MAP_FIXED_NOREPLACE, -1, 0);
65 int ret;
66
67 if (p == MAP_FAILED) {
68Index: qemu-8.2.0/linux-user/meson.build
69===================================================================
70--- qemu-8.2.0.orig/linux-user/meson.build
71+++ qemu-8.2.0/linux-user/meson.build
72@@ -14,6 +14,7 @@ linux_user_ss.add(files(
73 'linuxload.c',
74 'main.c',
75 'mmap.c',
76+ 'mmap-fixed.c',
77 'signal.c',
78 'strace.c',
79 'syscall.c',
80Index: qemu-8.2.0/linux-user/mmap-fixed.c
81===================================================================
82--- /dev/null
83+++ qemu-8.2.0/linux-user/mmap-fixed.c
84@@ -0,0 +1,63 @@
85+/*
86+ * Workaround for MAP_FIXED_NOREPLACE
87+ *
88+ * Copyright (c) 2024, Advanced Micro Devices, Inc.
89+ * Developed by Fred Konrad <fkonrad@amd.com>
90+ *
91+ * Permission is hereby granted, free of charge, to any person obtaining a copy
92+ * of this software and associated documentation files (the "Software"), to deal
93+ * in the Software without restriction, including without limitation the rights
94+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
95+ * copies of the Software, and to permit persons to whom the Software is
96+ * furnished to do so, subject to the following conditions:
97+ *
98+ * The above copyright notice and this permission notice shall be included in
99+ * all copies or substantial portions of the Software.
100+ *
101+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
102+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
103+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
104+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
105+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
106+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
107+ * THE SOFTWARE.
108+ */
109+
110+#include <sys/mman.h>
111+#include <errno.h>
112+
113+#ifndef MAP_FIXED_NOREPLACE
114+#include "mmap-fixed.h"
115+
116+void *mmap_fixed_noreplace(void *addr, size_t len, int prot, int flags,
117+ int fd, off_t offset)
118+{
119+ void *retaddr;
120+
121+ if (!(flags & MAP_FIXED_NOREPLACE)) {
122+ /* General case, use the regular mmap. */
123+ return mmap(addr, len, prot, flags, fd, offset);
124+ }
125+
126+ /* Since MAP_FIXED_NOREPLACE is not implemented, try to emulate it. */
127+ flags = flags & ~(MAP_FIXED_NOREPLACE | MAP_FIXED);
128+ retaddr = mmap(addr, len, prot, flags, fd, offset);
129+ if ((retaddr == addr) || (retaddr == MAP_FAILED)) {
130+ /*
131+ * Either the map worked and we get the good address so it can be
132+ * returned, or it failed and would have failed the same with
133+ * MAP_FIXED*, in which case return MAP_FAILED.
134+ */
135+ return retaddr;
136+ } else {
137+ /*
138+ * Page has been mapped but not at the requested address.. unmap it and
139+ * return EEXIST.
140+ */
141+ munmap(retaddr, len);
142+ errno = EEXIST;
143+ return MAP_FAILED;
144+ }
145+}
146+
147+#endif
148Index: qemu-8.2.0/linux-user/mmap-fixed.h
149===================================================================
150--- /dev/null
151+++ qemu-8.2.0/linux-user/mmap-fixed.h
152@@ -0,0 +1,39 @@
153+/*
154+ * Workaround for MAP_FIXED_NOREPLACE
155+ *
156+ * Copyright (c) 2024, Advanced Micro Devices, Inc.
157+ * Developed by Fred Konrad <fkonrad@amd.com>
158+ *
159+ * Permission is hereby granted, free of charge, to any person obtaining a copy
160+ * of this software and associated documentation files (the "Software"), to deal
161+ * in the Software without restriction, including without limitation the rights
162+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
163+ * copies of the Software, and to permit persons to whom the Software is
164+ * furnished to do so, subject to the following conditions:
165+ *
166+ * The above copyright notice and this permission notice shall be included in
167+ * all copies or substantial portions of the Software.
168+ *
169+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
170+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
172+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
173+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
174+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
175+ * THE SOFTWARE.
176+ */
177+
178+#ifndef MMAP_FIXED_H
179+#define MMAP_FIXED_H
180+
181+#ifndef MAP_FIXED_NOREPLACE
182+#define MAP_FIXED_NOREPLACE 0x100000
183+
184+void *mmap_fixed_noreplace(void *addr, size_t len, int prot, int flags,
185+ int fd, off_t offset);
186+
187+#else /* MAP_FIXED_NOREPLACE */
188+#define mmap_fixed_noreplace mmap
189+#endif /* MAP_FIXED_NOREPLACE */
190+
191+#endif /* MMAP_FIXED_H */
192Index: qemu-8.2.0/linux-user/mmap.c
193===================================================================
194--- qemu-8.2.0.orig/linux-user/mmap.c
195+++ qemu-8.2.0/linux-user/mmap.c
196@@ -25,6 +25,7 @@
197 #include "user-mmap.h"
198 #include "target_mman.h"
199 #include "qemu/interval-tree.h"
200+#include "mmap-fixed.h"
201
202 #ifdef TARGET_ARM
203 #include "target/arm/cpu-features.h"
204@@ -304,9 +305,9 @@ static bool mmap_frag(abi_ulong real_sta
205 * outside of the fragment we need to map. Allocate a new host
206 * page to cover, discarding whatever else may have been present.
207 */
208- void *p = mmap(host_start, qemu_host_page_size,
209- target_to_host_prot(prot),
210- flags | MAP_ANONYMOUS, -1, 0);
211+ void *p = mmap_fixed_noreplace(host_start, qemu_host_page_size,
212+ target_to_host_prot(prot),
213+ flags | MAP_ANONYMOUS, -1, 0);
214 if (p != host_start) {
215 if (p != MAP_FAILED) {
216 munmap(p, qemu_host_page_size);
217@@ -405,8 +406,9 @@ abi_ulong mmap_find_vma(abi_ulong start,
218 * - mremap() with MREMAP_FIXED flag
219 * - shmat() with SHM_REMAP flag
220 */
221- ptr = mmap(g2h_untagged(addr), size, PROT_NONE,
222- MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
223+ ptr = mmap_fixed_noreplace(g2h_untagged(addr), size, PROT_NONE,
224+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE,
225+ -1, 0);
226
227 /* ENOMEM, if host address space has no memory */
228 if (ptr == MAP_FAILED) {
229@@ -600,16 +602,16 @@ abi_long target_mmap(abi_ulong start, ab
230 * especially important if qemu_host_page_size >
231 * qemu_real_host_page_size.
232 */
233- p = mmap(g2h_untagged(start), host_len, host_prot,
234- flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
235+ p = mmap_fixed_noreplace(g2h_untagged(start), host_len, host_prot,
236+ flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
237 if (p == MAP_FAILED) {
238 goto fail;
239 }
240 /* update start so that it points to the file position at 'offset' */
241 host_start = (uintptr_t)p;
242 if (!(flags & MAP_ANONYMOUS)) {
243- p = mmap(g2h_untagged(start), len, host_prot,
244- flags | MAP_FIXED, fd, host_offset);
245+ p = mmap_fixed_noreplace(g2h_untagged(start), len, host_prot,
246+ flags | MAP_FIXED, fd, host_offset);
247 if (p == MAP_FAILED) {
248 munmap(g2h_untagged(start), host_len);
249 goto fail;
250@@ -734,8 +736,9 @@ abi_long target_mmap(abi_ulong start, ab
251 len1 = real_last - real_start + 1;
252 want_p = g2h_untagged(real_start);
253
254- p = mmap(want_p, len1, target_to_host_prot(target_prot),
255- flags, fd, offset1);
256+ p = mmap_fixed_noreplace(want_p, len1,
257+ target_to_host_prot(target_prot),
258+ flags, fd, offset1);
259 if (p != want_p) {
260 if (p != MAP_FAILED) {
261 munmap(p, len1);
262@@ -837,9 +840,9 @@ static int mmap_reserve_or_unmap(abi_ulo
263 host_start = g2h_untagged(real_start);
264
265 if (reserved_va) {
266- void *ptr = mmap(host_start, real_len, PROT_NONE,
267- MAP_FIXED | MAP_ANONYMOUS
268- | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
269+ void *ptr = mmap_fixed_noreplace(host_start, real_len, PROT_NONE,
270+ MAP_FIXED | MAP_ANONYMOUS
271+ | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
272 return ptr == host_start ? 0 : -1;
273 }
274 return munmap(host_start, real_len);
275Index: qemu-8.2.0/linux-user/syscall.c
276===================================================================
277--- qemu-8.2.0.orig/linux-user/syscall.c
278+++ qemu-8.2.0/linux-user/syscall.c
279@@ -145,6 +145,7 @@
280 #include "qapi/error.h"
281 #include "fd-trans.h"
282 #include "cpu_loop-common.h"
283+#include "mmap-fixed.h"
284
285 #ifndef CLONE_IO
286 #define CLONE_IO 0x80000000 /* Clone io context */
diff --git a/meta/recipes-devtools/qemu/qemu/0012-linux-user-workaround-for-missing-MAP_SHARED_VALIDAT.patch b/meta/recipes-devtools/qemu/qemu/0012-linux-user-workaround-for-missing-MAP_SHARED_VALIDAT.patch
new file mode 100644
index 0000000000..48034a4680
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/0012-linux-user-workaround-for-missing-MAP_SHARED_VALIDAT.patch
@@ -0,0 +1,51 @@
1From 5c73e53997df800a742f9cd7355f3045861984bb Mon Sep 17 00:00:00 2001
2From: Frederic Konrad <fkonrad@amd.com>
3Date: Thu, 18 Jan 2024 10:43:44 +0000
4Subject: [PATCH 2/2] linux-user/*: workaround for missing MAP_SHARED_VALIDATE
5
6QEMU v8.1.0 recently requires MAP_SHARED_VALIDATE flags implementation for mmap.
7
8This is missing from the Ubuntu 18.04 compiler but looks like to be in the
9kernel source.
10
11Signed-off-by: Frederic Konrad <fkonrad@amd.com>
12Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
13
14Upstream-Status: Inappropriate [OE specific]
15
16The upstream only supports the last two major releases of an OS. The ones
17they have declared all have kernel 4.17 or newer.
18
19See:
20https://xilinx.slack.com/archives/D04G2647CTV/p1705074697942019
21
22https://www.qemu.org/docs/master/about/build-platforms.html
23
24 The project aims to support the most recent major version at all times for up
25 to five years after its initial release. Support for the previous major
26 version will be dropped 2 years after the new major version is released or
27 when the vendor itself drops support, whichever comes first.
28
29Signed-off-by: Mark Hatle <mark.hatle@amd.com>
30---
31 linux-user/mmap-fixed.h | 4 ++++
32 1 file changed, 4 insertions(+)
33
34diff --git a/linux-user/mmap-fixed.h b/linux-user/mmap-fixed.h
35index ef6eef5114..ec86586c1f 100644
36--- a/linux-user/mmap-fixed.h
37+++ b/linux-user/mmap-fixed.h
38@@ -26,6 +26,10 @@
39 #ifndef MMAP_FIXED_H
40 #define MMAP_FIXED_H
41
42+#ifndef MAP_SHARED_VALIDATE
43+#define MAP_SHARED_VALIDATE 0x03
44+#endif
45+
46 #ifndef MAP_FIXED_NOREPLACE
47 #define MAP_FIXED_NOREPLACE 0x100000
48
49--
502.34.1
51