summary refs log tree commit diff stats
path: root/linux-user/mmap.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-02-04 17:17:15 +0000
committerPeter Maydell <peter.maydell@linaro.org>2023-02-04 17:17:15 +0000
commitceabf6e500570ecfb311d8896c4ba9da8cf21f2a (patch)
treeda84cc483c875f1d70fe49683a1354912a353b58 /linux-user/mmap.c
parent025274ad2f1cdcbbe9fc8ef2c6dbd7e9de0714da (diff)
parent3f0744f98b07c6fd2ce9d5840726d0915b2ae7c1 (diff)
downloadfocaccia-qemu-ceabf6e500570ecfb311d8896c4ba9da8cf21f2a.tar.gz
focaccia-qemu-ceabf6e500570ecfb311d8896c4ba9da8cf21f2a.zip
Merge tag 'linux-user-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging
linux-user branch pull request 20230204

Implement execveat()
un-parent OBJECT(cpu) when closing thread
Revert fix for glibc >= 2.36 sys/mount.h
Fix/update strace
move target_flat.h to target subdirs
Fix SO_ERROR return code of getsockopt()
Fix /proc/cpuinfo output for hppa
Add emulation for MADV_WIPEONFORK and MADV_KEEPONFORK in madvise()
Implement SOL_ALG encryption support
linux-user: Allow sendmsg() without IOV

# -----BEGIN PGP SIGNATURE-----
#
# iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmPeguUSHGxhdXJlbnRA
# dml2aWVyLmV1AAoJEPMMOL0/L748tnQP/1A4eu33pLe4+tjBuDGt2zcGAVuz+wN9
# rcwN5BQgjILwfECfRsy9QIkC8+M496tLk4W7pNkW9x/GSpzBp9x0+066uUghsa1Q
# c0bFU0FM8xpywEXvOrz3LvEWaWqeBV/R+XYMqKFaiBQXf/5kmmteei9guH42L3gV
# a+d0s1cWT48TslTaga9ECbiPD9lK+yfW879+wRhex1/BetkJPzLU1hZB4vfC5YQo
# XagcmLWiseT4U8uCysikOgKQE4g2bv1oJXUuYjBxW15s5/llg8e57dEboO7MFEPK
# a9P3Hl1qiA5Ol3scF1I7WURmGP6UVfdhTYe1aKYHhKY7QVBVjbU7r/NkdQ3dR6Nv
# db58Lkurnrf5dMksZk8+25F/fvJT0nZpnbipunZejetNjrDVPk19XK5E6kJf91hk
# 3W3vOeWMp4QjThpqghnlQ3gm2XfVmCGSMIOywTKZ4/M/TP28+9zY7GZqQXQXCBMy
# nJFahfVTCfiYaGAYGjlMe5CMOQ6tJ6lwxuTCl9O1X565ifMBNUj3rcte1FvO/i24
# Rk0/lQVO+tD9ImxHJrei0Y2C0xzo7V8kaB9+foAf6Ku91SY1X1FIOm81DEyAhK61
# Biv2zlNwUV0aCierrn3oLuDkviVaAg6FkLO9snPG+lQy2uxgyJJ2/Pv0OCZhniWI
# 9WifjYZKAXDa
# =AcC6
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 04 Feb 2023 16:08:05 GMT
# gpg:                using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C
# gpg:                issuer "laurent@vivier.eu"
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full]
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>" [full]
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full]
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* tag 'linux-user-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu: (22 commits)
  linux-user: Allow sendmsg() without IOV
  linux-user: Implement SOL_ALG encryption support
  linux-user: Enhance strace output for various syscalls
  linux-user: Show 4th argument of rt_sigprocmask() in strace
  linux-user: Add emulation for MADV_WIPEONFORK and MADV_KEEPONFORK in madvise()
  linux-user: Improve strace output of personality() and sysinfo()
  linux-user: Fix /proc/cpuinfo output for hppa
  linux-user: Fix SO_ERROR return code of getsockopt()
  linux-user: move target_flat.h to target subdirs
  linux-user: Improve strace output of getgroups() and setgroups()
  linux-user: Add strace output for clock_getres_time64() and futex_time64()
  Revert "linux-user: fix compat with glibc >= 2.36 sys/mount.h"
  Revert "linux-user: add more compat ioctl definitions"
  linux-user: add more netlink protocol constants
  linux-user: fix strace build w/out munlockall
  linux-user: un-parent OBJECT(cpu) when closing thread
  linux-user: Add missing MAP_HUGETLB and MAP_STACK flags in strace
  linux-user/syscall: Implement execveat()
  linux-user/syscall: Extract do_execve() from do_syscall1()
  linux-user/strace: Add output for execveat() syscall
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/mmap.c')
-rw-r--r--linux-user/mmap.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 10f5079331..28135c9e6a 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -857,7 +857,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
     return new_addr;
 }
 
-static bool can_passthrough_madv_dontneed(abi_ulong start, abi_ulong end)
+static bool can_passthrough_madvise(abi_ulong start, abi_ulong end)
 {
     ulong addr;
 
@@ -901,23 +901,53 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
         return -TARGET_EINVAL;
     }
 
+    /* Translate for some architectures which have different MADV_xxx values */
+    switch (advice) {
+    case TARGET_MADV_DONTNEED:      /* alpha */
+        advice = MADV_DONTNEED;
+        break;
+    case TARGET_MADV_WIPEONFORK:    /* parisc */
+        advice = MADV_WIPEONFORK;
+        break;
+    case TARGET_MADV_KEEPONFORK:    /* parisc */
+        advice = MADV_KEEPONFORK;
+        break;
+    /* we do not care about the other MADV_xxx values yet */
+    }
+
     /*
-     * A straight passthrough may not be safe because qemu sometimes turns
-     * private file-backed mappings into anonymous mappings.
+     * Most advice values are hints, so ignoring and returning success is ok.
+     *
+     * However, some advice values such as MADV_DONTNEED, MADV_WIPEONFORK and
+     * MADV_KEEPONFORK are not hints and need to be emulated.
      *
-     * This is a hint, so ignoring and returning success is ok.
+     * A straight passthrough for those may not be safe because qemu sometimes
+     * turns private file-backed mappings into anonymous mappings.
+     * can_passthrough_madvise() helps to check if a passthrough is possible by
+     * comparing mappings that are known to have the same semantics in the host
+     * and the guest. In this case passthrough is safe.
      *
-     * This breaks MADV_DONTNEED, completely implementing which is quite
-     * complicated. However, there is one low-hanging fruit: mappings that are
-     * known to have the same semantics in the host and the guest. In this case
-     * passthrough is safe, so do it.
+     * We pass through MADV_WIPEONFORK and MADV_KEEPONFORK if possible and
+     * return failure if not.
+     *
+     * MADV_DONTNEED is passed through as well, if possible.
+     * If passthrough isn't possible, we nevertheless (wrongly!) return
+     * success, which is broken but some userspace programs fail to work
+     * otherwise. Completely implementing such emulation is quite complicated
+     * though.
      */
     mmap_lock();
-    if (advice == TARGET_MADV_DONTNEED &&
-        can_passthrough_madv_dontneed(start, end)) {
-        ret = get_errno(madvise(g2h_untagged(start), len, MADV_DONTNEED));
-        if (ret == 0) {
-            page_reset_target_data(start, start + len);
+    switch (advice) {
+    case MADV_WIPEONFORK:
+    case MADV_KEEPONFORK:
+        ret = -EINVAL;
+        /* fall through */
+    case MADV_DONTNEED:
+        if (can_passthrough_madvise(start, end)) {
+            ret = get_errno(madvise(g2h_untagged(start), len, advice));
+            if ((advice == MADV_DONTNEED) && (ret == 0)) {
+                page_reset_target_data(start, start + len);
+            }
         }
     }
     mmap_unlock();