qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings
@ 2022-09-06  0:08 Ilya Leoshkevich
  2022-09-06  0:08 ` [PATCH v3 1/5] linux-user: Provide MADV_* definitions Ilya Leoshkevich
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Ilya Leoshkevich @ 2022-09-06  0:08 UTC (permalink / raw)
  To: Richard Henderson, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel, Ilya Leoshkevich

Hi,

This series is made of patches from [1]. I've added a test and noticed
that madvise(MADV_DONTNEED) was broken on alpha, fixing which required
adding per-arch MADV_* definitions. This in turn affected the strace
patch, so it made sense to make a series out of the results.

Patch 1 adds MADV_* constants for all architectures.
Patch 2 fixes the alpha bug.
Patch 3 adds madvise() support to strace.
Patch 4 adds MADV_DONTNEED support for file mappings.
Patch 5 adds a test.

Best regards,
Ilya

[1] https://lists.gnu.org/archive/html/qemu-devel/2022-09/msg00710.html

Ilya Leoshkevich (5):
  linux-user: Provide MADV_* definitions
  linux-user: Fix madvise(MADV_DONTNEED) on alpha
  linux-user: Implement stracing madvise()
  linux-user: Passthrough MADV_DONTNEED for certain file mappings
  tests/tcg/linux-test: Add linux-madvise test

 accel/tcg/translate-all.c                 |  2 +-
 include/exec/cpu-all.h                    |  6 ++
 linux-user/aarch64/target_mman.h          |  1 +
 linux-user/alpha/target_mman.h            |  8 ++
 linux-user/arm/target_mman.h              |  1 +
 linux-user/cris/target_mman.h             |  1 +
 linux-user/generic/target_mman.h          | 92 +++++++++++++++++++++++
 linux-user/hexagon/target_mman.h          |  1 +
 linux-user/hppa/target_mman.h             | 15 ++++
 linux-user/i386/target_mman.h             |  1 +
 linux-user/loongarch64/target_mman.h      |  1 +
 linux-user/m68k/target_mman.h             |  1 +
 linux-user/microblaze/target_mman.h       |  1 +
 linux-user/mips/target_mman.h             |  1 +
 linux-user/mips64/target_mman.h           |  1 +
 linux-user/mmap.c                         | 30 ++++++--
 linux-user/nios2/target_mman.h            |  1 +
 linux-user/openrisc/target_mman.h         |  1 +
 linux-user/ppc/target_mman.h              |  1 +
 linux-user/riscv/target_mman.h            |  1 +
 linux-user/s390x/target_mman.h            |  1 +
 linux-user/sh4/target_mman.h              |  1 +
 linux-user/sparc/target_mman.h            |  1 +
 linux-user/strace.c                       | 41 ++++++++++
 linux-user/strace.list                    |  2 +-
 linux-user/x86_64/target_mman.h           |  1 +
 linux-user/xtensa/target_mman.h           |  1 +
 tests/tcg/multiarch/linux/linux-madvise.c | 70 +++++++++++++++++
 28 files changed, 277 insertions(+), 8 deletions(-)
 create mode 100644 linux-user/aarch64/target_mman.h
 create mode 100644 linux-user/alpha/target_mman.h
 create mode 100644 linux-user/arm/target_mman.h
 create mode 100644 linux-user/cris/target_mman.h
 create mode 100644 linux-user/generic/target_mman.h
 create mode 100644 linux-user/hexagon/target_mman.h
 create mode 100644 linux-user/hppa/target_mman.h
 create mode 100644 linux-user/i386/target_mman.h
 create mode 100644 linux-user/loongarch64/target_mman.h
 create mode 100644 linux-user/m68k/target_mman.h
 create mode 100644 linux-user/microblaze/target_mman.h
 create mode 100644 linux-user/mips/target_mman.h
 create mode 100644 linux-user/mips64/target_mman.h
 create mode 100644 linux-user/nios2/target_mman.h
 create mode 100644 linux-user/openrisc/target_mman.h
 create mode 100644 linux-user/ppc/target_mman.h
 create mode 100644 linux-user/riscv/target_mman.h
 create mode 100644 linux-user/s390x/target_mman.h
 create mode 100644 linux-user/sh4/target_mman.h
 create mode 100644 linux-user/sparc/target_mman.h
 create mode 100644 linux-user/x86_64/target_mman.h
 create mode 100644 linux-user/xtensa/target_mman.h
 create mode 100644 tests/tcg/multiarch/linux/linux-madvise.c

-- 
2.37.2



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/5] linux-user: Provide MADV_* definitions
  2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
@ 2022-09-06  0:08 ` Ilya Leoshkevich
  2022-09-23 21:51   ` Laurent Vivier
  2022-09-06  0:08 ` [PATCH v3 2/5] linux-user: Fix madvise(MADV_DONTNEED) on alpha Ilya Leoshkevich
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Ilya Leoshkevich @ 2022-09-06  0:08 UTC (permalink / raw)
  To: Richard Henderson, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel, Ilya Leoshkevich

Provide MADV_* definitions using target_mman.h header, similar to what
kernel does. Most architectures use the same values, with the exception
of alpha and hppa.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 linux-user/aarch64/target_mman.h     |  1 +
 linux-user/alpha/target_mman.h       |  8 +++
 linux-user/arm/target_mman.h         |  1 +
 linux-user/cris/target_mman.h        |  1 +
 linux-user/generic/target_mman.h     | 92 ++++++++++++++++++++++++++++
 linux-user/hexagon/target_mman.h     |  1 +
 linux-user/hppa/target_mman.h        | 15 +++++
 linux-user/i386/target_mman.h        |  1 +
 linux-user/loongarch64/target_mman.h |  1 +
 linux-user/m68k/target_mman.h        |  1 +
 linux-user/microblaze/target_mman.h  |  1 +
 linux-user/mips/target_mman.h        |  1 +
 linux-user/mips64/target_mman.h      |  1 +
 linux-user/nios2/target_mman.h       |  1 +
 linux-user/openrisc/target_mman.h    |  1 +
 linux-user/ppc/target_mman.h         |  1 +
 linux-user/riscv/target_mman.h       |  1 +
 linux-user/s390x/target_mman.h       |  1 +
 linux-user/sh4/target_mman.h         |  1 +
 linux-user/sparc/target_mman.h       |  1 +
 linux-user/x86_64/target_mman.h      |  1 +
 linux-user/xtensa/target_mman.h      |  1 +
 22 files changed, 134 insertions(+)
 create mode 100644 linux-user/aarch64/target_mman.h
 create mode 100644 linux-user/alpha/target_mman.h
 create mode 100644 linux-user/arm/target_mman.h
 create mode 100644 linux-user/cris/target_mman.h
 create mode 100644 linux-user/generic/target_mman.h
 create mode 100644 linux-user/hexagon/target_mman.h
 create mode 100644 linux-user/hppa/target_mman.h
 create mode 100644 linux-user/i386/target_mman.h
 create mode 100644 linux-user/loongarch64/target_mman.h
 create mode 100644 linux-user/m68k/target_mman.h
 create mode 100644 linux-user/microblaze/target_mman.h
 create mode 100644 linux-user/mips/target_mman.h
 create mode 100644 linux-user/mips64/target_mman.h
 create mode 100644 linux-user/nios2/target_mman.h
 create mode 100644 linux-user/openrisc/target_mman.h
 create mode 100644 linux-user/ppc/target_mman.h
 create mode 100644 linux-user/riscv/target_mman.h
 create mode 100644 linux-user/s390x/target_mman.h
 create mode 100644 linux-user/sh4/target_mman.h
 create mode 100644 linux-user/sparc/target_mman.h
 create mode 100644 linux-user/x86_64/target_mman.h
 create mode 100644 linux-user/xtensa/target_mman.h

diff --git a/linux-user/aarch64/target_mman.h b/linux-user/aarch64/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/aarch64/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/alpha/target_mman.h b/linux-user/alpha/target_mman.h
new file mode 100644
index 0000000000..cd6e3d70a6
--- /dev/null
+++ b/linux-user/alpha/target_mman.h
@@ -0,0 +1,8 @@
+#ifndef ALPHA_TARGET_MMAN_H
+#define ALPHA_TARGET_MMAN_H
+
+#define TARGET_MADV_DONTNEED 6
+
+#include "../generic/target_mman.h"
+
+#endif
diff --git a/linux-user/arm/target_mman.h b/linux-user/arm/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/arm/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/cris/target_mman.h b/linux-user/cris/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/cris/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/generic/target_mman.h b/linux-user/generic/target_mman.h
new file mode 100644
index 0000000000..1436a3c543
--- /dev/null
+++ b/linux-user/generic/target_mman.h
@@ -0,0 +1,92 @@
+#ifndef LINUX_USER_TARGET_MMAN_H
+#define LINUX_USER_TARGET_MMAN_H
+
+#ifndef TARGET_MADV_NORMAL
+#define TARGET_MADV_NORMAL 0
+#endif
+
+#ifndef TARGET_MADV_RANDOM
+#define TARGET_MADV_RANDOM 1
+#endif
+
+#ifndef TARGET_MADV_SEQUENTIAL
+#define TARGET_MADV_SEQUENTIAL 2
+#endif
+
+#ifndef TARGET_MADV_WILLNEED
+#define TARGET_MADV_WILLNEED 3
+#endif
+
+#ifndef TARGET_MADV_DONTNEED
+#define TARGET_MADV_DONTNEED 4
+#endif
+
+#ifndef TARGET_MADV_FREE
+#define TARGET_MADV_FREE 8
+#endif
+
+#ifndef TARGET_MADV_REMOVE
+#define TARGET_MADV_REMOVE 9
+#endif
+
+#ifndef TARGET_MADV_DONTFORK
+#define TARGET_MADV_DONTFORK 10
+#endif
+
+#ifndef TARGET_MADV_DOFORK
+#define TARGET_MADV_DOFORK 11
+#endif
+
+#ifndef TARGET_MADV_MERGEABLE
+#define TARGET_MADV_MERGEABLE 12
+#endif
+
+#ifndef TARGET_MADV_UNMERGEABLE
+#define TARGET_MADV_UNMERGEABLE 13
+#endif
+
+#ifndef TARGET_MADV_HUGEPAGE
+#define TARGET_MADV_HUGEPAGE 14
+#endif
+
+#ifndef TARGET_MADV_NOHUGEPAGE
+#define TARGET_MADV_NOHUGEPAGE 15
+#endif
+
+#ifndef TARGET_MADV_DONTDUMP
+#define TARGET_MADV_DONTDUMP 16
+#endif
+
+#ifndef TARGET_MADV_DODUMP
+#define TARGET_MADV_DODUMP 17
+#endif
+
+#ifndef TARGET_MADV_WIPEONFORK
+#define TARGET_MADV_WIPEONFORK 18
+#endif
+
+#ifndef TARGET_MADV_KEEPONFORK
+#define TARGET_MADV_KEEPONFORK 19
+#endif
+
+#ifndef TARGET_MADV_COLD
+#define TARGET_MADV_COLD 20
+#endif
+
+#ifndef TARGET_MADV_PAGEOUT
+#define TARGET_MADV_PAGEOUT 21
+#endif
+
+#ifndef TARGET_MADV_POPULATE_READ
+#define TARGET_MADV_POPULATE_READ 22
+#endif
+
+#ifndef TARGET_MADV_POPULATE_WRITE
+#define TARGET_MADV_POPULATE_WRITE 23
+#endif
+
+#ifndef TARGET_MADV_DONTNEED_LOCKED
+#define TARGET_MADV_DONTNEED_LOCKED 24
+#endif
+
+#endif
diff --git a/linux-user/hexagon/target_mman.h b/linux-user/hexagon/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/hexagon/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/hppa/target_mman.h b/linux-user/hppa/target_mman.h
new file mode 100644
index 0000000000..66dd9f7941
--- /dev/null
+++ b/linux-user/hppa/target_mman.h
@@ -0,0 +1,15 @@
+#ifndef HPPA_TARGET_MMAN_H
+#define HPPA_TARGET_MMAN_H
+
+#define TARGET_MADV_MERGEABLE 65
+#define TARGET_MADV_UNMERGEABLE 66
+#define TARGET_MADV_HUGEPAGE 67
+#define TARGET_MADV_NOHUGEPAGE 68
+#define TARGET_MADV_DONTDUMP 69
+#define TARGET_MADV_DODUMP 70
+#define TARGET_MADV_WIPEONFORK 71
+#define TARGET_MADV_KEEPONFORK 72
+
+#include "../generic/target_mman.h"
+
+#endif
diff --git a/linux-user/i386/target_mman.h b/linux-user/i386/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/i386/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/loongarch64/target_mman.h b/linux-user/loongarch64/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/loongarch64/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/m68k/target_mman.h b/linux-user/m68k/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/m68k/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/microblaze/target_mman.h b/linux-user/microblaze/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/microblaze/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/mips/target_mman.h b/linux-user/mips/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/mips/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/mips64/target_mman.h b/linux-user/mips64/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/mips64/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/nios2/target_mman.h b/linux-user/nios2/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/nios2/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/openrisc/target_mman.h b/linux-user/openrisc/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/openrisc/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/ppc/target_mman.h b/linux-user/ppc/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/ppc/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/riscv/target_mman.h b/linux-user/riscv/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/riscv/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/s390x/target_mman.h b/linux-user/s390x/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/s390x/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/sh4/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/sparc/target_mman.h b/linux-user/sparc/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/sparc/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/x86_64/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
diff --git a/linux-user/xtensa/target_mman.h b/linux-user/xtensa/target_mman.h
new file mode 100644
index 0000000000..e7ba6070fe
--- /dev/null
+++ b/linux-user/xtensa/target_mman.h
@@ -0,0 +1 @@
+#include "../generic/target_mman.h"
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/5] linux-user: Fix madvise(MADV_DONTNEED) on alpha
  2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
  2022-09-06  0:08 ` [PATCH v3 1/5] linux-user: Provide MADV_* definitions Ilya Leoshkevich
@ 2022-09-06  0:08 ` Ilya Leoshkevich
  2022-09-23 21:51   ` Laurent Vivier
  2022-09-06  0:08 ` [PATCH v3 3/5] linux-user: Implement stracing madvise() Ilya Leoshkevich
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Ilya Leoshkevich @ 2022-09-06  0:08 UTC (permalink / raw)
  To: Richard Henderson, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel, Ilya Leoshkevich

MADV_DONTNEED has a different value on alpha, compared to all the other
architectures. Fix by using TARGET_MADV_DONTNEED instead of
MADV_DONTNEED.

Fixes: 892a4f6a750a ("linux-user: Add partial support for MADV_DONTNEED")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 linux-user/mmap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 048c4135af..a5f1ab129c 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -22,6 +22,7 @@
 #include "qemu.h"
 #include "user-internals.h"
 #include "user-mmap.h"
+#include "target_mman.h"
 
 static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
 static __thread int mmap_lock_count;
@@ -891,7 +892,7 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
      * anonymous mappings. In this case passthrough is safe, so do it.
      */
     mmap_lock();
-    if (advice == MADV_DONTNEED &&
+    if (advice == TARGET_MADV_DONTNEED &&
         can_passthrough_madv_dontneed(start, end)) {
         ret = get_errno(madvise(g2h_untagged(start), len, MADV_DONTNEED));
         if (ret == 0) {
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/5] linux-user: Implement stracing madvise()
  2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
  2022-09-06  0:08 ` [PATCH v3 1/5] linux-user: Provide MADV_* definitions Ilya Leoshkevich
  2022-09-06  0:08 ` [PATCH v3 2/5] linux-user: Fix madvise(MADV_DONTNEED) on alpha Ilya Leoshkevich
@ 2022-09-06  0:08 ` Ilya Leoshkevich
  2022-09-23 21:51   ` Laurent Vivier
  2022-09-06  0:08 ` [PATCH v3 4/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Ilya Leoshkevich @ 2022-09-06  0:08 UTC (permalink / raw)
  To: Richard Henderson, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel, Ilya Leoshkevich

The default implementation has several problems: the first argument is
not displayed as a pointer, making it harder to grep; the third
argument is not symbolized; and there are several extra unused
arguments.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 linux-user/strace.c    | 41 +++++++++++++++++++++++++++++++++++++++++
 linux-user/strace.list |  2 +-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 7d882526da..c262c0c9b6 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -17,6 +17,7 @@
 #include "qemu.h"
 #include "user-internals.h"
 #include "strace.h"
+#include "target_mman.h"
 
 struct syscallname {
     int nr;
@@ -2969,6 +2970,46 @@ print_stat(CPUArchState *cpu_env, const struct syscallname *name,
 #define print_lstat64   print_stat
 #endif
 
+#if defined(TARGET_NR_madvise)
+static struct enums madvise_advice[] = {
+    ENUM_TARGET(MADV_NORMAL),
+    ENUM_TARGET(MADV_RANDOM),
+    ENUM_TARGET(MADV_SEQUENTIAL),
+    ENUM_TARGET(MADV_WILLNEED),
+    ENUM_TARGET(MADV_DONTNEED),
+    ENUM_TARGET(MADV_FREE),
+    ENUM_TARGET(MADV_REMOVE),
+    ENUM_TARGET(MADV_DONTFORK),
+    ENUM_TARGET(MADV_DOFORK),
+    ENUM_TARGET(MADV_MERGEABLE),
+    ENUM_TARGET(MADV_UNMERGEABLE),
+    ENUM_TARGET(MADV_HUGEPAGE),
+    ENUM_TARGET(MADV_NOHUGEPAGE),
+    ENUM_TARGET(MADV_DONTDUMP),
+    ENUM_TARGET(MADV_DODUMP),
+    ENUM_TARGET(MADV_WIPEONFORK),
+    ENUM_TARGET(MADV_KEEPONFORK),
+    ENUM_TARGET(MADV_COLD),
+    ENUM_TARGET(MADV_PAGEOUT),
+    ENUM_TARGET(MADV_POPULATE_READ),
+    ENUM_TARGET(MADV_POPULATE_WRITE),
+    ENUM_TARGET(MADV_DONTNEED_LOCKED),
+    ENUM_END,
+};
+
+static void
+print_madvise(CPUArchState *cpu_env, const struct syscallname *name,
+              abi_long arg0, abi_long arg1, abi_long arg2,
+              abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_pointer(arg0, 0);
+    print_raw_param("%d", arg1, 0);
+    print_enums(madvise_advice, arg2, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
 #if defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
 static void
 print_fstat(CPUArchState *cpu_env, const struct syscallname *name,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 72e17b1acf..c93effdbc8 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -541,7 +541,7 @@
 { TARGET_NR_lstat64, "lstat64" , NULL, print_lstat64, NULL },
 #endif
 #ifdef TARGET_NR_madvise
-{ TARGET_NR_madvise, "madvise" , NULL, NULL, NULL },
+{ TARGET_NR_madvise, "madvise" , NULL, print_madvise, NULL },
 #endif
 #ifdef TARGET_NR_madvise1
 { TARGET_NR_madvise1, "madvise1" , NULL, NULL, NULL },
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings
  2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
                   ` (2 preceding siblings ...)
  2022-09-06  0:08 ` [PATCH v3 3/5] linux-user: Implement stracing madvise() Ilya Leoshkevich
@ 2022-09-06  0:08 ` Ilya Leoshkevich
  2022-09-23 21:51   ` Laurent Vivier
  2022-09-06  0:08 ` [PATCH v3 5/5] tests/tcg/linux-test: Add linux-madvise test Ilya Leoshkevich
  2022-09-06  7:35 ` [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Richard Henderson
  5 siblings, 1 reply; 12+ messages in thread
From: Ilya Leoshkevich @ 2022-09-06  0:08 UTC (permalink / raw)
  To: Richard Henderson, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel, Ilya Leoshkevich

This is a follow-up for commit 892a4f6a750a ("linux-user: Add partial
support for MADV_DONTNEED"), which added passthrough for anonymous
mappings. File mappings can be handled in a similar manner.

In order to do that, mark pages, for which mmap() was passed through,
with PAGE_PASSTHROUGH, and then allow madvise() passthrough for these
pages. Drop the explicit PAGE_ANON check, since anonymous mappings are
expected to have PAGE_PASSTHROUGH anyway.

Add PAGE_PASSTHROUGH to PAGE_STICKY in order to keep it on mprotect().

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Message-Id: <20220725125043.43048-1-iii@linux.ibm.com>
---
 accel/tcg/translate-all.c |  2 +-
 include/exec/cpu-all.h    |  6 ++++++
 linux-user/mmap.c         | 27 ++++++++++++++++++++++-----
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index b83161a081..a47cf38e38 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -2263,7 +2263,7 @@ int page_get_flags(target_ulong address)
 #ifndef PAGE_TARGET_STICKY
 #define PAGE_TARGET_STICKY  0
 #endif
-#define PAGE_STICKY  (PAGE_ANON | PAGE_TARGET_STICKY)
+#define PAGE_STICKY  (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY)
 
 /* Modify the flags of a page and invalidate the code if necessary.
    The flag PAGE_WRITE_ORG is positioned automatically depending
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 491629b9ba..16b7df41bf 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -262,6 +262,12 @@ extern const TargetPageBits target_page;
 #define PAGE_TARGET_1  0x0200
 #define PAGE_TARGET_2  0x0400
 
+/*
+ * For linux-user, indicates that the page is mapped with the same semantics
+ * in both guest and host.
+ */
+#define PAGE_PASSTHROUGH 0x0800
+
 #if defined(CONFIG_USER_ONLY)
 void page_dump(FILE *f);
 
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index a5f1ab129c..3a0f67619a 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -425,7 +425,8 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
 abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
                      int flags, int fd, abi_ulong offset)
 {
-    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
+    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len,
+              passthrough_start = -1, passthrough_end = -1;
     int page_flags, host_prot;
 
     mmap_lock();
@@ -538,6 +539,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
             host_start += offset - host_offset;
         }
         start = h2g(host_start);
+        passthrough_start = start;
+        passthrough_end = start + len;
     } else {
         if (start & ~TARGET_PAGE_MASK) {
             errno = EINVAL;
@@ -620,6 +623,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
                      host_prot, flags, fd, offset1);
             if (p == MAP_FAILED)
                 goto fail;
+            passthrough_start = real_start;
+            passthrough_end = real_end;
         }
     }
  the_end1:
@@ -627,7 +632,18 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
         page_flags |= PAGE_ANON;
     }
     page_flags |= PAGE_RESET;
-    page_set_flags(start, start + len, page_flags);
+    if (passthrough_start == passthrough_end) {
+        page_set_flags(start, start + len, page_flags);
+    } else {
+        if (start < passthrough_start) {
+            page_set_flags(start, passthrough_start, page_flags);
+        }
+        page_set_flags(passthrough_start, passthrough_end,
+                       page_flags | PAGE_PASSTHROUGH);
+        if (passthrough_end < start + len) {
+            page_set_flags(passthrough_end, start + len, page_flags);
+        }
+    }
  the_end:
     trace_target_mmap_complete(start);
     if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
@@ -846,7 +862,7 @@ static bool can_passthrough_madv_dontneed(abi_ulong start, abi_ulong end)
     }
 
     for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
-        if (!(page_get_flags(addr) & PAGE_ANON)) {
+        if (!(page_get_flags(addr) & PAGE_PASSTHROUGH)) {
             return false;
         }
     }
@@ -888,8 +904,9 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
      * This is a hint, so ignoring and returning success is ok.
      *
      * This breaks MADV_DONTNEED, completely implementing which is quite
-     * complicated. However, there is one low-hanging fruit: host-page-aligned
-     * anonymous mappings. In this case passthrough is safe, so do it.
+     * 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.
      */
     mmap_lock();
     if (advice == TARGET_MADV_DONTNEED &&
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 5/5] tests/tcg/linux-test: Add linux-madvise test
  2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
                   ` (3 preceding siblings ...)
  2022-09-06  0:08 ` [PATCH v3 4/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
@ 2022-09-06  0:08 ` Ilya Leoshkevich
  2022-09-23 21:52   ` Laurent Vivier
  2022-09-06  7:35 ` [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Richard Henderson
  5 siblings, 1 reply; 12+ messages in thread
From: Ilya Leoshkevich @ 2022-09-06  0:08 UTC (permalink / raw)
  To: Richard Henderson, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel, Ilya Leoshkevich

Add a test that checks madvise(MADV_DONTNEED) behavior with anonymous
and file mappings in order to prevent regressions.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 tests/tcg/multiarch/linux/linux-madvise.c | 70 +++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 tests/tcg/multiarch/linux/linux-madvise.c

diff --git a/tests/tcg/multiarch/linux/linux-madvise.c b/tests/tcg/multiarch/linux/linux-madvise.c
new file mode 100644
index 0000000000..29d0997e68
--- /dev/null
+++ b/tests/tcg/multiarch/linux/linux-madvise.c
@@ -0,0 +1,70 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+static void test_anonymous(void)
+{
+    int pagesize = getpagesize();
+    char *page;
+    int ret;
+
+    page = mmap(NULL, pagesize, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+    assert(page != MAP_FAILED);
+
+    /* Check that mprotect() does not interfere with MADV_DONTNEED. */
+    ret = mprotect(page, pagesize, PROT_READ | PROT_WRITE);
+    assert(ret == 0);
+
+    /* Check that MADV_DONTNEED clears the page. */
+    *page = 42;
+    ret = madvise(page, pagesize, MADV_DONTNEED);
+    assert(ret == 0);
+    assert(*page == 0);
+
+    ret = munmap(page, pagesize);
+    assert(ret == 0);
+}
+
+static void test_file(void)
+{
+    char tempname[] = "/tmp/.cmadviseXXXXXX";
+    int pagesize = getpagesize();
+    ssize_t written;
+    char c = 42;
+    char *page;
+    int ret;
+    int fd;
+
+    fd = mkstemp(tempname);
+    assert(fd != -1);
+    ret = unlink(tempname);
+    assert(ret == 0);
+    written = write(fd, &c, sizeof(c));
+    assert(written == sizeof(c));
+    page = mmap(NULL, pagesize, PROT_READ, MAP_PRIVATE, fd, 0);
+    assert(page != MAP_FAILED);
+
+    /* Check that mprotect() does not interfere with MADV_DONTNEED. */
+    ret = mprotect(page, pagesize, PROT_READ | PROT_WRITE);
+    assert(ret == 0);
+
+    /* Check that MADV_DONTNEED resets the page. */
+    *page = 0;
+    ret = madvise(page, pagesize, MADV_DONTNEED);
+    assert(ret == 0);
+    assert(*page == c);
+
+    ret = munmap(page, pagesize);
+    assert(ret == 0);
+    ret = close(fd);
+    assert(ret == 0);
+}
+
+int main(void)
+{
+    test_anonymous();
+    test_file();
+
+    return EXIT_SUCCESS;
+}
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings
  2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
                   ` (4 preceding siblings ...)
  2022-09-06  0:08 ` [PATCH v3 5/5] tests/tcg/linux-test: Add linux-madvise test Ilya Leoshkevich
@ 2022-09-06  7:35 ` Richard Henderson
  5 siblings, 0 replies; 12+ messages in thread
From: Richard Henderson @ 2022-09-06  7:35 UTC (permalink / raw)
  To: Ilya Leoshkevich, Paolo Bonzini, Laurent Vivier, Taylor Simpson,
	Alex Bennée
  Cc: qemu-devel

On 9/6/22 01:08, Ilya Leoshkevich wrote:
> Hi,
> 
> This series is made of patches from [1]. I've added a test and noticed
> that madvise(MADV_DONTNEED) was broken on alpha, fixing which required
> adding per-arch MADV_* definitions. This in turn affected the strace
> patch, so it made sense to make a series out of the results.
> 
> Patch 1 adds MADV_* constants for all architectures.
> Patch 2 fixes the alpha bug.
> Patch 3 adds madvise() support to strace.
> Patch 4 adds MADV_DONTNEED support for file mappings.
> Patch 5 adds a test.

Thanks for that, series
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/5] linux-user: Provide MADV_* definitions
  2022-09-06  0:08 ` [PATCH v3 1/5] linux-user: Provide MADV_* definitions Ilya Leoshkevich
@ 2022-09-23 21:51   ` Laurent Vivier
  0 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2022-09-23 21:51 UTC (permalink / raw)
  To: Ilya Leoshkevich, Richard Henderson, Paolo Bonzini,
	Taylor Simpson, Alex Bennée
  Cc: qemu-devel

Le 06/09/2022 à 02:08, Ilya Leoshkevich a écrit :
> Provide MADV_* definitions using target_mman.h header, similar to what
> kernel does. Most architectures use the same values, with the exception
> of alpha and hppa.
> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   linux-user/aarch64/target_mman.h     |  1 +
>   linux-user/alpha/target_mman.h       |  8 +++
>   linux-user/arm/target_mman.h         |  1 +
>   linux-user/cris/target_mman.h        |  1 +
>   linux-user/generic/target_mman.h     | 92 ++++++++++++++++++++++++++++
>   linux-user/hexagon/target_mman.h     |  1 +
>   linux-user/hppa/target_mman.h        | 15 +++++
>   linux-user/i386/target_mman.h        |  1 +
>   linux-user/loongarch64/target_mman.h |  1 +
>   linux-user/m68k/target_mman.h        |  1 +
>   linux-user/microblaze/target_mman.h  |  1 +
>   linux-user/mips/target_mman.h        |  1 +
>   linux-user/mips64/target_mman.h      |  1 +
>   linux-user/nios2/target_mman.h       |  1 +
>   linux-user/openrisc/target_mman.h    |  1 +
>   linux-user/ppc/target_mman.h         |  1 +
>   linux-user/riscv/target_mman.h       |  1 +
>   linux-user/s390x/target_mman.h       |  1 +
>   linux-user/sh4/target_mman.h         |  1 +
>   linux-user/sparc/target_mman.h       |  1 +
>   linux-user/x86_64/target_mman.h      |  1 +
>   linux-user/xtensa/target_mman.h      |  1 +
>   22 files changed, 134 insertions(+)
>   create mode 100644 linux-user/aarch64/target_mman.h
>   create mode 100644 linux-user/alpha/target_mman.h
>   create mode 100644 linux-user/arm/target_mman.h
>   create mode 100644 linux-user/cris/target_mman.h
>   create mode 100644 linux-user/generic/target_mman.h
>   create mode 100644 linux-user/hexagon/target_mman.h
>   create mode 100644 linux-user/hppa/target_mman.h
>   create mode 100644 linux-user/i386/target_mman.h
>   create mode 100644 linux-user/loongarch64/target_mman.h
>   create mode 100644 linux-user/m68k/target_mman.h
>   create mode 100644 linux-user/microblaze/target_mman.h
>   create mode 100644 linux-user/mips/target_mman.h
>   create mode 100644 linux-user/mips64/target_mman.h
>   create mode 100644 linux-user/nios2/target_mman.h
>   create mode 100644 linux-user/openrisc/target_mman.h
>   create mode 100644 linux-user/ppc/target_mman.h
>   create mode 100644 linux-user/riscv/target_mman.h
>   create mode 100644 linux-user/s390x/target_mman.h
>   create mode 100644 linux-user/sh4/target_mman.h
>   create mode 100644 linux-user/sparc/target_mman.h
>   create mode 100644 linux-user/x86_64/target_mman.h
>   create mode 100644 linux-user/xtensa/target_mman.h
> 
> diff --git a/linux-user/aarch64/target_mman.h b/linux-user/aarch64/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/aarch64/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/alpha/target_mman.h b/linux-user/alpha/target_mman.h
> new file mode 100644
> index 0000000000..cd6e3d70a6
> --- /dev/null
> +++ b/linux-user/alpha/target_mman.h
> @@ -0,0 +1,8 @@
> +#ifndef ALPHA_TARGET_MMAN_H
> +#define ALPHA_TARGET_MMAN_H
> +
> +#define TARGET_MADV_DONTNEED 6
> +
> +#include "../generic/target_mman.h"
> +
> +#endif
> diff --git a/linux-user/arm/target_mman.h b/linux-user/arm/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/arm/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/cris/target_mman.h b/linux-user/cris/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/cris/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/generic/target_mman.h b/linux-user/generic/target_mman.h
> new file mode 100644
> index 0000000000..1436a3c543
> --- /dev/null
> +++ b/linux-user/generic/target_mman.h
> @@ -0,0 +1,92 @@
> +#ifndef LINUX_USER_TARGET_MMAN_H
> +#define LINUX_USER_TARGET_MMAN_H
> +
> +#ifndef TARGET_MADV_NORMAL
> +#define TARGET_MADV_NORMAL 0
> +#endif
> +
> +#ifndef TARGET_MADV_RANDOM
> +#define TARGET_MADV_RANDOM 1
> +#endif
> +
> +#ifndef TARGET_MADV_SEQUENTIAL
> +#define TARGET_MADV_SEQUENTIAL 2
> +#endif
> +
> +#ifndef TARGET_MADV_WILLNEED
> +#define TARGET_MADV_WILLNEED 3
> +#endif
> +
> +#ifndef TARGET_MADV_DONTNEED
> +#define TARGET_MADV_DONTNEED 4
> +#endif
> +
> +#ifndef TARGET_MADV_FREE
> +#define TARGET_MADV_FREE 8
> +#endif
> +
> +#ifndef TARGET_MADV_REMOVE
> +#define TARGET_MADV_REMOVE 9
> +#endif
> +
> +#ifndef TARGET_MADV_DONTFORK
> +#define TARGET_MADV_DONTFORK 10
> +#endif
> +
> +#ifndef TARGET_MADV_DOFORK
> +#define TARGET_MADV_DOFORK 11
> +#endif
> +
> +#ifndef TARGET_MADV_MERGEABLE
> +#define TARGET_MADV_MERGEABLE 12
> +#endif
> +
> +#ifndef TARGET_MADV_UNMERGEABLE
> +#define TARGET_MADV_UNMERGEABLE 13
> +#endif
> +
> +#ifndef TARGET_MADV_HUGEPAGE
> +#define TARGET_MADV_HUGEPAGE 14
> +#endif
> +
> +#ifndef TARGET_MADV_NOHUGEPAGE
> +#define TARGET_MADV_NOHUGEPAGE 15
> +#endif
> +
> +#ifndef TARGET_MADV_DONTDUMP
> +#define TARGET_MADV_DONTDUMP 16
> +#endif
> +
> +#ifndef TARGET_MADV_DODUMP
> +#define TARGET_MADV_DODUMP 17
> +#endif
> +
> +#ifndef TARGET_MADV_WIPEONFORK
> +#define TARGET_MADV_WIPEONFORK 18
> +#endif
> +
> +#ifndef TARGET_MADV_KEEPONFORK
> +#define TARGET_MADV_KEEPONFORK 19
> +#endif
> +
> +#ifndef TARGET_MADV_COLD
> +#define TARGET_MADV_COLD 20
> +#endif
> +
> +#ifndef TARGET_MADV_PAGEOUT
> +#define TARGET_MADV_PAGEOUT 21
> +#endif
> +
> +#ifndef TARGET_MADV_POPULATE_READ
> +#define TARGET_MADV_POPULATE_READ 22
> +#endif
> +
> +#ifndef TARGET_MADV_POPULATE_WRITE
> +#define TARGET_MADV_POPULATE_WRITE 23
> +#endif
> +
> +#ifndef TARGET_MADV_DONTNEED_LOCKED
> +#define TARGET_MADV_DONTNEED_LOCKED 24
> +#endif
> +
> +#endif
> diff --git a/linux-user/hexagon/target_mman.h b/linux-user/hexagon/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/hexagon/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/hppa/target_mman.h b/linux-user/hppa/target_mman.h
> new file mode 100644
> index 0000000000..66dd9f7941
> --- /dev/null
> +++ b/linux-user/hppa/target_mman.h
> @@ -0,0 +1,15 @@
> +#ifndef HPPA_TARGET_MMAN_H
> +#define HPPA_TARGET_MMAN_H
> +
> +#define TARGET_MADV_MERGEABLE 65
> +#define TARGET_MADV_UNMERGEABLE 66
> +#define TARGET_MADV_HUGEPAGE 67
> +#define TARGET_MADV_NOHUGEPAGE 68
> +#define TARGET_MADV_DONTDUMP 69
> +#define TARGET_MADV_DODUMP 70
> +#define TARGET_MADV_WIPEONFORK 71
> +#define TARGET_MADV_KEEPONFORK 72
> +
> +#include "../generic/target_mman.h"
> +
> +#endif
> diff --git a/linux-user/i386/target_mman.h b/linux-user/i386/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/i386/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/loongarch64/target_mman.h b/linux-user/loongarch64/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/loongarch64/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/m68k/target_mman.h b/linux-user/m68k/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/m68k/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/microblaze/target_mman.h b/linux-user/microblaze/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/microblaze/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/mips/target_mman.h b/linux-user/mips/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/mips/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/mips64/target_mman.h b/linux-user/mips64/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/mips64/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/nios2/target_mman.h b/linux-user/nios2/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/nios2/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/openrisc/target_mman.h b/linux-user/openrisc/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/openrisc/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/ppc/target_mman.h b/linux-user/ppc/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/ppc/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/riscv/target_mman.h b/linux-user/riscv/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/riscv/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/s390x/target_mman.h b/linux-user/s390x/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/s390x/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/sh4/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/sparc/target_mman.h b/linux-user/sparc/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/sparc/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/x86_64/target_mman.h b/linux-user/x86_64/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/x86_64/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"
> diff --git a/linux-user/xtensa/target_mman.h b/linux-user/xtensa/target_mman.h
> new file mode 100644
> index 0000000000..e7ba6070fe
> --- /dev/null
> +++ b/linux-user/xtensa/target_mman.h
> @@ -0,0 +1 @@
> +#include "../generic/target_mman.h"

Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/5] linux-user: Fix madvise(MADV_DONTNEED) on alpha
  2022-09-06  0:08 ` [PATCH v3 2/5] linux-user: Fix madvise(MADV_DONTNEED) on alpha Ilya Leoshkevich
@ 2022-09-23 21:51   ` Laurent Vivier
  0 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2022-09-23 21:51 UTC (permalink / raw)
  To: Ilya Leoshkevich, Richard Henderson, Paolo Bonzini,
	Taylor Simpson, Alex Bennée
  Cc: qemu-devel

Le 06/09/2022 à 02:08, Ilya Leoshkevich a écrit :
> MADV_DONTNEED has a different value on alpha, compared to all the other
> architectures. Fix by using TARGET_MADV_DONTNEED instead of
> MADV_DONTNEED.
> 
> Fixes: 892a4f6a750a ("linux-user: Add partial support for MADV_DONTNEED")
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   linux-user/mmap.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index 048c4135af..a5f1ab129c 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -22,6 +22,7 @@
>   #include "qemu.h"
>   #include "user-internals.h"
>   #include "user-mmap.h"
> +#include "target_mman.h"
>   
>   static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
>   static __thread int mmap_lock_count;Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent

> @@ -891,7 +892,7 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
>        * anonymous mappings. In this case passthrough is safe, so do it.
>        */
>       mmap_lock();
> -    if (advice == MADV_DONTNEED &&
> +    if (advice == TARGET_MADV_DONTNEED &&
>           can_passthrough_madv_dontneed(start, end)) {
>           ret = get_errno(madvise(g2h_untagged(start), len, MADV_DONTNEED));
>           if (ret == 0) {
Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] linux-user: Implement stracing madvise()
  2022-09-06  0:08 ` [PATCH v3 3/5] linux-user: Implement stracing madvise() Ilya Leoshkevich
@ 2022-09-23 21:51   ` Laurent Vivier
  0 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2022-09-23 21:51 UTC (permalink / raw)
  To: Ilya Leoshkevich, Richard Henderson, Paolo Bonzini,
	Taylor Simpson, Alex Bennée
  Cc: qemu-devel

Le 06/09/2022 à 02:08, Ilya Leoshkevich a écrit :
> The default implementation has several problems: the first argument is
> not displayed as a pointer, making it harder to grep; the third
> argument is not symbolized; and there are several extra unused
> arguments.
> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   linux-user/strace.c    | 41 +++++++++++++++++++++++++++++++++++++++++
>   linux-user/strace.list |  2 +-
>   2 files changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 7d882526da..c262c0c9b6 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -17,6 +17,7 @@
>   #include "qemu.h"
>   #include "user-internals.h"
>   #include "strace.h"
> +#include "target_mman.h"
>   
>   struct syscallname {
>       int nr;
> @@ -2969,6 +2970,46 @@ print_stat(CPUArchState *cpu_env, const struct syscallname *name,
>   #define print_lstat64   print_stat
>   #endif
>   
> +#if defined(TARGET_NR_madvise)
> +static struct enums madvise_advice[] = {
> +    ENUM_TARGET(MADV_NORMAL),
> +    ENUM_TARGET(MADV_RANDOM),
> +    ENUM_TARGET(MADV_SEQUENTIAL),
> +    ENUM_TARGET(MADV_WILLNEED),
> +    ENUM_TARGET(MADV_DONTNEED),
> +    ENUM_TARGET(MADV_FREE),
> +    ENUM_TARGET(MADV_REMOVE),
> +    ENUM_TARGET(MADV_DONTFORK),
> +    ENUM_TARGET(MADV_DOFORK),
> +    ENUM_TARGET(MADV_MERGEABLE),
> +    ENUM_TARGET(MADV_UNMERGEABLE),
> +    ENUM_TARGET(MADV_HUGEPAGE),
> +    ENUM_TARGET(MADV_NOHUGEPAGE),
> +    ENUM_TARGET(MADV_DONTDUMP),
> +    ENUM_TARGET(MADV_DODUMP),
> +    ENUM_TARGET(MADV_WIPEONFORK),
> +    ENUM_TARGET(MADV_KEEPONFORK),
> +    ENUM_TARGET(MADV_COLD),
> +    ENUM_TARGET(MADV_PAGEOUT),
> +    ENUM_TARGET(MADV_POPULATE_READ),
> +    ENUM_TARGET(MADV_POPULATE_WRITE),
> +    ENUM_TARGET(MADV_DONTNEED_LOCKED),
> +    ENUM_END,
> +};
> +
> +static void
> +print_madvise(CPUArchState *cpu_env, const struct syscallname *name,
> +              abi_long arg0, abi_long arg1, abi_long arg2,
> +              abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);
> +    print_pointer(arg0, 0);
> +    print_raw_param("%d", arg1, 0);
> +    print_enums(madvise_advice, arg2, 1);
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>   #if defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
>   static void
>   print_fstat(CPUArchState *cpu_env, const struct syscallname *name,
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index 72e17b1acf..c93effdbc8 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -541,7 +541,7 @@
>   { TARGET_NR_lstat64, "lstat64" , NULL, print_lstat64, NULL },
>   #endif
>   #ifdef TARGET_NR_madvise
> -{ TARGET_NR_madvise, "madvise" , NULL, NULL, NULL },
> +{ TARGET_NR_madvise, "madvise" , NULL, print_madvise, NULL },
>   #endif
>   #ifdef TARGET_NR_madvise1
>   { TARGET_NR_madvise1, "madvise1" , NULL, NULL, NULL },
Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 4/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings
  2022-09-06  0:08 ` [PATCH v3 4/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
@ 2022-09-23 21:51   ` Laurent Vivier
  0 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2022-09-23 21:51 UTC (permalink / raw)
  To: Ilya Leoshkevich, Richard Henderson, Paolo Bonzini,
	Taylor Simpson, Alex Bennée
  Cc: qemu-devel

Le 06/09/2022 à 02:08, Ilya Leoshkevich a écrit :
> This is a follow-up for commit 892a4f6a750a ("linux-user: Add partial
> support for MADV_DONTNEED"), which added passthrough for anonymous
> mappings. File mappings can be handled in a similar manner.
> 
> In order to do that, mark pages, for which mmap() was passed through,
> with PAGE_PASSTHROUGH, and then allow madvise() passthrough for these
> pages. Drop the explicit PAGE_ANON check, since anonymous mappings are
> expected to have PAGE_PASSTHROUGH anyway.
> 
> Add PAGE_PASSTHROUGH to PAGE_STICKY in order to keep it on mprotect().
> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> Message-Id: <20220725125043.43048-1-iii@linux.ibm.com>
> ---
>   accel/tcg/translate-all.c |  2 +-
>   include/exec/cpu-all.h    |  6 ++++++
>   linux-user/mmap.c         | 27 ++++++++++++++++++++++-----
>   3 files changed, 29 insertions(+), 6 deletions(-)
> 
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index b83161a081..a47cf38e38 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -2263,7 +2263,7 @@ int page_get_flags(target_ulong address)
>   #ifndef PAGE_TARGET_STICKY
>   #define PAGE_TARGET_STICKY  0
>   #endif
> -#define PAGE_STICKY  (PAGE_ANON | PAGE_TARGET_STICKY)
> +#define PAGE_STICKY  (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY)
>   
>   /* Modify the flags of a page and invalidate the code if necessary.
>      The flag PAGE_WRITE_ORG is positioned automatically depending
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 491629b9ba..16b7df41bf 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -262,6 +262,12 @@ extern const TargetPageBits target_page;
>   #define PAGE_TARGET_1  0x0200
>   #define PAGE_TARGET_2  0x0400
>   
> +/*
> + * For linux-user, indicates that the page is mapped with the same semantics
> + * in both guest and host.
> + */
> +#define PAGE_PASSTHROUGH 0x0800
> +
>   #if defined(CONFIG_USER_ONLY)
>   void page_dump(FILE *f);
>   
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index a5f1ab129c..3a0f67619a 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -425,7 +425,8 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
>   abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>                        int flags, int fd, abi_ulong offset)
>   {
> -    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
> +    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len,
> +              passthrough_start = -1, passthrough_end = -1;
>       int page_flags, host_prot;
>   
>       mmap_lock();
> @@ -538,6 +539,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>               host_start += offset - host_offset;
>           }
>           start = h2g(host_start);
> +        passthrough_start = start;
> +        passthrough_end = start + len;
>       } else {
>           if (start & ~TARGET_PAGE_MASK) {
>               errno = EINVAL;
> @@ -620,6 +623,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>                        host_prot, flags, fd, offset1);
>               if (p == MAP_FAILED)
>                   goto fail;
> +            passthrough_start = real_start;
> +            passthrough_end = real_end;
>           }
>       }
>    the_end1:
> @@ -627,7 +632,18 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
>           page_flags |= PAGE_ANON;
>       }
>       page_flags |= PAGE_RESET;
> -    page_set_flags(start, start + len, page_flags);
> +    if (passthrough_start == passthrough_end) {
> +        page_set_flags(start, start + len, page_flags);
> +    } else {
> +        if (start < passthrough_start) {
> +            page_set_flags(start, passthrough_start, page_flags);
> +        }
> +        page_set_flags(passthrough_start, passthrough_end,
> +                       page_flags | PAGE_PASSTHROUGH);
> +        if (passthrough_end < start + len) {
> +            page_set_flags(passthrough_end, start + len, page_flags);
> +        }
> +    }
>    the_end:
>       trace_target_mmap_complete(start);
>       if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
> @@ -846,7 +862,7 @@ static bool can_passthrough_madv_dontneed(abi_ulong start, abi_ulong end)
>       }
>   
>       for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
> -        if (!(page_get_flags(addr) & PAGE_ANON)) {
> +        if (!(page_get_flags(addr) & PAGE_PASSTHROUGH)) {
>               return false;
>           }
>       }
> @@ -888,8 +904,9 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
>        * This is a hint, so ignoring and returning success is ok.
>        *
>        * This breaks MADV_DONTNEED, completely implementing which is quite
> -     * complicated. However, there is one low-hanging fruit: host-page-aligned
> -     * anonymous mappings. In this case passthrough is safe, so do it.
> +     * 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.
>        */
>       mmap_lock();
>       if (advice == TARGET_MADV_DONTNEED &&
Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 5/5] tests/tcg/linux-test: Add linux-madvise test
  2022-09-06  0:08 ` [PATCH v3 5/5] tests/tcg/linux-test: Add linux-madvise test Ilya Leoshkevich
@ 2022-09-23 21:52   ` Laurent Vivier
  0 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2022-09-23 21:52 UTC (permalink / raw)
  To: Ilya Leoshkevich, Richard Henderson, Paolo Bonzini,
	Taylor Simpson, Alex Bennée
  Cc: qemu-devel

Le 06/09/2022 à 02:08, Ilya Leoshkevich a écrit :
> Add a test that checks madvise(MADV_DONTNEED) behavior with anonymous
> and file mappings in order to prevent regressions.
> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   tests/tcg/multiarch/linux/linux-madvise.c | 70 +++++++++++++++++++++++
>   1 file changed, 70 insertions(+)
>   create mode 100644 tests/tcg/multiarch/linux/linux-madvise.c
> 
> diff --git a/tests/tcg/multiarch/linux/linux-madvise.c b/tests/tcg/multiarch/linux/linux-madvise.c
> new file mode 100644
> index 0000000000..29d0997e68
> --- /dev/null
> +++ b/tests/tcg/multiarch/linux/linux-madvise.c
> @@ -0,0 +1,70 @@
> +#include <assert.h>
> +#include <stdlib.h>
> +#include <sys/mman.h>
> +#include <unistd.h>
> +
> +static void test_anonymous(void)
> +{
> +    int pagesize = getpagesize();
> +    char *page;
> +    int ret;
> +
> +    page = mmap(NULL, pagesize, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
> +    assert(page != MAP_FAILED);
> +
> +    /* Check that mprotect() does not interfere with MADV_DONTNEED. */
> +    ret = mprotect(page, pagesize, PROT_READ | PROT_WRITE);
> +    assert(ret == 0);
> +
> +    /* Check that MADV_DONTNEED clears the page. */
> +    *page = 42;
> +    ret = madvise(page, pagesize, MADV_DONTNEED);
> +    assert(ret == 0);
> +    assert(*page == 0);
> +
> +    ret = munmap(page, pagesize);
> +    assert(ret == 0);
> +}
> +
> +static void test_file(void)
> +{
> +    char tempname[] = "/tmp/.cmadviseXXXXXX";
> +    int pagesize = getpagesize();
> +    ssize_t written;
> +    char c = 42;
> +    char *page;
> +    int ret;
> +    int fd;
> +
> +    fd = mkstemp(tempname);
> +    assert(fd != -1);
> +    ret = unlink(tempname);
> +    assert(ret == 0);
> +    written = write(fd, &c, sizeof(c));
> +    assert(written == sizeof(c));
> +    page = mmap(NULL, pagesize, PROT_READ, MAP_PRIVATE, fd, 0);
> +    assert(page != MAP_FAILED);
> +
> +    /* Check that mprotect() does not interfere with MADV_DONTNEED. */
> +    ret = mprotect(page, pagesize, PROT_READ | PROT_WRITE);
> +    assert(ret == 0);
> +
> +    /* Check that MADV_DONTNEED resets the page. */
> +    *page = 0;
> +    ret = madvise(page, pagesize, MADV_DONTNEED);
> +    assert(ret == 0);
> +    assert(*page == c);
> +
> +    ret = munmap(page, pagesize);
> +    assert(ret == 0);
> +    ret = close(fd);
> +    assert(ret == 0);
> +}
> +
> +int main(void)
> +{
> +    test_anonymous();
> +    test_file();
> +
> +    return EXIT_SUCCESS;
> +}
Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-09-23 22:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-06  0:08 [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
2022-09-06  0:08 ` [PATCH v3 1/5] linux-user: Provide MADV_* definitions Ilya Leoshkevich
2022-09-23 21:51   ` Laurent Vivier
2022-09-06  0:08 ` [PATCH v3 2/5] linux-user: Fix madvise(MADV_DONTNEED) on alpha Ilya Leoshkevich
2022-09-23 21:51   ` Laurent Vivier
2022-09-06  0:08 ` [PATCH v3 3/5] linux-user: Implement stracing madvise() Ilya Leoshkevich
2022-09-23 21:51   ` Laurent Vivier
2022-09-06  0:08 ` [PATCH v3 4/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Ilya Leoshkevich
2022-09-23 21:51   ` Laurent Vivier
2022-09-06  0:08 ` [PATCH v3 5/5] tests/tcg/linux-test: Add linux-madvise test Ilya Leoshkevich
2022-09-23 21:52   ` Laurent Vivier
2022-09-06  7:35 ` [PATCH v3 0/5] linux-user: Passthrough MADV_DONTNEED for certain file mappings Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).