master
c 1,586 lines 48.3 KB
Raw
1 /*
2 * mmap support for qemu
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "qemu/osdep.h"
20 #include <sys/shm.h>
21 #include "trace.h"
22 #include "exec/log.h"
23 #include "exec/page-protection.h"
24 #include "exec/mmap-lock.h"
25 #include "qemu.h"
26 #include "user/page-protection.h"
27 #include "user/mmap-min-addr.h"
28 #include "user-internals.h"
29 #include "user-mmap.h"
30 #include "target_mman.h"
31 #include "qemu/interval-tree.h"
32
33 #ifdef TARGET_ARM
34 #include "target/arm/cpu-features.h"
35 #endif
36
37 static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
38 static __thread int mmap_lock_count;
39
40 void mmap_lock(void)
41 {
42 if (mmap_lock_count++ == 0) {
43 pthread_mutex_lock(&mmap_mutex);
44 }
45 }
46
47 void mmap_unlock(void)
48 {
49 assert(mmap_lock_count > 0);
50 if (--mmap_lock_count == 0) {
51 pthread_mutex_unlock(&mmap_mutex);
52 }
53 }
54
55 bool have_mmap_lock(void)
56 {
57 return mmap_lock_count > 0 ? true : false;
58 }
59
60 /* Grab lock to make sure things are in a consistent state after fork(). */
61 void mmap_fork_start(void)
62 {
63 if (mmap_lock_count)
64 abort();
65 pthread_mutex_lock(&mmap_mutex);
66 }
67
68 void mmap_fork_end(int child)
69 {
70 if (child) {
71 pthread_mutex_init(&mmap_mutex, NULL);
72 } else {
73 pthread_mutex_unlock(&mmap_mutex);
74 }
75 }
76
77 /* Protected by mmap_lock. */
78 static IntervalTreeRoot shm_regions;
79
80 static void shm_region_add(abi_ptr start, abi_ptr last)
81 {
82 IntervalTreeNode *i = g_new0(IntervalTreeNode, 1);
83
84 i->start = start;
85 i->last = last;
86 interval_tree_insert(i, &shm_regions);
87 }
88
89 static abi_ptr shm_region_find(abi_ptr start)
90 {
91 IntervalTreeNode *i;
92
93 for (i = interval_tree_iter_first(&shm_regions, start, start); i;
94 i = interval_tree_iter_next(i, start, start)) {
95 if (i->start == start) {
96 return i->last;
97 }
98 }
99 return 0;
100 }
101
102 static void shm_region_rm_complete(abi_ptr start, abi_ptr last)
103 {
104 IntervalTreeNode *i, *n;
105
106 for (i = interval_tree_iter_first(&shm_regions, start, last); i; i = n) {
107 n = interval_tree_iter_next(i, start, last);
108 if (i->start >= start && i->last <= last) {
109 interval_tree_remove(i, &shm_regions);
110 g_free(i);
111 }
112 }
113 }
114
115 /*
116 * Validate target prot bitmask.
117 * Return the prot bitmask for the host in *HOST_PROT.
118 * Return 0 if the target prot bitmask is invalid, otherwise
119 * the internal qemu page_flags (which will include PAGE_VALID).
120 */
121 static int validate_prot_to_pageflags(int prot)
122 {
123 int valid = PROT_READ | PROT_WRITE | PROT_EXEC | TARGET_PROT_SEM;
124 int page_flags = (prot & PAGE_RWX) | PAGE_VALID;
125
126 #ifdef TARGET_AARCH64
127 {
128 ARMCPU *cpu = ARM_CPU(thread_cpu);
129
130 /*
131 * The PROT_BTI bit is only accepted if the cpu supports the feature.
132 * Since this is the unusual case, don't bother checking unless
133 * the bit has been requested. If set and valid, record the bit
134 * within QEMU's page_flags.
135 */
136 if ((prot & TARGET_PROT_BTI) && cpu_isar_feature(aa64_bti, cpu)) {
137 valid |= TARGET_PROT_BTI;
138 page_flags |= PAGE_BTI;
139 }
140 /* Similarly for the PROT_MTE bit. */
141 if ((prot & TARGET_PROT_MTE) && cpu_isar_feature(aa64_mte, cpu)) {
142 valid |= TARGET_PROT_MTE;
143 page_flags |= PAGE_MTE;
144 }
145 }
146 #elif defined(TARGET_HPPA)
147 valid |= PROT_GROWSDOWN | PROT_GROWSUP;
148 #endif
149
150 return prot & ~valid ? 0 : page_flags;
151 }
152
153 /*
154 * For the host, we need not pass anything except read/write/exec.
155 * While PROT_SEM is allowed by all hosts, it is also ignored, so
156 * don't bother transforming guest bit to host bit. Any other
157 * target-specific prot bits will not be understood by the host
158 * and will need to be encoded into page_flags for qemu emulation.
159 *
160 * Pages that are executable by the guest will never be executed
161 * by the host, but the host will need to be able to read them.
162 */
163 static int target_to_host_prot(int prot)
164 {
165 return (prot & (PROT_READ | PROT_WRITE)) |
166 (prot & PROT_EXEC ? PROT_READ : 0);
167 }
168
169 /* Target bits to be cleared by mprotect if not present in target_prot. */
170 #ifdef TARGET_AARCH64
171 #define TARGET_PAGE_NOTSTICKY PAGE_BTI
172 #else
173 #define TARGET_PAGE_NOTSTICKY 0
174 #endif
175
176 /* NOTE: all the constants are the HOST ones, but addresses are target. */
177 int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
178 {
179 int host_page_size = qemu_real_host_page_size();
180 abi_ulong starts[3];
181 abi_ulong lens[3];
182 int prots[3];
183 abi_ulong host_start, host_last, last;
184 int prot1, ret, page_flags, nranges;
185
186 trace_target_mprotect(start, len, target_prot);
187
188 if ((start & ~TARGET_PAGE_MASK) != 0) {
189 return -TARGET_EINVAL;
190 }
191 page_flags = validate_prot_to_pageflags(target_prot);
192 if (!page_flags) {
193 return -TARGET_EINVAL;
194 }
195 if (len == 0) {
196 return 0;
197 }
198 len = TARGET_PAGE_ALIGN(len);
199 if (!guest_range_valid_untagged(start, len)) {
200 return -TARGET_ENOMEM;
201 }
202
203 last = start + len - 1;
204 host_start = start & -host_page_size;
205 host_last = ROUND_UP(last, host_page_size) - 1;
206 nranges = 0;
207
208 mmap_lock();
209
210 if (host_last - host_start < host_page_size) {
211 /* Single host page contains all guest pages: sum the prot. */
212 prot1 = target_prot;
213 for (abi_ulong a = host_start; a < start; a += TARGET_PAGE_SIZE) {
214 prot1 |= page_get_flags(a);
215 }
216 for (abi_ulong a = last; a < host_last; a += TARGET_PAGE_SIZE) {
217 prot1 |= page_get_flags(a + 1);
218 }
219 starts[nranges] = host_start;
220 lens[nranges] = host_page_size;
221 prots[nranges] = prot1;
222 nranges++;
223 } else {
224 if (host_start < start) {
225 /* Host page contains more than one guest page: sum the prot. */
226 prot1 = target_prot;
227 for (abi_ulong a = host_start; a < start; a += TARGET_PAGE_SIZE) {
228 prot1 |= page_get_flags(a);
229 }
230 /* If the resulting sum differs, create a new range. */
231 if (prot1 != target_prot) {
232 starts[nranges] = host_start;
233 lens[nranges] = host_page_size;
234 prots[nranges] = prot1;
235 nranges++;
236 host_start += host_page_size;
237 }
238 }
239
240 if (last < host_last) {
241 /* Host page contains more than one guest page: sum the prot. */
242 prot1 = target_prot;
243 for (abi_ulong a = last; a < host_last; a += TARGET_PAGE_SIZE) {
244 prot1 |= page_get_flags(a + 1);
245 }
246 /* If the resulting sum differs, create a new range. */
247 if (prot1 != target_prot) {
248 host_last -= host_page_size;
249 starts[nranges] = host_last + 1;
250 lens[nranges] = host_page_size;
251 prots[nranges] = prot1;
252 nranges++;
253 }
254 }
255
256 /* Create a range for the middle, if any remains. */
257 if (host_start < host_last) {
258 starts[nranges] = host_start;
259 lens[nranges] = host_last - host_start + 1;
260 prots[nranges] = target_prot;
261 nranges++;
262 }
263 }
264
265 for (int i = 0; i < nranges; ++i) {
266 ret = mprotect(g2h_untagged(starts[i]), lens[i],
267 target_to_host_prot(prots[i]));
268 if (ret != 0) {
269 goto error;
270 }
271 }
272
273 page_set_flags(start, last, page_flags, PAGE_RWX | TARGET_PAGE_NOTSTICKY);
274 ret = 0;
275
276 error:
277 mmap_unlock();
278 return ret;
279 }
280
281 /*
282 * Perform munmap on behalf of the target, with host parameters.
283 * If reserved_va, we must replace the memory reservation.
284 */
285 static int do_munmap(void *addr, size_t len)
286 {
287 if (reserved_va) {
288 void *ptr = mmap(addr, len, PROT_NONE,
289 MAP_FIXED | MAP_ANONYMOUS
290 | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
291 return ptr == addr ? 0 : -1;
292 }
293 return munmap(addr, len);
294 }
295
296 /*
297 * Perform a pread on behalf of target_mmap. We can reach EOF, we can be
298 * interrupted by signals, and in general there's no good error return path.
299 * If @zero, zero the rest of the block at EOF.
300 * Return true on success.
301 */
302 static bool mmap_pread(int fd, void *p, size_t len, off_t offset, bool zero)
303 {
304 while (1) {
305 ssize_t r = pread(fd, p, len, offset);
306
307 if (likely(r == len)) {
308 /* Complete */
309 return true;
310 }
311 if (r == 0) {
312 /* EOF */
313 if (zero) {
314 memset(p, 0, len);
315 }
316 return true;
317 }
318 if (r > 0) {
319 /* Short read */
320 p += r;
321 len -= r;
322 offset += r;
323 } else if (errno != EINTR) {
324 /* Error */
325 return false;
326 }
327 }
328 }
329
330 /*
331 * Map an incomplete host page.
332 *
333 * Here be dragons. This case will not work if there is an existing
334 * overlapping host page, which is file mapped, and for which the mapping
335 * is beyond the end of the file. In that case, we will see SIGBUS when
336 * trying to write a portion of this page.
337 *
338 * FIXME: Work around this with a temporary signal handler and longjmp.
339 */
340 static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
341 int prot, int flags, int fd, off_t offset)
342 {
343 int host_page_size = qemu_real_host_page_size();
344 abi_ulong real_last;
345 void *host_start;
346 int prot_old, prot_new;
347 int host_prot_old, host_prot_new;
348
349 if (!(flags & MAP_ANONYMOUS)
350 && (flags & MAP_TYPE) == MAP_SHARED
351 && (prot & PROT_WRITE)) {
352 /*
353 * msync() won't work with the partial page, so we return an
354 * error if write is possible while it is a shared mapping.
355 */
356 errno = EINVAL;
357 return false;
358 }
359
360 real_last = real_start + host_page_size - 1;
361 host_start = g2h_untagged(real_start);
362
363 /* Get the protection of the target pages outside the mapping. */
364 prot_old = 0;
365 for (abi_ulong a = real_start; a < start; a += TARGET_PAGE_SIZE) {
366 prot_old |= page_get_flags(a);
367 }
368 for (abi_ulong a = real_last; a > last; a -= TARGET_PAGE_SIZE) {
369 prot_old |= page_get_flags(a);
370 }
371
372 if (prot_old == 0) {
373 /*
374 * Since !(prot_old & PAGE_VALID), there were no guest pages
375 * outside of the fragment we need to map. Allocate a new host
376 * page to cover, discarding whatever else may have been present.
377 */
378 void *p = mmap(host_start, host_page_size,
379 target_to_host_prot(prot),
380 flags | MAP_ANONYMOUS, -1, 0);
381 if (p != host_start) {
382 if (p != MAP_FAILED) {
383 do_munmap(p, host_page_size);
384 errno = EEXIST;
385 }
386 return false;
387 }
388 prot_old = prot;
389 }
390 prot_new = prot | prot_old;
391
392 host_prot_old = target_to_host_prot(prot_old);
393 host_prot_new = target_to_host_prot(prot_new);
394
395 /* Adjust protection to be able to write. */
396 if (!(host_prot_old & PROT_WRITE)) {
397 host_prot_old |= PROT_WRITE;
398 mprotect(host_start, host_page_size, host_prot_old);
399 }
400
401 /* Read or zero the new guest pages. */
402 if (flags & MAP_ANONYMOUS) {
403 memset(g2h_untagged(start), 0, last - start + 1);
404 } else if (!mmap_pread(fd, g2h_untagged(start), last - start + 1,
405 offset, true)) {
406 return false;
407 }
408
409 /* Put final protection */
410 if (host_prot_new != host_prot_old) {
411 mprotect(host_start, host_page_size, host_prot_new);
412 }
413 return true;
414 }
415
416 abi_ulong task_unmapped_base;
417 abi_ulong elf_et_dyn_base;
418 abi_ulong mmap_next_start;
419
420 /*
421 * Subroutine of mmap_find_vma, used when we have pre-allocated
422 * a chunk of guest address space.
423 */
424 static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
425 abi_ulong align)
426 {
427 target_ulong ret = -1;
428
429 if (start <= reserved_va) {
430 ret = page_find_range_empty(start, reserved_va, size, align);
431 }
432 if (ret == -1 && start > mmap_min_addr) {
433 /* Restart at the beginning of the address space. */
434 ret = page_find_range_empty(mmap_min_addr, MIN(start - 1, reserved_va),
435 size, align);
436 }
437
438 return ret;
439 }
440
441 /*
442 * Find and reserve a free memory area of size 'size'. The search
443 * starts at 'start'.
444 * It must be called with mmap_lock() held.
445 * Return -1 if error.
446 */
447 abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
448 {
449 int host_page_size = qemu_real_host_page_size();
450 void *ptr, *prev;
451 abi_ulong addr;
452 int wrapped, repeat;
453
454 align = MAX(align, host_page_size);
455
456 /* If 'start' == 0, then a default start address is used. */
457 if (start == 0) {
458 start = mmap_next_start;
459 } else {
460 start &= -host_page_size;
461 }
462 start = ROUND_UP(start, align);
463 size = ROUND_UP(size, host_page_size);
464
465 if (reserved_va) {
466 return mmap_find_vma_reserved(start, size, align);
467 }
468
469 addr = start;
470 wrapped = repeat = 0;
471 prev = 0;
472
473 for (;; prev = ptr) {
474 /*
475 * Reserve needed memory area to avoid a race.
476 * It should be discarded using:
477 * - mmap() with MAP_FIXED flag
478 * - mremap() with MREMAP_FIXED flag
479 * - shmat() with SHM_REMAP flag
480 */
481 ptr = mmap(g2h_untagged(addr), size, PROT_NONE,
482 MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
483
484 /* ENOMEM, if host address space has no memory */
485 if (ptr == MAP_FAILED) {
486 return (abi_ulong)-1;
487 }
488
489 /*
490 * Count the number of sequential returns of the same address.
491 * This is used to modify the search algorithm below.
492 */
493 repeat = (ptr == prev ? repeat + 1 : 0);
494
495 if (h2g_valid(ptr + size - 1)) {
496 addr = h2g(ptr);
497
498 if ((addr & (align - 1)) == 0) {
499 /* Success. */
500 if (start == mmap_next_start && addr >= task_unmapped_base) {
501 mmap_next_start = addr + size;
502 }
503 return addr;
504 }
505
506 /* The address is not properly aligned for the target. */
507 switch (repeat) {
508 case 0:
509 /*
510 * Assume the result that the kernel gave us is the
511 * first with enough free space, so start again at the
512 * next higher target page.
513 */
514 addr = ROUND_UP(addr, align);
515 break;
516 case 1:
517 /*
518 * Sometimes the kernel decides to perform the allocation
519 * at the top end of memory instead.
520 */
521 addr &= -align;
522 break;
523 case 2:
524 /* Start over at low memory. */
525 addr = 0;
526 break;
527 default:
528 /* Fail. This unaligned block must the last. */
529 addr = -1;
530 break;
531 }
532 } else {
533 /*
534 * Since the result the kernel gave didn't fit, start
535 * again at low memory. If any repetition, fail.
536 */
537 addr = (repeat ? -1 : 0);
538 }
539
540 /* Unmap and try again. */
541 munmap(ptr, size);
542
543 /* ENOMEM if we checked the whole of the target address space. */
544 if (addr == (abi_ulong)-1) {
545 return (abi_ulong)-1;
546 } else if (addr == 0) {
547 if (wrapped) {
548 return (abi_ulong)-1;
549 }
550 wrapped = 1;
551 /*
552 * Don't actually use 0 when wrapping, instead indicate
553 * that we'd truly like an allocation in low memory.
554 */
555 addr = (mmap_min_addr > TARGET_PAGE_SIZE
556 ? TARGET_PAGE_ALIGN(mmap_min_addr)
557 : TARGET_PAGE_SIZE);
558 } else if (wrapped && addr >= start) {
559 return (abi_ulong)-1;
560 }
561 }
562 }
563
564 /*
565 * Record a successful mmap within the user-exec interval tree.
566 */
567 static abi_long mmap_end(abi_ulong start, abi_ulong last,
568 abi_ulong passthrough_start,
569 abi_ulong passthrough_last,
570 int flags, int page_flags)
571 {
572 if (flags & MAP_ANONYMOUS) {
573 page_flags |= PAGE_ANON;
574 }
575 if (passthrough_start > passthrough_last) {
576 page_set_flags(start, last, page_flags, PAGE_VALID);
577 } else {
578 if (start < passthrough_start) {
579 page_set_flags(start, passthrough_start - 1,
580 page_flags, PAGE_VALID);
581 }
582 page_set_flags(passthrough_start, passthrough_last,
583 page_flags | PAGE_PASSTHROUGH, PAGE_VALID);
584 if (passthrough_last < last) {
585 page_set_flags(passthrough_last + 1, last, page_flags, PAGE_VALID);
586 }
587 }
588 shm_region_rm_complete(start, last);
589 trace_target_mmap_complete(start);
590 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
591 FILE *f = qemu_log_trylock();
592 if (f) {
593 fprintf(f, "page layout changed following mmap\n");
594 page_dump(f);
595 qemu_log_unlock(f);
596 }
597 }
598 return start;
599 }
600
601 /*
602 * Special case host page size == target page size,
603 * where there are no edge conditions.
604 */
605 static abi_long mmap_h_eq_g(abi_ulong start, abi_ulong len,
606 int host_prot, int flags, int page_flags,
607 int fd, off_t offset)
608 {
609 void *p, *want_p = NULL;
610 abi_ulong last;
611
612 if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
613 want_p = g2h_untagged(start);
614 }
615
616 p = mmap(want_p, len, host_prot, flags, fd, offset);
617 if (p == MAP_FAILED) {
618 return -1;
619 }
620 /* If the host kernel does not support MAP_FIXED_NOREPLACE, emulate. */
621 if ((flags & MAP_FIXED_NOREPLACE) && p != want_p) {
622 do_munmap(p, len);
623 errno = EEXIST;
624 return -1;
625 }
626
627 start = h2g(p);
628 last = start + len - 1;
629 return mmap_end(start, last, start, last, flags, page_flags);
630 }
631
632 /*
633 * Special case host page size < target page size.
634 *
635 * The two special cases are increased guest alignment, and mapping
636 * past the end of a file.
637 *
638 * When mapping files into a memory area larger than the file,
639 * accesses to pages beyond the file size will cause a SIGBUS.
640 *
641 * For example, if mmaping a file of 100 bytes on a host with 4K
642 * pages emulating a target with 8K pages, the target expects to
643 * be able to access the first 8K. But the host will trap us on
644 * any access beyond 4K.
645 *
646 * When emulating a target with a larger page-size than the hosts,
647 * we may need to truncate file maps at EOF and add extra anonymous
648 * pages up to the targets page boundary.
649 *
650 * This workaround only works for files that do not change.
651 * If the file is later extended (e.g. ftruncate), the SIGBUS
652 * vanishes and the proper behaviour is that changes within the
653 * anon page should be reflected in the file.
654 *
655 * However, this case is rather common with executable images,
656 * so the workaround is important for even trivial tests, whereas
657 * the mmap of a file being extended is less common.
658 */
659 static abi_long mmap_h_lt_g(abi_ulong start, abi_ulong len, int host_prot,
660 int mmap_flags, int page_flags, int fd,
661 off_t offset, int host_page_size)
662 {
663 void *p, *want_p = NULL;
664 off_t fileend_adj = 0;
665 int flags = mmap_flags;
666 abi_ulong last, pass_last;
667
668 if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
669 want_p = g2h_untagged(start);
670 }
671
672 if (!(flags & MAP_ANONYMOUS)) {
673 struct stat sb;
674
675 if (fstat(fd, &sb) == -1) {
676 return -1;
677 }
678 if (offset >= sb.st_size) {
679 /*
680 * The entire map is beyond the end of the file.
681 * Transform it to an anonymous mapping.
682 */
683 flags |= MAP_ANONYMOUS;
684 fd = -1;
685 offset = 0;
686 } else if (offset + len > sb.st_size) {
687 /*
688 * A portion of the map is beyond the end of the file.
689 * Truncate the file portion of the allocation.
690 */
691 fileend_adj = offset + len - sb.st_size;
692 }
693 }
694
695 if (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE)) {
696 if (fileend_adj) {
697 p = mmap(want_p, len, host_prot, flags | MAP_ANONYMOUS, -1, 0);
698 } else {
699 p = mmap(want_p, len, host_prot, flags, fd, offset);
700 }
701 if (p != want_p) {
702 if (p != MAP_FAILED) {
703 /* Host does not support MAP_FIXED_NOREPLACE: emulate. */
704 do_munmap(p, len);
705 errno = EEXIST;
706 }
707 return -1;
708 }
709
710 if (fileend_adj) {
711 void *t = mmap(p, len - fileend_adj, host_prot,
712 (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED,
713 fd, offset);
714
715 if (t == MAP_FAILED) {
716 int save_errno = errno;
717
718 /*
719 * We failed a map over the top of the successful anonymous
720 * mapping above. The only failure mode is running out of VMAs,
721 * and there's nothing that we can do to detect that earlier.
722 * If we have replaced an existing mapping with MAP_FIXED,
723 * then we cannot properly recover. It's a coin toss whether
724 * it would be better to exit or continue here.
725 */
726 if (!(flags & MAP_FIXED_NOREPLACE) &&
727 !page_check_range_empty(start, start + len - 1)) {
728 qemu_log("QEMU target_mmap late failure: %s",
729 strerror(save_errno));
730 }
731
732 do_munmap(want_p, len);
733 errno = save_errno;
734 return -1;
735 }
736 }
737 } else {
738 size_t host_len, part_len;
739
740 /*
741 * Take care to align the host memory. Perform a larger anonymous
742 * allocation and extract the aligned portion. Remap the file on
743 * top of that.
744 */
745 host_len = len + TARGET_PAGE_SIZE - host_page_size;
746 p = mmap(want_p, host_len, host_prot, flags | MAP_ANONYMOUS, -1, 0);
747 if (p == MAP_FAILED) {
748 return -1;
749 }
750
751 part_len = (uintptr_t)p & (TARGET_PAGE_SIZE - 1);
752 if (part_len) {
753 part_len = TARGET_PAGE_SIZE - part_len;
754 do_munmap(p, part_len);
755 p += part_len;
756 host_len -= part_len;
757 }
758 if (len < host_len) {
759 do_munmap(p + len, host_len - len);
760 }
761
762 if (!(flags & MAP_ANONYMOUS)) {
763 void *t = mmap(p, len - fileend_adj, host_prot,
764 flags | MAP_FIXED, fd, offset);
765
766 if (t == MAP_FAILED) {
767 int save_errno = errno;
768 do_munmap(p, len);
769 errno = save_errno;
770 return -1;
771 }
772 }
773
774 start = h2g(p);
775 }
776
777 last = start + len - 1;
778 if (fileend_adj) {
779 pass_last = ROUND_UP(last - fileend_adj, host_page_size) - 1;
780 } else {
781 pass_last = last;
782 }
783 return mmap_end(start, last, start, pass_last, mmap_flags, page_flags);
784 }
785
786 /*
787 * Special case host page size > target page size.
788 *
789 * The two special cases are address and file offsets that are valid
790 * for the guest that cannot be directly represented by the host.
791 */
792 static abi_long mmap_h_gt_g(abi_ulong start, abi_ulong len,
793 int target_prot, int host_prot,
794 int flags, int page_flags, int fd,
795 off_t offset, int host_page_size)
796 {
797 void *p, *want_p = NULL;
798 off_t host_offset = offset & -host_page_size;
799 abi_ulong last, real_start, real_last;
800 bool misaligned_offset = false;
801 size_t host_len;
802
803 if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
804 want_p = g2h_untagged(start);
805 }
806
807 if (!(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
808 /*
809 * Adjust the offset to something representable on the host.
810 */
811 host_len = len + offset - host_offset;
812 p = mmap(want_p, host_len, host_prot, flags, fd, host_offset);
813 if (p == MAP_FAILED) {
814 return -1;
815 }
816
817 /* Update start to the file position at offset. */
818 p += offset - host_offset;
819
820 start = h2g(p);
821 last = start + len - 1;
822 return mmap_end(start, last, start, last, flags, page_flags);
823 }
824
825 if (!(flags & MAP_ANONYMOUS)) {
826 misaligned_offset = (start ^ offset) & (host_page_size - 1);
827
828 /*
829 * The fallback for misalignment is a private mapping + read.
830 * This carries none of semantics required of MAP_SHARED.
831 */
832 if (misaligned_offset && (flags & MAP_TYPE) != MAP_PRIVATE) {
833 errno = EINVAL;
834 return -1;
835 }
836 }
837
838 last = start + len - 1;
839 real_start = start & -host_page_size;
840 real_last = ROUND_UP(last, host_page_size) - 1;
841
842 /*
843 * Handle the start and end of the mapping.
844 */
845 if (real_start < start) {
846 abi_ulong real_page_last = real_start + host_page_size - 1;
847 if (last <= real_page_last) {
848 /* Entire allocation a subset of one host page. */
849 if (!mmap_frag(real_start, start, last, target_prot,
850 flags, fd, offset)) {
851 return -1;
852 }
853 return mmap_end(start, last, -1, 0, flags, page_flags);
854 }
855
856 if (!mmap_frag(real_start, start, real_page_last, target_prot,
857 flags, fd, offset)) {
858 return -1;
859 }
860 real_start = real_page_last + 1;
861 }
862
863 if (last < real_last) {
864 abi_ulong real_page_start = real_last - host_page_size + 1;
865 if (!mmap_frag(real_page_start, real_page_start, last,
866 target_prot, flags, fd,
867 offset + real_page_start - start)) {
868 return -1;
869 }
870 real_last = real_page_start - 1;
871 }
872
873 if (real_start > real_last) {
874 return mmap_end(start, last, -1, 0, flags, page_flags);
875 }
876
877 /*
878 * Handle the middle of the mapping.
879 */
880
881 host_len = real_last - real_start + 1;
882 want_p += real_start - start;
883
884 if (flags & MAP_ANONYMOUS) {
885 p = mmap(want_p, host_len, host_prot, flags, -1, 0);
886 } else if (!misaligned_offset) {
887 p = mmap(want_p, host_len, host_prot, flags, fd,
888 offset + real_start - start);
889 } else {
890 p = mmap(want_p, host_len, host_prot | PROT_WRITE,
891 flags | MAP_ANONYMOUS, -1, 0);
892 }
893 if (p != want_p) {
894 if (p != MAP_FAILED) {
895 do_munmap(p, host_len);
896 errno = EEXIST;
897 }
898 return -1;
899 }
900
901 if (misaligned_offset) {
902 if (!mmap_pread(fd, p, host_len, offset + real_start - start, false)) {
903 do_munmap(p, host_len);
904 return -1;
905 }
906 if (!(host_prot & PROT_WRITE)) {
907 mprotect(p, host_len, host_prot);
908 }
909 }
910
911 return mmap_end(start, last, -1, 0, flags, page_flags);
912 }
913
914 static abi_long target_mmap__locked(abi_ulong start, abi_ulong len,
915 int target_prot, int flags, int page_flags,
916 int fd, off_t offset)
917 {
918 int host_page_size = qemu_real_host_page_size();
919 int host_prot;
920
921 /*
922 * For reserved_va, we are in full control of the allocation.
923 * Find a suitable hole and convert to MAP_FIXED.
924 */
925 if (reserved_va) {
926 if (flags & MAP_FIXED_NOREPLACE) {
927 /* Validate that the chosen range is empty. */
928 if (!page_check_range_empty(start, start + len - 1)) {
929 errno = EEXIST;
930 return -1;
931 }
932 flags = (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED;
933 } else if (!(flags & MAP_FIXED)) {
934 abi_ulong real_start = start & -host_page_size;
935 off_t host_offset = offset & -host_page_size;
936 size_t real_len = len + offset - host_offset;
937 abi_ulong align = MAX(host_page_size, TARGET_PAGE_SIZE);
938
939 start = mmap_find_vma(real_start, real_len, align);
940 if (start == (abi_ulong)-1) {
941 errno = ENOMEM;
942 return -1;
943 }
944 start += offset - host_offset;
945 flags |= MAP_FIXED;
946 }
947 }
948
949 host_prot = target_to_host_prot(target_prot);
950
951 if (host_page_size == TARGET_PAGE_SIZE) {
952 return mmap_h_eq_g(start, len, host_prot, flags,
953 page_flags, fd, offset);
954 } else if (host_page_size < TARGET_PAGE_SIZE) {
955 return mmap_h_lt_g(start, len, host_prot, flags,
956 page_flags, fd, offset, host_page_size);
957 } else {
958 return mmap_h_gt_g(start, len, target_prot, host_prot, flags,
959 page_flags, fd, offset, host_page_size);
960 }
961 }
962
963 /* NOTE: all the constants are the HOST ones */
964 abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
965 int flags, int fd, off_t offset)
966 {
967 abi_long ret;
968 int page_flags;
969
970 trace_target_mmap(start, len, target_prot, flags, fd, offset);
971
972 if (!len) {
973 errno = EINVAL;
974 return -1;
975 }
976
977 page_flags = validate_prot_to_pageflags(target_prot);
978 if (!page_flags) {
979 errno = EINVAL;
980 return -1;
981 }
982
983 /* Also check for overflows... */
984 len = TARGET_PAGE_ALIGN(len);
985 if (!len || len != (size_t)len) {
986 errno = ENOMEM;
987 return -1;
988 }
989
990 if (offset & ~TARGET_PAGE_MASK) {
991 errno = EINVAL;
992 return -1;
993 }
994 if (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE)) {
995 if (start & ~TARGET_PAGE_MASK) {
996 errno = EINVAL;
997 return -1;
998 }
999 if (!guest_range_valid_untagged(start, len)) {
1000 errno = ENOMEM;
1001 return -1;
1002 }
1003 }
1004
1005 mmap_lock();
1006
1007 ret = target_mmap__locked(start, len, target_prot, flags,
1008 page_flags, fd, offset);
1009
1010 mmap_unlock();
1011
1012 /*
1013 * If we're mapping shared memory, ensure we generate code for parallel
1014 * execution and flush old translations. This will work up to the level
1015 * supported by the host -- anything that requires EXCP_ATOMIC will not
1016 * be atomic with respect to an external process.
1017 */
1018 if (ret != -1 && (flags & MAP_TYPE) != MAP_PRIVATE) {
1019 begin_parallel_context(thread_cpu);
1020 }
1021
1022 return ret;
1023 }
1024
1025 static int mmap_reserve_or_unmap(abi_ulong start, abi_ulong len)
1026 {
1027 int host_page_size = qemu_real_host_page_size();
1028 abi_ulong real_start;
1029 abi_ulong real_last;
1030 abi_ulong real_len;
1031 abi_ulong last;
1032 abi_ulong a;
1033 void *host_start;
1034 int prot;
1035
1036 last = ROUND_UP(start + len, TARGET_PAGE_SIZE) - 1;
1037 real_start = start & -host_page_size;
1038 real_last = ROUND_UP(last + 1, host_page_size) - 1;
1039
1040 /*
1041 * If guest pages remain on the first or last host pages,
1042 * adjust the deallocation to retain those guest pages.
1043 * The single page special case is required for the last page,
1044 * lest real_start overflow to zero.
1045 */
1046 if (real_last - real_start < host_page_size) {
1047 prot = 0;
1048 for (a = real_start; a < start; a += TARGET_PAGE_SIZE) {
1049 prot |= page_get_flags(a);
1050 }
1051 for (a = last; a < real_last; a += TARGET_PAGE_SIZE) {
1052 prot |= page_get_flags(a + 1);
1053 }
1054 if (prot != 0) {
1055 return 0;
1056 }
1057 } else {
1058 for (prot = 0, a = real_start; a < start; a += TARGET_PAGE_SIZE) {
1059 prot |= page_get_flags(a);
1060 }
1061 if (prot != 0) {
1062 real_start += host_page_size;
1063 }
1064
1065 for (prot = 0, a = last; a < real_last; a += TARGET_PAGE_SIZE) {
1066 prot |= page_get_flags(a + 1);
1067 }
1068 if (prot != 0) {
1069 real_last -= host_page_size;
1070 }
1071
1072 if (real_last < real_start) {
1073 return 0;
1074 }
1075 }
1076
1077 real_len = real_last - real_start + 1;
1078 host_start = g2h_untagged(real_start);
1079
1080 return do_munmap(host_start, real_len);
1081 }
1082
1083 int target_munmap(abi_ulong start, abi_ulong len)
1084 {
1085 int ret;
1086
1087 trace_target_munmap(start, len);
1088
1089 if (start & ~TARGET_PAGE_MASK) {
1090 errno = EINVAL;
1091 return -1;
1092 }
1093 len = TARGET_PAGE_ALIGN(len);
1094 if (len == 0 || !guest_range_valid_untagged(start, len)) {
1095 errno = EINVAL;
1096 return -1;
1097 }
1098
1099 mmap_lock();
1100 ret = mmap_reserve_or_unmap(start, len);
1101 if (likely(ret == 0)) {
1102 page_set_flags(start, start + len - 1, 0, PAGE_VALID);
1103 shm_region_rm_complete(start, start + len - 1);
1104 }
1105 mmap_unlock();
1106
1107 return ret;
1108 }
1109
1110 abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
1111 abi_ulong new_size, unsigned long flags,
1112 abi_ulong new_addr)
1113 {
1114 int prot;
1115 void *host_addr;
1116
1117 if (((flags & MREMAP_FIXED) &&
1118 !guest_range_valid_untagged(new_addr, new_size)) ||
1119 ((flags & MREMAP_MAYMOVE) == 0 &&
1120 !guest_range_valid_untagged(old_addr, new_size))) {
1121 errno = EINVAL;
1122 return -1;
1123 }
1124
1125 if (!old_size) {
1126 if (!(flags & MREMAP_MAYMOVE)) {
1127 errno = EINVAL;
1128 return -1;
1129 }
1130 mmap_lock();
1131 if (flags & MREMAP_FIXED) {
1132 host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
1133 flags, g2h_untagged(new_addr));
1134 } else {
1135 /*
1136 * We ensure that the new mapping stands in the
1137 * region of guest mappable addresses.
1138 */
1139 abi_ulong mmap_start;
1140
1141 mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);
1142
1143 if (mmap_start == -1) {
1144 errno = ENOMEM;
1145 mmap_unlock();
1146 return -1;
1147 }
1148
1149 host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
1150 flags | MREMAP_FIXED, g2h_untagged(mmap_start));
1151
1152 new_addr = mmap_start;
1153 }
1154
1155 if (host_addr == MAP_FAILED) {
1156 mmap_unlock();
1157 return -1;
1158 }
1159
1160 if (flags & MREMAP_FIXED) {
1161 new_addr = h2g(host_addr);
1162 }
1163
1164 prot = page_get_flags(old_addr);
1165 /*
1166 * For old_size zero, there is nothing to clear at old_addr.
1167 * Only set the flags for the new mapping. They both are valid.
1168 */
1169 page_set_flags(new_addr, new_addr + new_size - 1,
1170 prot | PAGE_VALID, PAGE_VALID);
1171 shm_region_rm_complete(new_addr, new_addr + new_size - 1);
1172 mmap_unlock();
1173 return new_addr;
1174 }
1175
1176 if (!guest_range_valid_untagged(old_addr, old_size)) {
1177 errno = EFAULT;
1178 return -1;
1179 }
1180
1181 mmap_lock();
1182
1183 if (flags & MREMAP_FIXED) {
1184 host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
1185 flags, g2h_untagged(new_addr));
1186
1187 if (reserved_va && host_addr != MAP_FAILED) {
1188 /*
1189 * If new and old addresses overlap then the above mremap will
1190 * already have failed with EINVAL.
1191 */
1192 mmap_reserve_or_unmap(old_addr, old_size);
1193 }
1194 } else if (flags & MREMAP_MAYMOVE) {
1195 abi_ulong mmap_start;
1196
1197 mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);
1198
1199 if (mmap_start == -1) {
1200 errno = ENOMEM;
1201 host_addr = MAP_FAILED;
1202 } else {
1203 host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
1204 flags | MREMAP_FIXED,
1205 g2h_untagged(mmap_start));
1206 if (reserved_va) {
1207 mmap_reserve_or_unmap(old_addr, old_size);
1208 }
1209 }
1210 } else {
1211 int page_flags = 0;
1212 if (reserved_va && old_size < new_size) {
1213 abi_ulong addr;
1214 for (addr = old_addr + old_size;
1215 addr < old_addr + new_size;
1216 addr++) {
1217 page_flags |= page_get_flags(addr);
1218 }
1219 }
1220 if (page_flags == 0) {
1221 host_addr = mremap(g2h_untagged(old_addr),
1222 old_size, new_size, flags);
1223
1224 if (host_addr != MAP_FAILED) {
1225 /* Check if address fits target address space */
1226 if (!guest_range_valid_untagged(h2g(host_addr), new_size)) {
1227 /* Revert mremap() changes */
1228 host_addr = mremap(g2h_untagged(old_addr),
1229 new_size, old_size, flags);
1230 errno = ENOMEM;
1231 host_addr = MAP_FAILED;
1232 } else if (reserved_va && old_size > new_size) {
1233 /* Re-reserve pages we just shrunk out of the mapping */
1234 mmap_reserve_or_unmap(old_addr + new_size,
1235 old_size - new_size);
1236 }
1237 }
1238 } else {
1239 errno = ENOMEM;
1240 host_addr = MAP_FAILED;
1241 }
1242 }
1243
1244 if (host_addr == MAP_FAILED) {
1245 new_addr = -1;
1246 } else {
1247 new_addr = h2g(host_addr);
1248 prot = page_get_flags(old_addr);
1249 page_set_flags(old_addr, old_addr + old_size - 1, 0, PAGE_VALID);
1250 shm_region_rm_complete(old_addr, old_addr + old_size - 1);
1251 page_set_flags(new_addr, new_addr + new_size - 1,
1252 prot | PAGE_VALID, PAGE_VALID);
1253 shm_region_rm_complete(new_addr, new_addr + new_size - 1);
1254 }
1255 mmap_unlock();
1256 return new_addr;
1257 }
1258
1259 abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
1260 {
1261 abi_ulong len;
1262 int ret = 0;
1263
1264 if (start & ~TARGET_PAGE_MASK) {
1265 return -TARGET_EINVAL;
1266 }
1267 if (len_in == 0) {
1268 return 0;
1269 }
1270 len = TARGET_PAGE_ALIGN(len_in);
1271 if (len == 0 || !guest_range_valid_untagged(start, len)) {
1272 return -TARGET_EINVAL;
1273 }
1274
1275 /* Translate for some architectures which have different MADV_xxx values */
1276 switch (advice) {
1277 case TARGET_MADV_DONTNEED: /* alpha */
1278 advice = MADV_DONTNEED;
1279 break;
1280 case TARGET_MADV_WIPEONFORK: /* parisc */
1281 advice = MADV_WIPEONFORK;
1282 break;
1283 case TARGET_MADV_KEEPONFORK: /* parisc */
1284 advice = MADV_KEEPONFORK;
1285 break;
1286 /* all other MADV_xxx values are the same across architectures */
1287 }
1288
1289 /*
1290 * Most advice values are hints, so ignoring and returning success is ok.
1291 *
1292 * However, some advice values such as MADV_DONTNEED, MADV_WIPEONFORK and
1293 * MADV_KEEPONFORK are not hints and need to be emulated.
1294 *
1295 * A straight passthrough for those may not be safe because qemu sometimes
1296 * turns private file-backed mappings into anonymous mappings.
1297 * If all guest pages have PAGE_PASSTHROUGH set, mappings have the
1298 * same semantics for the host as for the guest.
1299 *
1300 * We pass through MADV_WIPEONFORK and MADV_KEEPONFORK if possible and
1301 * return failure if not.
1302 *
1303 * MADV_DONTNEED is passed through as well, if possible.
1304 * If passthrough isn't possible, we nevertheless (wrongly!) return
1305 * success, which is broken but some userspace programs fail to work
1306 * otherwise. Completely implementing such emulation is quite complicated
1307 * though.
1308 */
1309 mmap_lock();
1310 switch (advice) {
1311 case MADV_NORMAL:
1312 case MADV_RANDOM:
1313 case MADV_SEQUENTIAL:
1314 case MADV_WILLNEED:
1315 case MADV_DOFORK:
1316 case MADV_FREE:
1317 case MADV_COLD:
1318 case MADV_PAGEOUT:
1319 ret = 0; /* OK */
1320 break;
1321 case MADV_REMOVE:
1322 ret = -EOPNOTSUPP;
1323 break;
1324 case MADV_DONTDUMP:
1325 page_set_flags(start, start + len - 1, PAGE_DONTDUMP, 0);
1326 break;
1327 case MADV_DODUMP:
1328 page_set_flags(start, start + len - 1, 0, PAGE_DONTDUMP);
1329 break;
1330 case MADV_WIPEONFORK:
1331 case MADV_KEEPONFORK:
1332 ret = -EINVAL;
1333 /* fall through */
1334 case MADV_DONTNEED:
1335 if (page_check_range(start, len, PAGE_PASSTHROUGH)) {
1336 ret = get_errno(madvise(g2h_untagged(start), len, advice));
1337 if ((advice == MADV_DONTNEED) && (ret == 0)) {
1338 page_reset_target_data(start, start + len - 1);
1339 }
1340 }
1341 break;
1342 case MADV_DONTFORK:
1343 case MADV_HWPOISON:
1344 case MADV_MERGEABLE:
1345 case MADV_UNMERGEABLE:
1346 case MADV_HUGEPAGE:
1347 case MADV_NOHUGEPAGE:
1348 case MADV_POPULATE_READ:
1349 case MADV_POPULATE_WRITE:
1350 #ifdef MADV_COLLAPSE
1351 case MADV_COLLAPSE:
1352 #endif
1353 case -1: /* BoringSSL uses -1 to check if the environment is broken */
1354 ret = -EINVAL;
1355 break;
1356 default:
1357 qemu_log_mask(LOG_UNIMP, "Unhandled madvise(%d) call.\n", advice);
1358 ret = -EINVAL; /* not yet known advise */
1359 break;
1360 }
1361 mmap_unlock();
1362
1363 return ret;
1364 }
1365
1366 #ifndef TARGET_FORCE_SHMLBA
1367 /*
1368 * For most architectures, SHMLBA is the same as the page size;
1369 * some architectures have larger values, in which case they should
1370 * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
1371 * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
1372 * and defining its own value for SHMLBA.
1373 *
1374 * The kernel also permits SHMLBA to be set by the architecture to a
1375 * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
1376 * this means that addresses are rounded to the large size if
1377 * SHM_RND is set but addresses not aligned to that size are not rejected
1378 * as long as they are at least page-aligned. Since the only architecture
1379 * which uses this is ia64 this code doesn't provide for that oddity.
1380 */
1381 static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
1382 {
1383 return TARGET_PAGE_SIZE;
1384 }
1385 #endif
1386
1387 #if defined(__sparc__)
1388 #define HOST_FORCE_SHMLBA 1
1389 #else
1390 #define HOST_FORCE_SHMLBA 0
1391 #endif
1392
1393 abi_ulong target_shmat(CPUArchState *cpu_env, int shmid,
1394 abi_ulong shmaddr, int shmflg)
1395 {
1396 CPUState *cpu = env_cpu(cpu_env);
1397 struct shmid_ds shm_info;
1398 int ret;
1399 int h_pagesize;
1400 int t_shmlba, h_shmlba, m_shmlba;
1401 size_t t_len, h_len, m_len;
1402
1403 /* shmat pointers are always untagged */
1404
1405 /*
1406 * Because we can't use host shmat() unless the address is sufficiently
1407 * aligned for the host, we'll need to check both.
1408 * TODO: Could be fixed with softmmu.
1409 */
1410 t_shmlba = target_shmlba(cpu_env);
1411 h_pagesize = qemu_real_host_page_size();
1412 h_shmlba = (HOST_FORCE_SHMLBA ? SHMLBA : h_pagesize);
1413 m_shmlba = MAX(t_shmlba, h_shmlba);
1414
1415 if (shmaddr) {
1416 if (shmaddr & (m_shmlba - 1)) {
1417 if (shmflg & SHM_RND) {
1418 /*
1419 * The guest is allowing the kernel to round the address.
1420 * Assume that the guest is ok with us rounding to the
1421 * host required alignment too. Anyway if we don't, we'll
1422 * get an error from the kernel.
1423 */
1424 shmaddr &= ~(m_shmlba - 1);
1425 if (shmaddr == 0 && (shmflg & SHM_REMAP)) {
1426 return -TARGET_EINVAL;
1427 }
1428 } else {
1429 int require = TARGET_PAGE_SIZE;
1430 #ifdef TARGET_FORCE_SHMLBA
1431 require = t_shmlba;
1432 #endif
1433 /*
1434 * Include host required alignment, as otherwise we cannot
1435 * use host shmat at all.
1436 */
1437 require = MAX(require, h_shmlba);
1438 if (shmaddr & (require - 1)) {
1439 return -TARGET_EINVAL;
1440 }
1441 }
1442 }
1443 } else {
1444 if (shmflg & SHM_REMAP) {
1445 return -TARGET_EINVAL;
1446 }
1447 }
1448 /* All rounding now manually concluded. */
1449 shmflg &= ~SHM_RND;
1450
1451 /* Find out the length of the shared memory segment. */
1452 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
1453 if (is_error(ret)) {
1454 /* can't get length, bail out */
1455 return ret;
1456 }
1457 t_len = TARGET_PAGE_ALIGN(shm_info.shm_segsz);
1458 h_len = ROUND_UP(shm_info.shm_segsz, h_pagesize);
1459 m_len = MAX(t_len, h_len);
1460
1461 if (!guest_range_valid_untagged(shmaddr, m_len)) {
1462 return -TARGET_EINVAL;
1463 }
1464
1465 WITH_MMAP_LOCK_GUARD() {
1466 bool mapped = false;
1467 void *want, *test;
1468 abi_ulong last;
1469
1470 if (!shmaddr) {
1471 shmaddr = mmap_find_vma(0, m_len, m_shmlba);
1472 if (shmaddr == -1) {
1473 return -TARGET_ENOMEM;
1474 }
1475 mapped = !reserved_va;
1476 } else if (shmflg & SHM_REMAP) {
1477 /*
1478 * If host page size > target page size, the host shmat may map
1479 * more memory than the guest expects. Reject a mapping that
1480 * would replace memory in the unexpected gap.
1481 * TODO: Could be fixed with softmmu.
1482 */
1483 if (t_len < h_len &&
1484 !page_check_range_empty(shmaddr + t_len,
1485 shmaddr + h_len - 1)) {
1486 return -TARGET_EINVAL;
1487 }
1488 } else {
1489 if (!page_check_range_empty(shmaddr, shmaddr + m_len - 1)) {
1490 return -TARGET_EINVAL;
1491 }
1492 }
1493
1494 /* All placement is now complete. */
1495 want = (void *)g2h_untagged(shmaddr);
1496
1497 /*
1498 * Map anonymous pages across the entire range, then remap with
1499 * the shared memory. This is required for a number of corner
1500 * cases for which host and guest page sizes differ.
1501 */
1502 if (h_len != t_len) {
1503 int mmap_p = PROT_READ | (shmflg & SHM_RDONLY ? 0 : PROT_WRITE);
1504 int mmap_f = MAP_PRIVATE | MAP_ANONYMOUS
1505 | (reserved_va || mapped || (shmflg & SHM_REMAP)
1506 ? MAP_FIXED : MAP_FIXED_NOREPLACE);
1507
1508 test = mmap(want, m_len, mmap_p, mmap_f, -1, 0);
1509 if (unlikely(test != want)) {
1510 /* shmat returns EINVAL not EEXIST like mmap. */
1511 ret = (test == MAP_FAILED && errno != EEXIST
1512 ? get_errno(-1) : -TARGET_EINVAL);
1513 if (mapped) {
1514 do_munmap(want, m_len);
1515 }
1516 return ret;
1517 }
1518 mapped = true;
1519 }
1520
1521 if (reserved_va || mapped) {
1522 shmflg |= SHM_REMAP;
1523 }
1524 test = shmat(shmid, want, shmflg);
1525 if (test == MAP_FAILED) {
1526 ret = get_errno(-1);
1527 if (mapped) {
1528 do_munmap(want, m_len);
1529 }
1530 return ret;
1531 }
1532 assert(test == want);
1533
1534 last = shmaddr + m_len - 1;
1535 page_set_flags(shmaddr, last,
1536 PAGE_VALID | PAGE_READ |
1537 (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE) |
1538 (shmflg & SHM_EXEC ? PAGE_EXEC : 0),
1539 PAGE_VALID);
1540
1541 shm_region_rm_complete(shmaddr, last);
1542 shm_region_add(shmaddr, last);
1543 }
1544
1545 /*
1546 * We're mapping shared memory, so ensure we generate code for parallel
1547 * execution and flush old translations. This will work up to the level
1548 * supported by the host -- anything that requires EXCP_ATOMIC will not
1549 * be atomic with respect to an external process.
1550 */
1551 begin_parallel_context(cpu);
1552
1553 if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
1554 FILE *f = qemu_log_trylock();
1555 if (f) {
1556 fprintf(f, "page layout changed following shmat\n");
1557 page_dump(f);
1558 qemu_log_unlock(f);
1559 }
1560 }
1561 return shmaddr;
1562 }
1563
1564 abi_long target_shmdt(abi_ulong shmaddr)
1565 {
1566 abi_long rv;
1567
1568 /* shmdt pointers are always untagged */
1569
1570 WITH_MMAP_LOCK_GUARD() {
1571 abi_ulong last = shm_region_find(shmaddr);
1572 if (last == 0) {
1573 return -TARGET_EINVAL;
1574 }
1575
1576 rv = get_errno(shmdt(g2h_untagged(shmaddr)));
1577 if (rv == 0) {
1578 abi_ulong size = last - shmaddr + 1;
1579
1580 page_set_flags(shmaddr, last, 0, PAGE_VALID);
1581 shm_region_rm_complete(shmaddr, last);
1582 mmap_reserve_or_unmap(shmaddr, size);
1583 }
1584 }
1585 return rv;
1586 }