linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC6 PATCH v6 00/21] ILP32 for ARM64
@ 2016-04-05 22:08 Yury Norov
  2016-04-05 22:08 ` [PATCH 01/25] all: syscall wrappers: add documentation Yury Norov
                   ` (28 more replies)
  0 siblings, 29 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

This version is rebased on kernel v4.6-rc2, and has fixes in signal subsystem.
It works with updated glibc [1] (though very draft), and tested with LTP.

It was tested on QEMU and ThunderX machines. No major difference found.
This is RFC because ILP32 is not tested in big-endian mode.

 v3: https://lkml.org/lkml/2014/9/3/704
 v4: https://lkml.org/lkml/2015/4/13/691
 v5: https://lkml.org/lkml/2015/9/29/911

 v6:
 - time_t, __kenel_off_t and other types turned to be 32-bit
   for compatibility reasons (after v5 discussion);
 - related changes applied to ILP32 syscall table and handlers;
 - ILP32 VDSO code excluded. It's not mandatory, and caused questions
   during review process. We definitely make sure we will follow up
   with a VDSO later on because it is needed for performance reasons;
 - fixed build issues with different combinations of AARCH32 / ILP32
   enabling in config;
 - ILP32 TLS bug fixed;
 - entry32-common.S introduced to hold wrappers needed for both ILP32
   and AARCH32_EL0;
 - documentation updated according to latest changes;
 - rebased to the current head;
 - coding style re-checked;
 - ILP32 syscall table turned around.

   rfc3:
 - all structures and system calls are just like AARCH32 ones now. with 2
   exceptions: syscalls that take 64-bit parameter in 2 32-bit regosters
   are replaced with LP64 version; struct rt_sigframe is constructed both
   from LP64 and AARCH32 fields to be consistent with AARCH64 register set;
 - documentation rewritten accordingly;
 - common code for all 3 ABIs is moved to separated files for easy use,
   new headers and objects are introduced, incl: is_compat.h, thread_bits.h,
   signal_common.h, signal32_common.h.
 - ILP32 VDSO code restored, Nathans comments are addressed;
 - patch "arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl" removed, as
   Arnd suggested general solution for IPC_64 problem.

   rfc4:
 - sys_ilp32.c syscall list is fixed according to comments;
 - binfmt_elf32.c and binfmt_ilp32.c are introduced to host the code handling
   corresponding formats;
 - statfs64, fstsatfs64 and mmap wrappers are removed;
 - rebased on v4.4-rc8 + http://www.spinics.net/lists/kernel/msg2151759.html

 rfc5:
 - addressed rfc4 comments;
 - turned s390 compat wrappers to be generic and applied it to arm64/ilp32.
   Heiko Carsten and Martin Schwidefsky added to CC as s390 maintainers.

 rfc6:
 - glibc follows new ABI, [1];
 - significant rework for signal subsystem (patches 21, 23) - struct ucontext
   is now corresponds user representation;
 - compat wrappers and 32-bit off_t patchsets are joined with this patchset,
   as for now ilp32 is the only user for them;
 - moved to kernel v4.6-rc2;
 - few minor bugfixes.

[1] https://github.com/norov/glibc/tree/new-api

Andrew Pinski (7):
  arm64: ensure the kernel is compiled for LP64
  arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
    instead
  arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
  arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
    it
  arm64: ilp32: introduce ilp32-specific handlers for sigframe and
    ucontext
  arm64:ilp32: add ARM64_ILP32 to Kconfig

Bamvor Jian Zhang (1):
  arm64: compat: change config dependences to aarch32

Philipp Tomsich (1):
  arm64:ilp32: add vdso-ilp32 and use for signal return

Yury Norov (16):
  all: syscall wrappers: add documentation
  all: introduce COMPAT_WRAPPER option and enable it for s390
  all: s390: move wrapper infrastructure to generic headers
  all: s390: move compat_wrappers.c from arch/s390/kernel to kernel/
  all: wrap needed syscalls in generic unistd
  compat ABI: use non-compat openat and open_by_handle_at variants
  32-bit ABI: introduce ARCH_32BIT_OFF_T config option
  arm64: ilp32: add documentation on the ILP32 ABI for ARM64
  thread: move thread bits accessors to separated file
  arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
  arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
  arm64: introduce binfmt_elf32.c
  arm64: ilp32: introduce binfmt_ilp32.c
  arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
  arm64: signal: share lp64 signal routines to ilp32
  arm64: signal32: move ilp32 and aarch32 common code to separated file

 Documentation/adding-syscalls.txt             |  32 +++
 Documentation/arm64/ilp32.txt                 |  13 ++
 arch/Kconfig                                  |   8 +
 arch/arc/Kconfig                              |   1 +
 arch/arm/Kconfig                              |   1 +
 arch/arm64/Kconfig                            |  17 +-
 arch/arm64/Makefile                           |   5 +
 arch/arm64/include/asm/compat.h               |  19 +-
 arch/arm64/include/asm/elf.h                  |  35 +---
 arch/arm64/include/asm/fpsimd.h               |   2 +-
 arch/arm64/include/asm/ftrace.h               |   2 +-
 arch/arm64/include/asm/hwcap.h                |   6 +-
 arch/arm64/include/asm/is_compat.h            |  84 ++++++++
 arch/arm64/include/asm/memory.h               |   3 +-
 arch/arm64/include/asm/processor.h            |  11 +-
 arch/arm64/include/asm/ptrace.h               |   2 +-
 arch/arm64/include/asm/signal32.h             |   6 +-
 arch/arm64/include/asm/signal32_common.h      |  25 +++
 arch/arm64/include/asm/signal_common.h        |  33 +++
 arch/arm64/include/asm/signal_ilp32.h         |  34 ++++
 arch/arm64/include/asm/syscall.h              |   2 +-
 arch/arm64/include/asm/thread_info.h          |   3 +-
 arch/arm64/include/asm/unistd.h               |  11 +-
 arch/arm64/include/asm/unistd32.h             |   2 +-
 arch/arm64/include/asm/vdso.h                 |   6 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |   9 +-
 arch/arm64/kernel/Makefile                    |  12 +-
 arch/arm64/kernel/asm-offsets.c               |   2 +-
 arch/arm64/kernel/binfmt_elf32.c              |  33 +++
 arch/arm64/kernel/binfmt_ilp32.c              |  91 +++++++++
 arch/arm64/kernel/cpufeature.c                |   8 +-
 arch/arm64/kernel/cpuinfo.c                   |   4 +-
 arch/arm64/kernel/entry.S                     |  18 +-
 arch/arm64/kernel/entry_ilp32.S               |  23 +++
 arch/arm64/kernel/head.S                      |   2 +-
 arch/arm64/kernel/hw_breakpoint.c             |  10 +-
 arch/arm64/kernel/perf_regs.c                 |   2 +-
 arch/arm64/kernel/process.c                   |   7 +-
 arch/arm64/kernel/ptrace.c                    |  67 ++++++-
 arch/arm64/kernel/signal.c                    | 100 ++++++----
 arch/arm64/kernel/signal32.c                  |  85 --------
 arch/arm64/kernel/signal32_common.c           | 115 +++++++++++
 arch/arm64/kernel/signal_ilp32.c              | 192 ++++++++++++++++++
 arch/arm64/kernel/sys32.c                     |   1 +
 arch/arm64/kernel/sys_ilp32.c                 |  68 +++++++
 arch/arm64/kernel/traps.c                     |   5 +-
 arch/arm64/kernel/vdso-ilp32/.gitignore       |   2 +
 arch/arm64/kernel/vdso-ilp32/Makefile         |  72 +++++++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     |  33 +++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S |  95 +++++++++
 arch/arm64/kernel/vdso.c                      |  65 ++++--
 arch/blackfin/Kconfig                         |   1 +
 arch/cris/Kconfig                             |   1 +
 arch/frv/Kconfig                              |   1 +
 arch/h8300/Kconfig                            |   1 +
 arch/hexagon/Kconfig                          |   1 +
 arch/m32r/Kconfig                             |   1 +
 arch/m68k/Kconfig                             |   1 +
 arch/metag/Kconfig                            |   1 +
 arch/microblaze/Kconfig                       |   1 +
 arch/mips/Kconfig                             |   1 +
 arch/mn10300/Kconfig                          |   1 +
 arch/nios2/Kconfig                            |   1 +
 arch/openrisc/Kconfig                         |   1 +
 arch/parisc/Kconfig                           |   1 +
 arch/powerpc/Kconfig                          |   1 +
 arch/s390/Kconfig                             |   1 +
 arch/s390/include/asm/compat.h                |  17 +-
 arch/s390/kernel/Makefile                     |   2 +-
 arch/s390/kernel/compat_linux.c               |   4 +
 arch/s390/kernel/compat_wrapper.c             | 180 -----------------
 arch/score/Kconfig                            |   1 +
 arch/sh/Kconfig                               |   1 +
 arch/sparc/Kconfig                            |   1 +
 arch/tile/Kconfig                             |   1 +
 arch/tile/kernel/compat.c                     |   3 +
 arch/unicore32/Kconfig                        |   1 +
 arch/x86/Kconfig                              |   1 +
 arch/x86/um/Kconfig                           |   1 +
 arch/xtensa/Kconfig                           |   1 +
 drivers/clocksource/arm_arch_timer.c          |   2 +-
 include/linux/compat.h                        | 277 ++++++++++++++++++++++++++
 include/linux/fcntl.h                         |   2 +-
 include/linux/ptrace.h                        |   6 +
 include/linux/syscalls.h                      |  57 +-----
 include/linux/syscalls_structs.h              |  60 ++++++
 include/linux/thread_bits.h                   |  55 +++++
 include/linux/thread_info.h                   |  44 +---
 include/uapi/asm-generic/unistd.h             | 231 ++++++++++-----------
 kernel/Makefile                               |   1 +
 kernel/compat_wrapper.c                       | 175 ++++++++++++++++
 kernel/ptrace.c                               |  10 +-
 92 files changed, 1997 insertions(+), 637 deletions(-)
 create mode 100644 Documentation/arm64/ilp32.txt
 create mode 100644 arch/arm64/include/asm/is_compat.h
 create mode 100644 arch/arm64/include/asm/signal32_common.h
 create mode 100644 arch/arm64/include/asm/signal_common.h
 create mode 100644 arch/arm64/include/asm/signal_ilp32.h
 create mode 100644 arch/arm64/kernel/binfmt_elf32.c
 create mode 100644 arch/arm64/kernel/binfmt_ilp32.c
 create mode 100644 arch/arm64/kernel/entry_ilp32.S
 create mode 100644 arch/arm64/kernel/signal32_common.c
 create mode 100644 arch/arm64/kernel/signal_ilp32.c
 create mode 100644 arch/arm64/kernel/sys_ilp32.c
 create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
 create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
 create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
 create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
 delete mode 100644 arch/s390/kernel/compat_wrapper.c
 create mode 100644 include/linux/syscalls_structs.h
 create mode 100644 include/linux/thread_bits.h
 create mode 100644 kernel/compat_wrapper.c

-- 
2.5.0

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

* [PATCH 01/25] all: syscall wrappers: add documentation
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 02/25] all: introduce COMPAT_WRAPPER option and enable it for s390 Yury Norov
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
 Documentation/adding-syscalls.txt | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/Documentation/adding-syscalls.txt b/Documentation/adding-syscalls.txt
index cc2d4ac..d02a6bd 100644
--- a/Documentation/adding-syscalls.txt
+++ b/Documentation/adding-syscalls.txt
@@ -341,6 +341,38 @@ To summarize, you need:
  - instance of __SC_COMP not __SYSCALL in include/uapi/asm-generic/unistd.h
 
 
+Compatibility System Calls Wrappers
+--------------------------------
+
+Some architectures prevent 32-bit userspace from access to top halves of 64-bit
+registers, but some not. It's not a problem if specific argument is the same
+size in kernel and userspace. It also is not a problem if system call is already
+handled by compatible routine. Otherwise we'd take care of it. Usually, glibc
+and compiler handles register's top halve, but from kernel side, we cannot rely
+on it, as malicious code may cause incorrect behaviour and/or security
+vulnerabilities.
+
+For now, only s390 and arm64/ilp32 are affected.
+
+To clear that top halves, automatic wrappers are introduced. They clear all
+required registers before passing control to regular syscall handler.
+
+If your architecture allows userspace code to access top halves of register,
+you need to:
+ - enable COMPAT_WRAPPER in configuration file;
+ - declare: "#define __SC_WRAP(nr, sym) [nr] = compat_##sym,", just before
+   compatible syscall table declaration, if you use generic unistd; or
+ - declare compat wrappers manually, if you use non-generic syscall table.
+   The list of unsafe syscalls is in kernel/compat_wrapper.
+
+If you write new syscall, make sure, its arguments are the same size in both
+64- and 32-bits modes. If no, and if there's no explicit compat version for
+syscall handler, you need to:
+ - declare compat version prototype in 'include/linux/compat.h';
+ - in 'include/uapi/asm-generic/unistd.h' declare syscall with macro '__SC_WRAP'
+   instead of '__SYSCALL';
+ - add corresponding line to 'kernel/compat_wrapper.c' to let it generate wrapper.
+
 Compatibility System Calls (x86)
 --------------------------------
 
-- 
2.5.0

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

* [PATCH 02/25] all: introduce COMPAT_WRAPPER option and enable it for s390
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
  2016-04-05 22:08 ` [PATCH 01/25] all: syscall wrappers: add documentation Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 03/25] all: s390: move wrapper infrastructure to generic headers Yury Norov
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
 arch/Kconfig      | 4 ++++
 arch/s390/Kconfig | 1 +
 2 files changed, 5 insertions(+)

diff --git a/arch/Kconfig b/arch/Kconfig
index 81869a5..92fcbd4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -589,6 +589,10 @@ config HAVE_STACK_VALIDATION
 	  Architecture supports the 'objtool check' host tool command, which
 	  performs compile-time stack metadata validation.
 
+config COMPAT_WRAPPER
+	bool
+	depends on COMPAT
+
 #
 # ABI hall of shame
 #
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index aad23e3..cdc02e0 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -337,6 +337,7 @@ config COMPAT
 	select COMPAT_BINFMT_ELF if BINFMT_ELF
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT_OLD_SIGACTION
+	select COMPAT_WRAPPER
 	depends on MULTIUSER
 	help
 	  Select this option if you want to enable your system kernel to
-- 
2.5.0

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

* [PATCH 03/25] all: s390: move wrapper infrastructure to generic headers
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
  2016-04-05 22:08 ` [PATCH 01/25] all: syscall wrappers: add documentation Yury Norov
  2016-04-05 22:08 ` [PATCH 02/25] all: introduce COMPAT_WRAPPER option and enable it for s390 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 04/25] all: s390: move compat_wrappers.c from arch/s390/kernel to kernel/ Yury Norov
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

This patch moves required calls to generic files to let other arches use
it if needed. Here also, additional code is introduced, as s390 uses asm
syscall tables, while in general case, wrappers may be used in C code.

__SC_COMPAT_CAST for s390 is too specific due to 31-bit pointer length, so it's
moved to arch/s390/include/asm/compat.h. Generic declaration assumes that long,
unsigned long and pointer types are all 32-bit length.

linux/syscalls_structs.h header is introduced, because from now (see next patch)
structure types listed there are needed for both normal and compat mode.

cond_syscall_wrapped now defined two symbols: sys_foo() and compat_sys_foo(), if
compat wrappers are enabled.

Here __SC_WRAP() macro is introduced as well. s390 doesn't need it as it uses
asm-generated syscall table. But architectures that generate that tables with
C code (ARM64/ILP32) should redefine it as '#define __SC_WRAP(name) compat_##name'.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
 arch/s390/include/asm/compat.h    | 17 +++++++++--
 arch/s390/kernel/compat_wrapper.c | 51 ---------------------------------
 include/linux/compat.h            | 52 +++++++++++++++++++++++++++++++++
 include/linux/syscalls.h          | 57 +------------------------------------
 include/linux/syscalls_structs.h  | 60 +++++++++++++++++++++++++++++++++++++++
 include/uapi/asm-generic/unistd.h |  4 +++
 6 files changed, 132 insertions(+), 109 deletions(-)
 create mode 100644 include/linux/syscalls_structs.h

diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 352f7bd..f412723 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -7,13 +7,26 @@
 #include <linux/sched.h>
 #include <linux/thread_info.h>
 
-#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64))
-
 #define __SC_DELOUSE(t,v) ({ \
 	BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \
 	(t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \
 })
 
+#define __SC_COMPAT_CAST(t, a)						\
+({									\
+	long __ReS = a;							\
+									\
+	BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&		\
+		     !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));		\
+	if (__TYPE_IS_L(t))						\
+		__ReS = (s32)a;						\
+	if (__TYPE_IS_UL(t))						\
+		__ReS = (u32)a;						\
+	if (__TYPE_IS_PTR(t))						\
+		__ReS = a & 0x7fffffff;					\
+	(t)__ReS;							\
+})
+
 #define PSW32_MASK_PER		0x40000000UL
 #define PSW32_MASK_DAT		0x04000000UL
 #define PSW32_MASK_IO		0x02000000UL
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c
index ae2cda5..1614e15 100644
--- a/arch/s390/kernel/compat_wrapper.c
+++ b/arch/s390/kernel/compat_wrapper.c
@@ -8,57 +8,6 @@
 #include <linux/compat.h>
 #include "entry.h"
 
-#define COMPAT_SYSCALL_WRAP1(name, ...) \
-	COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__)
-#define COMPAT_SYSCALL_WRAP2(name, ...) \
-	COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__)
-#define COMPAT_SYSCALL_WRAP3(name, ...) \
-	COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__)
-#define COMPAT_SYSCALL_WRAP4(name, ...) \
-	COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__)
-#define COMPAT_SYSCALL_WRAP5(name, ...) \
-	COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__)
-#define COMPAT_SYSCALL_WRAP6(name, ...) \
-	COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__)
-
-#define __SC_COMPAT_TYPE(t, a) \
-	__typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a
-
-#define __SC_COMPAT_CAST(t, a)						\
-({									\
-	long __ReS = a;							\
-									\
-	BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&		\
-		     !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));		\
-	if (__TYPE_IS_L(t))						\
-		__ReS = (s32)a;						\
-	if (__TYPE_IS_UL(t))						\
-		__ReS = (u32)a;						\
-	if (__TYPE_IS_PTR(t))						\
-		__ReS = a & 0x7fffffff;					\
-	(t)__ReS;							\
-})
-
-/*
- * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by
- * compat tasks. These wrappers will only be used for system calls where only
- * the system call arguments need sign or zero extension or zeroing of the upper
- * 33 bits of pointers.
- * Note: since the wrapper function will afterwards call a system call which
- * again performs zero and sign extension for all system call arguments with
- * a size of less than eight bytes, these compat wrappers only touch those
- * system call arguments with a size of eight bytes ((unsigned) long and
- * pointers). Zero and sign extension for e.g. int parameters will be done by
- * the regular system call wrappers.
- */
-#define COMPAT_SYSCALL_WRAPx(x, name, ...)					\
-asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));			\
-asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\
-asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__))	\
-{										\
-	return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__));		\
-}
-
 COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode);
 COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname);
 COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index f964ef7..4eba16e 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -30,6 +30,10 @@
 #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v))
 #endif
 
+#ifndef __TYPE_IS_PTR
+#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64))
+#endif
+
 #define COMPAT_SYSCALL_DEFINE0(name) \
 	asmlinkage long compat_sys_##name(void)
 
@@ -739,4 +743,52 @@ static inline bool in_compat_syscall(void) { return false; }
 
 #endif /* CONFIG_COMPAT */
 
+#ifdef CONFIG_COMPAT_WRAPPER
+
+#define COMPAT_SYSCALL_WRAP1(name, ...) COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_WRAP2(name, ...) COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_WRAP3(name, ...) COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_WRAP4(name, ...) COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_WRAP5(name, ...) COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_WRAP6(name, ...) COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__)
+
+#ifndef __SC_COMPAT_TYPE
+#define __SC_COMPAT_TYPE(t, a) \
+	__typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a
+#endif
+
+#ifndef __SC_COMPAT_CAST
+#define __SC_COMPAT_CAST(t, a) ({					\
+	BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&		\
+		     !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));		\
+	((t) ((t)(-1) < 0 ? (s64)(s32)(a) : (u64)(u32)(a)));		\
+})
+#endif
+
+#ifndef COMPAT_SYSCALL_WRAPx
+/*
+ * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by
+ * compat tasks. These wrappers will only be used for system calls where only
+ * the system call arguments need sign or zero extension or zeroing of the upper
+ * parts of arguments passed in register.
+ * Note: since the wrapper function will afterwards call a system call which
+ * again performs zero and sign extension for all system call arguments with
+ * a size of less than eight bytes, these compat wrappers only touch those
+ * system call arguments with a size of eight bytes ((unsigned) long and
+ * pointers). Zero and sign extension for e.g. int parameters will be done by
+ * the regular system call wrappers.
+ */
+#define COMPAT_SYSCALL_WRAPx(x, name, ...)						\
+asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));				\
+asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))			\
+		__attribute__((alias(__stringify(compat_SyS##name))));			\
+asmlinkage long notrace compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));	\
+asmlinkage long notrace compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__))		\
+{											\
+	return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__));			\
+}
+#endif
+
+#endif /* CONFIG_COMPAT_WRAPPER */
+
 #endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index d795472..9d345eb 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -11,62 +11,7 @@
 #ifndef _LINUX_SYSCALLS_H
 #define _LINUX_SYSCALLS_H
 
-struct epoll_event;
-struct iattr;
-struct inode;
-struct iocb;
-struct io_event;
-struct iovec;
-struct itimerspec;
-struct itimerval;
-struct kexec_segment;
-struct linux_dirent;
-struct linux_dirent64;
-struct list_head;
-struct mmap_arg_struct;
-struct msgbuf;
-struct user_msghdr;
-struct mmsghdr;
-struct msqid_ds;
-struct new_utsname;
-struct nfsctl_arg;
-struct __old_kernel_stat;
-struct oldold_utsname;
-struct old_utsname;
-struct pollfd;
-struct rlimit;
-struct rlimit64;
-struct rusage;
-struct sched_param;
-struct sched_attr;
-struct sel_arg_struct;
-struct semaphore;
-struct sembuf;
-struct shmid_ds;
-struct sockaddr;
-struct stat;
-struct stat64;
-struct statfs;
-struct statfs64;
-struct __sysctl_args;
-struct sysinfo;
-struct timespec;
-struct timeval;
-struct timex;
-struct timezone;
-struct tms;
-struct utimbuf;
-struct mq_attr;
-struct compat_stat;
-struct compat_timeval;
-struct robust_list_head;
-struct getcpu_cache;
-struct old_linux_dirent;
-struct perf_event_attr;
-struct file_handle;
-struct sigaltstack;
-union bpf_attr;
-
+#include <linux/syscalls_structs.h>
 #include <linux/types.h>
 #include <linux/aio_abi.h>
 #include <linux/capability.h>
diff --git a/include/linux/syscalls_structs.h b/include/linux/syscalls_structs.h
new file mode 100644
index 0000000..a920cbc
--- /dev/null
+++ b/include/linux/syscalls_structs.h
@@ -0,0 +1,60 @@
+#ifndef _LINUX_SYSCALL_STRUCTS_H
+#define _LINUX_SYSCALL_STRUCTS_H
+
+struct epoll_event;
+struct iattr;
+struct inode;
+struct iocb;
+struct io_event;
+struct iovec;
+struct itimerspec;
+struct itimerval;
+struct kexec_segment;
+struct linux_dirent;
+struct linux_dirent64;
+struct list_head;
+struct mmap_arg_struct;
+struct msgbuf;
+struct user_msghdr;
+struct mmsghdr;
+struct msqid_ds;
+struct new_utsname;
+struct nfsctl_arg;
+struct __old_kernel_stat;
+struct oldold_utsname;
+struct old_utsname;
+struct pollfd;
+struct rlimit;
+struct rlimit64;
+struct rusage;
+struct sched_param;
+struct sched_attr;
+struct sel_arg_struct;
+struct semaphore;
+struct sembuf;
+struct shmid_ds;
+struct sockaddr;
+struct stat;
+struct stat64;
+struct statfs;
+struct statfs64;
+struct __sysctl_args;
+struct sysinfo;
+struct timespec;
+struct timeval;
+struct timex;
+struct timezone;
+struct tms;
+struct utimbuf;
+struct mq_attr;
+struct compat_stat;
+struct compat_timeval;
+struct robust_list_head;
+struct getcpu_cache;
+struct old_linux_dirent;
+struct perf_event_attr;
+struct file_handle;
+struct sigaltstack;
+union bpf_attr;
+
+#endif /* _LINUX_SYSCALL_STRUCTS_H */
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 2622b33..f10a316 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -29,6 +29,10 @@
 #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
 #endif
 
+#ifndef __SC_WRAP
+#define __SC_WRAP __SYSCALL
+#endif
+
 #define __NR_io_setup 0
 __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
 #define __NR_io_destroy 1
-- 
2.5.0

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

* [PATCH 04/25] all: s390: move compat_wrappers.c from arch/s390/kernel to kernel/
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (2 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 03/25] all: s390: move wrapper infrastructure to generic headers Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 05/25] all: wrap needed syscalls in generic unistd Yury Norov
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Some syscalls are declared conditionally, so corresponding wrappers
are conditional accordingly.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
 arch/s390/kernel/Makefile         |   2 +-
 arch/s390/kernel/compat_linux.c   |   4 +
 arch/s390/kernel/compat_wrapper.c | 129 ----------------------------
 kernel/Makefile                   |   1 +
 kernel/compat_wrapper.c           | 175 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 181 insertions(+), 130 deletions(-)
 delete mode 100644 arch/s390/kernel/compat_wrapper.c
 create mode 100644 kernel/compat_wrapper.c

diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 2f5586a..145d3d8 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -57,7 +57,7 @@ obj-$(CONFIG_HIBERNATION)	+= suspend.o swsusp.o
 obj-$(CONFIG_AUDIT)		+= audit.o
 compat-obj-$(CONFIG_AUDIT)	+= compat_audit.o
 obj-$(CONFIG_COMPAT)		+= compat_linux.o compat_signal.o
-obj-$(CONFIG_COMPAT)		+= compat_wrapper.o $(compat-obj-y)
+obj-$(CONFIG_COMPAT)		+= $(compat-obj-y)
 
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 437e611..783c208 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -86,6 +86,10 @@
 #define SET_STAT_UID(stat, uid)		(stat).st_uid = high2lowuid(uid)
 #define SET_STAT_GID(stat, gid)		(stat).st_gid = high2lowgid(gid)
 
+COMPAT_SYSCALL_WRAP3(s390_pci_mmio_write, const unsigned long, mmio_addr, const void __user *, user_buffer, const size_t, length);
+
+COMPAT_SYSCALL_WRAP3(s390_pci_mmio_read, const unsigned long, mmio_addr, void __user *, user_buffer, const size_t, length);
+
 COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename,
 		       u16, user, u16, group)
 {
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c
deleted file mode 100644
index 1614e15..0000000
--- a/arch/s390/kernel/compat_wrapper.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  Compat system call wrappers.
- *
- *    Copyright IBM Corp. 2014
- */
-
-#include <linux/syscalls.h>
-#include <linux/compat.h>
-#include "entry.h"
-
-COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode);
-COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname);
-COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname);
-COMPAT_SYSCALL_WRAP1(chdir, const char __user *, filename);
-COMPAT_SYSCALL_WRAP3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev);
-COMPAT_SYSCALL_WRAP2(chmod, const char __user *, filename, umode_t, mode);
-COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name);
-COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode);
-COMPAT_SYSCALL_WRAP2(rename, const char __user *, oldname, const char __user *, newname);
-COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode);
-COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname);
-COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes);
-COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk);
-COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler);
-COMPAT_SYSCALL_WRAP1(acct, const char __user *, name);
-COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags);
-COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename);
-COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask);
-COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len);
-COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new);
-COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz);
-COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library);
-COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags);
-COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg);
-COMPAT_SYSCALL_WRAP2(munmap, unsigned long, addr, size_t, len);
-COMPAT_SYSCALL_WRAP3(syslog, int, type, char __user *, buf, int, len);
-COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile);
-COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len);
-COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name);
-COMPAT_SYSCALL_WRAP3(mprotect, unsigned long, start, size_t, len, unsigned long, prot);
-COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs);
-COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags);
-COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr);
-COMPAT_SYSCALL_WRAP2(bdflush, int, func, long, data);
-COMPAT_SYSCALL_WRAP3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2);
-COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, unsigned long, high, unsigned long, low, loff_t __user *, result, unsigned int, whence);
-COMPAT_SYSCALL_WRAP3(msync, unsigned long, start, size_t, len, int, flags);
-COMPAT_SYSCALL_WRAP2(mlock, unsigned long, start, size_t, len);
-COMPAT_SYSCALL_WRAP2(munlock, unsigned long, start, size_t, len);
-COMPAT_SYSCALL_WRAP2(sched_setparam, pid_t, pid, struct sched_param __user *, param);
-COMPAT_SYSCALL_WRAP2(sched_getparam, pid_t, pid, struct sched_param __user *, param);
-COMPAT_SYSCALL_WRAP3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param);
-COMPAT_SYSCALL_WRAP5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr);
-COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout);
-COMPAT_SYSCALL_WRAP5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5);
-COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, unsigned long, size);
-COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr);
-COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data);
-COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, uid_t, user, gid_t, group);
-COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, gid_t __user *, grouplist);
-COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, gid_t __user *, grouplist);
-COMPAT_SYSCALL_WRAP3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid);
-COMPAT_SYSCALL_WRAP3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid);
-COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, uid_t, user, gid_t, group);
-COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old);
-COMPAT_SYSCALL_WRAP3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec);
-COMPAT_SYSCALL_WRAP3(madvise, unsigned long, start, size_t, len, int, behavior);
-COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags);
-COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags);
-COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, size_t, size, int, flags);
-COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count);
-COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size);
-COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size);
-COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size);
-COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, size_t, size);
-COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, size_t, size);
-COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, size_t, size);
-COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name);
-COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name);
-COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name);
-COMPAT_SYSCALL_WRAP1(set_tid_address, int __user *, tidptr);
-COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event);
-COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout);
-COMPAT_SYSCALL_WRAP1(io_destroy, aio_context_t, ctx);
-COMPAT_SYSCALL_WRAP3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result);
-COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name);
-COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, size_t, len, key_serial_t, id);
-COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id);
-COMPAT_SYSCALL_WRAP5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags);
-COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask);
-COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode);
-COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev);
-COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag);
-COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag);
-COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname);
-COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags);
-COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname);
-COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz);
-COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode);
-COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode);
-COMPAT_SYSCALL_WRAP1(unshare, unsigned long, unshare_flags);
-COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags);
-COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags);
-COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache);
-COMPAT_SYSCALL_WRAP2(pipe2, int __user *, fildes, int, flags);
-COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags);
-COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, unsigned long, tls);
-COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim);
-COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag);
-COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2);
-COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags);
-COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags);
-COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags);
-COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags);
-COMPAT_SYSCALL_WRAP3(seccomp, unsigned int, op, unsigned int, flags, const char __user *, uargs)
-COMPAT_SYSCALL_WRAP3(getrandom, char __user *, buf, size_t, count, unsigned int, flags)
-COMPAT_SYSCALL_WRAP2(memfd_create, const char __user *, uname, unsigned int, flags)
-COMPAT_SYSCALL_WRAP3(bpf, int, cmd, union bpf_attr *, attr, unsigned int, size);
-COMPAT_SYSCALL_WRAP3(s390_pci_mmio_write, const unsigned long, mmio_addr, const void __user *, user_buffer, const size_t, length);
-COMPAT_SYSCALL_WRAP3(s390_pci_mmio_read, const unsigned long, mmio_addr, void __user *, user_buffer, const size_t, length);
-COMPAT_SYSCALL_WRAP4(socketpair, int, family, int, type, int, protocol, int __user *, usockvec);
-COMPAT_SYSCALL_WRAP3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen);
-COMPAT_SYSCALL_WRAP3(connect, int, fd, struct sockaddr __user *, uservaddr, int, addrlen);
-COMPAT_SYSCALL_WRAP4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen, int, flags);
-COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
-COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
-COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len);
-COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags);
-COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags);
diff --git a/kernel/Makefile b/kernel/Makefile
index f0c40bf..882eec03 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
 obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o
 obj-$(CONFIG_COMPAT) += compat.o
+obj-$(CONFIG_COMPAT_WRAPPER) += compat_wrapper.o
 obj-$(CONFIG_CGROUPS) += cgroup.o
 obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o
 obj-$(CONFIG_CGROUP_PIDS) += cgroup_pids.o
diff --git a/kernel/compat_wrapper.c b/kernel/compat_wrapper.c
new file mode 100644
index 0000000..b6c050e
--- /dev/null
+++ b/kernel/compat_wrapper.c
@@ -0,0 +1,175 @@
+/*
+ *  Compat system call wrappers.
+ *
+ *    Copyright IBM Corp. 2014
+ */
+
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+
+COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode);
+COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname);
+COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname);
+COMPAT_SYSCALL_WRAP1(chdir, const char __user *, filename);
+COMPAT_SYSCALL_WRAP3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev);
+COMPAT_SYSCALL_WRAP2(chmod, const char __user *, filename, umode_t, mode);
+
+#ifdef __ARCH_WANT_SYS_OLDUMOUNT
+COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name);
+#endif
+
+COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode);
+COMPAT_SYSCALL_WRAP2(rename, const char __user *, oldname, const char __user *, newname);
+COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode);
+COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname);
+COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes);
+COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk);
+
+#ifdef __ARCH_WANT_SYS_SIGNAL
+COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler);
+#endif
+
+COMPAT_SYSCALL_WRAP1(acct, const char __user *, name);
+COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags);
+COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename);
+
+#ifdef CONFIG_OLD_SIGSUSPEND
+SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask);
+#endif
+
+#ifdef CONFIG_OLD_SIGSUSPEND3
+COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask);
+#endif
+
+COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len);
+COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new);
+COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz);
+COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library);
+COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags);
+COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg);
+COMPAT_SYSCALL_WRAP2(munmap, unsigned long, addr, size_t, len);
+COMPAT_SYSCALL_WRAP3(syslog, int, type, char __user *, buf, int, len);
+COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile);
+COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len);
+COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name);
+COMPAT_SYSCALL_WRAP3(mprotect, unsigned long, start, size_t, len, unsigned long, prot);
+COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs);
+COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags);
+COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr);
+COMPAT_SYSCALL_WRAP2(bdflush, int, func, long, data);
+COMPAT_SYSCALL_WRAP3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2);
+
+#ifdef __ARCH_WANT_SYS_LLSEEK
+COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, unsigned long, high, unsigned long, low, loff_t __user *, result, unsigned int, whence);
+#endif
+
+COMPAT_SYSCALL_WRAP3(msync, unsigned long, start, size_t, len, int, flags);
+COMPAT_SYSCALL_WRAP2(mlock, unsigned long, start, size_t, len);
+COMPAT_SYSCALL_WRAP2(munlock, unsigned long, start, size_t, len);
+COMPAT_SYSCALL_WRAP2(sched_setparam, pid_t, pid, struct sched_param __user *, param);
+COMPAT_SYSCALL_WRAP2(sched_getparam, pid_t, pid, struct sched_param __user *, param);
+COMPAT_SYSCALL_WRAP3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param);
+COMPAT_SYSCALL_WRAP5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr);
+COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout);
+COMPAT_SYSCALL_WRAP5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5);
+COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, unsigned long, size);
+COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr);
+COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data);
+COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, uid_t, user, gid_t, group);
+COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, gid_t __user *, grouplist);
+COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, gid_t __user *, grouplist);
+COMPAT_SYSCALL_WRAP3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid);
+COMPAT_SYSCALL_WRAP3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid);
+COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, uid_t, user, gid_t, group);
+COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old);
+COMPAT_SYSCALL_WRAP3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec);
+COMPAT_SYSCALL_WRAP3(madvise, unsigned long, start, size_t, len, int, behavior);
+COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags);
+COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags);
+COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, size_t, size, int, flags);
+
+#ifndef __ARCH_WANT_COMPAT_SYS_GETDENTS64
+COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count);
+#endif
+
+COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size);
+COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size);
+COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size);
+COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, size_t, size);
+COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, size_t, size);
+COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, size_t, size);
+COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name);
+COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name);
+COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name);
+COMPAT_SYSCALL_WRAP1(set_tid_address, int __user *, tidptr);
+COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event);
+COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout);
+COMPAT_SYSCALL_WRAP1(io_destroy, aio_context_t, ctx);
+COMPAT_SYSCALL_WRAP3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result);
+COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name);
+COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, size_t, len, key_serial_t, id);
+COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id);
+COMPAT_SYSCALL_WRAP5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags);
+COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask);
+COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode);
+COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev);
+COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag);
+COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag);
+COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname);
+COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags);
+COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname);
+COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz);
+COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode);
+COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode);
+COMPAT_SYSCALL_WRAP1(unshare, unsigned long, unshare_flags);
+COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags);
+COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags);
+COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache);
+COMPAT_SYSCALL_WRAP2(pipe2, int __user *, fildes, int, flags);
+COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags);
+
+#ifdef __ARCH_WANT_SYS_CLONE
+#ifdef CONFIG_CLONE_BACKWARDS
+COMPAT_SYSCALL_WRAP5(clone, unsigned long, clone_flags, unsigned long, newsp,
+                int __user *, parent_tidptr,
+                unsigned long, tls,
+                int __user *, child_tidptr);
+#elif defined(CONFIG_CLONE_BACKWARDS2)
+       COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags,
+               int __user *, parent_tidptr,
+               int __user *, child_tidptr,
+               unsigned long, tls);
+#elif defined(CONFIG_CLONE_BACKWARDS3)
+       COMPAT_SYSCALL_WRAP6(clone, unsigned long, clone_flags, unsigned long, newsp,
+              int, stack_size,
+              int __user *, parent_tidptr,
+              int __user *, child_tidptr,
+               unsigned long, tls);
+#else
+COMPAT_SYSCALL_WRAP5(clone, unsigned long, clone_flags, unsigned long, newsp,
+       int __user *, parent_tidptr,
+       int __user *, child_tidptr,
+       unsigned long, tls);
+#endif
+#endif
+
+COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim);
+COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag);
+COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2);
+COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags);
+COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags);
+COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags);
+COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags);
+COMPAT_SYSCALL_WRAP3(seccomp, unsigned int, op, unsigned int, flags, const char __user *, uargs)
+COMPAT_SYSCALL_WRAP3(getrandom, char __user *, buf, size_t, count, unsigned int, flags)
+COMPAT_SYSCALL_WRAP2(memfd_create, const char __user *, uname, unsigned int, flags)
+COMPAT_SYSCALL_WRAP3(bpf, int, cmd, union bpf_attr *, attr, unsigned int, size);
+COMPAT_SYSCALL_WRAP4(socketpair, int, family, int, type, int, protocol, int __user *, usockvec);
+COMPAT_SYSCALL_WRAP3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen);
+COMPAT_SYSCALL_WRAP3(connect, int, fd, struct sockaddr __user *, uservaddr, int, addrlen);
+COMPAT_SYSCALL_WRAP4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen, int, flags);
+COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
+COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len);
+COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len);
+COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags);
+COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags);
-- 
2.5.0

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

* [PATCH 05/25] all: wrap needed syscalls in generic unistd
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (3 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 04/25] all: s390: move compat_wrappers.c from arch/s390/kernel to kernel/ Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 06/25] compat ABI: use non-compat openat and open_by_handle_at variants Yury Norov
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

As generic unistd syscall table is written in C, syscall
prototypes declaration is needed. It's added to compat header.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
---
 include/linux/compat.h            | 225 +++++++++++++++++++++++++++++++++++++
 include/uapi/asm-generic/unistd.h | 227 +++++++++++++++++++-------------------
 2 files changed, 338 insertions(+), 114 deletions(-)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index 4eba16e..248e015 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -789,6 +789,231 @@ asmlinkage long notrace compat_SyS##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__))
 }
 #endif
 
+/* Compat wrappers */
+#include <linux/syscalls_structs.h>
+asmlinkage long compat_sys_creat(const char __user *pathname, umode_t mode);
+asmlinkage long compat_sys_link(const char __user *oldname,
+				const char __user *newname);
+asmlinkage long compat_sys_chdir(const char __user *filename);
+asmlinkage long compat_sys_mknod(const char __user *filename, umode_t mode,
+				unsigned dev);
+asmlinkage long compat_sys_chmod(const char __user *filename, umode_t mode);
+asmlinkage long compat_sys_oldumount(char __user *name);
+asmlinkage long compat_sys_access(const char __user *filename, int mode);
+asmlinkage long compat_sys_rename(const char __user *oldname,
+				const char __user *newname);
+asmlinkage long compat_sys_mkdir(const char __user *pathname, umode_t mode);
+asmlinkage long compat_sys_rmdir(const char __user *pathname);
+asmlinkage long compat_sys_pipe(int __user *fildes);
+asmlinkage long compat_sys_brk(unsigned long brk);
+asmlinkage long compat_sys_signal(int sig, __sighandler_t handler);
+asmlinkage long compat_sys_acct(const char __user *name);
+asmlinkage long compat_sys_umount(char __user *name, int flags);
+asmlinkage long compat_sys_chroot(const char __user *filename);
+
+#ifdef CONFIG_OLD_SIGSUSPEND
+asmlinkage long compat_sys_sigsuspend(old_sigset_t mask);
+#endif
+
+#ifdef CONFIG_OLD_SIGSUSPEND3
+asmlinkage long compat_sys_sigsuspend(int unused1, int unused2, old_sigset_t mask);
+#endif
+
+asmlinkage long compat_sys_sethostname(char __user *name, int len);
+asmlinkage long compat_sys_symlink(const char __user *old, const char __user *new);
+asmlinkage long compat_sys_readlink(const char __user *path,
+				char __user *buf, int bufsiz);
+asmlinkage long compat_sys_uselib(const char __user *library);
+asmlinkage long compat_sys_swapon(const char __user *specialfile, int swap_flags);
+asmlinkage long compat_sys_reboot(int magic1, int magic2, unsigned int cmd,
+				void __user *arg);
+asmlinkage long compat_sys_munmap(unsigned long addr, size_t len);
+asmlinkage long compat_sys_munmap(unsigned long addr, size_t len);
+asmlinkage long compat_sys_syslog(int type, char __user *buf, int len);
+asmlinkage long compat_sys_swapoff(const char __user *specialfile);
+asmlinkage long compat_sys_setdomainname(char __user *name, int len);
+asmlinkage long compat_sys_newuname(struct new_utsname __user *name);
+asmlinkage long compat_sys_mprotect(unsigned long start, size_t len,
+				unsigned long prot);
+asmlinkage long compat_sys_init_module(void __user *umod, unsigned long len,
+				const char __user *uargs);
+asmlinkage long compat_sys_delete_module(const char __user *name_user,
+				unsigned int flags);
+asmlinkage long compat_sys_quotactl(unsigned int cmd, const char __user *special,
+				qid_t id, void __user *addr);
+asmlinkage long compat_sys_bdflush(int func, long data);
+asmlinkage long compat_sys_sysfs(int option,
+				unsigned long arg1, unsigned long arg2);
+asmlinkage long compat_sys_llseek(unsigned int fd, unsigned long offset_high,
+			unsigned long offset_low, loff_t __user *result,
+			unsigned int whence);
+asmlinkage long compat_sys_msync(unsigned long start, size_t len, int flags);
+asmlinkage long compat_sys_mlock(unsigned long start, size_t len);
+asmlinkage long compat_sys_munlock(unsigned long start, size_t len);
+asmlinkage long compat_sys_sched_setparam(pid_t pid,
+					struct sched_param __user *param);
+asmlinkage long compat_sys_sched_getparam(pid_t pid,
+					struct sched_param __user *param);
+asmlinkage long compat_sys_sched_setscheduler(pid_t pid, int policy,
+					struct sched_param __user *param);
+asmlinkage long compat_sys_mremap(unsigned long addr,
+			   unsigned long old_len, unsigned long new_len,
+			   unsigned long flags, unsigned long new_addr);
+asmlinkage long compat_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
+				int timeout);
+asmlinkage long compat_sys_prctl(int option, unsigned long arg2, unsigned long arg3,
+			unsigned long arg4, unsigned long arg5);
+asmlinkage long compat_sys_getcwd(char __user *buf, unsigned long size);
+asmlinkage long compat_sys_capget(cap_user_header_t header,
+				cap_user_data_t dataptr);
+asmlinkage long compat_sys_capset(cap_user_header_t header,
+				const cap_user_data_t data);
+asmlinkage long compat_sys_lchown(const char __user *filename,
+				uid_t user, gid_t group);
+asmlinkage long compat_sys_getgroups(int gidsetsize, gid_t __user *grouplist);
+asmlinkage long compat_sys_setgroups(int gidsetsize, gid_t __user *grouplist);
+asmlinkage long compat_sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid);
+asmlinkage long compat_sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid);
+asmlinkage long compat_sys_chown(const char __user *filename,
+				uid_t user, gid_t group);
+asmlinkage long compat_sys_pivot_root(const char __user *new_root,
+				const char __user *put_old);
+asmlinkage long compat_sys_mincore(unsigned long start, size_t len,
+				unsigned char __user * vec);
+asmlinkage long compat_sys_madvise(unsigned long start, size_t len, int behavior);
+asmlinkage long compat_sys_setxattr(const char __user *path, const char __user *name,
+			     const void __user *value, size_t size, int flags);
+asmlinkage long compat_sys_lsetxattr(const char __user *path, const char __user *name,
+			      const void __user *value, size_t size, int flags);
+asmlinkage long compat_sys_fsetxattr(int fd, const char __user *name,
+			      const void __user *value, size_t size, int flags);
+asmlinkage long compat_sys_getdents64(unsigned int fd,
+				struct linux_dirent64 __user *dirent,
+				unsigned int count);
+asmlinkage long compat_sys_getxattr(const char __user *path, const char __user *name,
+			     void __user *value, size_t size);
+asmlinkage long compat_sys_lgetxattr(const char __user *path, const char __user *name,
+			      void __user *value, size_t size);
+asmlinkage long compat_sys_fgetxattr(int fd, const char __user *name,
+			      void __user *value, size_t size);
+asmlinkage long compat_sys_listxattr(const char __user *path, char __user *list,
+			      size_t size);
+asmlinkage long compat_sys_llistxattr(const char __user *path, char __user *list,
+			       size_t size);
+asmlinkage long compat_sys_flistxattr(int fd, char __user *list, size_t size);
+asmlinkage long compat_sys_listxattr(const char __user *path, char __user *list,
+			      size_t size);
+asmlinkage long compat_sys_llistxattr(const char __user *path, char __user *list,
+			       size_t size);
+asmlinkage long compat_sys_flistxattr(int fd, char __user *list, size_t size);
+asmlinkage long compat_sys_removexattr(const char __user *path,
+				const char __user *name);
+asmlinkage long compat_sys_lremovexattr(const char __user *path,
+				 const char __user *name);
+asmlinkage long compat_sys_fremovexattr(int fd, const char __user *name);
+asmlinkage long compat_sys_set_tid_address(int __user *tidptr);
+asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd,
+				struct epoll_event __user *event);
+asmlinkage long compat_sys_epoll_wait(int epfd, struct epoll_event __user *events,
+				int maxevents, int timeout);
+asmlinkage long compat_sys_io_destroy(aio_context_t ctx);
+asmlinkage long compat_sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
+			      struct io_event __user *result);
+asmlinkage long compat_sys_mq_unlink(const char __user *name);
+asmlinkage long compat_sys_add_key(const char __user *_type,
+			    const char __user *_description,
+			    const void __user *_payload,
+			    size_t plen,
+			    key_serial_t destringid);
+asmlinkage long compat_sys_request_key(const char __user *_type,
+				const char __user *_description,
+				const char __user *_callout_info,
+				key_serial_t destringid);
+asmlinkage long compat_sys_remap_file_pages(unsigned long start, unsigned long size,
+			unsigned long prot, unsigned long pgoff,
+			unsigned long flags);
+asmlinkage long compat_sys_inotify_add_watch(int fd, const char __user *path,
+					u32 mask);
+asmlinkage long compat_sys_mknodat(int dfd, const char __user * filename, umode_t mode,
+			    unsigned dev);
+asmlinkage long compat_sys_mkdirat(int dfd, const char __user * pathname, umode_t mode);
+asmlinkage long compat_sys_fchownat(int dfd, const char __user *filename, uid_t user,
+			     gid_t group, int flag);
+asmlinkage long compat_sys_unlinkat(int dfd, const char __user * pathname, int flag);
+asmlinkage long compat_sys_renameat(int olddfd, const char __user * oldname,
+			     int newdfd, const char __user * newname);
+asmlinkage long compat_sys_symlinkat(const char __user * oldname,
+			      int newdfd, const char __user * newname);
+asmlinkage long compat_sys_linkat(int olddfd, const char __user *oldname,
+			   int newdfd, const char __user *newname, int flags);
+asmlinkage long compat_sys_readlinkat(int dfd, const char __user *path, char __user *buf,
+			       int bufsiz);
+asmlinkage long compat_sys_fchmodat(int dfd, const char __user * filename,
+			     umode_t mode);
+asmlinkage long compat_sys_faccessat(int dfd, const char __user *filename, int mode);
+asmlinkage long compat_sys_unshare(unsigned long unshare_flags);
+asmlinkage long compat_sys_splice(int fd_in, loff_t __user *off_in,
+			   int fd_out, loff_t __user *off_out,
+			   size_t len, unsigned int flags);
+asmlinkage long compat_sys_tee(int fdin, int fdout, size_t len, unsigned int flags);
+asmlinkage long compat_sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
+asmlinkage long compat_sys_pipe2(int __user *fildes, int flags);
+asmlinkage long compat_sys_perf_event_open(
+		struct perf_event_attr __user *attr_uptr,
+		pid_t pid, int cpu, int group_fd, unsigned long flags);
+
+#ifdef CONFIG_CLONE_BACKWARDS
+asmlinkage long compat_sys_clone(unsigned long, unsigned long, int __user *, unsigned long,
+	       int __user *);
+#else
+#ifdef CONFIG_CLONE_BACKWARDS3
+asmlinkage long compat_sys_clone(unsigned long, unsigned long, int, int __user *,
+			  int __user *, unsigned long);
+#else
+asmlinkage long compat_sys_clone(unsigned long, unsigned long, int __user *,
+	       int __user *, unsigned long);
+#endif
+#endif
+
+asmlinkage long compat_sys_prlimit64(pid_t pid, unsigned int resource,
+				const struct rlimit64 __user *new_rlim,
+				struct rlimit64 __user *old_rlim);
+asmlinkage long compat_sys_name_to_handle_at(int dfd, const char __user *name,
+				      struct file_handle __user *handle,
+				      int __user *mnt_id, int flag);
+asmlinkage long compat_sys_kcmp(pid_t pid1, pid_t pid2, int type,
+			 unsigned long idx1, unsigned long idx2);
+asmlinkage long compat_sys_finit_module(int fd, const char __user *uargs, int flags);
+asmlinkage long compat_sys_sched_setattr(pid_t pid,
+					struct sched_attr __user *attr,
+					unsigned int flags);
+asmlinkage long compat_sys_sched_getattr(pid_t pid,
+					struct sched_attr __user *attr,
+					unsigned int size,
+					unsigned int flags);
+asmlinkage long compat_sys_renameat2(int olddfd, const char __user *oldname,
+			      int newdfd, const char __user *newname,
+			      unsigned int flags);
+asmlinkage long compat_sys_seccomp(unsigned int op, unsigned int flags,
+			    const char __user *uargs);
+asmlinkage long compat_sys_getrandom(char __user *buf, size_t count,
+			      unsigned int flags);
+asmlinkage long compat_sys_memfd_create(const char __user *uname_ptr, unsigned int flags);
+asmlinkage long compat_sys_bpf(int cmd, union bpf_attr *attr, unsigned int size);
+asmlinkage long compat_sys_socketpair(int, int, int, int __user *);
+asmlinkage long compat_sys_bind(int, struct sockaddr __user *, int);
+asmlinkage long compat_sys_connect(int, struct sockaddr __user *, int);
+asmlinkage long compat_sys_accept4(int, struct sockaddr __user *, int __user *, int);
+asmlinkage long compat_sys_getsockname(int, struct sockaddr __user *, int __user *);
+asmlinkage long compat_sys_getpeername(int, struct sockaddr __user *, int __user *);
+asmlinkage long compat_sys_sendto(int, void __user *, size_t, unsigned,
+				struct sockaddr __user *, int);
+asmlinkage long compat_sys_mlock2(unsigned long start, size_t len, int flags);
+
+asmlinkage long compat_sys_copy_file_range(int fd_in, loff_t __user *off_in,
+				    int fd_out, loff_t __user *off_out,
+				    size_t len, unsigned int flags);
+
 #endif /* CONFIG_COMPAT_WRAPPER */
 
 #endif /* _LINUX_COMPAT_H */
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index f10a316..01d43b0 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -36,43 +36,43 @@
 #define __NR_io_setup 0
 __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
 #define __NR_io_destroy 1
-__SYSCALL(__NR_io_destroy, sys_io_destroy)
+__SC_WRAP(__NR_io_destroy, sys_io_destroy)
 #define __NR_io_submit 2
 __SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
 #define __NR_io_cancel 3
-__SYSCALL(__NR_io_cancel, sys_io_cancel)
+__SC_WRAP(__NR_io_cancel, sys_io_cancel)
 #define __NR_io_getevents 4
 __SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
 
 /* fs/xattr.c */
 #define __NR_setxattr 5
-__SYSCALL(__NR_setxattr, sys_setxattr)
+__SC_WRAP(__NR_setxattr, sys_setxattr)
 #define __NR_lsetxattr 6
-__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
+__SC_WRAP(__NR_lsetxattr, sys_lsetxattr)
 #define __NR_fsetxattr 7
-__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
+__SC_WRAP(__NR_fsetxattr, sys_fsetxattr)
 #define __NR_getxattr 8
-__SYSCALL(__NR_getxattr, sys_getxattr)
+__SC_WRAP(__NR_getxattr, sys_getxattr)
 #define __NR_lgetxattr 9
-__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
+__SC_WRAP(__NR_lgetxattr, sys_lgetxattr)
 #define __NR_fgetxattr 10
-__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
+__SC_WRAP(__NR_fgetxattr, sys_fgetxattr)
 #define __NR_listxattr 11
-__SYSCALL(__NR_listxattr, sys_listxattr)
+__SC_WRAP(__NR_listxattr, sys_listxattr)
 #define __NR_llistxattr 12
-__SYSCALL(__NR_llistxattr, sys_llistxattr)
+__SC_WRAP(__NR_llistxattr, sys_llistxattr)
 #define __NR_flistxattr 13
-__SYSCALL(__NR_flistxattr, sys_flistxattr)
+__SC_WRAP(__NR_flistxattr, sys_flistxattr)
 #define __NR_removexattr 14
-__SYSCALL(__NR_removexattr, sys_removexattr)
+__SC_WRAP(__NR_removexattr, sys_removexattr)
 #define __NR_lremovexattr 15
-__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
+__SC_WRAP(__NR_lremovexattr, sys_lremovexattr)
 #define __NR_fremovexattr 16
-__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
+__SC_WRAP(__NR_fremovexattr, sys_fremovexattr)
 
 /* fs/dcache.c */
 #define __NR_getcwd 17
-__SYSCALL(__NR_getcwd, sys_getcwd)
+__SC_WRAP(__NR_getcwd, sys_getcwd)
 
 /* fs/cookies.c */
 #define __NR_lookup_dcookie 18
@@ -86,7 +86,7 @@ __SYSCALL(__NR_eventfd2, sys_eventfd2)
 #define __NR_epoll_create1 20
 __SYSCALL(__NR_epoll_create1, sys_epoll_create1)
 #define __NR_epoll_ctl 21
-__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
+__SC_WRAP(__NR_epoll_ctl, sys_epoll_ctl)
 #define __NR_epoll_pwait 22
 __SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
 
@@ -102,7 +102,7 @@ __SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
 #define __NR_inotify_init1 26
 __SYSCALL(__NR_inotify_init1, sys_inotify_init1)
 #define __NR_inotify_add_watch 27
-__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
+__SC_WRAP(__NR_inotify_add_watch, sys_inotify_add_watch)
 #define __NR_inotify_rm_watch 28
 __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
 
@@ -122,17 +122,17 @@ __SYSCALL(__NR_flock, sys_flock)
 
 /* fs/namei.c */
 #define __NR_mknodat 33
-__SYSCALL(__NR_mknodat, sys_mknodat)
+__SC_WRAP(__NR_mknodat, sys_mknodat)
 #define __NR_mkdirat 34
-__SYSCALL(__NR_mkdirat, sys_mkdirat)
+__SC_WRAP(__NR_mkdirat, sys_mkdirat)
 #define __NR_unlinkat 35
-__SYSCALL(__NR_unlinkat, sys_unlinkat)
+__SC_WRAP(__NR_unlinkat, sys_unlinkat)
 #define __NR_symlinkat 36
-__SYSCALL(__NR_symlinkat, sys_symlinkat)
+__SC_WRAP(__NR_symlinkat, sys_symlinkat)
 #define __NR_linkat 37
-__SYSCALL(__NR_linkat, sys_linkat)
+__SC_WRAP(__NR_linkat, sys_linkat)
 #define __NR_renameat 38
-__SYSCALL(__NR_renameat, sys_renameat)
+__SC_WRAP(__NR_renameat, sys_renameat)
 
 /* fs/namespace.c */
 #define __NR_umount2 39
@@ -140,7 +140,7 @@ __SYSCALL(__NR_umount2, sys_umount)
 #define __NR_mount 40
 __SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
 #define __NR_pivot_root 41
-__SYSCALL(__NR_pivot_root, sys_pivot_root)
+__SC_WRAP(__NR_pivot_root, sys_pivot_root)
 
 /* fs/nfsctl.c */
 #define __NR_nfsservctl 42
@@ -163,23 +163,23 @@ __SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
 #define __NR_fallocate 47
 __SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
 #define __NR_faccessat 48
-__SYSCALL(__NR_faccessat, sys_faccessat)
+__SC_WRAP(__NR_faccessat, sys_faccessat)
 #define __NR_chdir 49
-__SYSCALL(__NR_chdir, sys_chdir)
+__SC_WRAP(__NR_chdir, sys_chdir)
 #define __NR_fchdir 50
 __SYSCALL(__NR_fchdir, sys_fchdir)
 #define __NR_chroot 51
-__SYSCALL(__NR_chroot, sys_chroot)
+__SC_WRAP(__NR_chroot, sys_chroot)
 #define __NR_fchmod 52
 __SYSCALL(__NR_fchmod, sys_fchmod)
 #define __NR_fchmodat 53
-__SYSCALL(__NR_fchmodat, sys_fchmodat)
+__SC_WRAP(__NR_fchmodat, sys_fchmodat)
 #define __NR_fchownat 54
-__SYSCALL(__NR_fchownat, sys_fchownat)
+__SC_WRAP(__NR_fchownat, sys_fchownat)
 #define __NR_fchown 55
 __SYSCALL(__NR_fchown, sys_fchown)
 #define __NR_openat 56
-__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
+__SYSCALL(__NR_openat, sys_openat)
 #define __NR_close 57
 __SYSCALL(__NR_close, sys_close)
 #define __NR_vhangup 58
@@ -187,11 +187,11 @@ __SYSCALL(__NR_vhangup, sys_vhangup)
 
 /* fs/pipe.c */
 #define __NR_pipe2 59
-__SYSCALL(__NR_pipe2, sys_pipe2)
+__SC_WRAP(__NR_pipe2, sys_pipe2)
 
 /* fs/quota.c */
 #define __NR_quotactl 60
-__SYSCALL(__NR_quotactl, sys_quotactl)
+__SC_WRAP(__NR_quotactl, sys_quotactl)
 
 /* fs/readdir.c */
 #define __NR_getdents64 61
@@ -236,13 +236,13 @@ __SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
 #define __NR_vmsplice 75
 __SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
 #define __NR_splice 76
-__SYSCALL(__NR_splice, sys_splice)
+__SC_WRAP(__NR_splice, sys_splice)
 #define __NR_tee 77
-__SYSCALL(__NR_tee, sys_tee)
+__SC_WRAP(__NR_tee, sys_tee)
 
 /* fs/stat.c */
 #define __NR_readlinkat 78
-__SYSCALL(__NR_readlinkat, sys_readlinkat)
+__SC_WRAP(__NR_readlinkat, sys_readlinkat)
 #define __NR3264_fstatat 79
 __SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
 #define __NR3264_fstat 80
@@ -281,13 +281,13 @@ __SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
 
 /* kernel/acct.c */
 #define __NR_acct 89
-__SYSCALL(__NR_acct, sys_acct)
+__SC_WRAP(__NR_acct, sys_acct)
 
 /* kernel/capability.c */
 #define __NR_capget 90
-__SYSCALL(__NR_capget, sys_capget)
+__SC_WRAP(__NR_capget, sys_capget)
 #define __NR_capset 91
-__SYSCALL(__NR_capset, sys_capset)
+__SC_WRAP(__NR_capset, sys_capset)
 
 /* kernel/exec_domain.c */
 #define __NR_personality 92
@@ -303,9 +303,9 @@ __SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
 
 /* kernel/fork.c */
 #define __NR_set_tid_address 96
-__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
+__SC_WRAP(__NR_set_tid_address, sys_set_tid_address)
 #define __NR_unshare 97
-__SYSCALL(__NR_unshare, sys_unshare)
+__SC_WRAP(__NR_unshare, sys_unshare)
 
 /* kernel/futex.c */
 #define __NR_futex 98
@@ -333,9 +333,9 @@ __SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
 
 /* kernel/module.c */
 #define __NR_init_module 105
-__SYSCALL(__NR_init_module, sys_init_module)
+__SC_WRAP(__NR_init_module, sys_init_module)
 #define __NR_delete_module 106
-__SYSCALL(__NR_delete_module, sys_delete_module)
+__SC_WRAP(__NR_delete_module, sys_delete_module)
 
 /* kernel/posix-timers.c */
 #define __NR_timer_create 107
@@ -360,7 +360,7 @@ __SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
 
 /* kernel/printk.c */
 #define __NR_syslog 116
-__SYSCALL(__NR_syslog, sys_syslog)
+__SC_WRAP(__NR_syslog, sys_syslog)
 
 /* kernel/ptrace.c */
 #define __NR_ptrace 117
@@ -368,13 +368,13 @@ __SYSCALL(__NR_ptrace, sys_ptrace)
 
 /* kernel/sched/core.c */
 #define __NR_sched_setparam 118
-__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
+__SC_WRAP(__NR_sched_setparam, sys_sched_setparam)
 #define __NR_sched_setscheduler 119
-__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
+__SC_WRAP(__NR_sched_setscheduler, sys_sched_setscheduler)
 #define __NR_sched_getscheduler 120
 __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
 #define __NR_sched_getparam 121
-__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
+__SC_WRAP(__NR_sched_getparam, sys_sched_getparam)
 #define __NR_sched_setaffinity 122
 __SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
 	  compat_sys_sched_setaffinity)
@@ -425,7 +425,7 @@ __SYSCALL(__NR_setpriority, sys_setpriority)
 #define __NR_getpriority 141
 __SYSCALL(__NR_getpriority, sys_getpriority)
 #define __NR_reboot 142
-__SYSCALL(__NR_reboot, sys_reboot)
+__SC_WRAP(__NR_reboot, sys_reboot)
 #define __NR_setregid 143
 __SYSCALL(__NR_setregid, sys_setregid)
 #define __NR_setgid 144
@@ -437,11 +437,11 @@ __SYSCALL(__NR_setuid, sys_setuid)
 #define __NR_setresuid 147
 __SYSCALL(__NR_setresuid, sys_setresuid)
 #define __NR_getresuid 148
-__SYSCALL(__NR_getresuid, sys_getresuid)
+__SC_WRAP(__NR_getresuid, sys_getresuid)
 #define __NR_setresgid 149
 __SYSCALL(__NR_setresgid, sys_setresgid)
 #define __NR_getresgid 150
-__SYSCALL(__NR_getresgid, sys_getresgid)
+__SC_WRAP(__NR_getresgid, sys_getresgid)
 #define __NR_setfsuid 151
 __SYSCALL(__NR_setfsuid, sys_setfsuid)
 #define __NR_setfsgid 152
@@ -457,15 +457,15 @@ __SYSCALL(__NR_getsid, sys_getsid)
 #define __NR_setsid 157
 __SYSCALL(__NR_setsid, sys_setsid)
 #define __NR_getgroups 158
-__SYSCALL(__NR_getgroups, sys_getgroups)
+__SC_WRAP(__NR_getgroups, sys_getgroups)
 #define __NR_setgroups 159
-__SYSCALL(__NR_setgroups, sys_setgroups)
+__SC_WRAP(__NR_setgroups, sys_setgroups)
 #define __NR_uname 160
-__SYSCALL(__NR_uname, sys_newuname)
+__SC_WRAP(__NR_uname, sys_newuname)
 #define __NR_sethostname 161
-__SYSCALL(__NR_sethostname, sys_sethostname)
+__SC_WRAP(__NR_sethostname, sys_sethostname)
 #define __NR_setdomainname 162
-__SYSCALL(__NR_setdomainname, sys_setdomainname)
+__SC_WRAP(__NR_setdomainname, sys_setdomainname)
 #define __NR_getrlimit 163
 __SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
 #define __NR_setrlimit 164
@@ -475,9 +475,9 @@ __SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
 #define __NR_umask 166
 __SYSCALL(__NR_umask, sys_umask)
 #define __NR_prctl 167
-__SYSCALL(__NR_prctl, sys_prctl)
+__SC_WRAP(__NR_prctl, sys_prctl)
 #define __NR_getcpu 168
-__SYSCALL(__NR_getcpu, sys_getcpu)
+__SC_WRAP(__NR_getcpu, sys_getcpu)
 
 /* kernel/time.c */
 #define __NR_gettimeofday 169
@@ -509,7 +509,7 @@ __SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
 #define __NR_mq_open 180
 __SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
 #define __NR_mq_unlink 181
-__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
+__SC_WRAP(__NR_mq_unlink, sys_mq_unlink)
 #define __NR_mq_timedsend 182
 __SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
 #define __NR_mq_timedreceive 183
@@ -554,21 +554,21 @@ __SYSCALL(__NR_shmdt, sys_shmdt)
 #define __NR_socket 198
 __SYSCALL(__NR_socket, sys_socket)
 #define __NR_socketpair 199
-__SYSCALL(__NR_socketpair, sys_socketpair)
+__SC_WRAP(__NR_socketpair, sys_socketpair)
 #define __NR_bind 200
-__SYSCALL(__NR_bind, sys_bind)
+__SC_WRAP(__NR_bind, sys_bind)
 #define __NR_listen 201
 __SYSCALL(__NR_listen, sys_listen)
 #define __NR_accept 202
 __SYSCALL(__NR_accept, sys_accept)
 #define __NR_connect 203
-__SYSCALL(__NR_connect, sys_connect)
+__SC_WRAP(__NR_connect, sys_connect)
 #define __NR_getsockname 204
-__SYSCALL(__NR_getsockname, sys_getsockname)
+__SC_WRAP(__NR_getsockname, sys_getsockname)
 #define __NR_getpeername 205
-__SYSCALL(__NR_getpeername, sys_getpeername)
+__SC_WRAP(__NR_getpeername, sys_getpeername)
 #define __NR_sendto 206
-__SYSCALL(__NR_sendto, sys_sendto)
+__SC_WRAP(__NR_sendto, sys_sendto)
 #define __NR_recvfrom 207
 __SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
 #define __NR_setsockopt 208
@@ -588,23 +588,23 @@ __SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
 
 /* mm/nommu.c, also with MMU */
 #define __NR_brk 214
-__SYSCALL(__NR_brk, sys_brk)
+__SC_WRAP(__NR_brk, sys_brk)
 #define __NR_munmap 215
-__SYSCALL(__NR_munmap, sys_munmap)
+__SC_WRAP(__NR_munmap, sys_munmap)
 #define __NR_mremap 216
-__SYSCALL(__NR_mremap, sys_mremap)
+__SC_WRAP(__NR_mremap, sys_mremap)
 
 /* security/keys/keyctl.c */
 #define __NR_add_key 217
-__SYSCALL(__NR_add_key, sys_add_key)
+__SC_WRAP(__NR_add_key, sys_add_key)
 #define __NR_request_key 218
-__SYSCALL(__NR_request_key, sys_request_key)
+__SC_WRAP(__NR_request_key, sys_request_key)
 #define __NR_keyctl 219
 __SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
 
 /* arch/example/kernel/sys_example.c */
 #define __NR_clone 220
-__SYSCALL(__NR_clone, sys_clone)
+__SC_WRAP(__NR_clone, sys_clone)
 #define __NR_execve 221
 __SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
 
@@ -617,27 +617,27 @@ __SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
 /* mm/, CONFIG_MMU only */
 #ifndef __ARCH_NOMMU
 #define __NR_swapon 224
-__SYSCALL(__NR_swapon, sys_swapon)
+__SC_WRAP(__NR_swapon, sys_swapon)
 #define __NR_swapoff 225
-__SYSCALL(__NR_swapoff, sys_swapoff)
+__SC_WRAP(__NR_swapoff, sys_swapoff)
 #define __NR_mprotect 226
-__SYSCALL(__NR_mprotect, sys_mprotect)
+__SC_WRAP(__NR_mprotect, sys_mprotect)
 #define __NR_msync 227
-__SYSCALL(__NR_msync, sys_msync)
+__SC_WRAP(__NR_msync, sys_msync)
 #define __NR_mlock 228
-__SYSCALL(__NR_mlock, sys_mlock)
+__SC_WRAP(__NR_mlock, sys_mlock)
 #define __NR_munlock 229
-__SYSCALL(__NR_munlock, sys_munlock)
+__SC_WRAP(__NR_munlock, sys_munlock)
 #define __NR_mlockall 230
 __SYSCALL(__NR_mlockall, sys_mlockall)
 #define __NR_munlockall 231
 __SYSCALL(__NR_munlockall, sys_munlockall)
 #define __NR_mincore 232
-__SYSCALL(__NR_mincore, sys_mincore)
+__SC_WRAP(__NR_mincore, sys_mincore)
 #define __NR_madvise 233
-__SYSCALL(__NR_madvise, sys_madvise)
+__SC_WRAP(__NR_madvise, sys_madvise)
 #define __NR_remap_file_pages 234
-__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
+__SC_WRAP(__NR_remap_file_pages, sys_remap_file_pages)
 #define __NR_mbind 235
 __SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
 #define __NR_get_mempolicy 236
@@ -654,9 +654,9 @@ __SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
 __SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
 	  compat_sys_rt_tgsigqueueinfo)
 #define __NR_perf_event_open 241
-__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
+__SC_WRAP(__NR_perf_event_open, sys_perf_event_open)
 #define __NR_accept4 242
-__SYSCALL(__NR_accept4, sys_accept4)
+__SC_WRAP(__NR_accept4, sys_accept4)
 #define __NR_recvmmsg 243
 __SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
 
@@ -669,16 +669,15 @@ __SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
 #define __NR_wait4 260
 __SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
 #define __NR_prlimit64 261
-__SYSCALL(__NR_prlimit64, sys_prlimit64)
+__SC_WRAP(__NR_prlimit64, sys_prlimit64)
 #define __NR_fanotify_init 262
 __SYSCALL(__NR_fanotify_init, sys_fanotify_init)
 #define __NR_fanotify_mark 263
 __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
 #define __NR_name_to_handle_at         264
-__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
+__SC_WRAP(__NR_name_to_handle_at, sys_name_to_handle_at)
 #define __NR_open_by_handle_at         265
-__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
-	  compat_sys_open_by_handle_at)
+__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
 #define __NR_clock_adjtime 266
 __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
 #define __NR_syncfs 267
@@ -694,23 +693,23 @@ __SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
 __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
           compat_sys_process_vm_writev)
 #define __NR_kcmp 272
-__SYSCALL(__NR_kcmp, sys_kcmp)
+__SC_WRAP(__NR_kcmp, sys_kcmp)
 #define __NR_finit_module 273
-__SYSCALL(__NR_finit_module, sys_finit_module)
+__SC_WRAP(__NR_finit_module, sys_finit_module)
 #define __NR_sched_setattr 274
-__SYSCALL(__NR_sched_setattr, sys_sched_setattr)
+__SC_WRAP(__NR_sched_setattr, sys_sched_setattr)
 #define __NR_sched_getattr 275
-__SYSCALL(__NR_sched_getattr, sys_sched_getattr)
+__SC_WRAP(__NR_sched_getattr, sys_sched_getattr)
 #define __NR_renameat2 276
-__SYSCALL(__NR_renameat2, sys_renameat2)
+__SC_WRAP(__NR_renameat2, sys_renameat2)
 #define __NR_seccomp 277
-__SYSCALL(__NR_seccomp, sys_seccomp)
+__SC_WRAP(__NR_seccomp, sys_seccomp)
 #define __NR_getrandom 278
-__SYSCALL(__NR_getrandom, sys_getrandom)
+__SC_WRAP(__NR_getrandom, sys_getrandom)
 #define __NR_memfd_create 279
-__SYSCALL(__NR_memfd_create, sys_memfd_create)
+__SC_WRAP(__NR_memfd_create, sys_memfd_create)
 #define __NR_bpf 280
-__SYSCALL(__NR_bpf, sys_bpf)
+__SC_WRAP(__NR_bpf, sys_bpf)
 #define __NR_execveat 281
 __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
 #define __NR_userfaultfd 282
@@ -718,9 +717,9 @@ __SYSCALL(__NR_userfaultfd, sys_userfaultfd)
 #define __NR_membarrier 283
 __SYSCALL(__NR_membarrier, sys_membarrier)
 #define __NR_mlock2 284
-__SYSCALL(__NR_mlock2, sys_mlock2)
+__SC_WRAP(__NR_mlock2, sys_mlock2)
 #define __NR_copy_file_range 285
-__SYSCALL(__NR_copy_file_range, sys_copy_file_range)
+__SC_WRAP(__NR_copy_file_range, sys_copy_file_range)
 
 #undef __NR_syscalls
 #define __NR_syscalls 286
@@ -737,29 +736,29 @@ __SYSCALL(__NR_copy_file_range, sys_copy_file_range)
 #define __NR_open 1024
 __SYSCALL(__NR_open, sys_open)
 #define __NR_link 1025
-__SYSCALL(__NR_link, sys_link)
+__SC_WRAP(__NR_link, sys_link)
 #define __NR_unlink 1026
-__SYSCALL(__NR_unlink, sys_unlink)
+__SC_WRAP(__NR_unlink, sys_unlink)
 #define __NR_mknod 1027
-__SYSCALL(__NR_mknod, sys_mknod)
+__SC_WRAP(__NR_mknod, sys_mknod)
 #define __NR_chmod 1028
-__SYSCALL(__NR_chmod, sys_chmod)
+__SC_WRAP(__NR_chmod, sys_chmod)
 #define __NR_chown 1029
-__SYSCALL(__NR_chown, sys_chown)
+__SC_WRAP(__NR_chown, sys_chown)
 #define __NR_mkdir 1030
-__SYSCALL(__NR_mkdir, sys_mkdir)
+__SC_WRAP(__NR_mkdir, sys_mkdir)
 #define __NR_rmdir 1031
-__SYSCALL(__NR_rmdir, sys_rmdir)
+__SC_WRAP(__NR_rmdir, sys_rmdir)
 #define __NR_lchown 1032
-__SYSCALL(__NR_lchown, sys_lchown)
+__SC_WRAP(__NR_lchown, sys_lchown)
 #define __NR_access 1033
-__SYSCALL(__NR_access, sys_access)
+__SC_WRAP(__NR_access, sys_access)
 #define __NR_rename 1034
-__SYSCALL(__NR_rename, sys_rename)
+__SC_WRAP(__NR_rename, sys_rename)
 #define __NR_readlink 1035
-__SYSCALL(__NR_readlink, sys_readlink)
+__SC_WRAP(__NR_readlink, sys_readlink)
 #define __NR_symlink 1036
-__SYSCALL(__NR_symlink, sys_symlink)
+__SC_WRAP(__NR_symlink, sys_symlink)
 #define __NR_utimes 1037
 __SYSCALL(__NR_utimes, sys_utimes)
 #define __NR3264_stat 1038
@@ -773,7 +772,7 @@ __SC_3264(__NR3264_lstat, sys_lstat64, sys_newlstat)
 
 #ifdef __ARCH_WANT_SYSCALL_NO_FLAGS
 #define __NR_pipe 1040
-__SYSCALL(__NR_pipe, sys_pipe)
+__SC_WRAP(__NR_pipe, sys_pipe)
 #define __NR_dup2 1041
 __SYSCALL(__NR_dup2, sys_dup2)
 #define __NR_epoll_create 1042
@@ -843,7 +842,7 @@ __SYSCALL(__NR_time, sys_time)
 __SYSCALL(__NR_utime, sys_utime)
 
 #define __NR_creat 1064
-__SYSCALL(__NR_creat, sys_creat)
+__SC_WRAP(__NR_creat, sys_creat)
 #define __NR_getdents 1065
 #define __ARCH_WANT_SYS_GETDENTS
 __SYSCALL(__NR_getdents, sys_getdents)
@@ -853,9 +852,9 @@ __SYSCALL(__NR_futimesat, sys_futimesat)
 #define __ARCH_WANT_SYS_SELECT
 __SYSCALL(__NR_select, sys_select)
 #define __NR_poll 1068
-__SYSCALL(__NR_poll, sys_poll)
+__SC_WRAP(__NR_poll, sys_poll)
 #define __NR_epoll_wait 1069
-__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
+__SC_WRAP(__NR_epoll_wait, sys_epoll_wait)
 #define __NR_ustat 1070
 __SYSCALL(__NR_ustat, sys_ustat)
 #define __NR_vfork 1071
@@ -867,12 +866,12 @@ __SYSCALL(__NR_recv, sys_recv)
 #define __NR_send 1074
 __SYSCALL(__NR_send, sys_send)
 #define __NR_bdflush 1075
-__SYSCALL(__NR_bdflush, sys_bdflush)
+__SC_WRAP(__NR_bdflush, sys_bdflush)
 #define __NR_umount 1076
-__SYSCALL(__NR_umount, sys_oldumount)
+__SC_WRAP(__NR_umount, sys_oldumount)
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __NR_uselib 1077
-__SYSCALL(__NR_uselib, sys_uselib)
+__SC_WRAP(__NR_uselib, sys_uselib)
 #define __NR__sysctl 1078
 __SYSCALL(__NR__sysctl, sys_sysctl)
 
-- 
2.5.0

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

* [PATCH 06/25] compat ABI: use non-compat openat and open_by_handle_at variants
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (4 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 05/25] all: wrap needed syscalls in generic unistd Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 07/25] 32-bit ABI: introduce ARCH_32BIT_OFF_T config option Yury Norov
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

The only difference is that non-compat version forces O_LARGEFILE,
and it should be the default behaviour for all architectures, as
we don't support 32-bit off_t. The only exception is tile32, that
continues with compat version of syscalls.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Chris Metcalf <cmetcalf@ezchip.com> [for tile]
---
 arch/tile/kernel/compat.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
index 4912084..489ae19 100644
--- a/arch/tile/kernel/compat.c
+++ b/arch/tile/kernel/compat.c
@@ -94,6 +94,9 @@ COMPAT_SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned int, offset_high,
 #define compat_sys_readahead sys32_readahead
 #define sys_llseek compat_sys_llseek
 
+#define sys_openat		compat_sys_openat
+#define sys_open_by_handle_at	compat_sys_open_by_handle_at
+
 /* Call the assembly trampolines where necessary. */
 #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
 #define sys_clone _sys_clone
-- 
2.5.0

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

* [PATCH 07/25] 32-bit ABI: introduce ARCH_32BIT_OFF_T config option
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (5 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 06/25] compat ABI: use non-compat openat and open_by_handle_at variants Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 08/25] arm64: ilp32: add documentation on the ILP32 ABI for ARM64 Yury Norov
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

All new 32-bit architectures should have 64-bit off_t type, but existing
architectures has 32-bit ones.

To handle it, new config option is added to arch/Kconfig that defaults
ARCH_32BIT_OFF_T to be disabled for non-64 bit architectures. All existing
32-bit architectures enable it explicitly here.

New option affects force_o_largefile() behaviour. Namely, if off_t is
64-bits long, we have no reason to reject user to open big files.

Note that even if architectures has only 64-bit off_t in the kernel
(arc, c6x, h8300, hexagon, metag, nios2, openrisc, tile32 and unicore32),
a libc may use 32-bit off_t, and therefore want to limit the file size
to 4GB unless specified differently in the open flags.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de> (For the x86 part)
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/Kconfig            | 4 ++++
 arch/arc/Kconfig        | 1 +
 arch/arm/Kconfig        | 1 +
 arch/blackfin/Kconfig   | 1 +
 arch/cris/Kconfig       | 1 +
 arch/frv/Kconfig        | 1 +
 arch/h8300/Kconfig      | 1 +
 arch/hexagon/Kconfig    | 1 +
 arch/m32r/Kconfig       | 1 +
 arch/m68k/Kconfig       | 1 +
 arch/metag/Kconfig      | 1 +
 arch/microblaze/Kconfig | 1 +
 arch/mips/Kconfig       | 1 +
 arch/mn10300/Kconfig    | 1 +
 arch/nios2/Kconfig      | 1 +
 arch/openrisc/Kconfig   | 1 +
 arch/parisc/Kconfig     | 1 +
 arch/powerpc/Kconfig    | 1 +
 arch/score/Kconfig      | 1 +
 arch/sh/Kconfig         | 1 +
 arch/sparc/Kconfig      | 1 +
 arch/tile/Kconfig       | 1 +
 arch/unicore32/Kconfig  | 1 +
 arch/x86/Kconfig        | 1 +
 arch/x86/um/Kconfig     | 1 +
 arch/xtensa/Kconfig     | 1 +
 include/linux/fcntl.h   | 2 +-
 27 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 92fcbd4..a2b7cf3 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -230,6 +230,10 @@ config ARCH_THREAD_INFO_ALLOCATOR
 config ARCH_WANTS_DYNAMIC_TASK_STRUCT
 	bool
 
+config ARCH_32BIT_OFF_T
+	bool
+	depends on !64BIT
+
 config HAVE_REGS_AND_STACK_ACCESS_API
 	bool
 	help
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 208aae0..52e3f9b 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -9,6 +9,7 @@
 config ARC
 	def_bool y
 	select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
+	select ARCH_32BIT_OFF_T
 	select BUILDTIME_EXTABLE_SORT
 	select COMMON_CLK
 	select CLONE_BACKWARDS
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cdfa6c2..efe3ca2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,6 +1,7 @@
 config ARM
 	bool
 	default y
+	select ARCH_32BIT_OFF_T
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index a63c122..ef4368e 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -12,6 +12,7 @@ config RWSEM_XCHGADD_ALGORITHM
 
 config BLACKFIN
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DYNAMIC_FTRACE
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index e086f9e..5bc9203 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -50,6 +50,7 @@ config LOCKDEP_SUPPORT
 config CRIS
 	bool
 	default y
+	select ARCH_32BIT_OFF_T
 	select HAVE_IDE
 	select GENERIC_ATOMIC64
 	select HAVE_UID16
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index eefd9a4..2f14904 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -1,6 +1,7 @@
 config FRV
 	bool
 	default y
+	select ARCH_32BIT_OFF_T
 	select HAVE_IDE
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_PERF_EVENTS
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 986ea84..8c221f1 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -1,5 +1,6 @@
 config H8300
         def_bool y
+	select ARCH_32BIT_OFF_T
 	select GENERIC_ATOMIC64
 	select HAVE_UID16
 	select VIRT_TO_BUS
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 57298e7..df84602 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -3,6 +3,7 @@ comment "Linux Kernel Configuration for Hexagon"
 
 config HEXAGON
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select HAVE_OPROFILE
 	# Other pending projects/to-do items.
 	# select HAVE_REGS_AND_STACK_ACCESS_API
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index c82b292..7866bca 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -1,6 +1,7 @@
 config M32R
 	bool
 	default y
+	select ARCH_32BIT_OFF_T
 	select HAVE_IDE
 	select HAVE_OPROFILE
 	select INIT_ALL_POSSIBLE
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 498b567..e9897e4 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -1,6 +1,7 @@
 config M68K
 	bool
 	default y
+	select ARCH_32BIT_OFF_T
 	select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
 	select HAVE_IDE
 	select HAVE_AOUT if MMU
diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig
index a0fa88d..5b7620a 100644
--- a/arch/metag/Kconfig
+++ b/arch/metag/Kconfig
@@ -1,5 +1,6 @@
 config METAG
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select EMBEDDED
 	select GENERIC_ATOMIC64
 	select GENERIC_CLOCKEVENTS
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 3d793b5..bdb0f83 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -1,5 +1,6 @@
 config MICROBLAZE
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_WANT_IPC_PARSE_VERSION
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2018c2b..079a6d2 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1,6 +1,7 @@
 config MIPS
 	bool
 	default y
+	select ARCH_32BIT_OFF_T if !64BIT
 	select ARCH_SUPPORTS_UPROBES
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 06ddb55..bc1aae5 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -1,5 +1,6 @@
 config MN10300
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select HAVE_OPROFILE
 	select HAVE_UID16
 	select GENERIC_IRQ_SHOW
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 4375554..a38fc38 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -1,5 +1,6 @@
 config NIOS2
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select CLKSRC_OF
 	select GENERIC_ATOMIC64
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index e118c02..0271714 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -5,6 +5,7 @@
 
 config OPENRISC
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select OF
 	select OF_EARLY_FLATTREE
 	select IRQ_DOMAIN
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index bd3c873..a55a81b 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -1,5 +1,6 @@
 config PARISC
 	def_bool y
+	select ARCH_32BIT_OFF_T if !64BIT
 	select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select HAVE_IDE
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 7cd32c0..2c7a795 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -85,6 +85,7 @@ config ARCH_HAS_DMA_SET_COHERENT_MASK
 config PPC
 	bool
 	default y
+	select ARCH_32BIT_OFF_T if PPC32
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BINFMT_ELF
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index 366e1b5..bc7bc7a 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -2,6 +2,7 @@ menu "Machine selection"
 
 config SCORE
        def_bool y
+       select ARCH_32BIT_OFF_T
        select GENERIC_IRQ_SHOW
        select GENERIC_IOMAP
        select GENERIC_ATOMIC64
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 7ed20fc..2438390 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -52,6 +52,7 @@ config SUPERH
 
 config SUPERH32
 	def_bool ARCH = "sh"
+	select ARCH_32BIT_OFF_T
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
 	select HAVE_IOREMAP_PROT if MMU && !X2TLB
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 57ffaf2..c88b82d 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -45,6 +45,7 @@ config SPARC
 
 config SPARC32
 	def_bool !64BIT
+	select ARCH_32BIT_OFF_T
 	select GENERIC_ATOMIC64
 	select CLZ_TAB
 	select HAVE_UID16
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 8171930..f9d61e7 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -3,6 +3,7 @@
 
 config TILE
 	def_bool y
+	select ARCH_32BIT_OFF_T if !64BIT
 	select HAVE_PERF_EVENTS
 	select USE_PMC if PERF_EVENTS
 	select HAVE_DMA_API_DEBUG
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index e5602ee..b995104 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -1,6 +1,7 @@
 config UNICORE32
 	def_bool y
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
+	select ARCH_32BIT_OFF_T
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
 	select HAVE_MEMBLOCK
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2dc18605..3628b14 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -20,6 +20,7 @@ config X86
 	select ACPI_LEGACY_TABLES_LOOKUP	if ACPI
 	select ACPI_SYSTEM_POWER_STATES_SUPPORT	if ACPI
 	select ANON_INODES
+	select ARCH_32BIT_OFF_T			if X86_32
 	select ARCH_CLOCKSOURCE_DATA
 	select ARCH_DISCARD_MEMBLOCK
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index ed56a1c..8436bcd 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -21,6 +21,7 @@ config 64BIT
 config X86_32
 	def_bool !64BIT
 	select HAVE_AOUT
+	select ARCH_32BIT_OFF_T
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select MODULES_USE_ELF_REL
 	select CLONE_BACKWARDS
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index e832d3e..b68de31 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -3,6 +3,7 @@ config ZONE_DMA
 
 config XTENSA
 	def_bool y
+	select ARCH_32BIT_OFF_T
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 76ce329..46960a1 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -5,7 +5,7 @@
 
 
 #ifndef force_o_largefile
-#define force_o_largefile() (BITS_PER_LONG != 32)
+#define force_o_largefile() (!IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))
 #endif
 
 #if BITS_PER_LONG == 32
-- 
2.5.0

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

* [PATCH 08/25] arm64: ilp32: add documentation on the ILP32 ABI for ARM64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (6 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 07/25] 32-bit ABI: introduce ARCH_32BIT_OFF_T config option Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 09/25] arm64: ensure the kernel is compiled for LP64 Yury Norov
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Based on Andrew Pinski's patch-series.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 Documentation/arm64/ilp32.txt | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 Documentation/arm64/ilp32.txt

diff --git a/Documentation/arm64/ilp32.txt b/Documentation/arm64/ilp32.txt
new file mode 100644
index 0000000..15b5c83
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,13 @@
+ILP32 AARCH64 SYSCALL ABI
+=========================
+
+This document describes the ILP32 syscall ABI and where it differs
+from the generic compat linux syscall interface.
+
+Syscalls which normally would pass 64bit values as two arguments;
+now pass the 64bit value as one argument.
+
+struct rt_sigframe is redefined and contains struct compat_siginfo,
+as compat syscalls expects, and struct ilp32_sigframe, to handle
+AARCH64 register set and 32-bit userspace register representation.
+
-- 
2.5.0

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

* [PATCH 09/25] arm64: ensure the kernel is compiled for LP64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (7 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 08/25] arm64: ilp32: add documentation on the ILP32 ABI for ARM64 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig Yury Norov
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski, Philipp Tomsich

From: Andrew Pinski <apinski@cavium.com>

The kernel needs to be compiled as a LP64 binary for ARM64, even when
using a compiler that defaults to code-generation for the ILP32 ABI.
Consequently, we need to explicitly pass '-mabi=lp64' (supported on
gcc-4.9 and newer).

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/Makefile | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 354d754..29ebf23 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -35,14 +35,19 @@ KBUILD_CFLAGS	+= -fno-asynchronous-unwind-tables
 KBUILD_CFLAGS	+= $(call cc-option, -mpc-relative-literal-loads)
 KBUILD_AFLAGS	+= $(lseinstr)
 
+KBUILD_CFLAGS	+= $(call cc-option,-mabi=lp64)
+KBUILD_AFLAGS	+= $(call cc-option,-mabi=lp64)
+
 ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
 KBUILD_CPPFLAGS	+= -mbig-endian
 AS		+= -EB
 LD		+= -EB
+LDFLAGS		+= -maarch64linuxb
 else
 KBUILD_CPPFLAGS	+= -mlittle-endian
 AS		+= -EL
 LD		+= -EL
+LDFLAGS		+= -maarch64linux
 endif
 
 CHECKFLAGS	+= -D__aarch64__
-- 
2.5.0

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

* [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (8 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 09/25] arm64: ensure the kernel is compiled for LP64 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-14  3:20   ` Zhangjian (Bamvor)
  2016-04-05 22:08 ` [PATCH 11/25] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Yury Norov
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski, Philipp Tomsich

From: Andrew Pinski <apinski@cavium.com>

In this patchset  ILP32 ABI support is added. Additionally to AARCH32,
which is binary-compatible with ARM, ILP32 is (mostly) ABI-compatible.

>From now, AARCH32_EL0 (former COMPAT) config option means the support of
AARCH32 userspace, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and COMPAT indicates that one of them, or both, is enabled.

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4f43622..f923687 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -925,6 +925,10 @@ menu "Userspace binary formats"
 source "fs/Kconfig.binfmt"
 
 config COMPAT
+	def_bool y
+	depends on AARCH32_EL0
+
+config AARCH32_EL0
 	bool "Kernel support for 32-bit EL0"
 	depends on ARM64_4K_PAGES || EXPERT
 	select COMPAT_BINFMT_ELF
-- 
2.5.0

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

* [PATCH 11/25] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (9 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 12/25] arm64: compat: change config dependences to aarch32 Yury Norov
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski, Philipp Tomsich

From: Andrew Pinski <apinski@cavium.com>

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/include/asm/fpsimd.h      | 2 +-
 arch/arm64/include/asm/hwcap.h       | 4 ++--
 arch/arm64/include/asm/processor.h   | 6 +++---
 arch/arm64/include/asm/ptrace.h      | 2 +-
 arch/arm64/include/asm/signal32.h    | 6 ++++--
 arch/arm64/include/asm/unistd.h      | 2 +-
 arch/arm64/kernel/Makefile           | 2 +-
 arch/arm64/kernel/asm-offsets.c      | 2 +-
 arch/arm64/kernel/cpufeature.c       | 8 ++++----
 arch/arm64/kernel/cpuinfo.c          | 4 ++--
 arch/arm64/kernel/entry.S            | 6 +++---
 arch/arm64/kernel/head.S             | 2 +-
 arch/arm64/kernel/ptrace.c           | 8 ++++----
 arch/arm64/kernel/traps.c            | 2 +-
 arch/arm64/kernel/vdso.c             | 4 ++--
 drivers/clocksource/arm_arch_timer.c | 2 +-
 16 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 50f559f..63b19f1 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -52,7 +52,7 @@ struct fpsimd_partial_state {
 };
 
 
-#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+#if defined(__KERNEL__) && defined(CONFIG_AARCH32_EL0)
 /* Masks for extracting the FPSR and FPCR from the FPSCR */
 #define VFP_FPSCR_STAT_MASK	0xf800009f
 #define VFP_FPSCR_CTRL_MASK	0x07f79f00
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 400b80b..2c7fc5d 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -46,7 +46,7 @@
  */
 #define ELF_HWCAP		(elf_hwcap)
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define COMPAT_ELF_HWCAP	(compat_elf_hwcap)
 #define COMPAT_ELF_HWCAP2	(compat_elf_hwcap2)
 extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
@@ -54,7 +54,7 @@ extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
 
 enum {
 	CAP_HWCAP = 1,
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	CAP_COMPAT_HWCAP,
 	CAP_COMPAT_HWCAP2,
 #endif
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index cef1cf3..5bbdbb4 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -81,7 +81,7 @@ struct cpu_context {
 struct thread_struct {
 	struct cpu_context	cpu_context;	/* cpu context */
 	unsigned long		tp_value;	/* TLS register */
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	unsigned long		tp2_value;
 #endif
 	struct fpsimd_state	fpsimd_state;
@@ -90,7 +90,7 @@ struct thread_struct {
 	struct debug_info	debug;		/* debugging */
 };
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define task_user_tls(t)						\
 ({									\
 	unsigned long *__tls;						\
@@ -121,7 +121,7 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc,
 	regs->sp = sp;
 }
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 				       unsigned long sp)
 {
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index a307eb6..4c730c3 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -121,7 +121,7 @@ struct pt_regs {
 
 #define arch_has_single_step()	(1)
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define compat_thumb_mode(regs) \
 	(((regs)->pstate & COMPAT_PSR_T_BIT))
 #else
diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
index eeaa975..e68fcce 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -17,7 +17,9 @@
 #define __ASM_SIGNAL32_H
 
 #ifdef __KERNEL__
-#ifdef CONFIG_COMPAT
+
+#ifdef CONFIG_AARCH32_EL0
+
 #include <linux/compat.h>
 
 #define AARCH32_KERN_SIGRET_CODE_OFFSET	0x500
@@ -47,6 +49,6 @@ static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t
 static inline void compat_setup_restart_syscall(struct pt_regs *regs)
 {
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SIGNAL32_H */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 41e58fe..2971dea 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
 #define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 3793003..75dd250 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,7 +25,7 @@ OBJCOPYFLAGS := --prefix-symbols=__efistub_
 $(obj)/%.stub.o: $(obj)/%.o FORCE
 	$(call if_changed,objcopy)
 
-arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
+arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 3ae6b31..e229525 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -52,7 +52,7 @@ int main(void)
   DEFINE(S_X7,			offsetof(struct pt_regs, regs[7]));
   DEFINE(S_LR,			offsetof(struct pt_regs, regs[30]));
   DEFINE(S_SP,			offsetof(struct pt_regs, sp));
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
   DEFINE(S_COMPAT_SP,		offsetof(struct pt_regs, compat_sp));
 #endif
   DEFINE(S_PSTATE,		offsetof(struct pt_regs, pstate));
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 943f514..6f77412 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -32,7 +32,7 @@
 unsigned long elf_hwcap __read_mostly;
 EXPORT_SYMBOL_GPL(elf_hwcap);
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define COMPAT_ELF_HWCAP_DEFAULT	\
 				(COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\
 				 COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\
@@ -751,7 +751,7 @@ static const struct arm64_cpu_capabilities arm64_hwcaps[] = {
 	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_FPHP),
 	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_ASIMD),
 	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_ASIMDHP),
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
 	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
 	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
@@ -767,7 +767,7 @@ static void __init cap_set_hwcap(const struct arm64_cpu_capabilities *cap)
 	case CAP_HWCAP:
 		elf_hwcap |= cap->hwcap;
 		break;
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	case CAP_COMPAT_HWCAP:
 		compat_elf_hwcap |= (u32)cap->hwcap;
 		break;
@@ -790,7 +790,7 @@ static bool __maybe_unused cpus_have_hwcap(const struct arm64_cpu_capabilities *
 	case CAP_HWCAP:
 		rc = (elf_hwcap & cap->hwcap) != 0;
 		break;
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	case CAP_COMPAT_HWCAP:
 		rc = (compat_elf_hwcap & (u32)cap->hwcap) != 0;
 		break;
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 84c8684..32fb4f3 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -127,7 +127,7 @@ static int c_show(struct seq_file *m, void *v)
 		 */
 		seq_puts(m, "Features\t:");
 		if (personality(current->personality) == PER_LINUX32) {
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 			for (j = 0; compat_hwcap_str[j]; j++)
 				if (compat_elf_hwcap & (1 << j))
 					seq_printf(m, " %s", compat_hwcap_str[j]);
@@ -135,7 +135,7 @@ static int c_show(struct seq_file *m, void *v)
 			for (j = 0; compat_hwcap2_str[j]; j++)
 				if (compat_elf_hwcap2 & (1 << j))
 					seq_printf(m, " %s", compat_hwcap2_str[j]);
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 		} else {
 			for (j = 0; hwcap_str[j]; j++)
 				if (elf_hwcap & (1 << j))
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 12e8d2b..cf4d1ae 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -260,7 +260,7 @@ ENTRY(vectors)
 	ventry	el0_fiq_invalid			// FIQ 64-bit EL0
 	ventry	el0_error_invalid		// Error 64-bit EL0
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	ventry	el0_sync_compat			// Synchronous 32-bit EL0
 	ventry	el0_irq_compat			// IRQ 32-bit EL0
 	ventry	el0_fiq_invalid_compat		// FIQ 32-bit EL0
@@ -300,7 +300,7 @@ el0_error_invalid:
 	inv_entry 0, BAD_ERROR
 ENDPROC(el0_error_invalid)
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 el0_fiq_invalid_compat:
 	inv_entry 0, BAD_FIQ, 32
 ENDPROC(el0_fiq_invalid_compat)
@@ -462,7 +462,7 @@ el0_sync:
 	b.ge	el0_dbg
 	b	el0_inv
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	.align	6
 el0_sync_compat:
 	kernel_entry 0, 32
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 4203d5f..e407b08 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -598,7 +598,7 @@ CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
 	mov	x0, #0x33ff
 	msr	cptr_el2, x0			// Disable copro. traps to EL2
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	msr	hstr_el2, xzr			// Disable CP15 traps to EL2
 #endif
 
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 3f6cd5c..aa79e81 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -82,7 +82,7 @@ static void ptrace_hbptriggered(struct perf_event *bp,
 		.si_addr	= (void __user *)(bkpt->trigger),
 	};
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	int i;
 
 	if (!is_compat_task())
@@ -657,7 +657,7 @@ static const struct user_regset_view user_aarch64_view = {
 	.regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets)
 };
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #include <linux/compat.h>
 
 enum compat_regset {
@@ -1192,11 +1192,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	/*
 	 * Core dumping of 32-bit tasks or compat ptrace requests must use the
 	 * user_aarch32_view compatible with arm32. Native ptrace requests on
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index c539208..cdab14e 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -403,7 +403,7 @@ long compat_arm_syscall(struct pt_regs *regs);
 
 asmlinkage long do_ni_syscall(struct pt_regs *regs)
 {
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	long ret;
 	if (is_compat_task()) {
 		ret = compat_arm_syscall(regs);
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 97bc68f..26352a6 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -49,7 +49,7 @@ static union {
 } vdso_data_store __page_aligned_data;
 struct vdso_data *vdso_data = &vdso_data_store.data;
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 /*
  * Create and map the vectors page for AArch32 tasks.
  */
@@ -107,7 +107,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 
 	return PTR_ERR_OR_ZERO(ret);
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 
 static struct vm_special_mapping vdso_spec[2];
 
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5152b38..d5e699d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -321,7 +321,7 @@ static void arch_timer_evtstrm_enable(int divider)
 			| ARCH_TIMER_VIRT_EVT_EN;
 	arch_timer_set_cntkctl(cntkctl);
 	elf_hwcap |= HWCAP_EVTSTRM;
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
 #endif
 }
-- 
2.5.0

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

* [PATCH 12/25] arm64: compat: change config dependences to aarch32
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (10 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 11/25] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-22 15:58   ` Catalin Marinas
  2016-04-05 22:08 ` [PATCH 13/25] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64 Yury Norov
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Bamvor Jian Zhang

From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>

With the patches of ILP32, COMPAT is not equivalent to AARCH32 in EL0.
This patch fix this by updating the dependency from COMPAT to
AARCH32_EL0 for ARMV8_DEPRECATED and ARM64_ERRATUM_845719.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f923687..ebaf38a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -370,7 +370,7 @@ config ARM64_ERRATUM_834220
 
 config ARM64_ERRATUM_845719
 	bool "Cortex-A53: 845719: a load might read incorrect data"
-	depends on COMPAT
+	depends on AARCH32_EL0
 	default y
 	help
 	  This option adds an alternative code sequence to work around ARM
@@ -655,7 +655,7 @@ config FORCE_MAX_ZONEORDER
 
 menuconfig ARMV8_DEPRECATED
 	bool "Emulate deprecated/obsolete ARMv8 instructions"
-	depends on COMPAT
+	depends on AARCH32_EL0
 	help
 	  Legacy software support may require certain instructions
 	  that have been deprecated or obsoleted in the architecture.
-- 
2.5.0

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

* [PATCH 13/25] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (11 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 12/25] arm64: compat: change config dependences to aarch32 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 14/25] thread: move thread bits accessors to separated file Yury Norov
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Philipp Tomsich

From: Andrew Pinski <apinski@cavium.com>

Define __BITS_PER_LONG depending on the ABI used (i.e. check whether
__ILP32__ or __LP64__ is defined).  This is necessary for glibc to
determine the appropriate type definitions for the system call interface.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/include/uapi/asm/bitsperlong.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
index fce9c29..4265243 100644
--- a/arch/arm64/include/uapi/asm/bitsperlong.h
+++ b/arch/arm64/include/uapi/asm/bitsperlong.h
@@ -16,7 +16,14 @@
 #ifndef __ASM_BITSPERLONG_H
 #define __ASM_BITSPERLONG_H
 
-#define __BITS_PER_LONG 64
+#if defined(__LP64__)
+/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
+#  define __BITS_PER_LONG 64
+#elif defined(__ILP32__)
+#  define __BITS_PER_LONG 32
+#else
+#  error "Neither LP64 nor ILP32: unsupported ABI in asm/bitsperlong.h"
+#endif
 
 #include <asm-generic/bitsperlong.h>
 
-- 
2.5.0

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

* [PATCH 14/25] thread: move thread bits accessors to separated file
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (12 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 13/25] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 15/25] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat) Yury Norov
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

They may be accessed from low-level code, so isolating is a measure to
avoid circular dependencies in header files.

The exact reason for circular dependency is WARN_ON() macro added by Al
Viro in patch "set_restore_sigmask() is never called without SIGPENDING
(and never should be)" [edd63a27]

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 include/linux/thread_bits.h | 55 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/thread_info.h | 44 +-----------------------------------
 2 files changed, 56 insertions(+), 43 deletions(-)
 create mode 100644 include/linux/thread_bits.h

diff --git a/include/linux/thread_bits.h b/include/linux/thread_bits.h
new file mode 100644
index 0000000..0d05d16
--- /dev/null
+++ b/include/linux/thread_bits.h
@@ -0,0 +1,55 @@
+
+/* thread_bits.h: common low-level thread bits accessors */
+
+#ifndef _LINUX_THREAD_BITS_H
+#define _LINUX_THREAD_BITS_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/bitops.h>
+#include <asm/thread_info.h>
+
+/*
+ * flag set/clear/test wrappers
+ * - pass TIF_xxxx constants to these functions
+ */
+
+static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
+{
+	set_bit(flag, (unsigned long *)&ti->flags);
+}
+
+static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
+{
+	clear_bit(flag, (unsigned long *)&ti->flags);
+}
+
+static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
+{
+	return test_and_set_bit(flag, (unsigned long *)&ti->flags);
+}
+
+static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag)
+{
+	return test_and_clear_bit(flag, (unsigned long *)&ti->flags);
+}
+
+static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
+{
+	return test_bit(flag, (unsigned long *)&ti->flags);
+}
+
+#define set_thread_flag(flag) \
+	set_ti_thread_flag(current_thread_info(), flag)
+#define clear_thread_flag(flag) \
+	clear_ti_thread_flag(current_thread_info(), flag)
+#define test_and_set_thread_flag(flag) \
+	test_and_set_ti_thread_flag(current_thread_info(), flag)
+#define test_and_clear_thread_flag(flag) \
+	test_and_clear_ti_thread_flag(current_thread_info(), flag)
+#define test_thread_flag(flag) \
+	test_ti_thread_flag(current_thread_info(), flag)
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _LINUX_THREAD_BITS_H */
+
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index b4c2a48..b094aed 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -50,8 +50,7 @@ struct restart_block {
 
 extern long do_no_restart_syscall(struct restart_block *parm);
 
-#include <linux/bitops.h>
-#include <asm/thread_info.h>
+#include <linux/thread_bits.h>
 
 #ifdef __KERNEL__
 
@@ -62,47 +61,6 @@ extern long do_no_restart_syscall(struct restart_block *parm);
 # define THREADINFO_GFP		(GFP_KERNEL_ACCOUNT | __GFP_NOTRACK)
 #endif
 
-/*
- * flag set/clear/test wrappers
- * - pass TIF_xxxx constants to these functions
- */
-
-static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
-{
-	set_bit(flag, (unsigned long *)&ti->flags);
-}
-
-static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
-{
-	clear_bit(flag, (unsigned long *)&ti->flags);
-}
-
-static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
-{
-	return test_and_set_bit(flag, (unsigned long *)&ti->flags);
-}
-
-static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag)
-{
-	return test_and_clear_bit(flag, (unsigned long *)&ti->flags);
-}
-
-static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
-{
-	return test_bit(flag, (unsigned long *)&ti->flags);
-}
-
-#define set_thread_flag(flag) \
-	set_ti_thread_flag(current_thread_info(), flag)
-#define clear_thread_flag(flag) \
-	clear_ti_thread_flag(current_thread_info(), flag)
-#define test_and_set_thread_flag(flag) \
-	test_and_set_ti_thread_flag(current_thread_info(), flag)
-#define test_and_clear_thread_flag(flag) \
-	test_and_clear_ti_thread_flag(current_thread_info(), flag)
-#define test_thread_flag(flag) \
-	test_ti_thread_flag(current_thread_info(), flag)
-
 #define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)
 
 #if defined TIF_RESTORE_SIGMASK && !defined HAVE_SET_RESTORE_SIGMASK
-- 
2.5.0

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

* [PATCH 15/25] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (13 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 14/25] thread: move thread bits accessors to separated file Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-05-06 12:02   ` Zhangjian (Bamvor)
  2016-04-05 22:08 ` [PATCH 16/25] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64 Yury Norov
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Philipp Tomsich, Andrew Pinski

Based on patch of Andrew Pinski.

This patch introduces is_a32_compat_task and is_a32_thread so it is
easier to say this is a a32 specific thread or a generic compat thread/task.
Corresponding functions are located in <asm/is_compat.h> to avoid mess in
headers.

Some files include both <linux/compat.h> and <asm/compat.h>,
and this is wrong because <linux/compat.h> has <asm/compat.h> already
included. It was fixed too.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/include/asm/compat.h      | 19 ++----------
 arch/arm64/include/asm/elf.h         | 10 +++----
 arch/arm64/include/asm/ftrace.h      |  2 +-
 arch/arm64/include/asm/is_compat.h   | 58 ++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/memory.h      |  3 +-
 arch/arm64/include/asm/processor.h   |  5 ++--
 arch/arm64/include/asm/syscall.h     |  2 +-
 arch/arm64/include/asm/thread_info.h |  2 +-
 arch/arm64/kernel/hw_breakpoint.c    | 10 +++----
 arch/arm64/kernel/perf_regs.c        |  2 +-
 arch/arm64/kernel/process.c          |  7 ++---
 arch/arm64/kernel/ptrace.c           | 11 ++++---
 arch/arm64/kernel/signal.c           |  4 +--
 arch/arm64/kernel/traps.c            |  3 +-
 14 files changed, 91 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm64/include/asm/is_compat.h

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eb8432b..df2f72d 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -24,6 +24,8 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 
+#include <asm/is_compat.h>
+
 #define COMPAT_USER_HZ		100
 #ifdef __AARCH64EB__
 #define COMPAT_UTS_MACHINE	"armv8b\0\0"
@@ -298,23 +300,6 @@ struct compat_shmid64_ds {
 	compat_ulong_t __unused5;
 };
 
-static inline int is_compat_task(void)
-{
-	return test_thread_flag(TIF_32BIT);
-}
-
-static inline int is_compat_thread(struct thread_info *thread)
-{
-	return test_ti_thread_flag(thread, TIF_32BIT);
-}
-
-#else /* !CONFIG_COMPAT */
-
-static inline int is_compat_thread(struct thread_info *thread)
-{
-	return 0;
-}
-
 #endif /* CONFIG_COMPAT */
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 24ed037..b5437c5 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -16,6 +16,10 @@
 #ifndef __ASM_ELF_H
 #define __ASM_ELF_H
 
+#ifndef __ASSEMBLY__
+#include <linux/compat.h>
+#endif
+
 #include <asm/hwcap.h>
 
 /*
@@ -152,13 +156,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 				       int uses_interp);
 
 /* 1GB of VA */
-#ifdef CONFIG_COMPAT
-#define STACK_RND_MASK			(test_thread_flag(TIF_32BIT) ? \
+#define STACK_RND_MASK			(is_compat_task() ? \
 						0x7ff >> (PAGE_SHIFT - 12) : \
 						0x3ffff >> (PAGE_SHIFT - 12))
-#else
-#define STACK_RND_MASK			(0x3ffff >> (PAGE_SHIFT - 12))
-#endif
 
 #ifdef CONFIG_COMPAT
 
diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
index caa955f..0feb28a 100644
--- a/arch/arm64/include/asm/ftrace.h
+++ b/arch/arm64/include/asm/ftrace.h
@@ -54,7 +54,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
 #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
 static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
 {
-	return is_compat_task();
+	return is_a32_compat_task();
 }
 #endif /* ifndef __ASSEMBLY__ */
 
diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
new file mode 100644
index 0000000..6139b5a
--- /dev/null
+++ b/arch/arm64/include/asm/is_compat.h
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_IS_COMPAT_H
+#define __ASM_IS_COMPAT_H
+#ifndef __ASSEMBLY__
+
+#include <linux/thread_bits.h>
+
+#ifdef CONFIG_AARCH32_EL0
+
+static inline int is_a32_compat_task(void)
+{
+	return test_thread_flag(TIF_32BIT);
+}
+
+static inline int is_a32_compat_thread(struct thread_info *thread)
+{
+	return test_ti_thread_flag(thread, TIF_32BIT);
+}
+
+#else
+
+static inline int is_a32_compat_task(void)
+
+{
+	return 0;
+}
+
+static inline int is_a32_compat_thread(struct thread_info *thread)
+{
+	return 0;
+}
+
+#endif /* CONFIG_AARCH32_EL0 */
+
+#ifdef CONFIG_COMPAT
+
+static inline int is_compat_task(void)
+{
+	return is_a32_compat_task();
+}
+
+#endif /* CONFIG_COMPAT */
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_IS_COMPAT_H */
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 12f8a00..a66a0f7 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <asm/bug.h>
 #include <asm/sizes.h>
+#include <asm/is_compat.h>
 
 /*
  * Allow for constants defined here to be used from assembly code
@@ -61,7 +62,7 @@
 
 #ifdef CONFIG_COMPAT
 #define TASK_SIZE_32		UL(0x100000000)
-#define TASK_SIZE		(test_thread_flag(TIF_32BIT) ? \
+#define TASK_SIZE		(is_compat_task() ?		\
 				TASK_SIZE_32 : TASK_SIZE_64)
 #define TASK_SIZE_OF(tsk)	(test_tsk_thread_flag(tsk, TIF_32BIT) ? \
 				TASK_SIZE_32 : TASK_SIZE_64)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5bbdbb4..1eccf47 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 
 #include <asm/alternative.h>
+#include <asm/is_compat.h>
 #include <asm/fpsimd.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/lse.h>
@@ -41,7 +42,7 @@
 #define STACK_TOP_MAX		TASK_SIZE_64
 #ifdef CONFIG_COMPAT
 #define AARCH32_VECTORS_BASE	0xffff0000
-#define STACK_TOP		(test_thread_flag(TIF_32BIT) ? \
+#define STACK_TOP		(is_compat_task() ? \
 				AARCH32_VECTORS_BASE : STACK_TOP_MAX)
 #else
 #define STACK_TOP		STACK_TOP_MAX
@@ -94,7 +95,7 @@ struct thread_struct {
 #define task_user_tls(t)						\
 ({									\
 	unsigned long *__tls;						\
-	if (is_compat_thread(task_thread_info(t)))			\
+	if (is_a32_compat_thread(task_thread_info(t)))			\
 		__tls = &(t)->thread.tp2_value;				\
 	else								\
 		__tls = &(t)->thread.tp_value;				\
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 709a574..ce09641 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -113,7 +113,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
  */
 static inline int syscall_get_arch(void)
 {
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		return AUDIT_ARCH_ARM;
 
 	return AUDIT_ARCH_AARCH64;
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index abd64bd..4daa559 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -118,7 +118,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_FREEZE		19
 #define TIF_RESTORE_SIGMASK	20
 #define TIF_SINGLESTEP		21
-#define TIF_32BIT		22	/* 32bit process */
+#define TIF_32BIT		22	/* AARCH32 process */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index b45c95d..baa1eba 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -164,7 +164,7 @@ enum hw_breakpoint_ops {
 	HW_BREAKPOINT_RESTORE
 };
 
-static int is_compat_bp(struct perf_event *bp)
+static int is_a32_compat_bp(struct perf_event *bp)
 {
 	struct task_struct *tsk = bp->hw.target;
 
@@ -175,7 +175,7 @@ static int is_compat_bp(struct perf_event *bp)
 	 * deprecated behaviour if we use unaligned watchpoints in
 	 * AArch64 state.
 	 */
-	return tsk && is_compat_thread(task_thread_info(tsk));
+	return tsk && is_a32_compat_thread(task_thread_info(tsk));
 }
 
 /**
@@ -435,7 +435,7 @@ static int arch_build_bp_info(struct perf_event *bp)
 	 * Watchpoints can be of length 1, 2, 4 or 8 bytes.
 	 */
 	if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
-		if (is_compat_bp(bp)) {
+		if (is_a32_compat_bp(bp)) {
 			if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
 			    info->ctrl.len != ARM_BREAKPOINT_LEN_4)
 				return -EINVAL;
@@ -492,7 +492,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	 * AArch32 tasks expect some simple alignment fixups, so emulate
 	 * that here.
 	 */
-	if (is_compat_bp(bp)) {
+	if (is_a32_compat_bp(bp)) {
 		if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
 			alignment_mask = 0x7;
 		else
@@ -679,7 +679,7 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
 
 		info = counter_arch_bp(wp);
 		/* AArch32 watchpoints are either 4 or 8 bytes aligned. */
-		if (is_compat_task()) {
+		if (is_a32_compat_task()) {
 			if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
 				alignment_mask = 0x7;
 			else
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
index 3f62b35..a79058f 100644
--- a/arch/arm64/kernel/perf_regs.c
+++ b/arch/arm64/kernel/perf_regs.c
@@ -45,7 +45,7 @@ int perf_reg_validate(u64 mask)
 
 u64 perf_reg_abi(struct task_struct *task)
 {
-	if (is_compat_thread(task_thread_info(task)))
+	if (is_a32_compat_thread(task_thread_info(task)))
 		return PERF_SAMPLE_REGS_ABI_32;
 	else
 		return PERF_SAMPLE_REGS_ABI_64;
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 8062482..746f2d3 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -47,7 +47,6 @@
 #include <trace/events/power.h>
 
 #include <asm/alternative.h>
-#include <asm/compat.h>
 #include <asm/cacheflush.h>
 #include <asm/fpsimd.h>
 #include <asm/mmu_context.h>
@@ -211,7 +210,7 @@ static void tls_thread_flush(void)
 {
 	asm ("msr tpidr_el0, xzr");
 
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		current->thread.tp_value = 0;
 
 		/*
@@ -263,7 +262,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 		asm("mrs %0, tpidr_el0" : "=r" (*task_user_tls(p)));
 
 		if (stack_start) {
-			if (is_compat_thread(task_thread_info(p)))
+			if (is_a32_compat_thread(task_thread_info(p)))
 				childregs->compat_sp = stack_start;
 			/* 16-byte aligned stack mandatory on AArch64 */
 			else if (stack_start & 15)
@@ -303,7 +302,7 @@ static void tls_thread_switch(struct task_struct *next)
 	*task_user_tls(current) = tpidr;
 
 	tpidr = *task_user_tls(next);
-	tpidrro = is_compat_thread(task_thread_info(next)) ?
+	tpidrro = is_a32_compat_thread(task_thread_info(next)) ?
 		  next->thread.tp_value : 0;
 
 	asm(
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index aa79e81..38a09338 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -38,7 +38,6 @@
 #include <linux/tracehook.h>
 #include <linux/elf.h>
 
-#include <asm/compat.h>
 #include <asm/debug-monitors.h>
 #include <asm/pgtable.h>
 #include <asm/syscall.h>
@@ -85,7 +84,7 @@ static void ptrace_hbptriggered(struct perf_event *bp,
 #ifdef CONFIG_AARCH32_EL0
 	int i;
 
-	if (!is_compat_task())
+	if (!is_a32_compat_task())
 		goto send_sig;
 
 	for (i = 0; i < ARM_MAX_BRP; ++i) {
@@ -1203,9 +1202,9 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 	 * 32-bit children use an extended user_aarch32_ptrace_view to allow
 	 * access to the TLS register.
 	 */
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		return &user_aarch32_view;
-	else if (is_compat_thread(task_thread_info(task)))
+	else if (is_a32_compat_thread(task_thread_info(task)))
 		return &user_aarch32_ptrace_view;
 #endif
 	return &user_aarch64_view;
@@ -1232,7 +1231,7 @@ static void tracehook_report_syscall(struct pt_regs *regs,
 	 * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
 	 * used to denote syscall entry/exit:
 	 */
-	regno = (is_compat_task() ? 12 : 7);
+	regno = (is_a32_compat_task() ? 12 : 7);
 	saved_reg = regs->regs[regno];
 	regs->regs[regno] = dir;
 
@@ -1343,7 +1342,7 @@ int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task)
 	if (!test_tsk_thread_flag(task, TIF_SINGLESTEP))
 		regs->pstate &= ~DBG_SPSR_SS;
 
-	if (is_compat_thread(task_thread_info(task)))
+	if (is_a32_compat_thread(task_thread_info(task)))
 		return valid_compat_regs(regs);
 	else
 		return valid_native_regs(regs);
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index a8eafdb..be02f65 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -276,7 +276,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 
 static void setup_restart_syscall(struct pt_regs *regs)
 {
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		compat_setup_restart_syscall(regs);
 	else
 		regs->regs[8] = __NR_restart_syscall;
@@ -295,7 +295,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	/*
 	 * Set up the stack frame
 	 */
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 			ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
 		else
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index cdab14e..cacd30a 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -18,6 +18,7 @@
  */
 
 #include <linux/bug.h>
+#include <linux/compat.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
 #include <linux/kallsyms.h>
@@ -405,7 +406,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
 {
 #ifdef CONFIG_AARCH32_EL0
 	long ret;
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		ret = compat_arm_syscall(regs);
 		if (ret != -ENOSYS)
 			return ret;
-- 
2.5.0

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

* [PATCH 16/25] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (14 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 15/25] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat) Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 17/25] arm64: introduce binfmt_elf32.c Yury Norov
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Philipp Tomsich

ILP32 tasks are needed to be distinguished from lp64 and aarch32.
This patch adds helper functions is_ilp32_compat_{task,thread} and
thread flag TIF_32BIT_AARCH64 to address it. This is a preparation
for following patches in ilp32 patchset.

For consistency, SET_PERSONALITY are changed here accordingly.

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h         | 13 +++++++++++--
 arch/arm64/include/asm/is_compat.h   | 28 +++++++++++++++++++++++++++-
 arch/arm64/include/asm/thread_info.h |  1 +
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index b5437c5..e18bb8a 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -142,7 +142,11 @@ typedef struct user_fpsimd_state elf_fpregset_t;
  */
 #define ELF_PLAT_INIT(_r, load_addr)	(_r)->regs[0] = 0
 
-#define SET_PERSONALITY(ex)		clear_thread_flag(TIF_32BIT);
+#define SET_PERSONALITY(ex)		\
+do {						\
+	clear_thread_flag(TIF_32BIT_AARCH64);	\
+	clear_thread_flag(TIF_32BIT);		\
+} while (0)
 
 #define ARCH_DLINFO							\
 do {									\
@@ -181,7 +185,12 @@ typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_ELF_NGREG];
 					 ((x)->e_flags & EF_ARM_EABI_MASK))
 
 #define compat_start_thread		compat_start_thread
-#define COMPAT_SET_PERSONALITY(ex)	set_thread_flag(TIF_32BIT);
+#define COMPAT_SET_PERSONALITY(ex)		\
+do {						\
+	clear_thread_flag(TIF_32BIT_AARCH64);	\
+	set_thread_flag(TIF_32BIT);		\
+} while (0)
+
 #define COMPAT_ARCH_DLINFO
 extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 				      int uses_interp);
diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
index 6139b5a..55134cf 100644
--- a/arch/arm64/include/asm/is_compat.h
+++ b/arch/arm64/include/asm/is_compat.h
@@ -45,11 +45,37 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 
 #endif /* CONFIG_AARCH32_EL0 */
 
+#ifdef CONFIG_ARM64_ILP32
+
+static inline int is_ilp32_compat_task(void)
+{
+	return test_thread_flag(TIF_32BIT_AARCH64);
+}
+
+static inline int is_ilp32_compat_thread(struct thread_info *thread)
+{
+	return test_ti_thread_flag(thread, TIF_32BIT_AARCH64);
+}
+
+#else
+
+static inline int is_ilp32_compat_task(void)
+{
+	return 0;
+}
+
+static inline int is_ilp32_compat_thread(struct thread_info *thread)
+{
+	return 0;
+}
+
+#endif /* CONFIG_ARM64_ILP32 */
+
 #ifdef CONFIG_COMPAT
 
 static inline int is_compat_task(void)
 {
-	return is_a32_compat_task();
+	return is_a32_compat_task() || is_ilp32_compat_task();
 }
 
 #endif /* CONFIG_COMPAT */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 4daa559..8bcfa38 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -119,6 +119,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_RESTORE_SIGMASK	20
 #define TIF_SINGLESTEP		21
 #define TIF_32BIT		22	/* AARCH32 process */
+#define TIF_32BIT_AARCH64	23	/* 32 bit process on AArch64(ILP32) */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-- 
2.5.0

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

* [PATCH 17/25] arm64: introduce binfmt_elf32.c
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (15 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 16/25] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c Yury Norov
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

As we support more than one compat formats, it looks more reasonable
to not use fs/compat_binfmt.c. Custom binfmt_elf32.c allows to move aarch32
specific definitions there and make code more maintainable and readable.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/Kconfig               |  1 -
 arch/arm64/include/asm/elf.h     | 24 ------------------------
 arch/arm64/include/asm/hwcap.h   |  2 --
 arch/arm64/kernel/Makefile       |  2 +-
 arch/arm64/kernel/binfmt_elf32.c | 33 +++++++++++++++++++++++++++++++++
 5 files changed, 34 insertions(+), 28 deletions(-)
 create mode 100644 arch/arm64/kernel/binfmt_elf32.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ebaf38a..46fc295 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -931,7 +931,6 @@ config COMPAT
 config AARCH32_EL0
 	bool "Kernel support for 32-bit EL0"
 	depends on ARM64_4K_PAGES || EXPERT
-	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	select OLD_SIGSUSPEND3
 	select COMPAT_OLD_SIGACTION
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index e18bb8a..7a39683 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -166,12 +166,6 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #ifdef CONFIG_COMPAT
 
-#ifdef __AARCH64EB__
-#define COMPAT_ELF_PLATFORM		("v8b")
-#else
-#define COMPAT_ELF_PLATFORM		("v8l")
-#endif
-
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
 /* AArch32 registers. */
@@ -179,24 +173,6 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 typedef unsigned int			compat_elf_greg_t;
 typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_ELF_NGREG];
 
-/* AArch32 EABI. */
-#define EF_ARM_EABI_MASK		0xff000000
-#define compat_elf_check_arch(x)	(((x)->e_machine == EM_ARM) && \
-					 ((x)->e_flags & EF_ARM_EABI_MASK))
-
-#define compat_start_thread		compat_start_thread
-#define COMPAT_SET_PERSONALITY(ex)		\
-do {						\
-	clear_thread_flag(TIF_32BIT_AARCH64);	\
-	set_thread_flag(TIF_32BIT);		\
-} while (0)
-
-#define COMPAT_ARCH_DLINFO
-extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
-				      int uses_interp);
-#define compat_arch_setup_additional_pages \
-					aarch32_setup_vectors_page
-
 #endif /* CONFIG_COMPAT */
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 2c7fc5d..99dfd92 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -47,8 +47,6 @@
 #define ELF_HWCAP		(elf_hwcap)
 
 #ifdef CONFIG_AARCH32_EL0
-#define COMPAT_ELF_HWCAP	(compat_elf_hwcap)
-#define COMPAT_ELF_HWCAP2	(compat_elf_hwcap2)
 extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
 #endif
 
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 75dd250..6bc9738 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -27,7 +27,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
 
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
-					   ../../arm/kernel/opcodes.o
+					   ../../arm/kernel/opcodes.o binfmt_elf32.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
diff --git a/arch/arm64/kernel/binfmt_elf32.c b/arch/arm64/kernel/binfmt_elf32.c
new file mode 100644
index 0000000..5487872
--- /dev/null
+++ b/arch/arm64/kernel/binfmt_elf32.c
@@ -0,0 +1,33 @@
+/*
+ * Support for AArch32 Linux ELF binaries.
+ */
+
+/* AArch32 EABI. */
+#define EF_ARM_EABI_MASK		0xff000000
+#define compat_elf_check_arch(x)	(((x)->e_machine == EM_ARM) && \
+					 ((x)->e_flags & EF_ARM_EABI_MASK))
+
+#define compat_start_thread		compat_start_thread
+#define COMPAT_SET_PERSONALITY(ex)		\
+do {						\
+	clear_thread_flag(TIF_32BIT_AARCH64);	\
+	set_thread_flag(TIF_32BIT);		\
+} while (0)
+
+#define COMPAT_ARCH_DLINFO
+#define COMPAT_ELF_HWCAP		(compat_elf_hwcap)
+#define COMPAT_ELF_HWCAP2		(compat_elf_hwcap2)
+
+#ifdef __AARCH64EB__
+#define COMPAT_ELF_PLATFORM		("v8b")
+#else
+#define COMPAT_ELF_PLATFORM		("v8l")
+#endif
+
+#define compat_arch_setup_additional_pages \
+					aarch32_setup_vectors_page
+struct linux_binprm;
+extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
+				      int uses_interp);
+
+#include "../../../fs/compat_binfmt_elf.c"
-- 
2.5.0

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

* [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (16 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 17/25] arm64: introduce binfmt_elf32.c Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-22 16:51   ` Catalin Marinas
  2016-04-05 22:08 ` [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32 Yury Norov
                   ` (10 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

to handle ILP32 binaries

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/kernel/Makefile       |  1 +
 arch/arm64/kernel/binfmt_ilp32.c | 91 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 arch/arm64/kernel/binfmt_ilp32.c

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 6bc9738..9dfdf86 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,6 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
new file mode 100644
index 0000000..a934fd4
--- /dev/null
+++ b/arch/arm64/kernel/binfmt_ilp32.c
@@ -0,0 +1,91 @@
+/*
+ * Support for ILP32 Linux/aarch64 ELF binaries.
+ */
+
+#include <linux/elfcore-compat.h>
+#include <linux/time.h>
+
+#undef	ELF_CLASS
+#define ELF_CLASS	ELFCLASS32
+
+#undef	elfhdr
+#undef	elf_phdr
+#undef	elf_shdr
+#undef	elf_note
+#undef	elf_addr_t
+#define elfhdr		elf32_hdr
+#define elf_phdr	elf32_phdr
+#define elf_shdr	elf32_shdr
+#define elf_note	elf32_note
+#define elf_addr_t	Elf32_Addr
+
+/*
+ * Some data types as stored in coredump.
+ */
+#define user_long_t		compat_long_t
+#define user_siginfo_t		compat_siginfo_t
+#define copy_siginfo_to_user	copy_siginfo_to_user32
+
+/*
+ * The machine-dependent core note format types are defined in elfcore-compat.h,
+ * which requires asm/elf.h to define compat_elf_gregset_t et al.
+ */
+#define elf_prstatus	compat_elf_prstatus
+#define elf_prpsinfo	compat_elf_prpsinfo
+
+/*
+ * Compat version of cputime_to_compat_timeval, perhaps this
+ * should be an inline in <linux/compat.h>.
+ */
+static void cputime_to_compat_timeval(const cputime_t cputime,
+				      struct compat_timeval *value)
+{
+	struct timeval tv;
+	cputime_to_timeval(cputime, &tv);
+	value->tv_sec = tv.tv_sec;
+	value->tv_usec = tv.tv_usec;
+}
+
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
+
+/* AARCH64 ILP32 EABI. */
+#undef elf_check_arch
+#define elf_check_arch(x)		(((x)->e_machine == EM_AARCH64)	\
+					&& (x)->e_ident[EI_CLASS] == ELFCLASS32)
+
+#undef SET_PERSONALITY
+#define SET_PERSONALITY(ex)						\
+do {									\
+	set_thread_flag(TIF_32BIT_AARCH64);				\
+	clear_thread_flag(TIF_32BIT);					\
+} while (0)
+
+#undef ARCH_DLINFO
+#define ARCH_DLINFO							\
+do {									\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
+		    (elf_addr_t)(long)current->mm->context.vdso);	\
+} while (0)
+
+#ifdef __AARCH64EB__
+#define COMPAT_ELF_PLATFORM		("aarch64_be:ilp32")
+#else
+#define COMPAT_ELF_PLATFORM		("aarch64:ilp32")
+#endif
+
+#undef ELF_HWCAP
+#undef ELF_HWCAP2
+#define ELF_HWCAP			((u32) elf_hwcap)
+#define ELF_HWCAP2			((u32) (elf_hwcap >> 32))
+
+/*
+ * Rename a few of the symbols that binfmt_elf.c will define.
+ * These are all local so the names don't really matter, but it
+ * might make some debugging less confusing not to duplicate them.
+ */
+#define elf_format		compat_elf_format
+#define init_elf_binfmt		init_compat_elf_binfmt
+#define exit_elf_binfmt		exit_compat_elf_binfmt
+
+#include "../../../fs/binfmt_elf.c"
-- 
2.5.0

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

* [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (17 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-22 17:10   ` Catalin Marinas
  2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Here new aarch32 ptrace syscall handler is introsuced to avoid run-time
detection of the task type.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/unistd32.h |  2 +-
 arch/arm64/kernel/ptrace.c        | 50 ++++++++++++++++++++++++++++++++++++++-
 arch/arm64/kernel/sys32.c         |  1 +
 include/linux/ptrace.h            |  6 +++++
 kernel/ptrace.c                   | 10 ++++----
 5 files changed, 62 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 5b925b7..f57bbe3 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -74,7 +74,7 @@ __SYSCALL(__NR_getuid, sys_getuid16)
 			/* 25 was sys_stime */
 __SYSCALL(25, sys_ni_syscall)
 #define __NR_ptrace 26
-__SYSCALL(__NR_ptrace, compat_sys_ptrace)
+__SYSCALL(__NR_ptrace, compat_sys_aarch32_ptrace)
 			/* 27 was sys_alarm */
 __SYSCALL(27, sys_ni_syscall)
 			/* 28 was sys_fstat */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 38a09338..a861105 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -29,6 +29,7 @@
 #include <linux/user.h>
 #include <linux/seccomp.h>
 #include <linux/security.h>
+#include <linux/syscalls.h>
 #include <linux/init.h>
 #include <linux/signal.h>
 #include <linux/uaccess.h>
@@ -1114,7 +1115,7 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
 }
 #endif	/* CONFIG_HAVE_HW_BREAKPOINT */
 
-long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+static long compat_a32_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
 	unsigned long addr = caddr;
@@ -1191,8 +1192,55 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 	return ret;
 }
+
+COMPAT_SYSCALL_DEFINE4(aarch32_ptrace, compat_long_t, request, compat_long_t, pid,
+		       compat_long_t, addr, compat_long_t, data)
+{
+	struct task_struct *child;
+	long ret;
+
+	if (request == PTRACE_TRACEME) {
+		ret = ptrace_traceme();
+		goto out;
+	}
+
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
+		goto out;
+	}
+
+	if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
+		ret = ptrace_attach(child, request, addr, data);
+		goto out_put_task_struct;
+	}
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL ||
+				  request == PTRACE_INTERRUPT);
+	if (!ret) {
+		ret = compat_a32_ptrace(child, request, addr, data);
+		if (ret || request != PTRACE_DETACH)
+			ptrace_unfreeze_traced(child);
+	}
+
+ out_put_task_struct:
+	put_task_struct(child);
+ out:
+	return ret;
+}
+
 #endif /* CONFIG_AARCH32_EL0 */
 
+#ifdef CONFIG_COMPAT
+
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+			compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	return compat_ptrace_request(child, request, caddr, cdata);
+}
+
+#endif /* CONFIG_COMPAT */
+
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
 #ifdef CONFIG_AARCH32_EL0
diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c
index a40b134..3752443 100644
--- a/arch/arm64/kernel/sys32.c
+++ b/arch/arm64/kernel/sys32.c
@@ -38,6 +38,7 @@ asmlinkage long compat_sys_fadvise64_64_wrapper(void);
 asmlinkage long compat_sys_sync_file_range2_wrapper(void);
 asmlinkage long compat_sys_fallocate_wrapper(void);
 asmlinkage long compat_sys_mmap2_wrapper(void);
+asmlinkage long compat_sys_aarch32_ptrace(void);
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym)	[nr] = sym,
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 504c98a..75887a0 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -97,6 +97,12 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
 			    unsigned long data);
 int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
 			    unsigned long data);
+int ptrace_traceme(void);
+struct task_struct *ptrace_get_task_struct(pid_t pid);
+int ptrace_attach(struct task_struct *task, long request,
+			 unsigned long addr, unsigned long flags);
+int ptrace_check_attach(struct task_struct *child, bool ignore_state);
+void ptrace_unfreeze_traced(struct task_struct *task);
 
 /**
  * ptrace_parent - return the task that is tracing the given task
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index d49bfa1..cadf24c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -136,7 +136,7 @@ static bool ptrace_freeze_traced(struct task_struct *task)
 	return ret;
 }
 
-static void ptrace_unfreeze_traced(struct task_struct *task)
+void ptrace_unfreeze_traced(struct task_struct *task)
 {
 	if (task->state != __TASK_TRACED)
 		return;
@@ -168,7 +168,7 @@ static void ptrace_unfreeze_traced(struct task_struct *task)
  * RETURNS:
  * 0 on success, -ESRCH if %child is not ready.
  */
-static int ptrace_check_attach(struct task_struct *child, bool ignore_state)
+int ptrace_check_attach(struct task_struct *child, bool ignore_state)
 {
 	int ret = -ESRCH;
 
@@ -292,7 +292,7 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 	return !err;
 }
 
-static int ptrace_attach(struct task_struct *task, long request,
+int ptrace_attach(struct task_struct *task, long request,
 			 unsigned long addr,
 			 unsigned long flags)
 {
@@ -406,7 +406,7 @@ out:
  * Performs checks and sets PT_PTRACED.
  * Should be used by all ptrace implementations for PTRACE_TRACEME.
  */
-static int ptrace_traceme(void)
+ int ptrace_traceme(void)
 {
 	int ret = -EPERM;
 
@@ -1056,7 +1056,7 @@ int ptrace_request(struct task_struct *child, long request,
 	return ret;
 }
 
-static struct task_struct *ptrace_get_task_struct(pid_t pid)
+struct task_struct *ptrace_get_task_struct(pid_t pid)
 {
 	struct task_struct *child;
 
-- 
2.5.0

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

* [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (18 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-25 17:26   ` Catalin Marinas
                     ` (3 more replies)
  2016-04-05 22:08 ` [PATCH 21/25] arm64: signal: share lp64 signal routines to ilp32 Yury Norov
                   ` (8 subsequent siblings)
  28 siblings, 4 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

Add a separate syscall-table for ILP32, which dispatches either to native
LP64 system call implementation or to compat-syscalls, as appropriate.

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/unistd.h | 11 ++++++-
 arch/arm64/kernel/Makefile      |  2 +-
 arch/arm64/kernel/entry.S       | 12 +++++++-
 arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/kernel/sys_ilp32.c

diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 2971dea..5ea18ef 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,9 +13,18 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+
+#ifdef CONFIG_COMPAT
+#define __ARCH_WANT_COMPAT_STAT64
+#endif
+
+#ifdef CONFIG_ARM64_ILP32
+#define __ARCH_WANT_COMPAT_SYS_PREADV64
+#define __ARCH_WANT_COMPAT_SYS_PWRITEV64
+#endif
+
 #ifdef CONFIG_AARCH32_EL0
 #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
-#define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 9dfdf86..7aa65ea 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
-arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index cf4d1ae..1f7a145 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
  */
 	.align	6
 el0_svc:
-	adrp	stbl, sys_call_table		// load syscall table pointer
 	uxtw	scno, w8			// syscall number in w8
 	mov	sc_nr, #__NR_syscalls
+#ifdef CONFIG_ARM64_ILP32
+	ldr	x16, [tsk, #TI_FLAGS]
+	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
+#endif
+	adrp	stbl, sys_call_table		// load syscall table pointer
 el0_svc_naked:					// compat entry point
 	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
 	enable_dbg_and_irq
@@ -737,6 +741,12 @@ ni_sys:
 	b	ret_fast_syscall
 ENDPROC(el0_svc)
 
+#ifdef CONFIG_ARM64_ILP32
+el0_ilp32_svc:
+	adrp	stbl, sys_call_ilp32_table // load syscall table pointer
+	b el0_svc_naked
+#endif
+
 	/*
 	 * This is the really slow path.  We're going to be doing context
 	 * switches, and waiting for our parent to respond.
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
new file mode 100644
index 0000000..0996d8e
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,65 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2016 Cavium Inc.
+ * Author: Andrew Pinski <apinski@cavium.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/msg.h>
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+#include <asm-generic/syscalls.h>
+
+/* Using non-compat syscalls where necessary */
+#define compat_sys_fadvise64_64        sys_fadvise64_64
+#define compat_sys_fallocate           sys_fallocate
+#define compat_sys_ftruncate64         sys_ftruncate
+#define compat_sys_lookup_dcookie      sys_lookup_dcookie
+#define compat_sys_pread64             sys_pread64
+#define compat_sys_pwrite64            sys_pwrite64
+#define compat_sys_readahead           sys_readahead
+#define compat_sys_shmat               sys_shmat
+#define compat_sys_sync_file_range     sys_sync_file_range
+#define compat_sys_truncate64          sys_truncate
+#define sys_llseek                     sys_lseek
+#define sys_mmap2		       sys_mmap
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#undef __SC_COMP
+#undef __SC_WRAP
+#undef __SC_3264
+#undef __SC_COMP_3264
+
+#define __SYSCALL_COMPAT
+#define __SYSCALL(nr, sym)	[nr] = sym,
+#define __SC_WRAP(nr, sym)	[nr] = compat_##sym,
+
+/*
+ * The sys_call_ilp32_table array must be 4K aligned to be accessible from
+ * kernel/entry.S.
+ */
+void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = {
+	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
-- 
2.5.0

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

* [PATCH 21/25] arm64: signal: share lp64 signal routines to ilp32
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (19 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 22/25] arm64: signal32: move ilp32 and aarch32 common code to separated file Yury Norov
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

After that, it will be possible to reuse it in ilp32.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal_common.h | 33 ++++++++++++
 arch/arm64/kernel/signal.c             | 91 +++++++++++++++++++++-------------
 2 files changed, 90 insertions(+), 34 deletions(-)
 create mode 100644 arch/arm64/include/asm/signal_common.h

diff --git a/arch/arm64/include/asm/signal_common.h b/arch/arm64/include/asm/signal_common.h
new file mode 100644
index 0000000..756ed2c
--- /dev/null
+++ b/arch/arm64/include/asm/signal_common.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2016 Cavium Networks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_SIGNAL_COMMON_H
+#define __ASM_SIGNAL_COMMON_H
+
+#include <linux/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/fpsimd.h>
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx);
+int restore_fpsimd_context(struct fpsimd_context __user *ctx);
+int setup_sigcontext(struct sigcontext __user *uc_mcontext, struct pt_regs *regs);
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sf);
+void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+			void __user *frame, off_t sigframe_off, int usig);
+
+#endif /* __ASM_SIGNAL_COMMON_H */
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index be02f65..f9fbf8a 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -34,18 +34,23 @@
 #include <asm/fpsimd.h>
 #include <asm/signal32.h>
 #include <asm/vdso.h>
+#include <asm/signal_common.h>
+
+struct sigframe {
+	struct ucontext uc;
+	u64 fp;
+	u64 lr;
+};
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
  */
 struct rt_sigframe {
 	struct siginfo info;
-	struct ucontext uc;
-	u64 fp;
-	u64 lr;
+	struct sigframe sig;
 };
 
-static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 {
 	struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
 	int err;
@@ -65,7 +70,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 	return err ? -EFAULT : 0;
 }
 
-static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
+int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 {
 	struct fpsimd_state fpsimd;
 	__u32 magic, size;
@@ -93,22 +98,30 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 }
 
 static int restore_sigframe(struct pt_regs *regs,
-			    struct rt_sigframe __user *sf)
+			    struct sigframe __user *sf)
 {
 	sigset_t set;
-	int i, err;
-	void *aux = sf->uc.uc_mcontext.__reserved;
-
+	int err;
 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
 	if (err == 0)
 		set_current_blocked(&set);
 
+	err |= restore_sigcontext(regs, &sf->uc.uc_mcontext);
+	return err;
+}
+
+
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *uc_mcontext)
+{
+	int i, err = 0;
+	void *aux = uc_mcontext->__reserved;
+
 	for (i = 0; i < 31; i++)
-		__get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i],
+		__get_user_error(regs->regs[i], &uc_mcontext->regs[i],
 				 err);
-	__get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err);
-	__get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
-	__get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
+	__get_user_error(regs->sp, &uc_mcontext->sp, err);
+	__get_user_error(regs->pc, &uc_mcontext->pc, err);
+	__get_user_error(regs->pstate, &uc_mcontext->pstate, err);
 
 	/*
 	 * Avoid sys_rt_sigreturn() restarting.
@@ -145,10 +158,10 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 	if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
 		goto badframe;
 
-	if (restore_sigframe(regs, frame))
+	if (restore_sigframe(regs, &frame->sig))
 		goto badframe;
 
-	if (restore_altstack(&frame->uc.uc_stack))
+	if (restore_altstack(&frame->sig.uc.uc_stack))
 		goto badframe;
 
 	return regs->regs[0];
@@ -162,27 +175,36 @@ badframe:
 	return 0;
 }
 
-static int setup_sigframe(struct rt_sigframe __user *sf,
+static int setup_sigframe(struct sigframe __user *sf,
 			  struct pt_regs *regs, sigset_t *set)
 {
-	int i, err = 0;
-	void *aux = sf->uc.uc_mcontext.__reserved;
-	struct _aarch64_ctx *end;
+	int err = 0;
 
 	/* set up the stack frame for unwinding */
 	__put_user_error(regs->regs[29], &sf->fp, err);
 	__put_user_error(regs->regs[30], &sf->lr, err);
+	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
+	err |= setup_sigcontext(&sf->uc.uc_mcontext, regs);
+
+	return err;
+}
+
+int setup_sigcontext(struct sigcontext __user *uc_mcontext,
+			struct pt_regs *regs)
+{
+	void *aux = uc_mcontext->__reserved;
+	struct _aarch64_ctx *end;
+	int i, err = 0;
 
 	for (i = 0; i < 31; i++)
-		__put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i],
+		__put_user_error(regs->regs[i], &uc_mcontext->regs[i],
 				 err);
-	__put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err);
-	__put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err);
-	__put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err);
 
-	__put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
+	__put_user_error(regs->sp, &uc_mcontext->sp, err);
+	__put_user_error(regs->pc, &uc_mcontext->pc, err);
+	__put_user_error(regs->pstate, &uc_mcontext->pstate, err);
 
-	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
+	__put_user_error(current->thread.fault_address, &uc_mcontext->fault_address, err);
 
 	if (err == 0) {
 		struct fpsimd_context *fpsimd_ctx =
@@ -229,14 +251,14 @@ static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
 	return frame;
 }
 
-static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
-			 void __user *frame, int usig)
+void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+			 void __user *frame, off_t sigframe_off, int usig)
 {
 	__sigrestore_t sigtramp;
 
 	regs->regs[0] = usig;
 	regs->sp = (unsigned long)frame;
-	regs->regs[29] = regs->sp + offsetof(struct rt_sigframe, fp);
+	regs->regs[29] = regs->sp + sigframe_off + offsetof(struct sigframe, fp);
 	regs->pc = (unsigned long)ka->sa.sa_handler;
 
 	if (ka->sa.sa_flags & SA_RESTORER)
@@ -257,17 +279,18 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 	if (!frame)
 		return 1;
 
-	__put_user_error(0, &frame->uc.uc_flags, err);
-	__put_user_error(NULL, &frame->uc.uc_link, err);
+	__put_user_error(0, &frame->sig.uc.uc_flags, err);
+	__put_user_error(NULL, &frame->sig.uc.uc_link, err);
 
-	err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
-	err |= setup_sigframe(frame, regs, set);
+	err |= __save_altstack(&frame->sig.uc.uc_stack, regs->sp);
+	err |= setup_sigframe(&frame->sig, regs, set);
 	if (err == 0) {
-		setup_return(regs, &ksig->ka, frame, usig);
+		setup_return(regs, &ksig->ka, frame,
+			offsetof(struct rt_sigframe, sig), usig);
 		if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
 			err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 			regs->regs[1] = (unsigned long)&frame->info;
-			regs->regs[2] = (unsigned long)&frame->uc;
+			regs->regs[2] = (unsigned long)&frame->sig.uc;
 		}
 	}
 
-- 
2.5.0

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

* [PATCH 22/25] arm64: signal32: move ilp32 and aarch32 common code to separated file
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (20 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 21/25] arm64: signal: share lp64 signal routines to ilp32 Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 23/25] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Yury Norov
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal32_common.h |  25 +++++++
 arch/arm64/kernel/Makefile               |   1 +
 arch/arm64/kernel/signal32.c             |  85 -----------------------
 arch/arm64/kernel/signal32_common.c      | 115 +++++++++++++++++++++++++++++++
 4 files changed, 141 insertions(+), 85 deletions(-)
 create mode 100644 arch/arm64/include/asm/signal32_common.h
 create mode 100644 arch/arm64/kernel/signal32_common.c

diff --git a/arch/arm64/include/asm/signal32_common.h b/arch/arm64/include/asm/signal32_common.h
new file mode 100644
index 0000000..b4f2099
--- /dev/null
+++ b/arch/arm64/include/asm/signal32_common.h
@@ -0,0 +1,25 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_SIGNAL32_COMMON_H
+#define __ASM_SIGNAL32_COMMON_H
+
+#ifdef CONFIG_COMPAT
+
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from);
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from);
+
+#endif /* CONFIG_COMPAT*/
+
+#endif /* __ASM_SIGNAL32_COMMON_H */
+
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 7aa65ea..3ed55eb 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
 arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
+arm64-obj-$(CONFIG_COMPAT)		+= signal32_common.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index b7063de..b103af3 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -125,91 +125,6 @@ static inline int get_sigset_t(sigset_t *set,
 	return 0;
 }
 
-int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, to, sizeof(*to)))
-		return -EFAULT;
-
-	/* If you change siginfo_t structure, please be sure
-	 * this code is fixed accordingly.
-	 * It should never copy any pad contained in the structure
-	 * to avoid security leaks, but must copy the generic
-	 * 3 ints plus the relevant union member.
-	 * This routine must convert siginfo from 64bit to 32bit as well
-	 * at the same time.
-	 */
-	err = __put_user(from->si_signo, &to->si_signo);
-	err |= __put_user(from->si_errno, &to->si_errno);
-	err |= __put_user((short)from->si_code, &to->si_code);
-	if (from->si_code < 0)
-		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad,
-				      SI_PAD_SIZE);
-	else switch (from->si_code & __SI_MASK) {
-	case __SI_KILL:
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		break;
-	case __SI_TIMER:
-		 err |= __put_user(from->si_tid, &to->si_tid);
-		 err |= __put_user(from->si_overrun, &to->si_overrun);
-		 err |= __put_user(from->si_int, &to->si_int);
-		break;
-	case __SI_POLL:
-		err |= __put_user(from->si_band, &to->si_band);
-		err |= __put_user(from->si_fd, &to->si_fd);
-		break;
-	case __SI_FAULT:
-		err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr,
-				  &to->si_addr);
-#ifdef BUS_MCEERR_AO
-		/*
-		 * Other callers might not initialize the si_lsb field,
-		 * so check explicitly for the right codes here.
-		 */
-		if (from->si_signo == SIGBUS &&
-		    (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO))
-			err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
-#endif
-		break;
-	case __SI_CHLD:
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		err |= __put_user(from->si_status, &to->si_status);
-		err |= __put_user(from->si_utime, &to->si_utime);
-		err |= __put_user(from->si_stime, &to->si_stime);
-		break;
-	case __SI_RT: /* This is not generated by the kernel as of now. */
-	case __SI_MESGQ: /* But this is */
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		err |= __put_user(from->si_int, &to->si_int);
-		break;
-	case __SI_SYS:
-		err |= __put_user((compat_uptr_t)(unsigned long)
-				from->si_call_addr, &to->si_call_addr);
-		err |= __put_user(from->si_syscall, &to->si_syscall);
-		err |= __put_user(from->si_arch, &to->si_arch);
-		break;
-	default: /* this is just in case for now ... */
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		break;
-	}
-	return err;
-}
-
-int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
-{
-	if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) ||
-	    copy_from_user(to->_sifields._pad,
-			   from->_sifields._pad, SI_PAD_SIZE))
-		return -EFAULT;
-
-	return 0;
-}
-
 /*
  * VFP save/restore code.
  *
diff --git a/arch/arm64/kernel/signal32_common.c b/arch/arm64/kernel/signal32_common.c
new file mode 100644
index 0000000..8fbb609
--- /dev/null
+++ b/arch/arm64/kernel/signal32_common.c
@@ -0,0 +1,115 @@
+/*
+ * Based on arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Modified by Will Deacon <will.deacon@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/compat.h>
+#include <linux/signal.h>
+#include <linux/ratelimit.h>
+
+#include <asm/esr.h>
+#include <asm/fpsimd.h>
+#include <asm/signal32_common.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
+{
+	int err;
+
+	if (!access_ok(VERIFY_WRITE, to, sizeof(*to)))
+		return -EFAULT;
+
+	/* If you change siginfo_t structure, please be sure
+	 * this code is fixed accordingly.
+	 * It should never copy any pad contained in the structure
+	 * to avoid security leaks, but must copy the generic
+	 * 3 ints plus the relevant union member.
+	 * This routine must convert siginfo from 64bit to 32bit as well
+	 * at the same time.
+	 */
+	err = __put_user(from->si_signo, &to->si_signo);
+	err |= __put_user(from->si_errno, &to->si_errno);
+	err |= __put_user((short)from->si_code, &to->si_code);
+	if (from->si_code < 0)
+		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad,
+				      SI_PAD_SIZE);
+	else switch (from->si_code & __SI_MASK) {
+	case __SI_KILL:
+		err |= __put_user(from->si_pid, &to->si_pid);
+		err |= __put_user(from->si_uid, &to->si_uid);
+		break;
+	case __SI_TIMER:
+		 err |= __put_user(from->si_tid, &to->si_tid);
+		 err |= __put_user(from->si_overrun, &to->si_overrun);
+		 err |= __put_user(from->si_int, &to->si_int);
+		break;
+	case __SI_POLL:
+		err |= __put_user(from->si_band, &to->si_band);
+		err |= __put_user(from->si_fd, &to->si_fd);
+		break;
+	case __SI_FAULT:
+		err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr,
+				  &to->si_addr);
+#ifdef BUS_MCEERR_AO
+		/*
+		 * Other callers might not initialize the si_lsb field,
+		 * so check explicitly for the right codes here.
+		 */
+		if (from->si_signo == SIGBUS &&
+		    (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO))
+			err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
+#endif
+		break;
+	case __SI_CHLD:
+		err |= __put_user(from->si_pid, &to->si_pid);
+		err |= __put_user(from->si_uid, &to->si_uid);
+		err |= __put_user(from->si_status, &to->si_status);
+		err |= __put_user(from->si_utime, &to->si_utime);
+		err |= __put_user(from->si_stime, &to->si_stime);
+		break;
+	case __SI_RT: /* This is not generated by the kernel as of now. */
+	case __SI_MESGQ: /* But this is */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		err |= __put_user(from->si_uid, &to->si_uid);
+		err |= __put_user(from->si_int, &to->si_int);
+		break;
+	case __SI_SYS:
+		err |= __put_user((compat_uptr_t)(unsigned long)
+				from->si_call_addr, &to->si_call_addr);
+		err |= __put_user(from->si_syscall, &to->si_syscall);
+		err |= __put_user(from->si_arch, &to->si_arch);
+		break;
+	default: /* this is just in case for now ... */
+		err |= __put_user(from->si_pid, &to->si_pid);
+		err |= __put_user(from->si_uid, &to->si_uid);
+		break;
+	}
+	return err;
+}
+
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+{
+	if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) ||
+	    copy_from_user(to->_sifields._pad,
+			   from->_sifields._pad, SI_PAD_SIZE))
+		return -EFAULT;
+
+	return 0;
+}
+
-- 
2.5.0

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

* [PATCH 23/25] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (21 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 22/25] arm64: signal32: move ilp32 and aarch32 common code to separated file Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-05 22:08 ` [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

ILP32 uses AARCH32 compat structures and syscall handlers for signals.
But ILP32 struct rt_sigframe  and ucontext differs from both LP64 and
AARCH32. So some specific mechanism is needed to take care of it.

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal_ilp32.h |  34 ++++++
 arch/arm64/kernel/Makefile            |   3 +-
 arch/arm64/kernel/entry_ilp32.S       |  23 ++++
 arch/arm64/kernel/signal.c            |   3 +
 arch/arm64/kernel/signal_ilp32.c      | 192 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/sys_ilp32.c         |   3 +
 6 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/signal_ilp32.h
 create mode 100644 arch/arm64/kernel/entry_ilp32.S
 create mode 100644 arch/arm64/kernel/signal_ilp32.c

diff --git a/arch/arm64/include/asm/signal_ilp32.h b/arch/arm64/include/asm/signal_ilp32.h
new file mode 100644
index 0000000..30eff23
--- /dev/null
+++ b/arch/arm64/include/asm/signal_ilp32.h
@@ -0,0 +1,34 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_SIGNAL_ILP32_H
+#define __ASM_SIGNAL_ILP32_H
+
+#ifdef CONFIG_ARM64_ILP32
+
+#include <linux/compat.h>
+
+int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+			  struct pt_regs *regs);
+
+#else
+
+static inline int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+			  struct pt_regs *regs)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_ARM64_ILP32 */
+
+#endif /* __ASM_SIGNAL_ILP32_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 3ed55eb..09e4373 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,7 +28,8 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
-arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o 		\
+					   signal_ilp32.o entry_ilp32.o
 arm64-obj-$(CONFIG_COMPAT)		+= signal32_common.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
diff --git a/arch/arm64/kernel/entry_ilp32.S b/arch/arm64/kernel/entry_ilp32.S
new file mode 100644
index 0000000..5063172
--- /dev/null
+++ b/arch/arm64/kernel/entry_ilp32.S
@@ -0,0 +1,23 @@
+/*
+ * ILP32 system call wrappers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(ilp32_sys_rt_sigreturn_wrapper)
+	mov	x0, sp
+	b	ilp32_sys_rt_sigreturn
+ENDPROC(ilp32_sys_rt_sigreturn_wrapper)
+
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index f9fbf8a..45bcd96 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -35,6 +35,7 @@
 #include <asm/signal32.h>
 #include <asm/vdso.h>
 #include <asm/signal_common.h>
+#include <asm/signal_ilp32.h>
 
 struct sigframe {
 	struct ucontext uc;
@@ -323,6 +324,8 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 			ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
 		else
 			ret = compat_setup_frame(usig, ksig, oldset, regs);
+	} else if (is_ilp32_compat_task()) {
+		ret = ilp32_setup_rt_frame(usig, ksig, oldset, regs);
 	} else {
 		ret = setup_rt_frame(usig, ksig, oldset, regs);
 	}
diff --git a/arch/arm64/kernel/signal_ilp32.c b/arch/arm64/kernel/signal_ilp32.c
new file mode 100644
index 0000000..841e8f8
--- /dev/null
+++ b/arch/arm64/kernel/signal_ilp32.c
@@ -0,0 +1,192 @@
+/*
+ * Based on arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2016 Cavium Networks.
+ * Yury Norov <ynorov@caviumnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/compat.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/ratelimit.h>
+
+#include <asm/esr.h>
+#include <asm/fpsimd.h>
+#include <asm/signal32_common.h>
+#include <asm/signal_common.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/ucontext.h>
+
+
+struct ilp32_ucontext {
+        u32		uc_flags;
+        u32		uc_link;
+        compat_stack_t  uc_stack;
+        compat_sigset_t uc_sigmask;
+        /* glibc uses a 1024-bit sigset_t */
+        __u8            __unused[1024 / 8 - sizeof(compat_sigset_t)];
+        /* last for future expansion */
+        struct sigcontext uc_mcontext;
+};
+
+struct ilp32_sigframe {
+	struct ilp32_ucontext uc;
+	u64 fp;
+	u64 lr;
+};
+
+struct ilp32_rt_sigframe {
+	struct compat_siginfo info;
+	struct ilp32_sigframe sig;
+};
+
+static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
+{
+	compat_sigset_t cset;
+
+	cset.sig[0] = set->sig[0] & 0xffffffffull;
+	cset.sig[1] = set->sig[0] >> 32;
+
+	return copy_to_user(uset, &cset, sizeof(*uset));
+}
+
+static inline int get_sigset_t(sigset_t *set,
+                               const compat_sigset_t __user *uset)
+{
+	compat_sigset_t s32;
+
+	if (copy_from_user(&s32, uset, sizeof(*uset)))
+		return -EFAULT;
+
+	set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
+	return 0;
+}
+
+static int restore_ilp32_sigframe(struct pt_regs *regs,
+                            struct ilp32_sigframe __user *sf)
+{
+	sigset_t set;
+	int err;
+	err = get_sigset_t(&set, &sf->uc.uc_sigmask);
+	if (err == 0)
+		set_current_blocked(&set);
+	err |= restore_sigcontext(regs, &sf->uc.uc_mcontext);
+	return err;
+}
+
+static int setup_ilp32_sigframe(struct ilp32_sigframe __user *sf,
+                          struct pt_regs *regs, sigset_t *set)
+{
+	int err = 0;
+	/* set up the stack frame for unwinding */
+	__put_user_error(regs->regs[29], &sf->fp, err);
+	__put_user_error(regs->regs[30], &sf->lr, err);
+
+	err |= put_sigset_t(&sf->uc.uc_sigmask, set);
+	err |= setup_sigcontext(&sf->uc.uc_mcontext, regs);
+	return err;
+}
+
+asmlinkage long ilp32_sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct ilp32_rt_sigframe __user *frame;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current->restart_block.fn = do_no_restart_syscall;
+
+	/*
+	 * Since we stacked the signal on a 128-bit boundary,
+	 * then 'sp' should be word aligned here.  If it's
+	 * not, then the user is trying to mess with us.
+	 */
+	if (regs->sp & 15)
+		goto badframe;
+
+	frame = (struct ilp32_rt_sigframe __user *)regs->sp;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
+		goto badframe;
+
+	if (restore_ilp32_sigframe(regs, &frame->sig))
+		goto badframe;
+
+	if (compat_restore_altstack(&frame->sig.uc.uc_stack))
+		goto badframe;
+
+	return regs->regs[0];
+
+badframe:
+	if (show_unhandled_signals)
+		pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",
+				    current->comm, task_pid_nr(current), __func__,
+				    regs->pc, regs->compat_sp);
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+static struct ilp32_rt_sigframe __user *ilp32_get_sigframe(struct ksignal *ksig,
+					       struct pt_regs *regs)
+{
+	unsigned long sp, sp_top;
+	struct ilp32_rt_sigframe __user *frame;
+
+	sp = sp_top = sigsp(regs->sp, ksig);
+
+	sp = (sp - sizeof(struct ilp32_rt_sigframe)) & ~15;
+	frame = (struct ilp32_rt_sigframe __user *)sp;
+
+	/*
+	 * Check that we can actually write to the signal frame.
+	 */
+	if (!access_ok(VERIFY_WRITE, frame, sp_top - sp))
+		frame = NULL;
+
+	return frame;
+}
+
+/*
+ * ILP32 signal handling routines called from signal.c
+ */
+int ilp32_setup_rt_frame(int usig, struct ksignal *ksig,
+			  sigset_t *set, struct pt_regs *regs)
+{
+	struct ilp32_rt_sigframe __user *frame;
+	int err = 0;
+
+	frame = ilp32_get_sigframe(ksig, regs);
+
+	if (!frame)
+		return 1;
+
+	err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
+
+	__put_user_error(0, &frame->sig.uc.uc_flags, err);
+	__put_user_error(0, &frame->sig.uc.uc_link, err);
+
+	err |= __compat_save_altstack(&frame->sig.uc.uc_stack, regs->sp);
+	err |= setup_ilp32_sigframe(&frame->sig, regs, set);
+	if (err == 0) {
+		setup_return(regs, &ksig->ka, frame,
+				offsetof(struct ilp32_rt_sigframe, sig), usig);
+		regs->regs[1] = (unsigned long)&frame->info;
+		regs->regs[2] = (unsigned long)&frame->sig.uc;
+	}
+
+	return err;
+}
+
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index 0996d8e..1458ad7 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -43,6 +43,9 @@
 #define sys_llseek                     sys_lseek
 #define sys_mmap2		       sys_mmap
 
+asmlinkage long ilp32_sys_rt_sigreturn_wrapper(void);
+#define compat_sys_rt_sigreturn        ilp32_sys_rt_sigreturn_wrapper
+
 #include <asm/syscall.h>
 
 #undef __SYSCALL
-- 
2.5.0

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

* [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (22 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 23/25] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-13  9:19   ` Zhangjian (Bamvor)
  2016-04-29 16:01   ` Catalin Marinas
  2016-04-05 22:08 ` [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig Yury Norov
                   ` (4 subsequent siblings)
  28 siblings, 2 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Philipp Tomsich

From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>

ILP32 VDSO exports next symbols:
 __kernel_rt_sigreturn;
 __kernel_gettimeofday;
 __kernel_clock_gettime;
 __kernel_clock_getres;

What shared object to use, kernel selects depending on result of
is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
correct pages and spec.

Adjusted to move the move data page before code pages in sync with
commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/vdso.h                 |  6 ++
 arch/arm64/kernel/Makefile                    |  5 ++
 arch/arm64/kernel/signal.c                    |  2 +
 arch/arm64/kernel/vdso-ilp32/.gitignore       |  2 +
 arch/arm64/kernel/vdso-ilp32/Makefile         | 72 ++++++++++++++++++++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     | 33 ++++++++++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++
 arch/arm64/kernel/vdso.c                      | 61 ++++++++++++++---
 8 files changed, 266 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
 create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
 create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
 create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S

diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 839ce00..649a9a4 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -29,6 +29,12 @@
 
 #include <generated/vdso-offsets.h>
 
+#ifdef CONFIG_ARM64_ILP32
+#include <generated/vdso-ilp32-offsets.h>
+#else
+#define vdso_offset_sigtramp_ilp32
+#endif
+
 #define VDSO_SYMBOL(base, name)						   \
 ({									   \
 	(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 09e4373..b43ff12 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
 arm64-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
 
 obj-y					+= $(arm64-obj-y) vdso/
+obj-$(CONFIG_ARM64_ILP32)		+= vdso-ilp32/
 obj-m					+= $(arm64-obj-m)
 head-y					:= head.o
 extra-y					+= $(head-y) vmlinux.lds
@@ -57,3 +58,7 @@ extra-y					+= $(head-y) vmlinux.lds
 # vDSO - this must be built first to generate the symbol offsets
 $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
 $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
+
+# vDSO - this must be built first to generate the symbol offsets
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
+$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 45bcd96..933cdcf 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -264,6 +264,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 
 	if (ka->sa.sa_flags & SA_RESTORER)
 		sigtramp = ka->sa.sa_restorer;
+	else if (is_ilp32_compat_task())
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
 	else
 		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
 
diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore
new file mode 100644
index 0000000..61806c3
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/.gitignore
@@ -0,0 +1,2 @@
+vdso-ilp32.lds
+vdso-ilp32-offsets.h
diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile
new file mode 100644
index 0000000..c8f5472
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/Makefile
@@ -0,0 +1,72 @@
+#
+# Building a vDSO image for AArch64.
+#
+# Author: Will Deacon <will.deacon@arm.com>
+# Heavily based on the vDSO Makefiles for other archs.
+#
+
+obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o
+
+# Build rules
+targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
+obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))
+
+ccflags-y := -shared -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
+		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+
+obj-y += vdso-ilp32.o
+extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h
+CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32
+
+# Force dependency (incbin is bad)
+$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so
+
+# Link rule for the .so file, .lds has to be first
+$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
+	$(call if_changed,vdso-ilp32ld)
+
+# Strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+# Generate VDSO offsets using helper script
+gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+define cmd_vdsosym
+	$(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
+	cp $@ include/generated/
+endef
+
+$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
+	$(call if_changed,vdsosym)
+
+# Assembly rules for the .S files
+#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
+#	$(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
+	$(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/note-ilp32.o: $(src)/../vdso/note.S
+	$(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
+	$(call if_changed_dep,vdso-ilp32as)
+
+# Actual build commands
+quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
+      cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32  -Wl,-n -Wl,-T $^ -o $@
+quiet_cmd_vdso-ilp32as = VDSOILP32A $@
+      cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<
+
+# Install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: vdso-ilp32.so
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
new file mode 100644
index 0000000..46ac072
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+	__PAGE_ALIGNED_DATA
+
+	.globl vdso_ilp32_start, vdso_ilp32_end
+	.balign PAGE_SIZE
+vdso_ilp32_start:
+	.incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
+	.balign PAGE_SIZE
+vdso_ilp32_end:
+
+	.previous
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
new file mode 100644
index 0000000..ddc63fd
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -0,0 +1,95 @@
+/*
+ * GNU linker script for the VDSO library.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ * Heavily based on the vDSO linker scripts for other archs.
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+SECTIONS
+{
+	PROVIDE(_vdso_data = . - PAGE_SIZE);
+	. = VDSO_LBASE + SIZEOF_HEADERS;
+
+	.hash		: { *(.hash) }			:text
+	.gnu.hash	: { *(.gnu.hash) }
+	.dynsym		: { *(.dynsym) }
+	.dynstr		: { *(.dynstr) }
+	.gnu.version	: { *(.gnu.version) }
+	.gnu.version_d	: { *(.gnu.version_d) }
+	.gnu.version_r	: { *(.gnu.version_r) }
+
+	.note		: { *(.note.*) }		:text	:note
+
+	. = ALIGN(16);
+
+	.text		: { *(.text*) }			:text	=0xd503201f
+	PROVIDE (__etext = .);
+	PROVIDE (_etext = .);
+	PROVIDE (etext = .);
+
+	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
+	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
+
+	.dynamic	: { *(.dynamic) }		:text	:dynamic
+
+	.rodata		: { *(.rodata*) }		:text
+
+	_end = .;
+	PROVIDE(end = .);
+
+	/DISCARD/	: {
+		*(.note.GNU-stack)
+		*(.data .data.* .gnu.linkonce.d.* .sdata*)
+		*(.bss .sbss .dynbss .dynsbss)
+	}
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
+	note		PT_NOTE		FLAGS(4);		/* PF_R */
+	eh_frame_hdr	PT_GNU_EH_FRAME;
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+	LINUX_2.6 {
+	global:
+		__kernel_rt_sigreturn;
+		__kernel_gettimeofday;
+		__kernel_clock_gettime;
+		__kernel_clock_getres;
+	local: *;
+	};
+}
+
+/*
+ * Make the sigreturn code visible to the kernel.
+ */
+VDSO_sigtramp_ilp32		= __kernel_rt_sigreturn;
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 26352a6..521a8e4 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -40,6 +40,12 @@ extern char vdso_start, vdso_end;
 static unsigned long vdso_pages;
 static struct page **vdso_pagelist;
 
+#ifdef CONFIG_ARM64_ILP32
+extern char vdso_ilp32_start, vdso_ilp32_end;
+static unsigned long vdso_ilp32_pages;
+static struct page **vdso_ilp32_pagelist;
+#endif
+
 /*
  * The vDSO data page.
  */
@@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 }
 #endif /* CONFIG_AARCH32_EL0 */
 
-static struct vm_special_mapping vdso_spec[2];
-
-static int __init vdso_init(void)
+static int __init vdso_init_common(char *vdso_start, char *vdso_end,
+					  unsigned long *vdso_pagesp,
+					  struct page ***vdso_pagelistp,
+					  struct vm_special_mapping* vdso_spec)
 {
 	int i;
+	unsigned long vdso_pages;
+	struct page **vdso_pagelist;
 
-	if (memcmp(&vdso_start, "\177ELF", 4)) {
+	if (memcmp(vdso_start, "\177ELF", 4)) {
 		pr_err("vDSO is not a valid ELF object!\n");
 		return -EINVAL;
 	}
 
-	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+	*vdso_pagesp = vdso_pages;
 	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
-		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
+		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
 
 	/* Allocate the vDSO pagelist, plus a page for the data. */
 	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
 				GFP_KERNEL);
+	*vdso_pagelistp = vdso_pagelist;
 	if (vdso_pagelist == NULL)
 		return -ENOMEM;
 
@@ -135,7 +146,7 @@ static int __init vdso_init(void)
 
 	/* Grab the vDSO code pages. */
 	for (i = 0; i < vdso_pages; i++)
-		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
 
 	/* Populate the special mapping structures */
 	vdso_spec[0] = (struct vm_special_mapping) {
@@ -150,16 +161,46 @@ static int __init vdso_init(void)
 
 	return 0;
 }
+
+static struct vm_special_mapping vdso_spec[2];
+
+static int __init vdso_init(void)
+{
+	return vdso_init_common(&vdso_start, &vdso_end,
+				&vdso_pages, &vdso_pagelist,
+				vdso_spec);
+}
 arch_initcall(vdso_init);
 
+#ifdef CONFIG_ARM64_ILP32
+static struct vm_special_mapping vdso_ilp32_spec[2];
+
+static int __init vdso_ilp32_init(void)
+{
+	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
+				&vdso_ilp32_pages, &vdso_ilp32_pagelist,
+				vdso_ilp32_spec);
+}
+arch_initcall(vdso_ilp32_init);
+#endif
+
 int arch_setup_additional_pages(struct linux_binprm *bprm,
 				int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
 	void *ret;
+	unsigned long pages = vdso_pages;
+	struct vm_special_mapping *spec = vdso_spec;
+
+#ifdef CONFIG_ARM64_ILP32
+	if (is_ilp32_compat_task()) {
+	        pages = vdso_ilp32_pages;
+	        spec = vdso_ilp32_spec;
+	}
+#endif
 
-	vdso_text_len = vdso_pages << PAGE_SHIFT;
+	vdso_text_len = pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
 	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
 
@@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	}
 	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
 				       VM_READ|VM_MAYREAD,
-				       &vdso_spec[0]);
+				       &spec[0]);
 	if (IS_ERR(ret))
 		goto up_fail;
 
@@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
 				       VM_READ|VM_EXEC|
 				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				       &vdso_spec[1]);
+				       &spec[1]);
 	if (IS_ERR(ret))
 		goto up_fail;
 
-- 
2.5.0

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

* [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (23 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov
@ 2016-04-05 22:08 ` Yury Norov
  2016-04-29 16:03   ` Catalin Marinas
  2016-04-05 22:44 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results Yury Norov
                   ` (3 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:08 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, ynorov, pinskia, Prasun.Kapoor,
	schwab, Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski, Philipp Tomsich

From: Andrew Pinski <apinski@cavium.com>

This patch adds the config option for ILP32.

Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Reviewed-by: David Daney <ddaney@caviumnetworks.com>
---
 arch/arm64/Kconfig | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 46fc295..19d8e31 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -926,7 +926,7 @@ source "fs/Kconfig.binfmt"
 
 config COMPAT
 	def_bool y
-	depends on AARCH32_EL0
+	depends on AARCH32_EL0 || ARM64_ILP32
 
 config AARCH32_EL0
 	bool "Kernel support for 32-bit EL0"
@@ -946,6 +946,14 @@ config AARCH32_EL0
 
 	  If you want to execute 32-bit userspace applications, say Y.
 
+config ARM64_ILP32
+	bool "Kernel support for ILP32"
+	select COMPAT_WRAPPER
+	help
+	  This option enables support for AArch64 ILP32 user space.  ILP32
+	  is an ABI where long and pointers are 32bits but it uses the AARCH64
+	  instruction set.
+
 config SYSVIPC_COMPAT
 	def_bool y
 	depends on COMPAT && SYSVIPC
-- 
2.5.0

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (24 preceding siblings ...)
  2016-04-05 22:08 ` [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig Yury Norov
@ 2016-04-05 22:44 ` Yury Norov
  2016-04-23  3:37   ` Zhangjian (Bamvor)
  2016-04-06  6:51 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 Geert Uytterhoeven
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-05 22:44 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

[-- Attachment #1: Type: text/plain, Size: 1625 bytes --]

There are about 20 failing tests of 782 in lite scenario.
float_bessel 
float_exp_log
float_iperb
float_power
float_trigo
pipeio_1         
pipeio_3         
pipeio_5         
pipeio_8         
abort01          
clone02          
kill11           
mmap16           
open12           
pause01
rename11         
rmdir02          
umount2_01       
umount2_02       
umount2_03       
utime06          
mtest06          

The list is rough because some tests fail not every time.

Tests abort01 and kill11 fail for lp64 too, so maybe there's
a reason unrelated to ilp32 itself.

float_xxx tests fail because they call unwind() from signal context,
and GCC for ilp32 has problem with it, as Andrew told.

pipeio_x tests are very unstable and may fail randomly. I strongly
suspect race conditions, as they all work like a charm if pinned to
single CPU with taskset. Probably, race is the reason of clone02 too.
Though I'm not sure, is the race in kernel, glibc or test itself.

But I know for sure that pause01 fails due to test design:
	if (setitimer(ITIMER_REAL, &it, NULL)) // For 1000us
		tst_brkm(TBROK | TERRNO, NULL, "setitimer() failed");

	TEST(pause());

As setitimer() and pause() calls are not atomic, alarm may come before pause()
is called, and be silently dropped by the handler. Next pause() call hangs
test forever. I already reported to LTP list.

open12, rename11, rmdir02, mmap16, mtest06 - all call mkfs tool, and it returns
error code. I didn't investigate it much yet.

umount02_x, utime06 - cannot reproduce out of scenario, even run it in infinite
loop - they work fine.

Full test log is attached.

Yury

[-- Attachment #2: ltplite.tar.gz --]
[-- Type: application/gzip, Size: 57919 bytes --]

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (25 preceding siblings ...)
  2016-04-05 22:44 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results Yury Norov
@ 2016-04-06  6:51 ` Geert Uytterhoeven
  2016-04-06 12:29   ` Yury Norov
  2016-05-12  0:20 ` Yury Norov
  2016-05-17 12:10 ` Szabolcs Nagy
  28 siblings, 1 reply; 135+ messages in thread
From: Geert Uytterhoeven @ 2016-04-06  6:51 UTC (permalink / raw)
  To: Yury Norov
  Cc: Arnd Bergmann, Catalin Marinas, linux-arm-kernel, linux-kernel,
	Martin Schwidefsky, Heiko Carstens, Andrew Pinski, Prasun Kapoor,
	Andreas Schwab, Nathan Lynch, Alexander Graf, Alexey Klimov,
	Mark Brown, Joseph S. Myers, christoph.muellner,
	bamvor.zhangjian, linux-doc, Linux-Arch, linux-s390

Hi Yuri,

On Wed, Apr 6, 2016 at 12:08 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> This version is rebased on kernel v4.6-rc2, and has fixes in signal subsystem.
> It works with updated glibc [1] (though very draft), and tested with LTP.
>
> It was tested on QEMU and ThunderX machines. No major difference found.
> This is RFC because ILP32 is not tested in big-endian mode.
>
>  v3: https://lkml.org/lkml/2014/9/3/704
>  v4: https://lkml.org/lkml/2015/4/13/691
>  v5: https://lkml.org/lkml/2015/9/29/911
>
>  v6:
>  - time_t, __kenel_off_t and other types turned to be 32-bit
>    for compatibility reasons (after v5 discussion);

Reading this sparked my interest, so I went to the links above...

What makes you think these "applications that can’t readily be migrated to LP64
because they were written assuming an ILP32 data model, and that will never
become suitable for a LP64 data model and will remain locked into ILP32
operating environments" are more likely to be fixed for y2038 later, than for
LP64 now?

We're already closer to the (future) y2038 than to the (past) introduction of
LP64...

These unfixable legacy applications have been spreading through x32 to
the shiny new arm64 server architecture (does ppc64el also have an ILP32 mode,
or is it planned)? Lots of resources are spent on maintaining the status quo,
instead of on fixing the real problems.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-06  6:51 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 Geert Uytterhoeven
@ 2016-04-06 12:29   ` Yury Norov
  2016-04-07 12:28     ` Geert Uytterhoeven
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-06 12:29 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Arnd Bergmann, Catalin Marinas, linux-arm-kernel, linux-kernel,
	Martin Schwidefsky, Heiko Carstens, Andrew Pinski, Prasun Kapoor,
	Andreas Schwab, Nathan Lynch, Alexander Graf, Alexey Klimov,
	Mark Brown, Joseph S. Myers, christoph.muellner,
	bamvor.zhangjian, linux-doc, Linux-Arch, linux-s390

Hi Geert,

On Wed, Apr 06, 2016 at 08:51:50AM +0200, Geert Uytterhoeven wrote:
> Hi Yuri,
> 
> On Wed, Apr 6, 2016 at 12:08 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> > This version is rebased on kernel v4.6-rc2, and has fixes in signal subsystem.
> > It works with updated glibc [1] (though very draft), and tested with LTP.
> >
> > It was tested on QEMU and ThunderX machines. No major difference found.
> > This is RFC because ILP32 is not tested in big-endian mode.
> >
> >  v3: https://lkml.org/lkml/2014/9/3/704
> >  v4: https://lkml.org/lkml/2015/4/13/691
> >  v5: https://lkml.org/lkml/2015/9/29/911
> >
> >  v6:
> >  - time_t, __kenel_off_t and other types turned to be 32-bit
> >    for compatibility reasons (after v5 discussion);
> 
> Reading this sparked my interest, so I went to the links above...

Great! I'll add you to CC than.

> 
> What makes you think these "applications that can’t readily be migrated to LP64
> because they were written assuming an ILP32 data model, and that will never
> become suitable for a LP64 data model and will remain locked into ILP32
> operating environments" are more likely to be fixed for y2038 later, than for
> LP64 now?
> 

It was written by Philipp, not me:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-April/337350.html

I'm not the author of this, and I don't think so. Maybe just because I
didn't see all that legacy nightmare, as Philipp does...

Chris Tyler shares relatively common point of view in his video from
Linaro Connect:
https://www.youtube.com/watch?v=QsVLsw_LrJ0

Briefly, we need it (mostly) for compatibility and (then) for performance.
Maybe Prasun can share more details and examples.

> We're already closer to the (future) y2038 than to the (past) introduction of
> LP64...
> 

This is not about Y2038 at all. In fact, current version doesn't fix
Y2038 problem, as we decided finally.

After v4 and v5, it was spread discussion about what ilp32 should do,
and what not. Finally we decided to be not like aarch32, and not like
lp64, and don't fix any issues specifically, but be standard compat
format, as much as possible. So, any improvements and fixes applied
to generic compat will be applied to ilp32 with minimal efforts.

> These unfixable legacy applications have been spreading through x32 to
> the shiny new arm64 server architecture (does ppc64el also have an ILP32 mode,
> or is it planned)?

I don't think this is the question you really don't know the answer.
Almost everywhere shiny arm64 comes with old and ugly aarch32 IP core.
If no, like ThunderX, people really worry about that. And for me,
configurable option in kernel sources is better tradeoff than billions
transistors in every chip on market. So Cavium here is more
future-oriented than many others...

The other example is ACPI. We have nice and cute device tree, don't we?
Does it make sense to vendors?

> Lots of resources are spent on maintaining the status quo,
> instead of on fixing the real problems.
> 

I think, compatibility is one of real problems. Aarch32 is hardware
solution, and ilp32 is software one.

Yury.

> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-06 12:29   ` Yury Norov
@ 2016-04-07 12:28     ` Geert Uytterhoeven
  0 siblings, 0 replies; 135+ messages in thread
From: Geert Uytterhoeven @ 2016-04-07 12:28 UTC (permalink / raw)
  To: Yury Norov
  Cc: Arnd Bergmann, Catalin Marinas, linux-arm-kernel, linux-kernel,
	Martin Schwidefsky, Heiko Carstens, Andrew Pinski, Prasun Kapoor,
	Andreas Schwab, Nathan Lynch, Alexander Graf, Alexey Klimov,
	Mark Brown, Joseph S. Myers, christoph.muellner,
	bamvor.zhangjian, linux-doc, Linux-Arch, linux-s390

On Wed, Apr 6, 2016 at 2:29 PM, Yury Norov <ynorov@caviumnetworks.com> wrote:
>> We're already closer to the (future) y2038 than to the (past) introduction of
>> LP64...
>
> This is not about Y2038 at all. In fact, current version doesn't fix
> Y2038 problem, as we decided finally.

Indeed. So these legacy applications have to be fixed later anyway.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-05 22:08 ` [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov
@ 2016-04-13  9:19   ` Zhangjian (Bamvor)
  2016-04-13 15:55     ` Yury Norov
  2016-04-29 16:01   ` Catalin Marinas
  1 sibling, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-04-13  9:19 UTC (permalink / raw)
  To: Yury Norov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Philipp Tomsich, Zhangjian (Bamvor)

Hi, Yury and Philipp

There is a small fix for this patch. Othervise our tools of living
patch could not work.

Regards

Bamvor

 From e05770efca9f040e0039a4a9c4e0d7d3b2bd13e8 Mon Sep 17 00:00:00 2001
From: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
Date: Wed, 13 Apr 2016 15:46:28 +0800
Subject: [PATCH] arm64: ilp32: do not check vdso-ilp32-offsets.h when ILP32
  disabled

vdso-ilp32-offsets.h is the dependency of all the arm64-obj-y. And
it does not exist when CONFIG_ARM64_ILP32 is disable which lead to
all the arm64-obj-y are re-built unnecessarily.

Such rebuild may confuse the sofware(e.g. tools of living patch)
which need to know exactly which file(s) is(are) updated.

This patch fix this issue by adding the config checker.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
---
  arch/arm64/kernel/Makefile | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index b43ff12..0f27a10 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -60,5 +60,7 @@ $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
  $(obj)/vdso/vdso-offsets.h: $(obj)/vdso

  # vDSO - this must be built first to generate the symbol offsets
+ifeq ($(CONFIG_ARM64_ILP32),y)
  $(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
  $(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
+endif
--
1.8.4.5

On 2016/4/6 6:08, Yury Norov wrote:
> From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
>
> ILP32 VDSO exports next symbols:
>   __kernel_rt_sigreturn;
>   __kernel_gettimeofday;
>   __kernel_clock_gettime;
>   __kernel_clock_getres;
>
> What shared object to use, kernel selects depending on result of
> is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
> correct pages and spec.
>
> Adjusted to move the move data page before code pages in sync with
> commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1
>
> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
>   arch/arm64/include/asm/vdso.h                 |  6 ++
>   arch/arm64/kernel/Makefile                    |  5 ++
>   arch/arm64/kernel/signal.c                    |  2 +
>   arch/arm64/kernel/vdso-ilp32/.gitignore       |  2 +
>   arch/arm64/kernel/vdso-ilp32/Makefile         | 72 ++++++++++++++++++++
>   arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     | 33 ++++++++++
>   arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++
>   arch/arm64/kernel/vdso.c                      | 61 ++++++++++++++---
>   8 files changed, 266 insertions(+), 10 deletions(-)
>   create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
>   create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
>   create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
>   create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
>
> diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
> index 839ce00..649a9a4 100644
> --- a/arch/arm64/include/asm/vdso.h
> +++ b/arch/arm64/include/asm/vdso.h
> @@ -29,6 +29,12 @@
>
>   #include <generated/vdso-offsets.h>
>
> +#ifdef CONFIG_ARM64_ILP32
> +#include <generated/vdso-ilp32-offsets.h>
> +#else
> +#define vdso_offset_sigtramp_ilp32
> +#endif
> +
>   #define VDSO_SYMBOL(base, name)						   \
>   ({									   \
>   	(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 09e4373..b43ff12 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
>   arm64-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
>
>   obj-y					+= $(arm64-obj-y) vdso/
> +obj-$(CONFIG_ARM64_ILP32)		+= vdso-ilp32/
>   obj-m					+= $(arm64-obj-m)
>   head-y					:= head.o
>   extra-y					+= $(head-y) vmlinux.lds
> @@ -57,3 +58,7 @@ extra-y					+= $(head-y) vmlinux.lds
>   # vDSO - this must be built first to generate the symbol offsets
>   $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
>   $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
> +
> +# vDSO - this must be built first to generate the symbol offsets
> +$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
> +$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 45bcd96..933cdcf 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -264,6 +264,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
>
>   	if (ka->sa.sa_flags & SA_RESTORER)
>   		sigtramp = ka->sa.sa_restorer;
> +	else if (is_ilp32_compat_task())
> +		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
>   	else
>   		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
>
> diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore
> new file mode 100644
> index 0000000..61806c3
> --- /dev/null
> +++ b/arch/arm64/kernel/vdso-ilp32/.gitignore
> @@ -0,0 +1,2 @@
> +vdso-ilp32.lds
> +vdso-ilp32-offsets.h
> diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile
> new file mode 100644
> index 0000000..c8f5472
> --- /dev/null
> +++ b/arch/arm64/kernel/vdso-ilp32/Makefile
> @@ -0,0 +1,72 @@
> +#
> +# Building a vDSO image for AArch64.
> +#
> +# Author: Will Deacon <will.deacon@arm.com>
> +# Heavily based on the vDSO Makefiles for other archs.
> +#
> +
> +obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o
> +
> +# Build rules
> +targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
> +obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))
> +
> +ccflags-y := -shared -fno-common -fno-builtin
> +ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
> +		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
> +
> +obj-y += vdso-ilp32.o
> +extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h
> +CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32
> +
> +# Force dependency (incbin is bad)
> +$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so
> +
> +# Link rule for the .so file, .lds has to be first
> +$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
> +	$(call if_changed,vdso-ilp32ld)
> +
> +# Strip rule for the .so file
> +$(obj)/%.so: OBJCOPYFLAGS := -S
> +$(obj)/%.so: $(obj)/%.so.dbg FORCE
> +	$(call if_changed,objcopy)
> +
> +# Generate VDSO offsets using helper script
> +gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
> +quiet_cmd_vdsosym = VDSOSYM $@
> +define cmd_vdsosym
> +	$(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
> +	cp $@ include/generated/
> +endef
> +
> +$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
> +	$(call if_changed,vdsosym)
> +
> +# Assembly rules for the .S files
> +#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
> +#	$(call if_changed_dep,vdso-ilp32as)
> +
> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
> +	$(call if_changed_dep,vdso-ilp32as)
> +
> +$(obj)/note-ilp32.o: $(src)/../vdso/note.S
> +	$(call if_changed_dep,vdso-ilp32as)
> +
> +$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
> +	$(call if_changed_dep,vdso-ilp32as)
> +
> +# Actual build commands
> +quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
> +      cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32  -Wl,-n -Wl,-T $^ -o $@
> +quiet_cmd_vdso-ilp32as = VDSOILP32A $@
> +      cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<
> +
> +# Install commands for the unstripped file
> +quiet_cmd_vdso_install = INSTALL $@
> +      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
> +
> +vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
> +	@mkdir -p $(MODLIB)/vdso
> +	$(call cmd,vdso_install)
> +
> +vdso_install: vdso-ilp32.so
> diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
> new file mode 100644
> index 0000000..46ac072
> --- /dev/null
> +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
> @@ -0,0 +1,33 @@
> +/*
> + * Copyright (C) 2012 ARM Limited
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Author: Will Deacon <will.deacon@arm.com>
> + */
> +
> +#include <linux/init.h>
> +#include <linux/linkage.h>
> +#include <linux/const.h>
> +#include <asm/page.h>
> +
> +	__PAGE_ALIGNED_DATA
> +
> +	.globl vdso_ilp32_start, vdso_ilp32_end
> +	.balign PAGE_SIZE
> +vdso_ilp32_start:
> +	.incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
> +	.balign PAGE_SIZE
> +vdso_ilp32_end:
> +
> +	.previous
> diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> new file mode 100644
> index 0000000..ddc63fd
> --- /dev/null
> +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> @@ -0,0 +1,95 @@
> +/*
> + * GNU linker script for the VDSO library.
> + *
> + * Copyright (C) 2012 ARM Limited
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Author: Will Deacon <will.deacon@arm.com>
> + * Heavily based on the vDSO linker scripts for other archs.
> + */
> +
> +#include <linux/const.h>
> +#include <asm/page.h>
> +#include <asm/vdso.h>
> +
> +SECTIONS
> +{
> +	PROVIDE(_vdso_data = . - PAGE_SIZE);
> +	. = VDSO_LBASE + SIZEOF_HEADERS;
> +
> +	.hash		: { *(.hash) }			:text
> +	.gnu.hash	: { *(.gnu.hash) }
> +	.dynsym		: { *(.dynsym) }
> +	.dynstr		: { *(.dynstr) }
> +	.gnu.version	: { *(.gnu.version) }
> +	.gnu.version_d	: { *(.gnu.version_d) }
> +	.gnu.version_r	: { *(.gnu.version_r) }
> +
> +	.note		: { *(.note.*) }		:text	:note
> +
> +	. = ALIGN(16);
> +
> +	.text		: { *(.text*) }			:text	=0xd503201f
> +	PROVIDE (__etext = .);
> +	PROVIDE (_etext = .);
> +	PROVIDE (etext = .);
> +
> +	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
> +	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
> +
> +	.dynamic	: { *(.dynamic) }		:text	:dynamic
> +
> +	.rodata		: { *(.rodata*) }		:text
> +
> +	_end = .;
> +	PROVIDE(end = .);
> +
> +	/DISCARD/	: {
> +		*(.note.GNU-stack)
> +		*(.data .data.* .gnu.linkonce.d.* .sdata*)
> +		*(.bss .sbss .dynbss .dynsbss)
> +	}
> +}
> +
> +/*
> + * We must supply the ELF program headers explicitly to get just one
> + * PT_LOAD segment, and set the flags explicitly to make segments read-only.
> + */
> +PHDRS
> +{
> +	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
> +	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
> +	note		PT_NOTE		FLAGS(4);		/* PF_R */
> +	eh_frame_hdr	PT_GNU_EH_FRAME;
> +}
> +
> +/*
> + * This controls what symbols we export from the DSO.
> + */
> +VERSION
> +{
> +	LINUX_2.6 {
> +	global:
> +		__kernel_rt_sigreturn;
> +		__kernel_gettimeofday;
> +		__kernel_clock_gettime;
> +		__kernel_clock_getres;
> +	local: *;
> +	};
> +}
> +
> +/*
> + * Make the sigreturn code visible to the kernel.
> + */
> +VDSO_sigtramp_ilp32		= __kernel_rt_sigreturn;
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index 26352a6..521a8e4 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -40,6 +40,12 @@ extern char vdso_start, vdso_end;
>   static unsigned long vdso_pages;
>   static struct page **vdso_pagelist;
>
> +#ifdef CONFIG_ARM64_ILP32
> +extern char vdso_ilp32_start, vdso_ilp32_end;
> +static unsigned long vdso_ilp32_pages;
> +static struct page **vdso_ilp32_pagelist;
> +#endif
> +
>   /*
>    * The vDSO data page.
>    */
> @@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
>   }
>   #endif /* CONFIG_AARCH32_EL0 */
>
> -static struct vm_special_mapping vdso_spec[2];
> -
> -static int __init vdso_init(void)
> +static int __init vdso_init_common(char *vdso_start, char *vdso_end,
> +					  unsigned long *vdso_pagesp,
> +					  struct page ***vdso_pagelistp,
> +					  struct vm_special_mapping* vdso_spec)
>   {
>   	int i;
> +	unsigned long vdso_pages;
> +	struct page **vdso_pagelist;
>
> -	if (memcmp(&vdso_start, "\177ELF", 4)) {
> +	if (memcmp(vdso_start, "\177ELF", 4)) {
>   		pr_err("vDSO is not a valid ELF object!\n");
>   		return -EINVAL;
>   	}
>
> -	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
> +	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
> +	*vdso_pagesp = vdso_pages;
>   	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
> -		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
> +		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
>
>   	/* Allocate the vDSO pagelist, plus a page for the data. */
>   	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
>   				GFP_KERNEL);
> +	*vdso_pagelistp = vdso_pagelist;
>   	if (vdso_pagelist == NULL)
>   		return -ENOMEM;
>
> @@ -135,7 +146,7 @@ static int __init vdso_init(void)
>
>   	/* Grab the vDSO code pages. */
>   	for (i = 0; i < vdso_pages; i++)
> -		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
> +		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
>
>   	/* Populate the special mapping structures */
>   	vdso_spec[0] = (struct vm_special_mapping) {
> @@ -150,16 +161,46 @@ static int __init vdso_init(void)
>
>   	return 0;
>   }
> +
> +static struct vm_special_mapping vdso_spec[2];
> +
> +static int __init vdso_init(void)
> +{
> +	return vdso_init_common(&vdso_start, &vdso_end,
> +				&vdso_pages, &vdso_pagelist,
> +				vdso_spec);
> +}
>   arch_initcall(vdso_init);
>
> +#ifdef CONFIG_ARM64_ILP32
> +static struct vm_special_mapping vdso_ilp32_spec[2];
> +
> +static int __init vdso_ilp32_init(void)
> +{
> +	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
> +				&vdso_ilp32_pages, &vdso_ilp32_pagelist,
> +				vdso_ilp32_spec);
> +}
> +arch_initcall(vdso_ilp32_init);
> +#endif
> +
>   int arch_setup_additional_pages(struct linux_binprm *bprm,
>   				int uses_interp)
>   {
>   	struct mm_struct *mm = current->mm;
>   	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
>   	void *ret;
> +	unsigned long pages = vdso_pages;
> +	struct vm_special_mapping *spec = vdso_spec;
> +
> +#ifdef CONFIG_ARM64_ILP32
> +	if (is_ilp32_compat_task()) {
> +	        pages = vdso_ilp32_pages;
> +	        spec = vdso_ilp32_spec;
> +	}
> +#endif
>
> -	vdso_text_len = vdso_pages << PAGE_SHIFT;
> +	vdso_text_len = pages << PAGE_SHIFT;
>   	/* Be sure to map the data page */
>   	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
>
> @@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>   	}
>   	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
>   				       VM_READ|VM_MAYREAD,
> -				       &vdso_spec[0]);
> +				       &spec[0]);
>   	if (IS_ERR(ret))
>   		goto up_fail;
>
> @@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>   	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
>   				       VM_READ|VM_EXEC|
>   				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> -				       &vdso_spec[1]);
> +				       &spec[1]);
>   	if (IS_ERR(ret))
>   		goto up_fail;
>
>

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-13  9:19   ` Zhangjian (Bamvor)
@ 2016-04-13 15:55     ` Yury Norov
  2016-05-03 12:49       ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-13 15:55 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel,
	schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Philipp Tomsich

Hi Bamvor,

On Wed, Apr 13, 2016 at 05:19:28PM +0800, Zhangjian (Bamvor) wrote:
> Hi, Yury and Philipp
> 
> There is a small fix for this patch. Othervise our tools of living
> patch could not work.
> 
> Regards
> 
> Bamvor
> 
> From e05770efca9f040e0039a4a9c4e0d7d3b2bd13e8 Mon Sep 17 00:00:00 2001
> From: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
> Date: Wed, 13 Apr 2016 15:46:28 +0800
> Subject: [PATCH] arm64: ilp32: do not check vdso-ilp32-offsets.h when ILP32
>  disabled
> 
> vdso-ilp32-offsets.h is the dependency of all the arm64-obj-y. And
> it does not exist when CONFIG_ARM64_ILP32 is disable which lead to
> all the arm64-obj-y are re-built unnecessarily.
> 
> Such rebuild may confuse the sofware(e.g. tools of living patch)
> which need to know exactly which file(s) is(are) updated.
> 
> This patch fix this issue by adding the config checker.

It looks reasonable and correct.

I'll apply your patch in next submission (if it will be needed),
otherwise I think, Arnd may apply it. 

Though, I don't understand much, what 'tools of living patch' means.
Could you explain in details what you do, and what goes wrong?

Nevertheless, thank you for your attention to this patchset.

Yury.

> 
> Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
> ---
>  arch/arm64/kernel/Makefile | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index b43ff12..0f27a10 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -60,5 +60,7 @@ $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
>  $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
> 
>  # vDSO - this must be built first to generate the symbol offsets
> +ifeq ($(CONFIG_ARM64_ILP32),y)
>  $(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
>  $(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
> +endif
> --
> 1.8.4.5
> 
> On 2016/4/6 6:08, Yury Norov wrote:
> >From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> >
> >ILP32 VDSO exports next symbols:
> >  __kernel_rt_sigreturn;
> >  __kernel_gettimeofday;
> >  __kernel_clock_gettime;
> >  __kernel_clock_getres;
> >
> >What shared object to use, kernel selects depending on result of
> >is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
> >correct pages and spec.
> >
> >Adjusted to move the move data page before code pages in sync with
> >commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1
> >
> >Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> >Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
> >Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> >---
> >  arch/arm64/include/asm/vdso.h                 |  6 ++
> >  arch/arm64/kernel/Makefile                    |  5 ++
> >  arch/arm64/kernel/signal.c                    |  2 +
> >  arch/arm64/kernel/vdso-ilp32/.gitignore       |  2 +
> >  arch/arm64/kernel/vdso-ilp32/Makefile         | 72 ++++++++++++++++++++
> >  arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     | 33 ++++++++++
> >  arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++
> >  arch/arm64/kernel/vdso.c                      | 61 ++++++++++++++---
> >  8 files changed, 266 insertions(+), 10 deletions(-)
> >  create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
> >  create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
> >  create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
> >  create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> >
> >diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
> >index 839ce00..649a9a4 100644
> >--- a/arch/arm64/include/asm/vdso.h
> >+++ b/arch/arm64/include/asm/vdso.h
> >@@ -29,6 +29,12 @@
> >
> >  #include <generated/vdso-offsets.h>
> >
> >+#ifdef CONFIG_ARM64_ILP32
> >+#include <generated/vdso-ilp32-offsets.h>
> >+#else
> >+#define vdso_offset_sigtramp_ilp32
> >+#endif
> >+
> >  #define VDSO_SYMBOL(base, name)						   \
> >  ({									   \
> >  	(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
> >diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> >index 09e4373..b43ff12 100644
> >--- a/arch/arm64/kernel/Makefile
> >+++ b/arch/arm64/kernel/Makefile
> >@@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
> >  arm64-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
> >
> >  obj-y					+= $(arm64-obj-y) vdso/
> >+obj-$(CONFIG_ARM64_ILP32)		+= vdso-ilp32/
> >  obj-m					+= $(arm64-obj-m)
> >  head-y					:= head.o
> >  extra-y					+= $(head-y) vmlinux.lds
> >@@ -57,3 +58,7 @@ extra-y					+= $(head-y) vmlinux.lds
> >  # vDSO - this must be built first to generate the symbol offsets
> >  $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
> >  $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
> >+
> >+# vDSO - this must be built first to generate the symbol offsets
> >+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
> >+$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
> >diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> >index 45bcd96..933cdcf 100644
> >--- a/arch/arm64/kernel/signal.c
> >+++ b/arch/arm64/kernel/signal.c
> >@@ -264,6 +264,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
> >
> >  	if (ka->sa.sa_flags & SA_RESTORER)
> >  		sigtramp = ka->sa.sa_restorer;
> >+	else if (is_ilp32_compat_task())
> >+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> >  	else
> >  		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> >
> >diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore
> >new file mode 100644
> >index 0000000..61806c3
> >--- /dev/null
> >+++ b/arch/arm64/kernel/vdso-ilp32/.gitignore
> >@@ -0,0 +1,2 @@
> >+vdso-ilp32.lds
> >+vdso-ilp32-offsets.h
> >diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile
> >new file mode 100644
> >index 0000000..c8f5472
> >--- /dev/null
> >+++ b/arch/arm64/kernel/vdso-ilp32/Makefile
> >@@ -0,0 +1,72 @@
> >+#
> >+# Building a vDSO image for AArch64.
> >+#
> >+# Author: Will Deacon <will.deacon@arm.com>
> >+# Heavily based on the vDSO Makefiles for other archs.
> >+#
> >+
> >+obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o
> >+
> >+# Build rules
> >+targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
> >+obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))
> >+
> >+ccflags-y := -shared -fno-common -fno-builtin
> >+ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
> >+		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
> >+
> >+obj-y += vdso-ilp32.o
> >+extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h
> >+CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32
> >+
> >+# Force dependency (incbin is bad)
> >+$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so
> >+
> >+# Link rule for the .so file, .lds has to be first
> >+$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
> >+	$(call if_changed,vdso-ilp32ld)
> >+
> >+# Strip rule for the .so file
> >+$(obj)/%.so: OBJCOPYFLAGS := -S
> >+$(obj)/%.so: $(obj)/%.so.dbg FORCE
> >+	$(call if_changed,objcopy)
> >+
> >+# Generate VDSO offsets using helper script
> >+gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
> >+quiet_cmd_vdsosym = VDSOSYM $@
> >+define cmd_vdsosym
> >+	$(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
> >+	cp $@ include/generated/
> >+endef
> >+
> >+$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
> >+	$(call if_changed,vdsosym)
> >+
> >+# Assembly rules for the .S files
> >+#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
> >+#	$(call if_changed_dep,vdso-ilp32as)
> >+
> >+$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
> >+	$(call if_changed_dep,vdso-ilp32as)
> >+
> >+$(obj)/note-ilp32.o: $(src)/../vdso/note.S
> >+	$(call if_changed_dep,vdso-ilp32as)
> >+
> >+$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
> >+	$(call if_changed_dep,vdso-ilp32as)
> >+
> >+# Actual build commands
> >+quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
> >+      cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32  -Wl,-n -Wl,-T $^ -o $@
> >+quiet_cmd_vdso-ilp32as = VDSOILP32A $@
> >+      cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<
> >+
> >+# Install commands for the unstripped file
> >+quiet_cmd_vdso_install = INSTALL $@
> >+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
> >+
> >+vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
> >+	@mkdir -p $(MODLIB)/vdso
> >+	$(call cmd,vdso_install)
> >+
> >+vdso_install: vdso-ilp32.so
> >diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
> >new file mode 100644
> >index 0000000..46ac072
> >--- /dev/null
> >+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
> >@@ -0,0 +1,33 @@
> >+/*
> >+ * Copyright (C) 2012 ARM Limited
> >+ *
> >+ * This program is free software; you can redistribute it and/or modify
> >+ * it under the terms of the GNU General Public License version 2 as
> >+ * published by the Free Software Foundation.
> >+ *
> >+ * This program is distributed in the hope that it will be useful,
> >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >+ * GNU General Public License for more details.
> >+ *
> >+ * You should have received a copy of the GNU General Public License
> >+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >+ *
> >+ * Author: Will Deacon <will.deacon@arm.com>
> >+ */
> >+
> >+#include <linux/init.h>
> >+#include <linux/linkage.h>
> >+#include <linux/const.h>
> >+#include <asm/page.h>
> >+
> >+	__PAGE_ALIGNED_DATA
> >+
> >+	.globl vdso_ilp32_start, vdso_ilp32_end
> >+	.balign PAGE_SIZE
> >+vdso_ilp32_start:
> >+	.incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
> >+	.balign PAGE_SIZE
> >+vdso_ilp32_end:
> >+
> >+	.previous
> >diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> >new file mode 100644
> >index 0000000..ddc63fd
> >--- /dev/null
> >+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> >@@ -0,0 +1,95 @@
> >+/*
> >+ * GNU linker script for the VDSO library.
> >+ *
> >+ * Copyright (C) 2012 ARM Limited
> >+ *
> >+ * This program is free software; you can redistribute it and/or modify
> >+ * it under the terms of the GNU General Public License version 2 as
> >+ * published by the Free Software Foundation.
> >+ *
> >+ * This program is distributed in the hope that it will be useful,
> >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >+ * GNU General Public License for more details.
> >+ *
> >+ * You should have received a copy of the GNU General Public License
> >+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >+ *
> >+ * Author: Will Deacon <will.deacon@arm.com>
> >+ * Heavily based on the vDSO linker scripts for other archs.
> >+ */
> >+
> >+#include <linux/const.h>
> >+#include <asm/page.h>
> >+#include <asm/vdso.h>
> >+
> >+SECTIONS
> >+{
> >+	PROVIDE(_vdso_data = . - PAGE_SIZE);
> >+	. = VDSO_LBASE + SIZEOF_HEADERS;
> >+
> >+	.hash		: { *(.hash) }			:text
> >+	.gnu.hash	: { *(.gnu.hash) }
> >+	.dynsym		: { *(.dynsym) }
> >+	.dynstr		: { *(.dynstr) }
> >+	.gnu.version	: { *(.gnu.version) }
> >+	.gnu.version_d	: { *(.gnu.version_d) }
> >+	.gnu.version_r	: { *(.gnu.version_r) }
> >+
> >+	.note		: { *(.note.*) }		:text	:note
> >+
> >+	. = ALIGN(16);
> >+
> >+	.text		: { *(.text*) }			:text	=0xd503201f
> >+	PROVIDE (__etext = .);
> >+	PROVIDE (_etext = .);
> >+	PROVIDE (etext = .);
> >+
> >+	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
> >+	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
> >+
> >+	.dynamic	: { *(.dynamic) }		:text	:dynamic
> >+
> >+	.rodata		: { *(.rodata*) }		:text
> >+
> >+	_end = .;
> >+	PROVIDE(end = .);
> >+
> >+	/DISCARD/	: {
> >+		*(.note.GNU-stack)
> >+		*(.data .data.* .gnu.linkonce.d.* .sdata*)
> >+		*(.bss .sbss .dynbss .dynsbss)
> >+	}
> >+}
> >+
> >+/*
> >+ * We must supply the ELF program headers explicitly to get just one
> >+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
> >+ */
> >+PHDRS
> >+{
> >+	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
> >+	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
> >+	note		PT_NOTE		FLAGS(4);		/* PF_R */
> >+	eh_frame_hdr	PT_GNU_EH_FRAME;
> >+}
> >+
> >+/*
> >+ * This controls what symbols we export from the DSO.
> >+ */
> >+VERSION
> >+{
> >+	LINUX_2.6 {
> >+	global:
> >+		__kernel_rt_sigreturn;
> >+		__kernel_gettimeofday;
> >+		__kernel_clock_gettime;
> >+		__kernel_clock_getres;
> >+	local: *;
> >+	};
> >+}
> >+
> >+/*
> >+ * Make the sigreturn code visible to the kernel.
> >+ */
> >+VDSO_sigtramp_ilp32		= __kernel_rt_sigreturn;
> >diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> >index 26352a6..521a8e4 100644
> >--- a/arch/arm64/kernel/vdso.c
> >+++ b/arch/arm64/kernel/vdso.c
> >@@ -40,6 +40,12 @@ extern char vdso_start, vdso_end;
> >  static unsigned long vdso_pages;
> >  static struct page **vdso_pagelist;
> >
> >+#ifdef CONFIG_ARM64_ILP32
> >+extern char vdso_ilp32_start, vdso_ilp32_end;
> >+static unsigned long vdso_ilp32_pages;
> >+static struct page **vdso_ilp32_pagelist;
> >+#endif
> >+
> >  /*
> >   * The vDSO data page.
> >   */
> >@@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
> >  }
> >  #endif /* CONFIG_AARCH32_EL0 */
> >
> >-static struct vm_special_mapping vdso_spec[2];
> >-
> >-static int __init vdso_init(void)
> >+static int __init vdso_init_common(char *vdso_start, char *vdso_end,
> >+					  unsigned long *vdso_pagesp,
> >+					  struct page ***vdso_pagelistp,
> >+					  struct vm_special_mapping* vdso_spec)
> >  {
> >  	int i;
> >+	unsigned long vdso_pages;
> >+	struct page **vdso_pagelist;
> >
> >-	if (memcmp(&vdso_start, "\177ELF", 4)) {
> >+	if (memcmp(vdso_start, "\177ELF", 4)) {
> >  		pr_err("vDSO is not a valid ELF object!\n");
> >  		return -EINVAL;
> >  	}
> >
> >-	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
> >+	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
> >+	*vdso_pagesp = vdso_pages;
> >  	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
> >-		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
> >+		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
> >
> >  	/* Allocate the vDSO pagelist, plus a page for the data. */
> >  	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
> >  				GFP_KERNEL);
> >+	*vdso_pagelistp = vdso_pagelist;
> >  	if (vdso_pagelist == NULL)
> >  		return -ENOMEM;
> >
> >@@ -135,7 +146,7 @@ static int __init vdso_init(void)
> >
> >  	/* Grab the vDSO code pages. */
> >  	for (i = 0; i < vdso_pages; i++)
> >-		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
> >+		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
> >
> >  	/* Populate the special mapping structures */
> >  	vdso_spec[0] = (struct vm_special_mapping) {
> >@@ -150,16 +161,46 @@ static int __init vdso_init(void)
> >
> >  	return 0;
> >  }
> >+
> >+static struct vm_special_mapping vdso_spec[2];
> >+
> >+static int __init vdso_init(void)
> >+{
> >+	return vdso_init_common(&vdso_start, &vdso_end,
> >+				&vdso_pages, &vdso_pagelist,
> >+				vdso_spec);
> >+}
> >  arch_initcall(vdso_init);
> >
> >+#ifdef CONFIG_ARM64_ILP32
> >+static struct vm_special_mapping vdso_ilp32_spec[2];
> >+
> >+static int __init vdso_ilp32_init(void)
> >+{
> >+	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
> >+				&vdso_ilp32_pages, &vdso_ilp32_pagelist,
> >+				vdso_ilp32_spec);
> >+}
> >+arch_initcall(vdso_ilp32_init);
> >+#endif
> >+
> >  int arch_setup_additional_pages(struct linux_binprm *bprm,
> >  				int uses_interp)
> >  {
> >  	struct mm_struct *mm = current->mm;
> >  	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
> >  	void *ret;
> >+	unsigned long pages = vdso_pages;
> >+	struct vm_special_mapping *spec = vdso_spec;
> >+
> >+#ifdef CONFIG_ARM64_ILP32
> >+	if (is_ilp32_compat_task()) {
> >+	        pages = vdso_ilp32_pages;
> >+	        spec = vdso_ilp32_spec;
> >+	}
> >+#endif
> >
> >-	vdso_text_len = vdso_pages << PAGE_SHIFT;
> >+	vdso_text_len = pages << PAGE_SHIFT;
> >  	/* Be sure to map the data page */
> >  	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
> >
> >@@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
> >  	}
> >  	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
> >  				       VM_READ|VM_MAYREAD,
> >-				       &vdso_spec[0]);
> >+				       &spec[0]);
> >  	if (IS_ERR(ret))
> >  		goto up_fail;
> >
> >@@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
> >  	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
> >  				       VM_READ|VM_EXEC|
> >  				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> >-				       &vdso_spec[1]);
> >+				       &spec[1]);
> >  	if (IS_ERR(ret))
> >  		goto up_fail;
> >
> >

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

* Re: [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  2016-04-05 22:08 ` [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig Yury Norov
@ 2016-04-14  3:20   ` Zhangjian (Bamvor)
  2016-04-22 15:28     ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-04-14  3:20 UTC (permalink / raw)
  To: Yury Norov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Andrew Pinski, Andrew Pinski, Philipp Tomsich, Hanjun Guo,
	Zhangjian (Bamvor)

Hi, yury

I suggest we enable AARCH32_EL0 by default explicitly. I am not sure
if it should be a dedicated commit. I am ok if you merge my commit, add

Reviewed-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>

commit 926ad48847c9fbc665285c49ff823666e145a083
Author: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
Date:   Wed Apr 6 17:59:03 2016 +0800

     arm64: enable aarch32 application by default

     After introduce the AARCH32_EL0. The aarch32 application is disabled
     by default which was enabled by default. And the aarch32 application
     could not run on these kernels consequently.

     This commit enable it in Kconfig explicitly.

     Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 19d8e31..3b543c7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -934,6 +934,7 @@ config AARCH32_EL0
         select HAVE_UID16
         select OLD_SIGSUSPEND3
         select COMPAT_OLD_SIGACTION
+       default y
         help
           This option enables support for a 32-bit EL0 running under a 64-bit
           kernel at EL1. AArch32-specific components such as system calls,


On 2016/4/6 6:08, Yury Norov wrote:
> From: Andrew Pinski <apinski@cavium.com>
>
> In this patchset  ILP32 ABI support is added. Additionally to AARCH32,
> which is binary-compatible with ARM, ILP32 is (mostly) ABI-compatible.
>
>  From now, AARCH32_EL0 (former COMPAT) config option means the support of
> AARCH32 userspace, ARM64_ILP32 - support of ILP32 ABI (see next patches),
> and COMPAT indicates that one of them, or both, is enabled.
>
> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> Reviewed-by: David Daney <ddaney@caviumnetworks.com>
> ---
>   arch/arm64/Kconfig | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 4f43622..f923687 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -925,6 +925,10 @@ menu "Userspace binary formats"
>   source "fs/Kconfig.binfmt"
>
>   config COMPAT
> +	def_bool y
> +	depends on AARCH32_EL0
> +
> +config AARCH32_EL0
>   	bool "Kernel support for 32-bit EL0"
>   	depends on ARM64_4K_PAGES || EXPERT
>   	select COMPAT_BINFMT_ELF
>

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

* Re: [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  2016-04-14  3:20   ` Zhangjian (Bamvor)
@ 2016-04-22 15:28     ` Catalin Marinas
  0 siblings, 0 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-04-22 15:28 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Yury Norov, arnd, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, Hanjun Guo, pinskia, Prasun.Kapoor, heiko.carstens,
	linux-doc, Nathan_Lynch, agraf, klimov.linux, Andrew Pinski,
	broonie, Andrew Pinski, schwab, schwidefsky, Philipp Tomsich,
	joseph, christoph.muellner

On Thu, Apr 14, 2016 at 11:20:29AM +0800, Zhangjian (Bamvor) wrote:
> I suggest we enable AARCH32_EL0 by default explicitly. I am not sure
> if it should be a dedicated commit. I am ok if you merge my commit, add

We currently enable COMPAT in defconfig. I think we keep the same
approach and change CONFIG_COMPAT to CONFIG_AARCH32_EL0 in defconfig.

-- 
Catalin

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

* Re: [PATCH 12/25] arm64: compat: change config dependences to aarch32
  2016-04-05 22:08 ` [PATCH 12/25] arm64: compat: change config dependences to aarch32 Yury Norov
@ 2016-04-22 15:58   ` Catalin Marinas
  2016-04-22 21:59     ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-22 15:58 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, Bamvor Jian Zhang, joseph,
	christoph.muellner

On Wed, Apr 06, 2016 at 01:08:34AM +0300, Yury Norov wrote:
> From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> 
> With the patches of ILP32, COMPAT is not equivalent to AARCH32 in EL0.
> This patch fix this by updating the dependency from COMPAT to
> AARCH32_EL0 for ARMV8_DEPRECATED and ARM64_ERRATUM_845719.
> 
> Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>

Can you not merge patches 10-12 into a single one? They all deal with
the s/COMPAT/AARCH32_EL0/ replacement. I'm not even sure the series is
bisectable after patch 10.

-- 
Catalin

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

* Re: [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c
  2016-04-05 22:08 ` [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c Yury Norov
@ 2016-04-22 16:51   ` Catalin Marinas
  2016-04-22 17:41     ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-22 16:51 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, joseph, christoph.muellner

On Wed, Apr 06, 2016 at 01:08:40AM +0300, Yury Norov wrote:
> --- /dev/null
> +++ b/arch/arm64/kernel/binfmt_ilp32.c

[...]

> +#include "../../../fs/binfmt_elf.c"

How different is this new binfmt_ilp32.c file from the first part of
compat_binfmt_elf.c? I wonder whether we could include the latter here
instead and make this similar to binfmt_elf32.c introduced by the
previous patch.

-- 
Catalin

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

* Re: [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
  2016-04-05 22:08 ` [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32 Yury Norov
@ 2016-04-22 17:10   ` Catalin Marinas
  2016-04-22 21:40     ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-22 17:10 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, joseph, christoph.muellner

On Wed, Apr 06, 2016 at 01:08:41AM +0300, Yury Norov wrote:
> Here new aarch32 ptrace syscall handler is introsuced to avoid run-time
> detection of the task type.

The reason for this patch isn't clear to me. What's wrong with the
run-time detection? It's not some performance critical code.

-- 
Catalin

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

* Re: [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c
  2016-04-22 16:51   ` Catalin Marinas
@ 2016-04-22 17:41     ` Arnd Bergmann
  0 siblings, 0 replies; 135+ messages in thread
From: Arnd Bergmann @ 2016-04-22 17:41 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Yury Norov, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, joseph, christoph.muellner

On Friday 22 April 2016 17:51:30 Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:40AM +0300, Yury Norov wrote:
> > --- /dev/null
> > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> 
> [...]
> 
> > +#include "../../../fs/binfmt_elf.c"
> 
> How different is this new binfmt_ilp32.c file from the first part of
> compat_binfmt_elf.c? I wonder whether we could include the latter here
> instead and make this similar to binfmt_elf32.c introduced by the
> previous patch.

That is how the earlier versions did it, and I thought it ended up 
too ugly with lots of runtime checks instead of compile-time checks.

The current version is how I asked it to be done. A slight
variation would be to keep using fs/compat_binfmt_elf.c for one
of the two compat modes (today it is used for aarch32) and have
a separate file include "../../../fs/binfmt_elf.c" for the other
mode (as this patch does for ilp32). I think that is what I asked
for, but there was probably a good reason for having two files
in the same directory. The result is basically the same.

	Arnd

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

* Re: [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
  2016-04-22 17:10   ` Catalin Marinas
@ 2016-04-22 21:40     ` Yury Norov
  2016-04-25 16:57       ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-22 21:40 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, joseph, christoph.muellner

On Fri, Apr 22, 2016 at 06:10:09PM +0100, Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:41AM +0300, Yury Norov wrote:
> > Here new aarch32 ptrace syscall handler is introsuced to avoid run-time
> > detection of the task type.
> 
> The reason for this patch isn't clear to me. What's wrong with the
> run-time detection? It's not some performance critical code.
> 
> -- 
> Catalin

Hi Catalin,

It was requested by Arnd, 
It's not 'new' syscall basically,
just an attempt to avoid run-time 
detection of things that may be
detected an compile-time.

Yury.

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

* Re: [PATCH 12/25] arm64: compat: change config dependences to aarch32
  2016-04-22 15:58   ` Catalin Marinas
@ 2016-04-22 21:59     ` Yury Norov
  2016-04-23  2:33       ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-22 21:59 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, Bamvor Jian Zhang, joseph,
	christoph.muellner

On Fri, Apr 22, 2016 at 04:58:18PM +0100, Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:34AM +0300, Yury Norov wrote:
> > From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> > 
> > With the patches of ILP32, COMPAT is not equivalent to AARCH32 in EL0.
> > This patch fix this by updating the dependency from COMPAT to
> > AARCH32_EL0 for ARMV8_DEPRECATED and ARM64_ERRATUM_845719.
> > 
> > Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> > Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> 
> Can you not merge patches 10-12 into a single one? They all deal with
> the s/COMPAT/AARCH32_EL0/ replacement. I'm not even sure the series is
> bisectable after patch 10.
> 
> -- 
> Catalin

 OK, if Bamvoor is not objecting
 

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

* Re: [PATCH 12/25] arm64: compat: change config dependences to aarch32
  2016-04-22 21:59     ` Yury Norov
@ 2016-04-23  2:33       ` Zhangjian (Bamvor)
  0 siblings, 0 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-04-23  2:33 UTC (permalink / raw)
  To: Yury Norov, Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, schwidefsky, Nathan_Lynch,
	Bamvor Jian Zhang, joseph, christoph.muellner, Hanjun Guo,
	Bamvor Zhang Jian

Hi, Yury

On 2016/4/23 5:59, Yury Norov wrote:
> On Fri, Apr 22, 2016 at 04:58:18PM +0100, Catalin Marinas wrote:
>> On Wed, Apr 06, 2016 at 01:08:34AM +0300, Yury Norov wrote:
>>> From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
>>>
>>> With the patches of ILP32, COMPAT is not equivalent to AARCH32 in EL0.
>>> This patch fix this by updating the dependency from COMPAT to
>>> AARCH32_EL0 for ARMV8_DEPRECATED and ARM64_ERRATUM_845719.
>>>
>>> Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
>>> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
>>
>> Can you not merge patches 10-12 into a single one? They all deal with
>> the s/COMPAT/AARCH32_EL0/ replacement. I'm not even sure the series is
>> bisectable after patch 10.
>>
>> --
>> Catalin
>
>   OK, if Bamvoor is not objecting
It is ok.

Bamvor
>
>

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results
  2016-04-05 22:44 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results Yury Norov
@ 2016-04-23  3:37   ` Zhangjian (Bamvor)
  2016-04-27  7:30     ` Andrew Pinski
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-04-23  3:37 UTC (permalink / raw)
  To: Yury Norov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Hanjun Guo, Zhangjian (Bamvor),
	gcc

[-- Attachment #1: Type: text/plain, Size: 5248 bytes --]

Hi, Yury

On 2016/4/6 6:44, Yury Norov wrote:
> There are about 20 failing tests of 782 in lite scenario.
> float_bessel
> float_exp_log
> float_iperb
> float_power
> float_trigo
> pipeio_1
> pipeio_3
> pipeio_5
> pipeio_8
> abort01
> clone02
> kill11
> mmap16
> open12
> pause01
> rename11
> rmdir02
> umount2_01
> umount2_02
> umount2_03
> utime06
> mtest06
>
> The list is rough because some tests fail not every time.
>
> Tests abort01 and kill11 fail for lp64 too, so maybe there's
> a reason unrelated to ilp32 itself.
>
> float_xxx tests fail because they call unwind() from signal context,
> and GCC for ilp32 has problem with it, as Andrew told.
Is there some progress about this issue. When we talk about unwind
functions, do you mean the function in libgcc?

We encountered another issue(abort not segfault) which also called
pthread_cancel(). The test code is in the attachment. Here is the
backtrace:

```
Program received signal SIGABRT, Aborted.
[Switching to Thread 0xf77ee330 (LWP 2958)]
0x000000000040f5bc in raise (sig=sig@entry=6)
     at ../sysdeps/unix/sysv/linux/raise.c:55
55      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x000000000040f5bc in raise (sig=sig@entry=6)
     at ../sysdeps/unix/sysv/linux/raise.c:55
#1  0x000000000040f884 in abort () at abort.c:89

#2  0x00000000004073b4 in uw_update_context_1 (
     context=context@entry=0xf77ec820, fs=fs@entry=0xf77ebec8)
at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1430

#3  0x00000000004078c0 in uw_update_context (context=context@entry=0xf77ec820,
     fs=fs@entry=0xf77ebec8)
    at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1506
#4  0x0000000000407a9c in uw_advance_context (fs=0xf77ebec8,
     context=0xf77ec820)
     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1529
#5  _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0xf77ee580,
     context=context@entry=0xf77ec820)
     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:185
#6  0x0000000000408228 in _Unwind_ForcedUnwind (exc=0xf77ee580,
     stop=stop@entry=0x405440 <unwind_stop>, stop_argument=0xf77eddd8)
     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:207
#7  0x00000000004055c4 in __pthread_unwind (buf=<optimized out>)
     at unwind.c:126
#8  0x00000000004050b4 in __do_cancel () at ./pthreadP.h:283
#9  sigcancel_handler (sig=<optimized out>, si=<optimized out>,
     ctx=<optimized out>) at nptl-init.c:225
---Type <return> to continue, or q <return> to quit---
#10 <signal handler called>

#11 0x0000000000000000 in ?? ()

#12 0x0000000000423084 in __select (nfds=-66661, readfds=<optimized out>,
     writefds=<optimized out>, exceptfds=<optimized out>, timeout=0x0)
     at ../sysdeps/unix/sysv/linux/generic/select.c:45
#13 0x0000000000400604 in TEST_TaskDelay (
     uiMillSecs=<error reading variable: can't compute CFA for this frame>)
     at test-cancel.c:18
#14 0x0000000000400680 in printids (
     s=<error reading variable: can't compute CFA for this frame>)
     at test-cancel.c:38
#15 0x00000000004006d0 in thr_fn (
     arg=<error reading variable: can't compute CFA for this frame>)
     at test-cancel.c:49
#16 0x0000000000401b28 in start_thread (arg=0x4a3000) at pthread_create.c:335
#17 0x0000000000401b28 in start_thread (arg=0x4a3000) at pthread_create.c:335
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
```

Such abort is raise by the following code:
```
static void
uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
//...
   /* Compute this frame's CFA.  */
   switch (fs->regs.cfa_how)
     {
     case CFA_REG_OFFSET:
       cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
       cfa += fs->regs.cfa_offset;
       break;

     case CFA_EXP:
       {
         const unsigned char *exp = fs->regs.cfa_exp;
         _uleb128_t len;

         exp = read_uleb128 (exp, &len);
         cfa = (void *) (_Unwind_Ptr)
           execute_stack_op (exp, exp + len, &orig_context, 0);
         break;
       }

     default:
       gcc_unreachable ();
     }
   context->cfa = cfa;
//...
}
``

Any suggestion is appreciated.

CC gcc mailing list. Sorry if it is off topic.

Regards

Bamvor



> pipeio_x tests are very unstable and may fail randomly. I strongly
> suspect race conditions, as they all work like a charm if pinned to
> single CPU with taskset. Probably, race is the reason of clone02 too.
> Though I'm not sure, is the race in kernel, glibc or test itself.
>
> But I know for sure that pause01 fails due to test design:
> 	if (setitimer(ITIMER_REAL, &it, NULL)) // For 1000us
> 		tst_brkm(TBROK | TERRNO, NULL, "setitimer() failed");
>
> 	TEST(pause());
>
> As setitimer() and pause() calls are not atomic, alarm may come before pause()
> is called, and be silently dropped by the handler. Next pause() call hangs
> test forever. I already reported to LTP list.
>
> open12, rename11, rmdir02, mmap16, mtest06 - all call mkfs tool, and it returns
> error code. I didn't investigate it much yet.
>
> umount02_x, utime06 - cannot reproduce out of scenario, even run it in infinite
> loop - they work fine.
>
> Full test log is attached.
>
> Yury
>

[-- Attachment #2: test-cancel.c --]
[-- Type: text/plain, Size: 1299 bytes --]

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>

int TEST_TaskDelay(int uiMillSecs)
{
    int iRet;
    struct timeval tv;

    tv.tv_usec = (uiMillSecs % 1000) * 1000;
    tv.tv_sec  = uiMillSecs / 1000;

    do{
        iRet = select(1, NULL, NULL, NULL, &tv );
    }while((-1 == iRet) && (EINTR == errno));

    return 0;
}


void printids(const char *s)
{
    unsigned int uiIndex;
	pid_t pid;
	pthread_t tid;
	pid = getpid();
	tid = pthread_self();
	printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid, (unsigned int) tid, (unsigned int) tid);



    for(uiIndex = 0; uiIndex < 9000; uiIndex++)
    {
        TEST_TaskDelay(100);
	printf("\n jijun TEST_TaskDelay uiIndex=%d return \n ",uiIndex);
    }
    return 0;



}

void *thr_fn(void *arg)
{
	printids("new thread: ");
	return NULL;
}


int main(void)
{
	int err;
	pthread_t ntid;
	//pthread_t ntid1;	
	err = pthread_create(&ntid,NULL,thr_fn,NULL);
	if (err != 0)
		printf("can't create thread: %s\n", strerror(err));
#if 0
	err = pthread_create(&ntid1,NULL,thr_fn,NULL);
	if (err != 0)
		printf("can't create thread: %s\n", strerror(err));
#endif


	sleep(2);
	pthread_cancel(ntid);
	//pthread_cancel(ntid1);
	sleep(2);
	
	return 0;

}

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

* Re: [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
  2016-04-22 21:40     ` Yury Norov
@ 2016-04-25 16:57       ` Catalin Marinas
  0 siblings, 0 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-04-25 16:57 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor, schwab,
	linux-doc, heiko.carstens, linux-kernel, agraf, klimov.linux,
	broonie, bamvor.zhangjian, joseph, schwidefsky, Nathan_Lynch,
	linux-arm-kernel, christoph.muellner

On Sat, Apr 23, 2016 at 12:40:13AM +0300, Yury Norov wrote:
> On Fri, Apr 22, 2016 at 06:10:09PM +0100, Catalin Marinas wrote:
> > On Wed, Apr 06, 2016 at 01:08:41AM +0300, Yury Norov wrote:
> > > Here new aarch32 ptrace syscall handler is introsuced to avoid run-time
> > > detection of the task type.
> > 
> > The reason for this patch isn't clear to me. What's wrong with the
> > run-time detection? It's not some performance critical code.
> 
> It was requested by Arnd, It's not 'new' syscall basically, just an
> attempt to avoid run-time detection of things that may be detected an
> compile-time.

OK. I noticed that it touches core files and wondering whether it was
necessary but I'm fine with this approach.

-- 
Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
@ 2016-04-25 17:26   ` Catalin Marinas
  2016-04-25 18:19     ` Yury Norov
  2016-04-26 16:57   ` Catalin Marinas
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-25 17:26 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Wed, Apr 06, 2016 at 01:08:42AM +0300, Yury Norov wrote:
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
>   */
>  	.align	6
>  el0_svc:
> -	adrp	stbl, sys_call_table		// load syscall table pointer
>  	uxtw	scno, w8			// syscall number in w8
>  	mov	sc_nr, #__NR_syscalls
> +#ifdef CONFIG_ARM64_ILP32
> +	ldr	x16, [tsk, #TI_FLAGS]
> +	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
> +#endif

There is another ldr x16, [tsk, #TI_FLAGS] load further down in the
el0_svc_naked block. We should rework these a bit to avoid loading the
same location twice unnecessarily. E.g. move the ldr x16 just before
el0_svc_naked and branch one line after in case of the ILP32 syscall.

> +	adrp	stbl, sys_call_table		// load syscall table pointer
>  el0_svc_naked:					// compat entry point
>  	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
>  	enable_dbg_and_irq
> @@ -737,6 +741,12 @@ ni_sys:
>  	b	ret_fast_syscall
>  ENDPROC(el0_svc)
>  
> +#ifdef CONFIG_ARM64_ILP32
> +el0_ilp32_svc:
> +	adrp	stbl, sys_call_ilp32_table // load syscall table pointer
> +	b el0_svc_naked
> +#endif
> +
>  	/*
>  	 * This is the really slow path.  We're going to be doing context
>  	 * switches, and waiting for our parent to respond.

-- 
Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-25 17:26   ` Catalin Marinas
@ 2016-04-25 18:19     ` Yury Norov
  2016-04-25 18:47       ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-25 18:19 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Mon, Apr 25, 2016 at 06:26:56PM +0100, Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:42AM +0300, Yury Norov wrote:
> > --- a/arch/arm64/kernel/entry.S
> > +++ b/arch/arm64/kernel/entry.S
> > @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
> >   */
> >  	.align	6
> >  el0_svc:
> > -	adrp	stbl, sys_call_table		// load syscall table pointer
> >  	uxtw	scno, w8			// syscall number in w8
> >  	mov	sc_nr, #__NR_syscalls
> > +#ifdef CONFIG_ARM64_ILP32
> > +	ldr	x16, [tsk, #TI_FLAGS]
> > +	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
> > +#endif
> 
> There is another ldr x16, [tsk, #TI_FLAGS] load further down in the
> el0_svc_naked block. We should rework these a bit to avoid loading the
> same location twice unnecessarily. E.g. move the ldr x16 just before
> el0_svc_naked and branch one line after in case of the ILP32 syscall.
> 

Yes, I thiks we can refactor it. Thanks for a catch.

> > +	adrp	stbl, sys_call_table		// load syscall table pointer
> >  el0_svc_naked:					// compat entry point
> >  	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
> >  	enable_dbg_and_irq
> > @@ -737,6 +741,12 @@ ni_sys:
> >  	b	ret_fast_syscall
> >  ENDPROC(el0_svc)
> >  
> > +#ifdef CONFIG_ARM64_ILP32
> > +el0_ilp32_svc:
> > +	adrp	stbl, sys_call_ilp32_table // load syscall table pointer
> > +	b el0_svc_naked
> > +#endif
> > +
> >  	/*
> >  	 * This is the really slow path.  We're going to be doing context
> >  	 * switches, and waiting for our parent to respond.
> 
> -- 
> Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-25 18:19     ` Yury Norov
@ 2016-04-25 18:47       ` Yury Norov
  2016-04-26 10:08         ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-25 18:47 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Mon, Apr 25, 2016 at 09:19:13PM +0300, Yury Norov wrote:
> On Mon, Apr 25, 2016 at 06:26:56PM +0100, Catalin Marinas wrote:
> > On Wed, Apr 06, 2016 at 01:08:42AM +0300, Yury Norov wrote:
> > > --- a/arch/arm64/kernel/entry.S
> > > +++ b/arch/arm64/kernel/entry.S
> > > @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
> > >   */
> > >  	.align	6
> > >  el0_svc:
> > > -	adrp	stbl, sys_call_table		// load syscall table pointer
> > >  	uxtw	scno, w8			// syscall number in w8
> > >  	mov	sc_nr, #__NR_syscalls
> > > +#ifdef CONFIG_ARM64_ILP32
> > > +	ldr	x16, [tsk, #TI_FLAGS]
> > > +	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
> > > +#endif
> > 
> > There is another ldr x16, [tsk, #TI_FLAGS] load further down in the
> > el0_svc_naked block. We should rework these a bit to avoid loading the
> > same location twice unnecessarily. E.g. move the ldr x16 just before
> > el0_svc_naked and branch one line after in case of the ILP32 syscall.
> > 
> 
> Yes, I thiks we can refactor it. Thanks for a catch.

Now it's better, I think


diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index cf4d1ae..21312bb 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -715,16 +715,22 @@ ENDPROC(ret_from_fork)
  */
 	.align	6
 el0_svc:
-	adrp	stbl, sys_call_table		// load syscall table pointer
 	uxtw	scno, w8			// syscall number in w8
 	mov	sc_nr, #__NR_syscalls
+	ldr	x16, [tsk, #TI_FLAGS]
+#ifdef CONFIG_ARM64_ILP32
+	tbz	x16, #TIF_32BIT_AARCH64, el0_lp64_svc // We are using ILP32
+	adrp	stbl, sys_call_ilp32_table	// load ilp32 syscall table pointer
+	b el0_svc_naked
+el0_lp64_svc:
+#endif
+	adrp	stbl, sys_call_table		// load syscall table pointer
 el0_svc_naked:					// compat entry point
 	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
 	enable_dbg_and_irq
 	ct_user_exit 1
 
-	ldr	x16, [tsk, #TI_FLAGS]		// check for syscall hooks
-	tst	x16, #_TIF_SYSCALL_WORK
+	tst	x16, #_TIF_SYSCALL_WORK		// check for syscall hooks
 	b.ne	__sys_trace
 	cmp     scno, sc_nr                     // check upper syscall limit
 	b.hs	ni_sys

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-25 18:47       ` Yury Norov
@ 2016-04-26 10:08         ` Catalin Marinas
  0 siblings, 0 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-04-26 10:08 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor, schwab,
	joseph, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwidefsky, Nathan_Lynch, linux-arm-kernel,
	christoph.muellner

On Mon, Apr 25, 2016 at 09:47:40PM +0300, Yury Norov wrote:
> On Mon, Apr 25, 2016 at 09:19:13PM +0300, Yury Norov wrote:
> > On Mon, Apr 25, 2016 at 06:26:56PM +0100, Catalin Marinas wrote:
> > > On Wed, Apr 06, 2016 at 01:08:42AM +0300, Yury Norov wrote:
> > > > --- a/arch/arm64/kernel/entry.S
> > > > +++ b/arch/arm64/kernel/entry.S
> > > > @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
> > > >   */
> > > >  	.align	6
> > > >  el0_svc:
> > > > -	adrp	stbl, sys_call_table		// load syscall table pointer
> > > >  	uxtw	scno, w8			// syscall number in w8
> > > >  	mov	sc_nr, #__NR_syscalls
> > > > +#ifdef CONFIG_ARM64_ILP32
> > > > +	ldr	x16, [tsk, #TI_FLAGS]
> > > > +	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
> > > > +#endif
> > > 
> > > There is another ldr x16, [tsk, #TI_FLAGS] load further down in the
> > > el0_svc_naked block. We should rework these a bit to avoid loading the
> > > same location twice unnecessarily. E.g. move the ldr x16 just before
> > > el0_svc_naked and branch one line after in case of the ILP32 syscall.
> > > 
> > 
> > Yes, I thiks we can refactor it. Thanks for a catch.
> 
> Now it's better, I think
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index cf4d1ae..21312bb 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -715,16 +715,22 @@ ENDPROC(ret_from_fork)
>   */
>  	.align	6
>  el0_svc:
> -	adrp	stbl, sys_call_table		// load syscall table pointer
>  	uxtw	scno, w8			// syscall number in w8
>  	mov	sc_nr, #__NR_syscalls
> +	ldr	x16, [tsk, #TI_FLAGS]

You can move this higher up for interlocking reasons (though these days
CPUs do a lot of speculative loads).

> +#ifdef CONFIG_ARM64_ILP32
> +	tbz	x16, #TIF_32BIT_AARCH64, el0_lp64_svc // We are using ILP32

	// We are *not* using ILP32

> +	adrp	stbl, sys_call_ilp32_table	// load ilp32 syscall table pointer
> +	b el0_svc_naked
> +el0_lp64_svc:
> +#endif
> +	adrp	stbl, sys_call_table		// load syscall table pointer

You can avoid the branches by using csel, something like this:

	ldr	x16, [tsk, #TI_FLAGS]
	adrp	stbl, sys_call_table
	...
#ifdef CONFIG_ARM64_ILP32
	adrp	x17, sys_call_ilp32_table
	tst	x16, #_TIF_32BIT_AARCH64
	csel	stbl, stbl, x17, eq
#endif
el0_svc_naked:
	...

>  el0_svc_naked:					// compat entry point
>  	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
>  	enable_dbg_and_irq
>  	ct_user_exit 1
>  
> -	ldr	x16, [tsk, #TI_FLAGS]		// check for syscall hooks
> -	tst	x16, #_TIF_SYSCALL_WORK
> +	tst	x16, #_TIF_SYSCALL_WORK		// check for syscall hooks
>  	b.ne	__sys_trace
>  	cmp     scno, sc_nr                     // check upper syscall limit
>  	b.hs	ni_sys

There is el0_svc_compat branching to el0_svc_naked and it won't have x16
set anymore. So you need to add an ldr x16 to el0_svc_compat as well.

-- 
Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
  2016-04-25 17:26   ` Catalin Marinas
@ 2016-04-26 16:57   ` Catalin Marinas
  2016-04-28 19:19     ` Yury Norov
  2016-05-06 12:16   ` Zhangjian (Bamvor)
  2016-05-14 15:03   ` Yury Norov
  3 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-26 16:57 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Wed, Apr 06, 2016 at 01:08:42AM +0300, Yury Norov wrote:
> +/* Using non-compat syscalls where necessary */
> +#define compat_sys_fadvise64_64        sys_fadvise64_64
> +#define compat_sys_fallocate           sys_fallocate
> +#define compat_sys_ftruncate64         sys_ftruncate
> +#define compat_sys_lookup_dcookie      sys_lookup_dcookie
> +#define compat_sys_pread64             sys_pread64
> +#define compat_sys_pwrite64            sys_pwrite64
> +#define compat_sys_readahead           sys_readahead
> +#define compat_sys_shmat               sys_shmat

Why don't we use compat_sys_shmat? Is it because of COMPAT_SHMLBA?

> +#define compat_sys_sync_file_range     sys_sync_file_range
> +#define compat_sys_truncate64          sys_truncate
> +#define sys_llseek                     sys_lseek
> +#define sys_mmap2		       sys_mmap

Nitpick: there are some whitespace inconsistencies above (just convert
all spaces to tabs).

I think you should also update Documentation/arm64/ilp32.txt to include
the list above.

> +
> +#include <asm/syscall.h>
> +
> +#undef __SYSCALL
> +#undef __SC_COMP
> +#undef __SC_WRAP
> +#undef __SC_3264
> +#undef __SC_COMP_3264

Minor detail: do we actually need to undef all these? Maybe we can get
away with just defining __SYSCALL_COMPAT at the top of the file.

> +
> +#define __SYSCALL_COMPAT
> +#define __SYSCALL(nr, sym)	[nr] = sym,
> +#define __SC_WRAP(nr, sym)	[nr] = compat_##sym,
> +
> +/*
> + * The sys_call_ilp32_table array must be 4K aligned to be accessible from
> + * kernel/entry.S.
> + */
> +void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = {
> +	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
> +#include <asm/unistd.h>
> +};

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results
  2016-04-23  3:37   ` Zhangjian (Bamvor)
@ 2016-04-27  7:30     ` Andrew Pinski
  2016-04-27 21:15       ` Andrew Pinski
  0 siblings, 1 reply; 135+ messages in thread
From: Andrew Pinski @ 2016-04-27  7:30 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Yury Norov, Arnd Bergmann, Catalin Marinas, linux-arm-kernel,
	LKML, Martin Schwidefsky, Heiko Carstens, Kapoor, Prasun,
	Andreas Schwab, Nathan Lynch, Alexander Graf, Alexey Klimov,
	Mark Brown, Joseph S. Myers, christoph.muellner, linux-doc,
	Linux-Arch, linux-s390, Hanjun Guo, GCC Mailing List

On Fri, Apr 22, 2016 at 8:37 PM, Zhangjian (Bamvor)
<bamvor.zhangjian@huawei.com> wrote:
> Hi, Yury
>
>
> On 2016/4/6 6:44, Yury Norov wrote:
>>
>> There are about 20 failing tests of 782 in lite scenario.
>> float_bessel
>> float_exp_log
>> float_iperb
>> float_power
>> float_trigo
>> pipeio_1
>> pipeio_3
>> pipeio_5
>> pipeio_8
>> abort01
>> clone02
>> kill11
>> mmap16
>> open12
>> pause01
>> rename11
>> rmdir02
>> umount2_01
>> umount2_02
>> umount2_03
>> utime06
>> mtest06
>>
>> The list is rough because some tests fail not every time.
>>
>> Tests abort01 and kill11 fail for lp64 too, so maybe there's
>> a reason unrelated to ilp32 itself.
>>
>> float_xxx tests fail because they call unwind() from signal context,
>> and GCC for ilp32 has problem with it, as Andrew told.
>
> Is there some progress about this issue. When we talk about unwind
> functions, do you mean the function in libgcc?
>
> We encountered another issue(abort not segfault) which also called
> pthread_cancel(). The test code is in the attachment. Here is the
> backtrace:

Yes this was a known issue I knew about.  I have a patch GCC to fix
this.  Basically REG_VALUE_IN_UNWIND_CONTEXT needs to be defined while
building libgcc to support the correct unwind information.
I will be posting a GCC patch to fix this tomorrow.  This was a bug
even in the original set of ilp32 patches.  I only finally was able to
sit down and fix it today.


Thanks,
Andrew

>
> ```
> Program received signal SIGABRT, Aborted.
> [Switching to Thread 0xf77ee330 (LWP 2958)]
> 0x000000000040f5bc in raise (sig=sig@entry=6)
>     at ../sysdeps/unix/sysv/linux/raise.c:55
> 55      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
> (gdb) bt
> #0  0x000000000040f5bc in raise (sig=sig@entry=6)
>     at ../sysdeps/unix/sysv/linux/raise.c:55
> #1  0x000000000040f884 in abort () at abort.c:89
>
> #2  0x00000000004073b4 in uw_update_context_1 (
>     context=context@entry=0xf77ec820, fs=fs@entry=0xf77ebec8)
> at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1430
>
> #3  0x00000000004078c0 in uw_update_context
> (context=context@entry=0xf77ec820,
>     fs=fs@entry=0xf77ebec8)
>    at
> /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1506
> #4  0x0000000000407a9c in uw_advance_context (fs=0xf77ebec8,
>     context=0xf77ec820)
>     at
> /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1529
> #5  _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0xf77ee580,
>     context=context@entry=0xf77ec820)
>     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:185
> #6  0x0000000000408228 in _Unwind_ForcedUnwind (exc=0xf77ee580,
>     stop=stop@entry=0x405440 <unwind_stop>, stop_argument=0xf77eddd8)
>     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:207
> #7  0x00000000004055c4 in __pthread_unwind (buf=<optimized out>)
>     at unwind.c:126
> #8  0x00000000004050b4 in __do_cancel () at ./pthreadP.h:283
> #9  sigcancel_handler (sig=<optimized out>, si=<optimized out>,
>     ctx=<optimized out>) at nptl-init.c:225
> ---Type <return> to continue, or q <return> to quit---
> #10 <signal handler called>
>
> #11 0x0000000000000000 in ?? ()
>
> #12 0x0000000000423084 in __select (nfds=-66661, readfds=<optimized out>,
>     writefds=<optimized out>, exceptfds=<optimized out>, timeout=0x0)
>     at ../sysdeps/unix/sysv/linux/generic/select.c:45
> #13 0x0000000000400604 in TEST_TaskDelay (
>     uiMillSecs=<error reading variable: can't compute CFA for this frame>)
>     at test-cancel.c:18
> #14 0x0000000000400680 in printids (
>     s=<error reading variable: can't compute CFA for this frame>)
>     at test-cancel.c:38
> #15 0x00000000004006d0 in thr_fn (
>     arg=<error reading variable: can't compute CFA for this frame>)
>     at test-cancel.c:49
> #16 0x0000000000401b28 in start_thread (arg=0x4a3000) at
> pthread_create.c:335
> #17 0x0000000000401b28 in start_thread (arg=0x4a3000) at
> pthread_create.c:335
> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
> ```
>
> Such abort is raise by the following code:
> ```
> static void
> uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState
> *fs)
> {
> //...
>   /* Compute this frame's CFA.  */
>   switch (fs->regs.cfa_how)
>     {
>     case CFA_REG_OFFSET:
>       cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
>       cfa += fs->regs.cfa_offset;
>       break;
>
>     case CFA_EXP:
>       {
>         const unsigned char *exp = fs->regs.cfa_exp;
>         _uleb128_t len;
>
>         exp = read_uleb128 (exp, &len);
>         cfa = (void *) (_Unwind_Ptr)
>           execute_stack_op (exp, exp + len, &orig_context, 0);
>         break;
>       }
>
>     default:
>       gcc_unreachable ();
>     }
>   context->cfa = cfa;
> //...
> }
> ``
>
> Any suggestion is appreciated.
>
> CC gcc mailing list. Sorry if it is off topic.
>
> Regards
>
> Bamvor
>
>
>
>
>> pipeio_x tests are very unstable and may fail randomly. I strongly
>> suspect race conditions, as they all work like a charm if pinned to
>> single CPU with taskset. Probably, race is the reason of clone02 too.
>> Though I'm not sure, is the race in kernel, glibc or test itself.
>>
>> But I know for sure that pause01 fails due to test design:
>>         if (setitimer(ITIMER_REAL, &it, NULL)) // For 1000us
>>                 tst_brkm(TBROK | TERRNO, NULL, "setitimer() failed");
>>
>>         TEST(pause());
>>
>> As setitimer() and pause() calls are not atomic, alarm may come before
>> pause()
>> is called, and be silently dropped by the handler. Next pause() call hangs
>> test forever. I already reported to LTP list.
>>
>> open12, rename11, rmdir02, mmap16, mtest06 - all call mkfs tool, and it
>> returns
>> error code. I didn't investigate it much yet.
>>
>> umount02_x, utime06 - cannot reproduce out of scenario, even run it in
>> infinite
>> loop - they work fine.
>>
>> Full test log is attached.
>>
>> Yury
>>
>

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results
  2016-04-27  7:30     ` Andrew Pinski
@ 2016-04-27 21:15       ` Andrew Pinski
  2016-04-28 12:16         ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Andrew Pinski @ 2016-04-27 21:15 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Yury Norov, Arnd Bergmann, Catalin Marinas, linux-arm-kernel,
	LKML, Martin Schwidefsky, Heiko Carstens, Kapoor, Prasun,
	Andreas Schwab, Nathan Lynch, Alexander Graf, Alexey Klimov,
	Mark Brown, Joseph S. Myers, christoph.muellner, linux-doc,
	Linux-Arch, linux-s390, Hanjun Guo, GCC Mailing List

On Wed, Apr 27, 2016 at 12:30 AM, Andrew Pinski <pinskia@gmail.com> wrote:
> On Fri, Apr 22, 2016 at 8:37 PM, Zhangjian (Bamvor)
> <bamvor.zhangjian@huawei.com> wrote:
>> Hi, Yury
>>
>>
>> On 2016/4/6 6:44, Yury Norov wrote:
>>>
>>> There are about 20 failing tests of 782 in lite scenario.
>>> float_bessel
>>> float_exp_log
>>> float_iperb
>>> float_power
>>> float_trigo
>>> pipeio_1
>>> pipeio_3
>>> pipeio_5
>>> pipeio_8
>>> abort01
>>> clone02
>>> kill11
>>> mmap16
>>> open12
>>> pause01
>>> rename11
>>> rmdir02
>>> umount2_01
>>> umount2_02
>>> umount2_03
>>> utime06
>>> mtest06
>>>
>>> The list is rough because some tests fail not every time.
>>>
>>> Tests abort01 and kill11 fail for lp64 too, so maybe there's
>>> a reason unrelated to ilp32 itself.
>>>
>>> float_xxx tests fail because they call unwind() from signal context,
>>> and GCC for ilp32 has problem with it, as Andrew told.
>>
>> Is there some progress about this issue. When we talk about unwind
>> functions, do you mean the function in libgcc?
>>
>> We encountered another issue(abort not segfault) which also called
>> pthread_cancel(). The test code is in the attachment. Here is the
>> backtrace:
>
> Yes this was a known issue I knew about.  I have a patch GCC to fix
> this.  Basically REG_VALUE_IN_UNWIND_CONTEXT needs to be defined while
> building libgcc to support the correct unwind information.
> I will be posting a GCC patch to fix this tomorrow.  This was a bug
> even in the original set of ilp32 patches.  I only finally was able to
> sit down and fix it today.

Here is the link to the GCC patch which I said was going to submit today:
https://gcc.gnu.org/ml/gcc-patches/2016-04/msg01726.html

Thanks,
Andrew

>
>
> Thanks,
> Andrew
>
>>
>> ```
>> Program received signal SIGABRT, Aborted.
>> [Switching to Thread 0xf77ee330 (LWP 2958)]
>> 0x000000000040f5bc in raise (sig=sig@entry=6)
>>     at ../sysdeps/unix/sysv/linux/raise.c:55
>> 55      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
>> (gdb) bt
>> #0  0x000000000040f5bc in raise (sig=sig@entry=6)
>>     at ../sysdeps/unix/sysv/linux/raise.c:55
>> #1  0x000000000040f884 in abort () at abort.c:89
>>
>> #2  0x00000000004073b4 in uw_update_context_1 (
>>     context=context@entry=0xf77ec820, fs=fs@entry=0xf77ebec8)
>> at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1430
>>
>> #3  0x00000000004078c0 in uw_update_context
>> (context=context@entry=0xf77ec820,
>>     fs=fs@entry=0xf77ebec8)
>>    at
>> /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1506
>> #4  0x0000000000407a9c in uw_advance_context (fs=0xf77ebec8,
>>     context=0xf77ec820)
>>     at
>> /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1529
>> #5  _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0xf77ee580,
>>     context=context@entry=0xf77ec820)
>>     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:185
>> #6  0x0000000000408228 in _Unwind_ForcedUnwind (exc=0xf77ee580,
>>     stop=stop@entry=0x405440 <unwind_stop>, stop_argument=0xf77eddd8)
>>     at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:207
>> #7  0x00000000004055c4 in __pthread_unwind (buf=<optimized out>)
>>     at unwind.c:126
>> #8  0x00000000004050b4 in __do_cancel () at ./pthreadP.h:283
>> #9  sigcancel_handler (sig=<optimized out>, si=<optimized out>,
>>     ctx=<optimized out>) at nptl-init.c:225
>> ---Type <return> to continue, or q <return> to quit---
>> #10 <signal handler called>
>>
>> #11 0x0000000000000000 in ?? ()
>>
>> #12 0x0000000000423084 in __select (nfds=-66661, readfds=<optimized out>,
>>     writefds=<optimized out>, exceptfds=<optimized out>, timeout=0x0)
>>     at ../sysdeps/unix/sysv/linux/generic/select.c:45
>> #13 0x0000000000400604 in TEST_TaskDelay (
>>     uiMillSecs=<error reading variable: can't compute CFA for this frame>)
>>     at test-cancel.c:18
>> #14 0x0000000000400680 in printids (
>>     s=<error reading variable: can't compute CFA for this frame>)
>>     at test-cancel.c:38
>> #15 0x00000000004006d0 in thr_fn (
>>     arg=<error reading variable: can't compute CFA for this frame>)
>>     at test-cancel.c:49
>> #16 0x0000000000401b28 in start_thread (arg=0x4a3000) at
>> pthread_create.c:335
>> #17 0x0000000000401b28 in start_thread (arg=0x4a3000) at
>> pthread_create.c:335
>> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>> ```
>>
>> Such abort is raise by the following code:
>> ```
>> static void
>> uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState
>> *fs)
>> {
>> //...
>>   /* Compute this frame's CFA.  */
>>   switch (fs->regs.cfa_how)
>>     {
>>     case CFA_REG_OFFSET:
>>       cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
>>       cfa += fs->regs.cfa_offset;
>>       break;
>>
>>     case CFA_EXP:
>>       {
>>         const unsigned char *exp = fs->regs.cfa_exp;
>>         _uleb128_t len;
>>
>>         exp = read_uleb128 (exp, &len);
>>         cfa = (void *) (_Unwind_Ptr)
>>           execute_stack_op (exp, exp + len, &orig_context, 0);
>>         break;
>>       }
>>
>>     default:
>>       gcc_unreachable ();
>>     }
>>   context->cfa = cfa;
>> //...
>> }
>> ``
>>
>> Any suggestion is appreciated.
>>
>> CC gcc mailing list. Sorry if it is off topic.
>>
>> Regards
>>
>> Bamvor
>>
>>
>>
>>
>>> pipeio_x tests are very unstable and may fail randomly. I strongly
>>> suspect race conditions, as they all work like a charm if pinned to
>>> single CPU with taskset. Probably, race is the reason of clone02 too.
>>> Though I'm not sure, is the race in kernel, glibc or test itself.
>>>
>>> But I know for sure that pause01 fails due to test design:
>>>         if (setitimer(ITIMER_REAL, &it, NULL)) // For 1000us
>>>                 tst_brkm(TBROK | TERRNO, NULL, "setitimer() failed");
>>>
>>>         TEST(pause());
>>>
>>> As setitimer() and pause() calls are not atomic, alarm may come before
>>> pause()
>>> is called, and be silently dropped by the handler. Next pause() call hangs
>>> test forever. I already reported to LTP list.
>>>
>>> open12, rename11, rmdir02, mmap16, mtest06 - all call mkfs tool, and it
>>> returns
>>> error code. I didn't investigate it much yet.
>>>
>>> umount02_x, utime06 - cannot reproduce out of scenario, even run it in
>>> infinite
>>> loop - they work fine.
>>>
>>> Full test log is attached.
>>>
>>> Yury
>>>
>>

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results
  2016-04-27 21:15       ` Andrew Pinski
@ 2016-04-28 12:16         ` Zhangjian (Bamvor)
  0 siblings, 0 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-04-28 12:16 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Yury Norov, Arnd Bergmann, Catalin Marinas, linux-arm-kernel,
	LKML, Martin Schwidefsky, Heiko Carstens, Kapoor, Prasun,
	Andreas Schwab, Nathan Lynch, Alexander Graf, Alexey Klimov,
	Mark Brown, Joseph S. Myers, christoph.muellner, linux-doc,
	Linux-Arch, linux-s390, Hanjun Guo, GCC Mailing List,
	Zhangjian (Bamvor)

Hi, Andrew

On 2016/4/28 5:15, Andrew Pinski wrote:
> On Wed, Apr 27, 2016 at 12:30 AM, Andrew Pinski <pinskia@gmail.com> wrote:
>> On Fri, Apr 22, 2016 at 8:37 PM, Zhangjian (Bamvor)
>> <bamvor.zhangjian@huawei.com> wrote:
>>> Hi, Yury
>>>
>>>
>>> On 2016/4/6 6:44, Yury Norov wrote:
>>>>
>>>> There are about 20 failing tests of 782 in lite scenario.
>>>> float_bessel
>>>> float_exp_log
>>>> float_iperb
>>>> float_power
>>>> float_trigo
>>>> pipeio_1
>>>> pipeio_3
>>>> pipeio_5
>>>> pipeio_8
>>>> abort01
>>>> clone02
>>>> kill11
>>>> mmap16
>>>> open12
>>>> pause01
>>>> rename11
>>>> rmdir02
>>>> umount2_01
>>>> umount2_02
>>>> umount2_03
>>>> utime06
>>>> mtest06
>>>>
>>>> The list is rough because some tests fail not every time.
>>>>
>>>> Tests abort01 and kill11 fail for lp64 too, so maybe there's
>>>> a reason unrelated to ilp32 itself.
>>>>
>>>> float_xxx tests fail because they call unwind() from signal context,
>>>> and GCC for ilp32 has problem with it, as Andrew told.
>>>
>>> Is there some progress about this issue. When we talk about unwind
>>> functions, do you mean the function in libgcc?
>>>
>>> We encountered another issue(abort not segfault) which also called
>>> pthread_cancel(). The test code is in the attachment. Here is the
>>> backtrace:
>>
>> Yes this was a known issue I knew about.  I have a patch GCC to fix
>> this.  Basically REG_VALUE_IN_UNWIND_CONTEXT needs to be defined while
>> building libgcc to support the correct unwind information.
>> I will be posting a GCC patch to fix this tomorrow.  This was a bug
>> even in the original set of ilp32 patches.  I only finally was able to
>> sit down and fix it today.
>
> Here is the link to the GCC patch which I said was going to submit today:
> https://gcc.gnu.org/ml/gcc-patches/2016-04/msg01726.html
It works for me. Both float_xx in ltp and my pthread_cancel testcase is
pass.

Regards

Bamvor

>
> Thanks,
> Andrew
>
>>
>>
>> Thanks,
>> Andrew
>>
>>>
>>> ```
>>> Program received signal SIGABRT, Aborted.
>>> [Switching to Thread 0xf77ee330 (LWP 2958)]
>>> 0x000000000040f5bc in raise (sig=sig@entry=6)
>>>      at ../sysdeps/unix/sysv/linux/raise.c:55
>>> 55      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
>>> (gdb) bt
>>> #0  0x000000000040f5bc in raise (sig=sig@entry=6)
>>>      at ../sysdeps/unix/sysv/linux/raise.c:55
>>> #1  0x000000000040f884 in abort () at abort.c:89
>>>
>>> #2  0x00000000004073b4 in uw_update_context_1 (
>>>      context=context@entry=0xf77ec820, fs=fs@entry=0xf77ebec8)
>>> at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1430
>>>
>>> #3  0x00000000004078c0 in uw_update_context
>>> (context=context@entry=0xf77ec820,
>>>      fs=fs@entry=0xf77ebec8)
>>>     at
>>> /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1506
>>> #4  0x0000000000407a9c in uw_advance_context (fs=0xf77ebec8,
>>>      context=0xf77ec820)
>>>      at
>>> /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind-dw2.c:1529
>>> #5  _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0xf77ee580,
>>>      context=context@entry=0xf77ec820)
>>>      at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:185
>>> #6  0x0000000000408228 in _Unwind_ForcedUnwind (exc=0xf77ee580,
>>>      stop=stop@entry=0x405440 <unwind_stop>, stop_argument=0xf77eddd8)
>>>      at /home/GCC-Build/p660/p660_build_dir/src/gcc-4.9/libgcc/unwind.inc:207
>>> #7  0x00000000004055c4 in __pthread_unwind (buf=<optimized out>)
>>>      at unwind.c:126
>>> #8  0x00000000004050b4 in __do_cancel () at ./pthreadP.h:283
>>> #9  sigcancel_handler (sig=<optimized out>, si=<optimized out>,
>>>      ctx=<optimized out>) at nptl-init.c:225
>>> ---Type <return> to continue, or q <return> to quit---
>>> #10 <signal handler called>
>>>
>>> #11 0x0000000000000000 in ?? ()
>>>
>>> #12 0x0000000000423084 in __select (nfds=-66661, readfds=<optimized out>,
>>>      writefds=<optimized out>, exceptfds=<optimized out>, timeout=0x0)
>>>      at ../sysdeps/unix/sysv/linux/generic/select.c:45
>>> #13 0x0000000000400604 in TEST_TaskDelay (
>>>      uiMillSecs=<error reading variable: can't compute CFA for this frame>)
>>>      at test-cancel.c:18
>>> #14 0x0000000000400680 in printids (
>>>      s=<error reading variable: can't compute CFA for this frame>)
>>>      at test-cancel.c:38
>>> #15 0x00000000004006d0 in thr_fn (
>>>      arg=<error reading variable: can't compute CFA for this frame>)
>>>      at test-cancel.c:49
>>> #16 0x0000000000401b28 in start_thread (arg=0x4a3000) at
>>> pthread_create.c:335
>>> #17 0x0000000000401b28 in start_thread (arg=0x4a3000) at
>>> pthread_create.c:335
>>> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>>> ```
>>>
>>> Such abort is raise by the following code:
>>> ```
>>> static void
>>> uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState
>>> *fs)
>>> {
>>> //...
>>>    /* Compute this frame's CFA.  */
>>>    switch (fs->regs.cfa_how)
>>>      {
>>>      case CFA_REG_OFFSET:
>>>        cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
>>>        cfa += fs->regs.cfa_offset;
>>>        break;
>>>
>>>      case CFA_EXP:
>>>        {
>>>          const unsigned char *exp = fs->regs.cfa_exp;
>>>          _uleb128_t len;
>>>
>>>          exp = read_uleb128 (exp, &len);
>>>          cfa = (void *) (_Unwind_Ptr)
>>>            execute_stack_op (exp, exp + len, &orig_context, 0);
>>>          break;
>>>        }
>>>
>>>      default:
>>>        gcc_unreachable ();
>>>      }
>>>    context->cfa = cfa;
>>> //...
>>> }
>>> ``
>>>
>>> Any suggestion is appreciated.
>>>
>>> CC gcc mailing list. Sorry if it is off topic.
>>>
>>> Regards
>>>
>>> Bamvor
>>>
>>>
>>>
>>>
>>>> pipeio_x tests are very unstable and may fail randomly. I strongly
>>>> suspect race conditions, as they all work like a charm if pinned to
>>>> single CPU with taskset. Probably, race is the reason of clone02 too.
>>>> Though I'm not sure, is the race in kernel, glibc or test itself.
>>>>
>>>> But I know for sure that pause01 fails due to test design:
>>>>          if (setitimer(ITIMER_REAL, &it, NULL)) // For 1000us
>>>>                  tst_brkm(TBROK | TERRNO, NULL, "setitimer() failed");
>>>>
>>>>          TEST(pause());
>>>>
>>>> As setitimer() and pause() calls are not atomic, alarm may come before
>>>> pause()
>>>> is called, and be silently dropped by the handler. Next pause() call hangs
>>>> test forever. I already reported to LTP list.
>>>>
>>>> open12, rename11, rmdir02, mmap16, mtest06 - all call mkfs tool, and it
>>>> returns
>>>> error code. I didn't investigate it much yet.
>>>>
>>>> umount02_x, utime06 - cannot reproduce out of scenario, even run it in
>>>> infinite
>>>> loop - they work fine.
>>>>
>>>> Full test log is attached.
>>>>
>>>> Yury
>>>>
>>>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-26 16:57   ` Catalin Marinas
@ 2016-04-28 19:19     ` Yury Norov
  2016-04-28 20:43       ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-28 19:19 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Tue, Apr 26, 2016 at 05:57:01PM +0100, Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:42AM +0300, Yury Norov wrote:
> > +/* Using non-compat syscalls where necessary */
> > +#define compat_sys_fadvise64_64        sys_fadvise64_64
> > +#define compat_sys_fallocate           sys_fallocate
> > +#define compat_sys_ftruncate64         sys_ftruncate
> > +#define compat_sys_lookup_dcookie      sys_lookup_dcookie
> > +#define compat_sys_pread64             sys_pread64
> > +#define compat_sys_pwrite64            sys_pwrite64
> > +#define compat_sys_readahead           sys_readahead
> > +#define compat_sys_shmat               sys_shmat
> 
> Why don't we use compat_sys_shmat? Is it because of COMPAT_SHMLBA?

Yes. COMPAT_SHMLBA is 4 pages, and it's aarch32-only limitation.

> 
> > +#define compat_sys_sync_file_range     sys_sync_file_range
> > +#define compat_sys_truncate64          sys_truncate
> > +#define sys_llseek                     sys_lseek
> > +#define sys_mmap2		       sys_mmap
> 
> Nitpick: there are some whitespace inconsistencies above (just convert
> all spaces to tabs).
> 
> I think you should also update Documentation/arm64/ilp32.txt to include
> the list above.

OK

> 
> > +
> > +#include <asm/syscall.h>
> > +
> > +#undef __SYSCALL
> > +#undef __SC_COMP
> > +#undef __SC_WRAP
> > +#undef __SC_3264
> > +#undef __SC_COMP_3264
> 
> Minor detail: do we actually need to undef all these? Maybe we can get
> away with just defining __SYSCALL_COMPAT at the top of the file.
> 

Yes, we need. Otherwise we have circular dependency like this:
arch/arm64/kernel/sys_ilp32.c:60:0: warning: "__SC_WRAP" redefined
 #define __SC_WRAP(nr, sym) [nr] = compat_##sym,
  ^
  In file included from include/asm-generic/unistd.h:1:0,
                   from ./arch/arm64/include/uapi/asm/unistd.h:16,
                   from ./arch/arm64/include/asm/unistd.h:62,
                   from ./include/uapi/linux/unistd.h:7,
                   from include/linux/syscalls.h:23,
                   from arch/arm64/kernel/sys_ilp32.c:30:
include/uapi/asm-generic/unistd.h:33:0: note: this is the location of the previous definition
 #define __SC_WRAP __SYSCALL

Defining __SYSCALL_COMPAT at the top of the file does not help much.

> > +
> > +#define __SYSCALL_COMPAT
> > +#define __SYSCALL(nr, sym)	[nr] = sym,
> > +#define __SC_WRAP(nr, sym)	[nr] = compat_##sym,
> > +
> > +/*
> > + * The sys_call_ilp32_table array must be 4K aligned to be accessible from
> > + * kernel/entry.S.
> > + */
> > +void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = {
> > +	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
> > +#include <asm/unistd.h>
> > +};
> 
> -- 
> Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-28 19:19     ` Yury Norov
@ 2016-04-28 20:43       ` Arnd Bergmann
  2016-04-28 22:21         ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-04-28 20:43 UTC (permalink / raw)
  To: Yury Norov
  Cc: Catalin Marinas, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Thursday 28 April 2016 22:19:14 Yury Norov wrote:
> 
> Yes, we need. Otherwise we have circular dependency like this:
> arch/arm64/kernel/sys_ilp32.c:60:0: warning: "__SC_WRAP" redefined
>  #define __SC_WRAP(nr, sym) [nr] = compat_##sym,
>   ^
>   In file included from include/asm-generic/unistd.h:1:0,
>                    from ./arch/arm64/include/uapi/asm/unistd.h:16,
>                    from ./arch/arm64/include/asm/unistd.h:62,
>                    from ./include/uapi/linux/unistd.h:7,
>                    from include/linux/syscalls.h:23,
>                    from arch/arm64/kernel/sys_ilp32.c:30:
> include/uapi/asm-generic/unistd.h:33:0: note: this is the location of the previous definition
>  #define __SC_WRAP __SYSCALL
> 
> Defining __SYSCALL_COMPAT at the top of the file does not help much.

Hmm, this sounds like something that we should fix in the asm-generic/unistd.h
file. Is it just for __SC_WRAP, or also the other macros?

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-28 20:43       ` Arnd Bergmann
@ 2016-04-28 22:21         ` Yury Norov
  2016-04-28 22:43           ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-28 22:21 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Catalin Marinas, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Thu, Apr 28, 2016 at 10:43:59PM +0200, Arnd Bergmann wrote:
> On Thursday 28 April 2016 22:19:14 Yury Norov wrote:
> > 
> > Yes, we need. Otherwise we have circular dependency like this:
> > arch/arm64/kernel/sys_ilp32.c:60:0: warning: "__SC_WRAP" redefined
> >  #define __SC_WRAP(nr, sym) [nr] = compat_##sym,
> >   ^
> >   In file included from include/asm-generic/unistd.h:1:0,
> >                    from ./arch/arm64/include/uapi/asm/unistd.h:16,
> >                    from ./arch/arm64/include/asm/unistd.h:62,
> >                    from ./include/uapi/linux/unistd.h:7,
> >                    from include/linux/syscalls.h:23,
> >                    from arch/arm64/kernel/sys_ilp32.c:30:
> > include/uapi/asm-generic/unistd.h:33:0: note: this is the location of the previous definition
> >  #define __SC_WRAP __SYSCALL
> > 
> > Defining __SYSCALL_COMPAT at the top of the file does not help much.
> 
> Hmm, this sounds like something that we should fix in the asm-generic/unistd.h
> file. Is it just for __SC_WRAP, or also the other macros?
> 
> 	Arnd

For __SYSCALL and __SC_WRAP:

diff --git a/arch/arm64/kernel/sys_ilp32.c
b/arch/arm64/kernel/sys_ilp32.c
index 1458ad7..410d817 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -17,6 +17,8 @@
 * along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */
    
+#define __SYSCALL_COMPAT
+
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -48,13 +50,12 @@ asmlinkage long
 ilp32_sys_rt_sigreturn_wrapper(void);
   
 #include <asm/syscall.h>
     
-#undef __SYSCALL
-#undef __SC_COMP
-#undef __SC_WRAP
-#undef __SC_3264
-#undef __SC_COMP_3264
 
-#define __SYSCALL_COMPAT
 #define __SYSCALL(nr, sym)     [nr] = sym,
 #define __SC_WRAP(nr, sym)     [nr] = compat_##sym,
         
This patch makes gcc warn about redefinition.

arch/arm64/kernel/sys_ilp32.c:59:0: warning: "__SYSCALL" redefined
 #define __SYSCALL(nr, sym) [nr] = sym,
 ^
In file included from include/asm-generic/unistd.h:1:0,
                 from ./arch/arm64/include/uapi/asm/unistd.h:16,
                 from ./arch/arm64/include/asm/unistd.h:62,
                 from ./include/uapi/linux/unistd.h:7,
                 from include/linux/syscalls.h:23,
                 from arch/arm64/kernel/sys_ilp32.c:30:
include/uapi/asm-generic/unistd.h:15:0: note: this is the location of the previous definition
 #define __SYSCALL(x, y)
 ^
arch/arm64/kernel/sys_ilp32.c:60:0: warning: "__SC_WRAP" redefined
 #define __SC_WRAP(nr, sym) [nr] = compat_##sym,
 ^
In file included from include/asm-generic/unistd.h:1:0,
                 from ./arch/arm64/include/uapi/asm/unistd.h:16,
                 from ./arch/arm64/include/asm/unistd.h:62,
                 from ./include/uapi/linux/unistd.h:7,
                 from include/linux/syscalls.h:23,
                 from arch/arm64/kernel/sys_ilp32.c:30:
include/uapi/asm-generic/unistd.h:33:0: note: this is the location of the previous definition
 #define __SC_WRAP __SYSCALL
 ^

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-28 22:21         ` Yury Norov
@ 2016-04-28 22:43           ` Arnd Bergmann
  2016-04-29 13:13             ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-04-28 22:43 UTC (permalink / raw)
  To: Yury Norov
  Cc: Catalin Marinas, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Friday 29 April 2016 01:21:37 Yury Norov wrote:
> index 1458ad7..410d817 100644
> --- a/arch/arm64/kernel/sys_ilp32.c
> +++ b/arch/arm64/kernel/sys_ilp32.c
> @@ -17,6 +17,8 @@
>  * along with this program.  If not, see
>  * <http://www.gnu.org/licenses/>.
>  */
>     
> +#define __SYSCALL_COMPAT
> +
>  #include <linux/compiler.h>
>  #include <linux/errno.h>
>  #include <linux/fs.h>
> @@ -48,13 +50,12 @@ asmlinkage long
>  ilp32_sys_rt_sigreturn_wrapper(void);
>    
>  #include <asm/syscall.h>
>      
> -#undef __SYSCALL
> -#undef __SC_COMP
> -#undef __SC_WRAP
> -#undef __SC_3264
> -#undef __SC_COMP_3264
>  
> -#define __SYSCALL_COMPAT
>  #define __SYSCALL(nr, sym)     [nr] = sym,
>  #define __SC_WRAP(nr, sym)     [nr] = compat_##sym,
>          
> This patch makes gcc warn about redefinition.
> 
> arch/arm64/kernel/sys_ilp32.c:59:0: warning: "__SYSCALL" redefined
>  #define __SYSCALL(nr, sym) [nr] = sym,
>  ^
> In file included from include/asm-generic/unistd.h:1:0,
> 

Ok, I think I see it now. Can you #undef the two symbols at the
end of arch/arm64/include/uapi/asm/unistd.h or possibly
include/uapi/asm-generic/unistd.h?

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-28 22:43           ` Arnd Bergmann
@ 2016-04-29 13:13             ` Yury Norov
  2016-04-29 15:45               ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-29 13:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Catalin Marinas, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Fri, Apr 29, 2016 at 12:43:41AM +0200, Arnd Bergmann wrote:
> On Friday 29 April 2016 01:21:37 Yury Norov wrote:
> > index 1458ad7..410d817 100644
> > --- a/arch/arm64/kernel/sys_ilp32.c
> > +++ b/arch/arm64/kernel/sys_ilp32.c
> > @@ -17,6 +17,8 @@
> >  * along with this program.  If not, see
> >  * <http://www.gnu.org/licenses/>.
> >  */
> >     
> > +#define __SYSCALL_COMPAT
> > +
> >  #include <linux/compiler.h>
> >  #include <linux/errno.h>
> >  #include <linux/fs.h>
> > @@ -48,13 +50,12 @@ asmlinkage long
> >  ilp32_sys_rt_sigreturn_wrapper(void);
> >    
> >  #include <asm/syscall.h>
> >      
> > -#undef __SYSCALL
> > -#undef __SC_COMP
> > -#undef __SC_WRAP
> > -#undef __SC_3264
> > -#undef __SC_COMP_3264
> >  
> > -#define __SYSCALL_COMPAT
> >  #define __SYSCALL(nr, sym)     [nr] = sym,
> >  #define __SC_WRAP(nr, sym)     [nr] = compat_##sym,
> >          
> > This patch makes gcc warn about redefinition.
> > 
> > arch/arm64/kernel/sys_ilp32.c:59:0: warning: "__SYSCALL" redefined
> >  #define __SYSCALL(nr, sym) [nr] = sym,
> >  ^
> > In file included from include/asm-generic/unistd.h:1:0,
> > 
> 
> Ok, I think I see it now. Can you #undef the two symbols at the
> end of arch/arm64/include/uapi/asm/unistd.h

I think it doesn't look better than what we have now, but not worse
as well. If you like it, I'll change.

> or possibly
> include/uapi/asm-generic/unistd.h?
> 
> 	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-29 13:13             ` Yury Norov
@ 2016-04-29 15:45               ` Arnd Bergmann
  0 siblings, 0 replies; 135+ messages in thread
From: Arnd Bergmann @ 2016-04-29 15:45 UTC (permalink / raw)
  To: Yury Norov
  Cc: Catalin Marinas, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	joseph, christoph.muellner

On Friday 29 April 2016 16:13:38 Yury Norov wrote:
> On Fri, Apr 29, 2016 at 12:43:41AM +0200, Arnd Bergmann wrote:
> > On Friday 29 April 2016 01:21:37 Yury Norov wrote:

> > > 
> > > arch/arm64/kernel/sys_ilp32.c:59:0: warning: "__SYSCALL" redefined
> > >  #define __SYSCALL(nr, sym) [nr] = sym,
> > >  ^
> > > In file included from include/asm-generic/unistd.h:1:0,
> > > 
> > 
> > Ok, I think I see it now. Can you #undef the two symbols at the
> > end of arch/arm64/include/uapi/asm/unistd.h
> 
> I think it doesn't look better than what we have now, but not worse
> as well. If you like it, I'll change.

I looked again and saw that the existing architectures also #undef __SYSCALL,
and they don't have __SC_WRAP. It's probably fine to just #undef the
two here (don't undef SC_COMP, __SC_3264 and SC_COMP_3264).

Changing the asm-generic header to not require the #undef would be nice,
but then we should do that for all 12 users of that file.

	Arnd

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-05 22:08 ` [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov
  2016-04-13  9:19   ` Zhangjian (Bamvor)
@ 2016-04-29 16:01   ` Catalin Marinas
  2016-04-29 17:30     ` Arnd Bergmann
  1 sibling, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-29 16:01 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, Philipp Tomsich, joseph,
	christoph.muellner

On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
> ILP32 VDSO exports next symbols:
>  __kernel_rt_sigreturn;
>  __kernel_gettimeofday;
>  __kernel_clock_gettime;
>  __kernel_clock_getres;

[...]

> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
> +	$(call if_changed_dep,vdso-ilp32as)

Are struct timeval and timespec the same between ILP32 and LP64? For
example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
asm-offsets.c based on the LP64 timeval.

> +$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
> +	$(call if_changed_dep,vdso-ilp32as)

This one should be fine because ILP32 uses the same generic
__NR_rt_sigreturn syscall number.

-- 
Catalin

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

* Re: [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig
  2016-04-05 22:08 ` [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig Yury Norov
@ 2016-04-29 16:03   ` Catalin Marinas
  2016-04-29 16:08     ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-29 16:03 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	Philipp Tomsich, joseph, christoph.muellner

On Wed, Apr 06, 2016 at 01:08:47AM +0300, Yury Norov wrote:
> +config ARM64_ILP32
> +	bool "Kernel support for ILP32"
> +	select COMPAT_WRAPPER
> +	help
> +	  This option enables support for AArch64 ILP32 user space.  ILP32
> +	  is an ABI where long and pointers are 32bits but it uses the AARCH64
> +	  instruction set.

Is there any penalty for AArch32 tasks when selecting COMPAT_WRAPPER?

-- 
Catalin

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

* Re: [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig
  2016-04-29 16:03   ` Catalin Marinas
@ 2016-04-29 16:08     ` Yury Norov
  2016-04-29 16:14       ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-04-29 16:08 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, Andrew Pinski,
	bamvor.zhangjian, Andrew Pinski, schwidefsky, Nathan_Lynch,
	Philipp Tomsich, joseph, christoph.muellner

On Fri, Apr 29, 2016 at 05:03:34PM +0100, Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:47AM +0300, Yury Norov wrote:
> > +config ARM64_ILP32
> > +	bool "Kernel support for ILP32"
> > +	select COMPAT_WRAPPER
> > +	help
> > +	  This option enables support for AArch64 ILP32 user space.  ILP32
> > +	  is an ABI where long and pointers are 32bits but it uses the AARCH64
> > +	  instruction set.
> 
> Is there any penalty for AArch32 tasks when selecting COMPAT_WRAPPER?
> 
> -- 
> Catalin

No. AARCH32 doesn't define __SC_WRAP and so __SYSCALL macro is used,
which fills syscall table with sys_xxx versions, not compat_sys_xxx.

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

* Re: [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig
  2016-04-29 16:08     ` Yury Norov
@ 2016-04-29 16:14       ` Catalin Marinas
  2016-04-29 16:26         ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-04-29 16:14 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor, schwab,
	joseph, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwidefsky, Nathan_Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner

On Fri, Apr 29, 2016 at 07:08:55PM +0300, Yury Norov wrote:
> On Fri, Apr 29, 2016 at 05:03:34PM +0100, Catalin Marinas wrote:
> > On Wed, Apr 06, 2016 at 01:08:47AM +0300, Yury Norov wrote:
> > > +config ARM64_ILP32
> > > +	bool "Kernel support for ILP32"
> > > +	select COMPAT_WRAPPER
> > > +	help
> > > +	  This option enables support for AArch64 ILP32 user space.  ILP32
> > > +	  is an ABI where long and pointers are 32bits but it uses the AARCH64
> > > +	  instruction set.
> > 
> > Is there any penalty for AArch32 tasks when selecting COMPAT_WRAPPER?
> 
> No. AARCH32 doesn't define __SC_WRAP and so __SYSCALL macro is used,
> which fills syscall table with sys_xxx versions, not compat_sys_xxx.

Ah, I forgot it has its own unistd32.h.

Thanks.

-- 
Catalin

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

* Re: [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig
  2016-04-29 16:14       ` Catalin Marinas
@ 2016-04-29 16:26         ` Yury Norov
  0 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-04-29 16:26 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor, schwab,
	joseph, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwidefsky, Nathan_Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner

On Fri, Apr 29, 2016 at 05:14:46PM +0100, Catalin Marinas wrote:
> On Fri, Apr 29, 2016 at 07:08:55PM +0300, Yury Norov wrote:
> > On Fri, Apr 29, 2016 at 05:03:34PM +0100, Catalin Marinas wrote:
> > > On Wed, Apr 06, 2016 at 01:08:47AM +0300, Yury Norov wrote:
> > > > +config ARM64_ILP32
> > > > +	bool "Kernel support for ILP32"
> > > > +	select COMPAT_WRAPPER
> > > > +	help
> > > > +	  This option enables support for AArch64 ILP32 user space.  ILP32
> > > > +	  is an ABI where long and pointers are 32bits but it uses the AARCH64
> > > > +	  instruction set.
> > > 
> > > Is there any penalty for AArch32 tasks when selecting COMPAT_WRAPPER?
> > 
> > No. AARCH32 doesn't define __SC_WRAP and so __SYSCALL macro is used,
> > which fills syscall table with sys_xxx versions, not compat_sys_xxx.
> 
> Ah, I forgot it has its own unistd32.h.
> 
> Thanks.

Even if it was sharing generic unistd,h, it's OK as well. To use
wrappers, you have to enable COMPAT_WRAPPER (which is enabled even if
only a single ABI needs it) *and* define  __SC_WRAP in corresponding
sys_xxx.c, which is individual for each abi, of course.

> 
> -- 
> Catalin

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-29 16:01   ` Catalin Marinas
@ 2016-04-29 17:30     ` Arnd Bergmann
  2016-05-03  9:00       ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-04-29 17:30 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Yury Norov, linux-arm-kernel, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, schwab, broonie, linux-doc,
	heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, Philipp Tomsich, joseph,
	christoph.muellner

On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
> On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
> > ILP32 VDSO exports next symbols:
> >  __kernel_rt_sigreturn;
> >  __kernel_gettimeofday;
> >  __kernel_clock_gettime;
> >  __kernel_clock_getres;
> 
> [...]
> 
> > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
> > +	$(call if_changed_dep,vdso-ilp32as)
> 
> Are struct timeval and timespec the same between ILP32 and LP64? For
> example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
> asm-offsets.c based on the LP64 timeval.

No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
time_t. I guess that means it can work for little-endian but not
big-endian, right?

	Arnd

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-29 17:30     ` Arnd Bergmann
@ 2016-05-03  9:00       ` Catalin Marinas
  2016-05-03  9:05         ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-03  9:00 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, linux-s390, pinskia, Prasun.Kapoor, schwab, broonie,
	linux-doc, heiko.carstens, linux-kernel, agraf, klimov.linux,
	Yury Norov, bamvor.zhangjian, joseph, schwidefsky, Nathan_Lynch,
	Philipp Tomsich, linux-arm-kernel, christoph.muellner

On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote:
> On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
> > On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
> > > ILP32 VDSO exports next symbols:
> > >  __kernel_rt_sigreturn;
> > >  __kernel_gettimeofday;
> > >  __kernel_clock_gettime;
> > >  __kernel_clock_getres;
> > 
> > [...]
> > 
> > > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
> > > +	$(call if_changed_dep,vdso-ilp32as)
> > 
> > Are struct timeval and timespec the same between ILP32 and LP64? For
> > example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
> > asm-offsets.c based on the LP64 timeval.
> 
> No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
> time_t. I guess that means it can work for little-endian but not
> big-endian, right?

I don't think it works for little-endian either. The LP64 struct timeval
is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is
storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC])

-- 
Catalin

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-03  9:00       ` Catalin Marinas
@ 2016-05-03  9:05         ` Arnd Bergmann
  2016-05-03 11:07           ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-03  9:05 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arch, linux-s390, pinskia, Prasun.Kapoor, schwab, broonie,
	linux-doc, heiko.carstens, linux-kernel, agraf, klimov.linux,
	Yury Norov, bamvor.zhangjian, joseph, schwidefsky, Nathan_Lynch,
	Philipp Tomsich, linux-arm-kernel, christoph.muellner

On Tuesday 03 May 2016 10:00:45 Catalin Marinas wrote:
> On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote:
> > On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
> > > On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
> > > > ILP32 VDSO exports next symbols:
> > > >  __kernel_rt_sigreturn;
> > > >  __kernel_gettimeofday;
> > > >  __kernel_clock_gettime;
> > > >  __kernel_clock_getres;
> > > 
> > > [...]
> > > 
> > > > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
> > > > + $(call if_changed_dep,vdso-ilp32as)
> > > 
> > > Are struct timeval and timespec the same between ILP32 and LP64? For
> > > example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
> > > asm-offsets.c based on the LP64 timeval.
> > 
> > No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
> > time_t. I guess that means it can work for little-endian but not
> > big-endian, right?
> 
> I don't think it works for little-endian either. The LP64 struct timeval
> is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is
> storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC])

You are right. Yury asked pointed out the same thing on IRC as well.
Using the 64-bit gettimeofday() will put the right number in the
.tv_sec member on little-endian, but will write zeroes to tv_nsec
and corrupt the memory following it.

Yury also tried it out and noticed that for a (so far) unknown reason,
the vdso gets never used by his glibc build, so it has not triggered
any test case failures.

	Arnd

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-03  9:05         ` Arnd Bergmann
@ 2016-05-03 11:07           ` Zhangjian (Bamvor)
  2016-05-03 12:41             ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-03 11:07 UTC (permalink / raw)
  To: Arnd Bergmann, Catalin Marinas
  Cc: linux-arch, linux-s390, pinskia, Prasun.Kapoor, schwab, broonie,
	linux-doc, heiko.carstens, linux-kernel, agraf, klimov.linux,
	Yury Norov, joseph, schwidefsky, Nathan_Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner, Hanjun Guo,
	Zhangjian (Bamvor)



On 2016/5/3 17:05, Arnd Bergmann wrote:
> On Tuesday 03 May 2016 10:00:45 Catalin Marinas wrote:
>> On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote:
>>> On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
>>>> On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
>>>>> ILP32 VDSO exports next symbols:
>>>>>   __kernel_rt_sigreturn;
>>>>>   __kernel_gettimeofday;
>>>>>   __kernel_clock_gettime;
>>>>>   __kernel_clock_getres;
>>>>
>>>> [...]
>>>>
>>>>> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
>>>>> + $(call if_changed_dep,vdso-ilp32as)
>>>>
>>>> Are struct timeval and timespec the same between ILP32 and LP64? For
>>>> example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
>>>> asm-offsets.c based on the LP64 timeval.
>>>
>>> No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
>>> time_t. I guess that means it can work for little-endian but not
>>> big-endian, right?
>>
>> I don't think it works for little-endian either. The LP64 struct timeval
>> is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is
>> storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC])
>
> You are right. Yury asked pointed out the same thing on IRC as well.
> Using the 64-bit gettimeofday() will put the right number in the
> .tv_sec member on little-endian, but will write zeroes to tv_nsec
> and corrupt the memory following it.
>
> Yury also tried it out and noticed that for a (so far) unknown reason,
> the vdso gets never used by his glibc build, so it has not triggered
> any test case failures.
We found this issue too. And it is because the version is different from
the glibc wanted. We define 2.6.39 for lp64 but 2.6 for ilp32 in vdso
in kernel:
+VERSION
+{
+	LINUX_2.6 {
+	global:
+		__kernel_rt_sigreturn;
+		__kernel_gettimeofday;
+		__kernel_clock_gettime;
+		__kernel_clock_getres;
+	local: *;
+	};
+}
If I change 2.6 to 2.6.39, the ilp32 application will call vdso instead
of syscall. But the result is wrong as Catalin mentioned before.

Should we set this version to 4.6 or higher version? We will need to update
the version in "sysdeps/unix/sysv/linux/aarch64/init-first.c" too:
static inline void
_libc_vdso_platform_setup (void)
{
   PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537);

   void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639);
   PTR_MANGLE (p);
   VDSO_SYMBOL(gettimeofday) = p;

   p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639);
   PTR_MANGLE (p);
   VDSO_SYMBOL(clock_gettime) = p;

   p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639);
   PTR_MANGLE (p);
   VDSO_SYMBOL(clock_getres) = p;
}

Regards

Bamvor

>
> 	Arnd
>

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-03 11:07           ` Zhangjian (Bamvor)
@ 2016-05-03 12:41             ` Zhangjian (Bamvor)
  2016-05-04 21:49               ` Yury Norov
  2016-05-05  8:22               ` Yury Norov
  0 siblings, 2 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-03 12:41 UTC (permalink / raw)
  To: Arnd Bergmann, Catalin Marinas
  Cc: linux-arch, linux-s390, pinskia, Prasun.Kapoor, schwab, broonie,
	linux-doc, heiko.carstens, linux-kernel, agraf, klimov.linux,
	Yury Norov, joseph, schwidefsky, Nathan_Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner, Hanjun Guo,
	Zhangjian (Bamvor)

Hi, all

On 2016/5/3 19:07, Zhangjian (Bamvor) wrote:
>
>
> On 2016/5/3 17:05, Arnd Bergmann wrote:
>> On Tuesday 03 May 2016 10:00:45 Catalin Marinas wrote:
>>> On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote:
>>>> On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
>>>>> On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
>>>>>> ILP32 VDSO exports next symbols:
>>>>>>   __kernel_rt_sigreturn;
>>>>>>   __kernel_gettimeofday;
>>>>>>   __kernel_clock_gettime;
>>>>>>   __kernel_clock_getres;
>>>>>
>>>>> [...]
>>>>>
>>>>>> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
>>>>>> + $(call if_changed_dep,vdso-ilp32as)
>>>>>
>>>>> Are struct timeval and timespec the same between ILP32 and LP64? For
>>>>> example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
>>>>> asm-offsets.c based on the LP64 timeval.
>>>>
>>>> No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
>>>> time_t. I guess that means it can work for little-endian but not
>>>> big-endian, right?
>>>
>>> I don't think it works for little-endian either. The LP64 struct timeval
>>> is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is
>>> storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC])
>>
>> You are right. Yury asked pointed out the same thing on IRC as well.
>> Using the 64-bit gettimeofday() will put the right number in the
>> .tv_sec member on little-endian, but will write zeroes to tv_nsec
>> and corrupt the memory following it.
>>
>> Yury also tried it out and noticed that for a (so far) unknown reason,
>> the vdso gets never used by his glibc build, so it has not triggered
>> any test case failures.
> We found this issue too. And it is because the version is different from
> the glibc wanted. We define 2.6.39 for lp64 but 2.6 for ilp32 in vdso
> in kernel:
> +VERSION
> +{
> +    LINUX_2.6 {
> +    global:
> +        __kernel_rt_sigreturn;
> +        __kernel_gettimeofday;
> +        __kernel_clock_gettime;
> +        __kernel_clock_getres;
> +    local: *;
> +    };
> +}
> If I change 2.6 to 2.6.39, the ilp32 application will call vdso instead
> of syscall. But the result is wrong as Catalin mentioned before.
>
> Should we set this version to 4.6 or higher version? We will need to update
> the version in "sysdeps/unix/sysv/linux/aarch64/init-first.c" too:
> static inline void
> _libc_vdso_platform_setup (void)
> {
>    PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537);
>
>    void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639);
>    PTR_MANGLE (p);
>    VDSO_SYMBOL(gettimeofday) = p;
>
>    p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639);
>    PTR_MANGLE (p);
>    VDSO_SYMBOL(clock_gettime) = p;
>
>    p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639);
>    PTR_MANGLE (p);
>    VDSO_SYMBOL(clock_getres) = p;
> }

After apply this patch with my small testcase, the vsyscall of gettimeofday in
ilp32 works in both big endian and small endian. In this patch, I use the
different register and offset for ilp32 and lp64. Actually, the
COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
of vdso to 4.6. It should change to 2.6.39 if glibc is not update.

diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 574081f..c8e32eb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -101,6 +101,11 @@ int main(void)
    DEFINE(TSPEC_TV_SEC,		offsetof(struct timespec, tv_sec));
    DEFINE(TSPEC_TV_NSEC,		offsetof(struct timespec, tv_nsec));
    BLANK();
+  DEFINE(COMPAT_TVAL_TV_SEC,	offsetof(struct compat_timeval, tv_sec));
+  DEFINE(COMPAT_TVAL_TV_USEC,	offsetof(struct compat_timeval, tv_usec));
+  DEFINE(COMPAT_TSPEC_TV_SEC,	offsetof(struct compat_timespec, tv_sec));
+  DEFINE(COMPAT_TSPEC_TV_NSEC,	offsetof(struct compat_timespec, tv_nsec));
+  BLANK();
    DEFINE(TZ_MINWEST,		offsetof(struct timezone, tz_minuteswest));
    DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
    BLANK();
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
index ddc63fd..d182a8d 100644
--- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -79,7 +79,7 @@ PHDRS
   */
  VERSION
  {
-	LINUX_2.6 {
+	LINUX_4.6 {
  	global:
  		__kernel_rt_sigreturn;
  		__kernel_gettimeofday;
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index efa79e8..4551f55 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -25,6 +25,14 @@
  #define NSEC_PER_SEC_LO16	0xca00
  #define NSEC_PER_SEC_HI16	0x3b9a

+#ifdef __LP64__
+#define PTR_REG(n)      x##n
+#define OFFSET(n)	n
+#else
+#define PTR_REG(n)      w##n
+#define OFFSET(n)	COMPAT_##n
+#endif
+
  vdso_data	.req	x6
  use_syscall	.req	w7
  seqcnt		.req	w8
@@ -68,7 +76,7 @@ ENTRY(__kernel_gettimeofday)
  	mov	x13, #1000
  	lsl	x13, x13, x12
  	udiv	x11, x11, x13
-	stp	x10, x11, [x0, #TVAL_TV_SEC]
+	stp	PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
  2:
  	/* If tz is NULL, return 0. */
  	cbz	x1, 3f
@@ -159,7 +167,7 @@ ENTRY(__kernel_clock_gettime)

  6:	/* Store to the user timespec. */
  	lsr	x11, x11, x12
-	stp	x10, x11, [x1, #TSPEC_TV_SEC]
+	stp	PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
  	mov	x0, xzr
  	ret
  7:
-- 
1.8.4.5

I am not sure if I should merge above patch into original one. If I
merge it with another patch I send in 13, April, The overall patch is
as follows. I could resend the following patch to this thread if
needed:

 From b0a74395cbf18643f3f5b410be425df85d8d68d1 Mon Sep 17 00:00:00 2001
From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Date: Wed, 6 Apr 2016 01:08:46 +0300
Subject: [PATCH] arm64:ilp32: add vdso-ilp32 and use for signal return

ILP32 VDSO exports next symbols:
  __kernel_rt_sigreturn;
  __kernel_gettimeofday;
  __kernel_clock_gettime;
  __kernel_clock_getres;

What shared object to use, kernel selects depending on result of
is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
correct pages and spec.

Adjusted to move the move data page before code pages in sync with
commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1

Care must be taken when we update time to user space for ilp32.
Because the size of time struct(timeval, timespec) is different from
lp64.

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
---
  arch/arm64/include/asm/vdso.h                 |  6 ++
  arch/arm64/kernel/Makefile                    |  7 ++
  arch/arm64/kernel/asm-offsets.c               |  5 ++
  arch/arm64/kernel/signal.c                    |  2 +
  arch/arm64/kernel/vdso-ilp32/.gitignore       |  2 +
  arch/arm64/kernel/vdso-ilp32/Makefile         | 72 ++++++++++++++++++++
  arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     | 33 ++++++++++
  arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++
  arch/arm64/kernel/vdso.c                      | 61 ++++++++++++++---
  arch/arm64/kernel/vdso/gettimeofday.S         | 12 +++-
  10 files changed, 283 insertions(+), 12 deletions(-)
  create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
  create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
  create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
  create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S

diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 839ce00..649a9a4 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -29,6 +29,12 @@

  #include <generated/vdso-offsets.h>

+#ifdef CONFIG_ARM64_ILP32
+#include <generated/vdso-ilp32-offsets.h>
+#else
+#define vdso_offset_sigtramp_ilp32
+#endif
+
  #define VDSO_SYMBOL(base, name)						   \
  ({									   \
  	(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 09e4373..0f27a10 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
  arm64-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o

  obj-y					+= $(arm64-obj-y) vdso/
+obj-$(CONFIG_ARM64_ILP32)		+= vdso-ilp32/
  obj-m					+= $(arm64-obj-m)
  head-y					:= head.o
  extra-y					+= $(head-y) vmlinux.lds
@@ -57,3 +58,9 @@ extra-y					+= $(head-y) vmlinux.lds
  # vDSO - this must be built first to generate the symbol offsets
  $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
  $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
+
+# vDSO - this must be built first to generate the symbol offsets
+ifeq ($(CONFIG_ARM64_ILP32),y)
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
+$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
+endif
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index e229525..e5db887 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -101,6 +101,11 @@ int main(void)
    DEFINE(TSPEC_TV_SEC,		offsetof(struct timespec, tv_sec));
    DEFINE(TSPEC_TV_NSEC,		offsetof(struct timespec, tv_nsec));
    BLANK();
+  DEFINE(COMPAT_TVAL_TV_SEC,	offsetof(struct compat_timeval, tv_sec));
+  DEFINE(COMPAT_TVAL_TV_USEC,	offsetof(struct compat_timeval, tv_usec));
+  DEFINE(COMPAT_TSPEC_TV_SEC,	offsetof(struct compat_timespec, tv_sec));
+  DEFINE(COMPAT_TSPEC_TV_NSEC,	offsetof(struct compat_timespec, tv_nsec));
+  BLANK();
    DEFINE(TZ_MINWEST,		offsetof(struct timezone, tz_minuteswest));
    DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
    BLANK();
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 45bcd96..933cdcf 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -264,6 +264,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka,

  	if (ka->sa.sa_flags & SA_RESTORER)
  		sigtramp = ka->sa.sa_restorer;
+	else if (is_ilp32_compat_task())
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
  	else
  		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);

diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore
new file mode 100644
index 0000000..61806c3
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/.gitignore
@@ -0,0 +1,2 @@
+vdso-ilp32.lds
+vdso-ilp32-offsets.h
diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile
new file mode 100644
index 0000000..c8f5472
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/Makefile
@@ -0,0 +1,72 @@
+#
+# Building a vDSO image for AArch64.
+#
+# Author: Will Deacon <will.deacon@arm.com>
+# Heavily based on the vDSO Makefiles for other archs.
+#
+
+obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o
+
+# Build rules
+targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
+obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))
+
+ccflags-y := -shared -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
+		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+
+obj-y += vdso-ilp32.o
+extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h
+CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32
+
+# Force dependency (incbin is bad)
+$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so
+
+# Link rule for the .so file, .lds has to be first
+$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
+	$(call if_changed,vdso-ilp32ld)
+
+# Strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+# Generate VDSO offsets using helper script
+gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+define cmd_vdsosym
+	$(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
+	cp $@ include/generated/
+endef
+
+$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
+	$(call if_changed,vdsosym)
+
+# Assembly rules for the .S files
+#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
+#	$(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
+	$(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/note-ilp32.o: $(src)/../vdso/note.S
+	$(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
+	$(call if_changed_dep,vdso-ilp32as)
+
+# Actual build commands
+quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
+      cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32  -Wl,-n -Wl,-T $^ -o $@
+quiet_cmd_vdso-ilp32as = VDSOILP32A $@
+      cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<
+
+# Install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: vdso-ilp32.so
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
new file mode 100644
index 0000000..46ac072
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+	__PAGE_ALIGNED_DATA
+
+	.globl vdso_ilp32_start, vdso_ilp32_end
+	.balign PAGE_SIZE
+vdso_ilp32_start:
+	.incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
+	.balign PAGE_SIZE
+vdso_ilp32_end:
+
+	.previous
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
new file mode 100644
index 0000000..d182a8d
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -0,0 +1,95 @@
+/*
+ * GNU linker script for the VDSO library.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ * Heavily based on the vDSO linker scripts for other archs.
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>


+#include <asm/vdso.h>
+
+SECTIONS
+{
+	PROVIDE(_vdso_data = . - PAGE_SIZE);
+	. = VDSO_LBASE + SIZEOF_HEADERS;
+
+	.hash		: { *(.hash) }			:text
+	.gnu.hash	: { *(.gnu.hash) }
+	.dynsym		: { *(.dynsym) }
+	.dynstr		: { *(.dynstr) }
+	.gnu.version	: { *(.gnu.version) }
+	.gnu.version_d	: { *(.gnu.version_d) }
+	.gnu.version_r	: { *(.gnu.version_r) }
+
+	.note		: { *(.note.*) }		:text	:note
+
+	. = ALIGN(16);
+
+	.text		: { *(.text*) }			:text	=0xd503201f
+	PROVIDE (__etext = .);
+	PROVIDE (_etext = .);
+	PROVIDE (etext = .);
+
+	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
+	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
+
+	.dynamic	: { *(.dynamic) }		:text	:dynamic
+
+	.rodata		: { *(.rodata*) }		:text
+
+	_end = .;
+	PROVIDE(end = .);
+
+	/DISCARD/	: {
+		*(.note.GNU-stack)
+		*(.data .data.* .gnu.linkonce.d.* .sdata*)
+		*(.bss .sbss .dynbss .dynsbss)
+	}
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
+	note		PT_NOTE		FLAGS(4);		/* PF_R */
+	eh_frame_hdr	PT_GNU_EH_FRAME;
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+	LINUX_4.6 {
+	global:
+		__kernel_rt_sigreturn;
+		__kernel_gettimeofday;
+		__kernel_clock_gettime;
+		__kernel_clock_getres;
+	local: *;
+	};
+}
+
+/*
+ * Make the sigreturn code visible to the kernel.
+ */
+VDSO_sigtramp_ilp32		= __kernel_rt_sigreturn;
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 26352a6..521a8e4 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -40,6 +40,12 @@ extern char vdso_start, vdso_end;
  static unsigned long vdso_pages;
  static struct page **vdso_pagelist;

+#ifdef CONFIG_ARM64_ILP32
+extern char vdso_ilp32_start, vdso_ilp32_end;
+static unsigned long vdso_ilp32_pages;
+static struct page **vdso_ilp32_pagelist;
+#endif
+
  /*
   * The vDSO data page.
   */
@@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
  }
  #endif /* CONFIG_AARCH32_EL0 */

-static struct vm_special_mapping vdso_spec[2];
-
-static int __init vdso_init(void)
+static int __init vdso_init_common(char *vdso_start, char *vdso_end,
+					  unsigned long *vdso_pagesp,
+					  struct page ***vdso_pagelistp,
+					  struct vm_special_mapping* vdso_spec)
  {
  	int i;
+	unsigned long vdso_pages;
+	struct page **vdso_pagelist;

-	if (memcmp(&vdso_start, "\177ELF", 4)) {
+	if (memcmp(vdso_start, "\177ELF", 4)) {
  		pr_err("vDSO is not a valid ELF object!\n");
  		return -EINVAL;
  	}

-	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+	*vdso_pagesp = vdso_pages;
  	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
-		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
+		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);

  	/* Allocate the vDSO pagelist, plus a page for the data. */
  	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
  				GFP_KERNEL);
+	*vdso_pagelistp = vdso_pagelist;
  	if (vdso_pagelist == NULL)
  		return -ENOMEM;

@@ -135,7 +146,7 @@ static int __init vdso_init(void)

  	/* Grab the vDSO code pages. */
  	for (i = 0; i < vdso_pages; i++)
-		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);

  	/* Populate the special mapping structures */
  	vdso_spec[0] = (struct vm_special_mapping) {
@@ -150,16 +161,46 @@ static int __init vdso_init(void)

  	return 0;
  }
+
+static struct vm_special_mapping vdso_spec[2];
+
+static int __init vdso_init(void)
+{
+	return vdso_init_common(&vdso_start, &vdso_end,
+				&vdso_pages, &vdso_pagelist,
+				vdso_spec);
+}
  arch_initcall(vdso_init);

+#ifdef CONFIG_ARM64_ILP32
+static struct vm_special_mapping vdso_ilp32_spec[2];
+
+static int __init vdso_ilp32_init(void)
+{
+	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
+				&vdso_ilp32_pages, &vdso_ilp32_pagelist,
+				vdso_ilp32_spec);
+}
+arch_initcall(vdso_ilp32_init);
+#endif
+
  int arch_setup_additional_pages(struct linux_binprm *bprm,
  				int uses_interp)
  {
  	struct mm_struct *mm = current->mm;
  	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
  	void *ret;
+	unsigned long pages = vdso_pages;
+	struct vm_special_mapping *spec = vdso_spec;
+
+#ifdef CONFIG_ARM64_ILP32
+	if (is_ilp32_compat_task()) {
+	        pages = vdso_ilp32_pages;
+	        spec = vdso_ilp32_spec;
+	}
+#endif

-	vdso_text_len = vdso_pages << PAGE_SHIFT;
+	vdso_text_len = pages << PAGE_SHIFT;
  	/* Be sure to map the data page */
  	vdso_mapping_len = vdso_text_len + PAGE_SIZE;

@@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
  	}
  	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
  				       VM_READ|VM_MAYREAD,
-				       &vdso_spec[0]);
+				       &spec[0]);
  	if (IS_ERR(ret))
  		goto up_fail;

@@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
  	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
  				       VM_READ|VM_EXEC|
  				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				       &vdso_spec[1]);
+				       &spec[1]);
  	if (IS_ERR(ret))
  		goto up_fail;

diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index efa79e8..4551f55 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -25,6 +25,14 @@
  #define NSEC_PER_SEC_LO16	0xca00
  #define NSEC_PER_SEC_HI16	0x3b9a

+#ifdef __LP64__
+#define PTR_REG(n)      x##n
+#define OFFSET(n)	n
+#else
+#define PTR_REG(n)      w##n
+#define OFFSET(n)	COMPAT_##n
+#endif
+
  vdso_data	.req	x6
  use_syscall	.req	w7
  seqcnt		.req	w8
@@ -68,7 +76,7 @@ ENTRY(__kernel_gettimeofday)
  	mov	x13, #1000
  	lsl	x13, x13, x12
  	udiv	x11, x11, x13
-	stp	x10, x11, [x0, #TVAL_TV_SEC]
+	stp	PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
  2:
  	/* If tz is NULL, return 0. */
  	cbz	x1, 3f
@@ -159,7 +167,7 @@ ENTRY(__kernel_clock_gettime)

  6:	/* Store to the user timespec. */
  	lsr	x11, x11, x12
-	stp	x10, x11, [x1, #TSPEC_TV_SEC]
+	stp	PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
  	mov	x0, xzr
  	ret
  7:
-- 
1.8.4.5

Regads

Bamvor
> Regards
>
> Bamvor
>
>>
>>     Arnd
>>
>

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-04-13 15:55     ` Yury Norov
@ 2016-05-03 12:49       ` Zhangjian (Bamvor)
  0 siblings, 0 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-03 12:49 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel,
	schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Philipp Tomsich, Zhangjian (Bamvor),
	Hanjun Guo

Hi, yury

On 2016/4/13 23:55, Yury Norov wrote:
> Hi Bamvor,
>
> On Wed, Apr 13, 2016 at 05:19:28PM +0800, Zhangjian (Bamvor) wrote:
>> Hi, Yury and Philipp
>>
>> There is a small fix for this patch. Othervise our tools of living
>> patch could not work.
>>
>> Regards
>>
>> Bamvor
>>
>>  From e05770efca9f040e0039a4a9c4e0d7d3b2bd13e8 Mon Sep 17 00:00:00 2001
>> From: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
>> Date: Wed, 13 Apr 2016 15:46:28 +0800
>> Subject: [PATCH] arm64: ilp32: do not check vdso-ilp32-offsets.h when ILP32
>>   disabled
>>
>> vdso-ilp32-offsets.h is the dependency of all the arm64-obj-y. And
>> it does not exist when CONFIG_ARM64_ILP32 is disable which lead to
>> all the arm64-obj-y are re-built unnecessarily.
>>
>> Such rebuild may confuse the sofware(e.g. tools of living patch)
>> which need to know exactly which file(s) is(are) updated.
>>
>> This patch fix this issue by adding the config checker.
>
> It looks reasonable and correct.
>
> I'll apply your patch in next submission (if it will be needed),
> otherwise I think, Arnd may apply it.
>
> Though, I don't understand much, what 'tools of living patch' means.
> Could you explain in details what you do, and what goes wrong?
Our tools need to monitor the what *.o is changed after recompile.
But without this patch, all the object in arch/arm64/kernel is
recompiled. Because the vdso-ilp32-offsets.h is dependency of
these files, reference this line of patch:
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h

Regards

Bamvor
>
> Nevertheless, thank you for your attention to this patchset.
>
> Yury.
>
>>
>> Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
>> ---
>>   arch/arm64/kernel/Makefile | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> index b43ff12..0f27a10 100644
>> --- a/arch/arm64/kernel/Makefile
>> +++ b/arch/arm64/kernel/Makefile
>> @@ -60,5 +60,7 @@ $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
>>   $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
>>
>>   # vDSO - this must be built first to generate the symbol offsets
>> +ifeq ($(CONFIG_ARM64_ILP32),y)
>>   $(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
>>   $(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
>> +endif
>> --
>> 1.8.4.5
>>
>> On 2016/4/6 6:08, Yury Norov wrote:
>>> From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
>>>
>>> ILP32 VDSO exports next symbols:
>>>   __kernel_rt_sigreturn;
>>>   __kernel_gettimeofday;
>>>   __kernel_clock_gettime;
>>>   __kernel_clock_getres;
>>>
>>> What shared object to use, kernel selects depending on result of
>>> is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
>>> correct pages and spec.
>>>
>>> Adjusted to move the move data page before code pages in sync with
>>> commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1
>>>
>>> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
>>> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
>>> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
>>> ---
>>>   arch/arm64/include/asm/vdso.h                 |  6 ++
>>>   arch/arm64/kernel/Makefile                    |  5 ++
>>>   arch/arm64/kernel/signal.c                    |  2 +
>>>   arch/arm64/kernel/vdso-ilp32/.gitignore       |  2 +
>>>   arch/arm64/kernel/vdso-ilp32/Makefile         | 72 ++++++++++++++++++++
>>>   arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     | 33 ++++++++++
>>>   arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++
>>>   arch/arm64/kernel/vdso.c                      | 61 ++++++++++++++---
>>>   8 files changed, 266 insertions(+), 10 deletions(-)
>>>   create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
>>>   create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
>>>   create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
>>>   create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
>>>
>>> diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
>>> index 839ce00..649a9a4 100644
>>> --- a/arch/arm64/include/asm/vdso.h
>>> +++ b/arch/arm64/include/asm/vdso.h
>>> @@ -29,6 +29,12 @@
>>>
>>>   #include <generated/vdso-offsets.h>
>>>
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +#include <generated/vdso-ilp32-offsets.h>
>>> +#else
>>> +#define vdso_offset_sigtramp_ilp32
>>> +#endif
>>> +
>>>   #define VDSO_SYMBOL(base, name)						   \
>>>   ({									   \
>>>   	(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
>>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>>> index 09e4373..b43ff12 100644
>>> --- a/arch/arm64/kernel/Makefile
>>> +++ b/arch/arm64/kernel/Makefile
>>> @@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
>>>   arm64-obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
>>>
>>>   obj-y					+= $(arm64-obj-y) vdso/
>>> +obj-$(CONFIG_ARM64_ILP32)		+= vdso-ilp32/
>>>   obj-m					+= $(arm64-obj-m)
>>>   head-y					:= head.o
>>>   extra-y					+= $(head-y) vmlinux.lds
>>> @@ -57,3 +58,7 @@ extra-y					+= $(head-y) vmlinux.lds
>>>   # vDSO - this must be built first to generate the symbol offsets
>>>   $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
>>>   $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
>>> +
>>> +# vDSO - this must be built first to generate the symbol offsets
>>> +$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
>>> +$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
>>> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
>>> index 45bcd96..933cdcf 100644
>>> --- a/arch/arm64/kernel/signal.c
>>> +++ b/arch/arm64/kernel/signal.c
>>> @@ -264,6 +264,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
>>>
>>>   	if (ka->sa.sa_flags & SA_RESTORER)
>>>   		sigtramp = ka->sa.sa_restorer;
>>> +	else if (is_ilp32_compat_task())
>>> +		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
>>>   	else
>>>   		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
>>>
>>> diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore
>>> new file mode 100644
>>> index 0000000..61806c3
>>> --- /dev/null
>>> +++ b/arch/arm64/kernel/vdso-ilp32/.gitignore
>>> @@ -0,0 +1,2 @@
>>> +vdso-ilp32.lds
>>> +vdso-ilp32-offsets.h
>>> diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile
>>> new file mode 100644
>>> index 0000000..c8f5472
>>> --- /dev/null
>>> +++ b/arch/arm64/kernel/vdso-ilp32/Makefile
>>> @@ -0,0 +1,72 @@
>>> +#
>>> +# Building a vDSO image for AArch64.
>>> +#
>>> +# Author: Will Deacon <will.deacon@arm.com>
>>> +# Heavily based on the vDSO Makefiles for other archs.
>>> +#
>>> +
>>> +obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o
>>> +
>>> +# Build rules
>>> +targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
>>> +obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))
>>> +
>>> +ccflags-y := -shared -fno-common -fno-builtin
>>> +ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
>>> +		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
>>> +
>>> +obj-y += vdso-ilp32.o
>>> +extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h
>>> +CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32
>>> +
>>> +# Force dependency (incbin is bad)
>>> +$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so
>>> +
>>> +# Link rule for the .so file, .lds has to be first
>>> +$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
>>> +	$(call if_changed,vdso-ilp32ld)
>>> +
>>> +# Strip rule for the .so file
>>> +$(obj)/%.so: OBJCOPYFLAGS := -S
>>> +$(obj)/%.so: $(obj)/%.so.dbg FORCE
>>> +	$(call if_changed,objcopy)
>>> +
>>> +# Generate VDSO offsets using helper script
>>> +gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
>>> +quiet_cmd_vdsosym = VDSOSYM $@
>>> +define cmd_vdsosym
>>> +	$(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
>>> +	cp $@ include/generated/
>>> +endef
>>> +
>>> +$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
>>> +	$(call if_changed,vdsosym)
>>> +
>>> +# Assembly rules for the .S files
>>> +#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
>>> +#	$(call if_changed_dep,vdso-ilp32as)
>>> +
>>> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
>>> +	$(call if_changed_dep,vdso-ilp32as)
>>> +
>>> +$(obj)/note-ilp32.o: $(src)/../vdso/note.S
>>> +	$(call if_changed_dep,vdso-ilp32as)
>>> +
>>> +$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
>>> +	$(call if_changed_dep,vdso-ilp32as)
>>> +
>>> +# Actual build commands
>>> +quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
>>> +      cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32  -Wl,-n -Wl,-T $^ -o $@
>>> +quiet_cmd_vdso-ilp32as = VDSOILP32A $@
>>> +      cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<
>>> +
>>> +# Install commands for the unstripped file
>>> +quiet_cmd_vdso_install = INSTALL $@
>>> +      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
>>> +
>>> +vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
>>> +	@mkdir -p $(MODLIB)/vdso
>>> +	$(call cmd,vdso_install)
>>> +
>>> +vdso_install: vdso-ilp32.so
>>> diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
>>> new file mode 100644
>>> index 0000000..46ac072
>>> --- /dev/null
>>> +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
>>> @@ -0,0 +1,33 @@
>>> +/*
>>> + * Copyright (C) 2012 ARM Limited
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>> + *
>>> + * Author: Will Deacon <will.deacon@arm.com>
>>> + */
>>> +
>>> +#include <linux/init.h>
>>> +#include <linux/linkage.h>
>>> +#include <linux/const.h>
>>> +#include <asm/page.h>
>>> +
>>> +	__PAGE_ALIGNED_DATA
>>> +
>>> +	.globl vdso_ilp32_start, vdso_ilp32_end
>>> +	.balign PAGE_SIZE
>>> +vdso_ilp32_start:
>>> +	.incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
>>> +	.balign PAGE_SIZE
>>> +vdso_ilp32_end:
>>> +
>>> +	.previous
>>> diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
>>> new file mode 100644
>>> index 0000000..ddc63fd
>>> --- /dev/null
>>> +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
>>> @@ -0,0 +1,95 @@
>>> +/*
>>> + * GNU linker script for the VDSO library.
>>> + *
>>> + * Copyright (C) 2012 ARM Limited
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>> + *
>>> + * Author: Will Deacon <will.deacon@arm.com>
>>> + * Heavily based on the vDSO linker scripts for other archs.
>>> + */
>>> +
>>> +#include <linux/const.h>
>>> +#include <asm/page.h>
>>> +#include <asm/vdso.h>
>>> +
>>> +SECTIONS
>>> +{
>>> +	PROVIDE(_vdso_data = . - PAGE_SIZE);
>>> +	. = VDSO_LBASE + SIZEOF_HEADERS;
>>> +
>>> +	.hash		: { *(.hash) }			:text
>>> +	.gnu.hash	: { *(.gnu.hash) }
>>> +	.dynsym		: { *(.dynsym) }
>>> +	.dynstr		: { *(.dynstr) }
>>> +	.gnu.version	: { *(.gnu.version) }
>>> +	.gnu.version_d	: { *(.gnu.version_d) }
>>> +	.gnu.version_r	: { *(.gnu.version_r) }
>>> +
>>> +	.note		: { *(.note.*) }		:text	:note
>>> +
>>> +	. = ALIGN(16);
>>> +
>>> +	.text		: { *(.text*) }			:text	=0xd503201f
>>> +	PROVIDE (__etext = .);
>>> +	PROVIDE (_etext = .);
>>> +	PROVIDE (etext = .);
>>> +
>>> +	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
>>> +	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
>>> +
>>> +	.dynamic	: { *(.dynamic) }		:text	:dynamic
>>> +
>>> +	.rodata		: { *(.rodata*) }		:text
>>> +
>>> +	_end = .;
>>> +	PROVIDE(end = .);
>>> +
>>> +	/DISCARD/	: {
>>> +		*(.note.GNU-stack)
>>> +		*(.data .data.* .gnu.linkonce.d.* .sdata*)
>>> +		*(.bss .sbss .dynbss .dynsbss)
>>> +	}
>>> +}
>>> +
>>> +/*
>>> + * We must supply the ELF program headers explicitly to get just one
>>> + * PT_LOAD segment, and set the flags explicitly to make segments read-only.
>>> + */
>>> +PHDRS
>>> +{
>>> +	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
>>> +	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
>>> +	note		PT_NOTE		FLAGS(4);		/* PF_R */
>>> +	eh_frame_hdr	PT_GNU_EH_FRAME;
>>> +}
>>> +
>>> +/*
>>> + * This controls what symbols we export from the DSO.
>>> + */
>>> +VERSION
>>> +{
>>> +	LINUX_2.6 {
>>> +	global:
>>> +		__kernel_rt_sigreturn;
>>> +		__kernel_gettimeofday;
>>> +		__kernel_clock_gettime;
>>> +		__kernel_clock_getres;
>>> +	local: *;
>>> +	};
>>> +}
>>> +
>>> +/*
>>> + * Make the sigreturn code visible to the kernel.
>>> + */
>>> +VDSO_sigtramp_ilp32		= __kernel_rt_sigreturn;
>>> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
>>> index 26352a6..521a8e4 100644
>>> --- a/arch/arm64/kernel/vdso.c
>>> +++ b/arch/arm64/kernel/vdso.c
>>> @@ -40,6 +40,12 @@ extern char vdso_start, vdso_end;
>>>   static unsigned long vdso_pages;
>>>   static struct page **vdso_pagelist;
>>>
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +extern char vdso_ilp32_start, vdso_ilp32_end;
>>> +static unsigned long vdso_ilp32_pages;
>>> +static struct page **vdso_ilp32_pagelist;
>>> +#endif
>>> +
>>>   /*
>>>    * The vDSO data page.
>>>    */
>>> @@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
>>>   }
>>>   #endif /* CONFIG_AARCH32_EL0 */
>>>
>>> -static struct vm_special_mapping vdso_spec[2];
>>> -
>>> -static int __init vdso_init(void)
>>> +static int __init vdso_init_common(char *vdso_start, char *vdso_end,
>>> +					  unsigned long *vdso_pagesp,
>>> +					  struct page ***vdso_pagelistp,
>>> +					  struct vm_special_mapping* vdso_spec)
>>>   {
>>>   	int i;
>>> +	unsigned long vdso_pages;
>>> +	struct page **vdso_pagelist;
>>>
>>> -	if (memcmp(&vdso_start, "\177ELF", 4)) {
>>> +	if (memcmp(vdso_start, "\177ELF", 4)) {
>>>   		pr_err("vDSO is not a valid ELF object!\n");
>>>   		return -EINVAL;
>>>   	}
>>>
>>> -	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
>>> +	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
>>> +	*vdso_pagesp = vdso_pages;
>>>   	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
>>> -		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
>>> +		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
>>>
>>>   	/* Allocate the vDSO pagelist, plus a page for the data. */
>>>   	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
>>>   				GFP_KERNEL);
>>> +	*vdso_pagelistp = vdso_pagelist;
>>>   	if (vdso_pagelist == NULL)
>>>   		return -ENOMEM;
>>>
>>> @@ -135,7 +146,7 @@ static int __init vdso_init(void)
>>>
>>>   	/* Grab the vDSO code pages. */
>>>   	for (i = 0; i < vdso_pages; i++)
>>> -		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
>>> +		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
>>>
>>>   	/* Populate the special mapping structures */
>>>   	vdso_spec[0] = (struct vm_special_mapping) {
>>> @@ -150,16 +161,46 @@ static int __init vdso_init(void)
>>>
>>>   	return 0;
>>>   }
>>> +
>>> +static struct vm_special_mapping vdso_spec[2];
>>> +
>>> +static int __init vdso_init(void)
>>> +{
>>> +	return vdso_init_common(&vdso_start, &vdso_end,
>>> +				&vdso_pages, &vdso_pagelist,
>>> +				vdso_spec);
>>> +}
>>>   arch_initcall(vdso_init);
>>>
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +static struct vm_special_mapping vdso_ilp32_spec[2];
>>> +
>>> +static int __init vdso_ilp32_init(void)
>>> +{
>>> +	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
>>> +				&vdso_ilp32_pages, &vdso_ilp32_pagelist,
>>> +				vdso_ilp32_spec);
>>> +}
>>> +arch_initcall(vdso_ilp32_init);
>>> +#endif
>>> +
>>>   int arch_setup_additional_pages(struct linux_binprm *bprm,
>>>   				int uses_interp)
>>>   {
>>>   	struct mm_struct *mm = current->mm;
>>>   	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
>>>   	void *ret;
>>> +	unsigned long pages = vdso_pages;
>>> +	struct vm_special_mapping *spec = vdso_spec;
>>> +
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +	if (is_ilp32_compat_task()) {
>>> +	        pages = vdso_ilp32_pages;
>>> +	        spec = vdso_ilp32_spec;
>>> +	}
>>> +#endif
>>>
>>> -	vdso_text_len = vdso_pages << PAGE_SHIFT;
>>> +	vdso_text_len = pages << PAGE_SHIFT;
>>>   	/* Be sure to map the data page */
>>>   	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
>>>
>>> @@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>>>   	}
>>>   	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
>>>   				       VM_READ|VM_MAYREAD,
>>> -				       &vdso_spec[0]);
>>> +				       &spec[0]);
>>>   	if (IS_ERR(ret))
>>>   		goto up_fail;
>>>
>>> @@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>>>   	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
>>>   				       VM_READ|VM_EXEC|
>>>   				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
>>> -				       &vdso_spec[1]);
>>> +				       &spec[1]);
>>>   	if (IS_ERR(ret))
>>>   		goto up_fail;
>>>
>>>

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-03 12:41             ` Zhangjian (Bamvor)
@ 2016-05-04 21:49               ` Yury Norov
  2016-05-04 23:23                 ` Andrew Pinski
  2016-05-05  8:22               ` Yury Norov
  1 sibling, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-04 21:49 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Arnd Bergmann, Catalin Marinas, linux-arch, linux-s390, pinskia,
	Prasun.Kapoor, schwab, broonie, linux-doc, heiko.carstens,
	linux-kernel, agraf, klimov.linux, joseph, schwidefsky,
	Nathan_Lynch, Philipp Tomsich, linux-arm-kernel,
	christoph.muellner, Hanjun Guo

On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
> Hi, all
> 
> After apply this patch with my small testcase, the vsyscall of gettimeofday in
> ilp32 works in both big endian and small endian. In this patch, I use the
> different register and offset for ilp32 and lp64. Actually, the
> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
> 

[...]

Hi Bamvor,

It works for me as well. Thank you.
I'll incorporate it in next submission.

Yury.

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-04 21:49               ` Yury Norov
@ 2016-05-04 23:23                 ` Andrew Pinski
  2016-05-05  2:24                   ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Andrew Pinski @ 2016-05-04 23:23 UTC (permalink / raw)
  To: Yury Norov
  Cc: Zhangjian (Bamvor),
	Arnd Bergmann, Catalin Marinas, Linux-Arch, linux-s390, Kapoor,
	Prasun, Andreas Schwab, Mark Brown, linux-doc, Heiko Carstens,
	LKML, Alexander Graf, Alexey Klimov, Joseph S. Myers,
	Martin Schwidefsky, Nathan Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner, Hanjun Guo

On Wed, May 4, 2016 at 2:49 PM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
>> Hi, all
>>
>> After apply this patch with my small testcase, the vsyscall of gettimeofday in
>> ilp32 works in both big endian and small endian. In this patch, I use the
>> different register and offset for ilp32 and lp64. Actually, the
>> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
>> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
>> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
>>
>
> [...]
>
> Hi Bamvor,
>
> It works for me as well. Thank you.
> I'll incorporate it in next submission.

We should add the following so we are complaint to the ILP32 ABI
dealing with pointers don't have to be zero extended for arguments,
Note ZERO should most likely be ZERO_PTR or something to do that
effect, I am not so good with names.
#ifdef __LP64__
#define ZERO(n)
#else
#define ZERO(n)         mov     w##n, w##n
#endif

...
ENTRY(__kernel_gettimeofday)
        .cfi_startproc
        ZERO(0)
        ZERO(1)
...
ENTRY(__kernel_clock_gettime)
        .cfi_startproc
        ZERO(1)
...
ENTRY(__kernel_clock_getres)
        .cfi_startproc
        ZERO(1)

Thanks,
Andrew Pinski

>
> Yury.

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-04 23:23                 ` Andrew Pinski
@ 2016-05-05  2:24                   ` Zhangjian (Bamvor)
  2016-05-05  6:40                     ` Andrew Pinski
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-05  2:24 UTC (permalink / raw)
  To: Andrew Pinski, Yury Norov
  Cc: Arnd Bergmann, Catalin Marinas, Linux-Arch, linux-s390, Kapoor,
	Prasun, Andreas Schwab, Mark Brown, linux-doc, Heiko Carstens,
	LKML, Alexander Graf, Alexey Klimov, Joseph S. Myers,
	Martin Schwidefsky, Nathan Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner, Hanjun Guo,
	Zhangjian (Bamvor)

Hi,

On 2016/5/5 7:23, Andrew Pinski wrote:
> On Wed, May 4, 2016 at 2:49 PM, Yury Norov <ynorov@caviumnetworks.com> wrote:
>> On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
>>> Hi, all
>>>
>>> After apply this patch with my small testcase, the vsyscall of gettimeofday in
>>> ilp32 works in both big endian and small endian. In this patch, I use the
>>> different register and offset for ilp32 and lp64. Actually, the
>>> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
>>> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
>>> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
>>>
>>
>> [...]
>>
>> Hi Bamvor,
>>
>> It works for me as well. Thank you.
>> I'll incorporate it in next submission.
>
> We should add the following so we are complaint to the ILP32 ABI
> dealing with pointers don't have to be zero extended for arguments,
> Note ZERO should most likely be ZERO_PTR or something to do that
> effect, I am not so good with names.
> #ifdef __LP64__
> #define ZERO(n)
> #else
> #define ZERO(n)         mov     w##n, w##n
> #endif
>
> ...
> ENTRY(__kernel_gettimeofday)
>          .cfi_startproc
>          ZERO(0)
>          ZERO(1)
> ...
> ENTRY(__kernel_clock_gettime)
>          .cfi_startproc
>          ZERO(1)
> ...
> ENTRY(__kernel_clock_getres)
>          .cfi_startproc
>          ZERO(1)
Thanks. I will test and send a new version.

Thanks.

Bamvor
> Thanks,
> Andrew Pinski
>
>>
>> Yury.

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-05  2:24                   ` Zhangjian (Bamvor)
@ 2016-05-05  6:40                     ` Andrew Pinski
  2016-05-06 14:00                       ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Andrew Pinski @ 2016-05-05  6:40 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Yury Norov, Arnd Bergmann, Catalin Marinas, Linux-Arch,
	linux-s390, Kapoor, Prasun, Andreas Schwab, Mark Brown,
	linux-doc, Heiko Carstens, LKML, Alexander Graf, Alexey Klimov,
	Joseph S. Myers, Martin Schwidefsky, Nathan Lynch,
	Philipp Tomsich, linux-arm-kernel, christoph.muellner,
	Hanjun Guo

On Wed, May 4, 2016 at 7:24 PM, Zhangjian (Bamvor)
<bamvor.zhangjian@huawei.com> wrote:
> Hi,
>
>
> On 2016/5/5 7:23, Andrew Pinski wrote:
>>
>> On Wed, May 4, 2016 at 2:49 PM, Yury Norov <ynorov@caviumnetworks.com>
>> wrote:
>>>
>>> On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
>>>>
>>>> Hi, all
>>>>
>>>> After apply this patch with my small testcase, the vsyscall of
>>>> gettimeofday in
>>>> ilp32 works in both big endian and small endian. In this patch, I use
>>>> the
>>>> different register and offset for ilp32 and lp64. Actually, the
>>>> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC
>>>> and
>>>> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the
>>>> version
>>>> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
>>>>
>>>
>>> [...]
>>>
>>> Hi Bamvor,
>>>
>>> It works for me as well. Thank you.
>>> I'll incorporate it in next submission.
>>
>>
>> We should add the following so we are complaint to the ILP32 ABI
>> dealing with pointers don't have to be zero extended for arguments,
>> Note ZERO should most likely be ZERO_PTR or something to do that
>> effect, I am not so good with names.
>> #ifdef __LP64__
>> #define ZERO(n)
>> #else
>> #define ZERO(n)         mov     w##n, w##n
>> #endif
>>
>> ...
>> ENTRY(__kernel_gettimeofday)
>>          .cfi_startproc
>>          ZERO(0)
>>          ZERO(1)
>> ...
>> ENTRY(__kernel_clock_gettime)
>>          .cfi_startproc
>>          ZERO(1)
>> ...
>> ENTRY(__kernel_clock_getres)
>>          .cfi_startproc
>>          ZERO(1)
>
> Thanks. I will test and send a new version.


Note there is one more patch needed to __kernel_clock_getres to store
using 32bit rather than 64bit too.
@@ -213,7 +213,7 @@ ENTRY(__kernel_clock_getres)
        ldr     x2, 6f
 2:
        cbz     w1, 3f
-       stp     xzr, x2, [x1]
+       stp     PTR_REG(zr), PTR_REG(2), [x1]

 3:     /* res == NULL. */
        mov     w0, wzr


Thanks,
Andrew

>
> Thanks.
>
> Bamvor
>>
>> Thanks,
>> Andrew Pinski
>>
>>>
>>> Yury.
>
>

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-03 12:41             ` Zhangjian (Bamvor)
  2016-05-04 21:49               ` Yury Norov
@ 2016-05-05  8:22               ` Yury Norov
  1 sibling, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-05  8:22 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Arnd Bergmann, Catalin Marinas, linux-arch, linux-s390, pinskia,
	Prasun.Kapoor, schwab, broonie, linux-doc, heiko.carstens,
	linux-kernel, agraf, klimov.linux, joseph, schwidefsky,
	Nathan_Lynch, Philipp Tomsich, linux-arm-kernel,
	christoph.muellner, Hanjun Guo

On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
[...]

> After apply this patch with my small testcase, the vsyscall of gettimeofday in
> ilp32 works in both big endian and small endian. In this patch, I use the
> different register and offset for ilp32 and lp64. Actually, the
> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
> 
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 574081f..c8e32eb 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -101,6 +101,11 @@ int main(void)
>    DEFINE(TSPEC_TV_SEC,		offsetof(struct timespec, tv_sec));
>    DEFINE(TSPEC_TV_NSEC,		offsetof(struct timespec, tv_nsec));
>    BLANK();
> +  DEFINE(COMPAT_TVAL_TV_SEC,	offsetof(struct compat_timeval, tv_sec));
> +  DEFINE(COMPAT_TVAL_TV_USEC,	offsetof(struct compat_timeval, tv_usec));
> +  DEFINE(COMPAT_TSPEC_TV_SEC,	offsetof(struct compat_timespec, tv_sec));
> +  DEFINE(COMPAT_TSPEC_TV_NSEC,	offsetof(struct compat_timespec, tv_nsec));
> +  BLANK();

Hi Bamvor,

We just found this lines break build if ILP32 is disabled. I think we
need to wrap them with #ifdef CONFIG_ARM64_ILP32

Yury

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

* Re: [PATCH 15/25] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
  2016-04-05 22:08 ` [PATCH 15/25] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat) Yury Norov
@ 2016-05-06 12:02   ` Zhangjian (Bamvor)
  0 siblings, 0 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-06 12:02 UTC (permalink / raw)
  To: Yury Norov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Philipp Tomsich, Andrew Pinski, Hanjun Guo, Zhangjian (Bamvor)

Hi,

On 2016/4/6 6:08, Yury Norov wrote:
> Based on patch of Andrew Pinski.
>
> This patch introduces is_a32_compat_task and is_a32_thread so it is
> easier to say this is a a32 specific thread or a generic compat thread/task.
> Corresponding functions are located in <asm/is_compat.h> to avoid mess in
> headers.
>
> Some files include both <linux/compat.h> and <asm/compat.h>,
> and this is wrong because <linux/compat.h> has <asm/compat.h> already
> included. It was fixed too.

1.  in "kernel/seccomp.c"
     There are different list for a32 and LP64. I do not know we
     should add a new one or align to one of them. Currently, we
     align ilp32 to a32 list.
```
/*
  * Secure computing mode 1 allows only read/write/exit/sigreturn.
  * To be fully secure this must be combined with rlimit
  * to limit the stack allocations too.
  */
static int mode1_syscalls[] = {
         __NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
         0, /* null terminated */
};

#ifdef CONFIG_COMPAT
static int mode1_syscalls_32[] = {
         __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
         0, /* null terminated */
};
#endif

static void __secure_computing_strict(int this_syscall)
{
         int *syscall_whitelist = mode1_syscalls;
#ifdef CONFIG_COMPAT
         if (in_compat_syscall())
                 syscall_whitelist = mode1_syscalls_32;
#endif
```

2.  in "kernel/auditsc.c"
     __audit_seccomp will print if compat or not. But in the same file,
     it call syscall_get_arch() to get the architecture in which ILP32
     is same as LP64.
     And consequenly, do we need to split in_compat_syscall to
     in_a32_compat_syscall and in_ilp32 compat_syscall?

```
void __audit_seccomp(unsigned long syscall, long signr, int code)
{
         struct audit_buffer *ab;

         ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP);
         if (unlikely(!ab))
                 return;
         audit_log_task(ab);
         audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x",
                          signr, syscall_get_arch(), syscall,
                          in_compat_syscall(), KSTK_EIP(current), code);
         audit_log_end(ab);
}
```

Thanks

Bamvor

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
  2016-04-25 17:26   ` Catalin Marinas
  2016-04-26 16:57   ` Catalin Marinas
@ 2016-05-06 12:16   ` Zhangjian (Bamvor)
  2016-05-06 12:37     ` Yury Norov
  2016-05-14 15:03   ` Yury Norov
  3 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-06 12:16 UTC (permalink / raw)
  To: Yury Norov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, linux-doc, linux-arch, linux-s390,
	Andrew Pinski, Andrew Pinski, Hanjun Guo, Zhangjian (Bamvor)

Hi,

On 2016/4/6 6:08, Yury Norov wrote:
> From: Andrew Pinski <apinski@cavium.com>
>
> Add a separate syscall-table for ILP32, which dispatches either to native
> LP64 system call implementation or to compat-syscalls, as appropriate.
>
> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
>   arch/arm64/include/asm/unistd.h | 11 ++++++-
>   arch/arm64/kernel/Makefile      |  2 +-
>   arch/arm64/kernel/entry.S       | 12 +++++++-
>   arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
>   4 files changed, 87 insertions(+), 3 deletions(-)
>   create mode 100644 arch/arm64/kernel/sys_ilp32.c
>
> diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
> index 2971dea..5ea18ef 100644
> --- a/arch/arm64/include/asm/unistd.h
> +++ b/arch/arm64/include/asm/unistd.h
> @@ -13,9 +13,18 @@
>    * You should have received a copy of the GNU General Public License
>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>    */
> +
> +#ifdef CONFIG_COMPAT
> +#define __ARCH_WANT_COMPAT_STAT64
> +#endif
> +
> +#ifdef CONFIG_ARM64_ILP32
> +#define __ARCH_WANT_COMPAT_SYS_PREADV64
> +#define __ARCH_WANT_COMPAT_SYS_PWRITEV64
> +#endif
> +
>   #ifdef CONFIG_AARCH32_EL0
>   #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
> -#define __ARCH_WANT_COMPAT_STAT64
>   #define __ARCH_WANT_SYS_GETHOSTNAME
>   #define __ARCH_WANT_SYS_PAUSE
>   #define __ARCH_WANT_SYS_GETPGRP
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 9dfdf86..7aa65ea 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
>   arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
>   					   sys_compat.o entry32.o		\
>   					   ../../arm/kernel/opcodes.o binfmt_elf32.o
> -arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
> +arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
>   arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
>   arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
>   arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index cf4d1ae..1f7a145 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
>    */
>   	.align	6
>   el0_svc:
> -	adrp	stbl, sys_call_table		// load syscall table pointer
>   	uxtw	scno, w8			// syscall number in w8
>   	mov	sc_nr, #__NR_syscalls
> +#ifdef CONFIG_ARM64_ILP32
> +	ldr	x16, [tsk, #TI_FLAGS]
> +	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
> +#endif
> +	adrp	stbl, sys_call_table		// load syscall table pointer
>   el0_svc_naked:					// compat entry point
>   	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
>   	enable_dbg_and_irq
> @@ -737,6 +741,12 @@ ni_sys:
>   	b	ret_fast_syscall
>   ENDPROC(el0_svc)
>
> +#ifdef CONFIG_ARM64_ILP32
> +el0_ilp32_svc:
> +	adrp	stbl, sys_call_ilp32_table // load syscall table pointer
> +	b el0_svc_naked
> +#endif
> +
>   	/*
>   	 * This is the really slow path.  We're going to be doing context
>   	 * switches, and waiting for our parent to respond.
> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> new file mode 100644
> index 0000000..0996d8e
> --- /dev/null
> +++ b/arch/arm64/kernel/sys_ilp32.c
> @@ -0,0 +1,65 @@
> +/*
> + * AArch64- ILP32 specific system calls implementation
> + *
> + * Copyright (C) 2016 Cavium Inc.
> + * Author: Andrew Pinski <apinski@cavium.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/compiler.h>
> +#include <linux/errno.h>
> +#include <linux/fs.h>
> +#include <linux/mm.h>
> +#include <linux/msg.h>
> +#include <linux/export.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/syscalls.h>
> +#include <linux/compat.h>
> +#include <asm-generic/syscalls.h>
> +
> +/* Using non-compat syscalls where necessary */
> +#define compat_sys_fadvise64_64        sys_fadvise64_64
> +#define compat_sys_fallocate           sys_fallocate
> +#define compat_sys_ftruncate64         sys_ftruncate
> +#define compat_sys_lookup_dcookie      sys_lookup_dcookie
> +#define compat_sys_pread64             sys_pread64
> +#define compat_sys_pwrite64            sys_pwrite64
> +#define compat_sys_readahead           sys_readahead
> +#define compat_sys_shmat               sys_shmat
> +#define compat_sys_sync_file_range     sys_sync_file_range
> +#define compat_sys_truncate64          sys_truncate
> +#define sys_llseek                     sys_lseek
> +#define sys_mmap2		       sys_mmap
I am a little bit confused here. We wrap the mmap to mmap2 in glibc
without shift the 4096 and We map mmap2 to mmap in kernel which
means we shift with the real page size. It works unless the
application want to mmap the offset bigger then 2G. In ILP32 app,
if the offset is bigger than 2G(e.g. 0xfb000000), it is a negative
number and extend to 64bit nagetive number in kernel
(0xfffffff fb000000). I add the "COMPAT_SYSCALL_WRAP6(mmap, ...)" in
kernel/compat_wrapper.c. But it is not works. I am not sure if it is
already sign extended in userspace.

On the other hand, I read the code of mmap in arm and other
architecture. Usually, they will shift 4096 in userspace and shift
others in kernel if needed. Should we follow the similar ways or we
could call mmap_pgoff in glibc and do the shift according the real
page shift(getpages())?

Thanks

Bamvor

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-06 12:16   ` Zhangjian (Bamvor)
@ 2016-05-06 12:37     ` Yury Norov
  2016-05-10  7:42       ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-06 12:37 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel,
	linux-arch, linux-s390, Hanjun Guo, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, broonie, Andrew Pinski, schwab, schwidefsky,
	joseph, christoph.muellner

On Fri, May 06, 2016 at 08:16:48PM +0800, Zhangjian (Bamvor) wrote:
> Hi,
> 
> On 2016/4/6 6:08, Yury Norov wrote:
> >From: Andrew Pinski <apinski@cavium.com>
> >
> >Add a separate syscall-table for ILP32, which dispatches either to native
> >LP64 system call implementation or to compat-syscalls, as appropriate.
> >
> >Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> >Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> >---
> >  arch/arm64/include/asm/unistd.h | 11 ++++++-
> >  arch/arm64/kernel/Makefile      |  2 +-
> >  arch/arm64/kernel/entry.S       | 12 +++++++-
> >  arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 87 insertions(+), 3 deletions(-)
> >  create mode 100644 arch/arm64/kernel/sys_ilp32.c
> >
> >diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
> >index 2971dea..5ea18ef 100644
> >--- a/arch/arm64/include/asm/unistd.h
> >+++ b/arch/arm64/include/asm/unistd.h
> >@@ -13,9 +13,18 @@
> >   * You should have received a copy of the GNU General Public License
> >   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >   */
> >+
> >+#ifdef CONFIG_COMPAT
> >+#define __ARCH_WANT_COMPAT_STAT64
> >+#endif
> >+
> >+#ifdef CONFIG_ARM64_ILP32
> >+#define __ARCH_WANT_COMPAT_SYS_PREADV64
> >+#define __ARCH_WANT_COMPAT_SYS_PWRITEV64
> >+#endif
> >+
> >  #ifdef CONFIG_AARCH32_EL0
> >  #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
> >-#define __ARCH_WANT_COMPAT_STAT64
> >  #define __ARCH_WANT_SYS_GETHOSTNAME
> >  #define __ARCH_WANT_SYS_PAUSE
> >  #define __ARCH_WANT_SYS_GETPGRP
> >diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> >index 9dfdf86..7aa65ea 100644
> >--- a/arch/arm64/kernel/Makefile
> >+++ b/arch/arm64/kernel/Makefile
> >@@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
> >  arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
> >  					   sys_compat.o entry32.o		\
> >  					   ../../arm/kernel/opcodes.o binfmt_elf32.o
> >-arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
> >+arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
> >  arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
> >  arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
> >  arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
> >diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> >index cf4d1ae..1f7a145 100644
> >--- a/arch/arm64/kernel/entry.S
> >+++ b/arch/arm64/kernel/entry.S
> >@@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
> >   */
> >  	.align	6
> >  el0_svc:
> >-	adrp	stbl, sys_call_table		// load syscall table pointer
> >  	uxtw	scno, w8			// syscall number in w8
> >  	mov	sc_nr, #__NR_syscalls
> >+#ifdef CONFIG_ARM64_ILP32
> >+	ldr	x16, [tsk, #TI_FLAGS]
> >+	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
> >+#endif
> >+	adrp	stbl, sys_call_table		// load syscall table pointer
> >  el0_svc_naked:					// compat entry point
> >  	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
> >  	enable_dbg_and_irq
> >@@ -737,6 +741,12 @@ ni_sys:
> >  	b	ret_fast_syscall
> >  ENDPROC(el0_svc)
> >
> >+#ifdef CONFIG_ARM64_ILP32
> >+el0_ilp32_svc:
> >+	adrp	stbl, sys_call_ilp32_table // load syscall table pointer
> >+	b el0_svc_naked
> >+#endif
> >+
> >  	/*
> >  	 * This is the really slow path.  We're going to be doing context
> >  	 * switches, and waiting for our parent to respond.
> >diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> >new file mode 100644
> >index 0000000..0996d8e
> >--- /dev/null
> >+++ b/arch/arm64/kernel/sys_ilp32.c
> >@@ -0,0 +1,65 @@
> >+/*
> >+ * AArch64- ILP32 specific system calls implementation
> >+ *
> >+ * Copyright (C) 2016 Cavium Inc.
> >+ * Author: Andrew Pinski <apinski@cavium.com>
> >+ *
> >+ * This program is free software; you can redistribute it and/or modify
> >+ * it under the terms of the GNU General Public License version 2 as
> >+ * published by the Free Software Foundation.
> >+ *
> >+ * This program is distributed in the hope that it will be useful,
> >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >+ * GNU General Public License for more details.
> >+ *
> >+ * You should have received a copy of the GNU General Public License
> >+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >+ */
> >+
> >+#include <linux/compiler.h>
> >+#include <linux/errno.h>
> >+#include <linux/fs.h>
> >+#include <linux/mm.h>
> >+#include <linux/msg.h>
> >+#include <linux/export.h>
> >+#include <linux/sched.h>
> >+#include <linux/slab.h>
> >+#include <linux/syscalls.h>
> >+#include <linux/compat.h>
> >+#include <asm-generic/syscalls.h>
> >+
> >+/* Using non-compat syscalls where necessary */
> >+#define compat_sys_fadvise64_64        sys_fadvise64_64
> >+#define compat_sys_fallocate           sys_fallocate
> >+#define compat_sys_ftruncate64         sys_ftruncate
> >+#define compat_sys_lookup_dcookie      sys_lookup_dcookie
> >+#define compat_sys_pread64             sys_pread64
> >+#define compat_sys_pwrite64            sys_pwrite64
> >+#define compat_sys_readahead           sys_readahead
> >+#define compat_sys_shmat               sys_shmat
> >+#define compat_sys_sync_file_range     sys_sync_file_range
> >+#define compat_sys_truncate64          sys_truncate
> >+#define sys_llseek                     sys_lseek
> >+#define sys_mmap2		       sys_mmap
> I am a little bit confused here. We wrap the mmap to mmap2 in glibc
> without shift the 4096 and We map mmap2 to mmap in kernel which
> means we shift with the real page size. It works unless the
> application want to mmap the offset bigger then 2G. In ILP32 app,
> if the offset is bigger than 2G(e.g. 0xfb000000), it is a negative
> number and extend to 64bit nagetive number in kernel
> (0xfffffff fb000000). I add the "COMPAT_SYSCALL_WRAP6(mmap, ...)" in
> kernel/compat_wrapper.c. But it is not works. I am not sure if it is
> already sign extended in userspace.
> 
> On the other hand, I read the code of mmap in arm and other
> architecture. Usually, they will shift 4096 in userspace and shift
> others in kernel if needed. Should we follow the similar ways or we
> could call mmap_pgoff in glibc and do the shift according the real
> page shift(getpages())?
> 
> Thanks
> 
> Bamvor
> 
> 

Hi,

AFAIR, here we don't shift offset, as it's 64-bit both in user-
and kernel-space, and just pass it from user to kernel thru glibc
with no changes.

It definitely works, as there are many mappings made by linker and
libc in 2G+ area, and there are no problems with them. This is a
typical ILP32 application map:

00400000-00401000 r-xp 00000000 08:00 130400     /root/mykill
00410000-00411000 rwxp 00000000 08:00 130400     /root/mykill
00527000-00549000 rwxp 00000000 00:00 0          [heap]
c6278000-c6298000 rwxp 00000000 00:00 0 
c6298000-c63d0000 r-xp 00000000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
c63d0000-c63e0000 ---p 00138000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
c63e0000-c63e2000 r-xp 00138000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
c63e2000-c63e3000 rwxp 0013a000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
c63e3000-c63e6000 rwxp 00000000 00:00 0 
c63e6000-c63fc000 r-xp 00000000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
c63fc000-c640b000 ---p 00016000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
c640b000-c640c000 r-xp 00015000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
c640c000-c640d000 rwxp 00016000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
c640d000-c640f000 rwxp 00000000 00:00 0 
c640f000-c642c000 r-xp 00000000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
c6437000-c6439000 rwxp 00000000 00:00 0 
c6439000-c643a000 r--p 00000000 00:00 0          [vvar]
c643a000-c643b000 r-xp 00000000 00:00 0          [vdso]
c643b000-c643c000 r-xp 0001c000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
c643c000-c643d000 rwxp 0001d000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
ffe2d000-ffe4e000 rw-p 00000000 00:00 0          [stack]


> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-05  6:40                     ` Andrew Pinski
@ 2016-05-06 14:00                       ` Yury Norov
  2016-05-09 10:07                         ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-06 14:00 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Zhangjian (Bamvor),
	Arnd Bergmann, Catalin Marinas, Linux-Arch, linux-s390, Kapoor,
	Prasun, Andreas Schwab, Mark Brown, linux-doc, Heiko Carstens,
	LKML, Alexander Graf, Alexey Klimov, Joseph S. Myers,
	Martin Schwidefsky, Nathan Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner, Hanjun Guo

Hello colleagues,

After all comments, VDSO fix looks like this for me.

Note I renamed Andrew's ZERO macro to DELOUSE, as
there already is __SC_DELOUSE which does the same,
but in C, not asm.

Like Bamvor, I'm not sure how we'd apply this patch - 
standalone or meld to VDSO. I think, VDSO patch is too
big and bad-structurized, and if I find how to refactor
it, I'll incorporate this fix.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/kernel/asm-offsets.c               |  7 +++++++
 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S |  2 +-
 arch/arm64/kernel/vdso/gettimeofday.S         | 20 +++++++++++++++++---
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index e229525..fcfd087 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -101,6 +101,13 @@ int main(void)
   DEFINE(TSPEC_TV_SEC,		offsetof(struct timespec, tv_sec));
   DEFINE(TSPEC_TV_NSEC,		offsetof(struct timespec, tv_nsec));
   BLANK();
+#ifdef CONFIG_ARM64_ILP32
+  DEFINE(COMPAT_TVAL_TV_SEC,	offsetof(struct compat_timeval, tv_sec));
+  DEFINE(COMPAT_TVAL_TV_USEC,	offsetof(struct compat_timeval, tv_usec));
+  DEFINE(COMPAT_TSPEC_TV_SEC,	offsetof(struct compat_timespec, tv_sec));
+  DEFINE(COMPAT_TSPEC_TV_NSEC,	offsetof(struct compat_timespec, tv_nsec));
+  BLANK();
+#endif
   DEFINE(TZ_MINWEST,		offsetof(struct timezone, tz_minuteswest));
   DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
   BLANK();
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
index ddc63fd..d182a8d 100644
--- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -79,7 +79,7 @@ PHDRS
  */
 VERSION
 {
-	LINUX_2.6 {
+	LINUX_2.6.39 {
 	global:
 		__kernel_rt_sigreturn;
 		__kernel_gettimeofday;
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index efa79e8..a2d8a70 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -25,6 +25,16 @@
 #define NSEC_PER_SEC_LO16	0xca00
 #define NSEC_PER_SEC_HI16	0x3b9a
 
+#ifdef __LP64__
+#define PTR_REG(n)	x##n
+#define OFFSET(n)	n
+#define DELOUSE(n)
+#else
+#define PTR_REG(n)	w##n
+#define OFFSET(n)	COMPAT_##n
+#define DELOUSE(n)	mov     w##n, w##n
+#endif
+
 vdso_data	.req	x6
 use_syscall	.req	w7
 seqcnt		.req	w8
@@ -51,6 +61,8 @@ seqcnt		.req	w8
 /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
 ENTRY(__kernel_gettimeofday)
 	.cfi_startproc
+	DELOUSE(0)
+	DELOUSE(1)
 	mov	x2, x30
 	.cfi_register x30, x2
 
@@ -68,7 +80,7 @@ ENTRY(__kernel_gettimeofday)
 	mov	x13, #1000
 	lsl	x13, x13, x12
 	udiv	x11, x11, x13
-	stp	x10, x11, [x0, #TVAL_TV_SEC]
+	stp	PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
 2:
 	/* If tz is NULL, return 0. */
 	cbz	x1, 3f
@@ -88,6 +100,7 @@ ENDPROC(__kernel_gettimeofday)
 /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
 ENTRY(__kernel_clock_gettime)
 	.cfi_startproc
+	DELOUSE(1)
 	cmp	w0, #CLOCK_REALTIME
 	ccmp	w0, #CLOCK_MONOTONIC, #0x4, ne
 	b.ne	2f
@@ -159,7 +172,7 @@ ENTRY(__kernel_clock_gettime)
 
 6:	/* Store to the user timespec. */
 	lsr	x11, x11, x12
-	stp	x10, x11, [x1, #TSPEC_TV_SEC]
+	stp	PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
 	mov	x0, xzr
 	ret
 7:
@@ -174,6 +187,7 @@ ENDPROC(__kernel_clock_gettime)
 /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
 ENTRY(__kernel_clock_getres)
 	.cfi_startproc
+	DELOUSE(1)
 	cmp	w0, #CLOCK_REALTIME
 	ccmp	w0, #CLOCK_MONOTONIC, #0x4, ne
 	b.ne	1f
@@ -187,7 +201,7 @@ ENTRY(__kernel_clock_getres)
 	ldr	x2, 6f
 2:
 	cbz	w1, 3f
-	stp	xzr, x2, [x1]
+	stp	PTR_REG(zr), PTR_REG(2), [x1]
 
 3:	/* res == NULL. */
 	mov	w0, wzr
-- 
2.5.0

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

* Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return
  2016-05-06 14:00                       ` Yury Norov
@ 2016-05-09 10:07                         ` Zhangjian (Bamvor)
  0 siblings, 0 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-09 10:07 UTC (permalink / raw)
  To: Yury Norov, Andrew Pinski
  Cc: Arnd Bergmann, Catalin Marinas, Linux-Arch, linux-s390, Kapoor,
	Prasun, Andreas Schwab, Mark Brown, linux-doc, Heiko Carstens,
	LKML, Alexander Graf, Alexey Klimov, Joseph S. Myers,
	Martin Schwidefsky, Nathan Lynch, Philipp Tomsich,
	linux-arm-kernel, christoph.muellner, Hanjun Guo,
	Zhangjian (Bamvor)

Hi, yury

I tested successful in both little endian and big endian.
Just two comments below:

On 2016/5/6 22:00, Yury Norov wrote:
> Hello colleagues,
>
> After all comments, VDSO fix looks like this for me.
>
> Note I renamed Andrew's ZERO macro to DELOUSE, as
> there already is __SC_DELOUSE which does the same,
> but in C, not asm.
>
> Like Bamvor, I'm not sure how we'd apply this patch -
> standalone or meld to VDSO. I think, VDSO patch is too
> big and bad-structurized, and if I find how to refactor
> it, I'll incorporate this fix.
>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
>   arch/arm64/kernel/asm-offsets.c               |  7 +++++++
>   arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S |  2 +-
>   arch/arm64/kernel/vdso/gettimeofday.S         | 20 +++++++++++++++++---
>   3 files changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index e229525..fcfd087 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -101,6 +101,13 @@ int main(void)
>     DEFINE(TSPEC_TV_SEC,		offsetof(struct timespec, tv_sec));
>     DEFINE(TSPEC_TV_NSEC,		offsetof(struct timespec, tv_nsec));
>     BLANK();
> +#ifdef CONFIG_ARM64_ILP32
The following structs exist in both aarch32 el0 and ilp32. How about change it to
"#ifdef CONFIG_COMPAT"?
> +  DEFINE(COMPAT_TVAL_TV_SEC,	offsetof(struct compat_timeval, tv_sec));
> +  DEFINE(COMPAT_TVAL_TV_USEC,	offsetof(struct compat_timeval, tv_usec));
> +  DEFINE(COMPAT_TSPEC_TV_SEC,	offsetof(struct compat_timespec, tv_sec));
> +  DEFINE(COMPAT_TSPEC_TV_NSEC,	offsetof(struct compat_timespec, tv_nsec));
> +  BLANK();
> +#endif
>     DEFINE(TZ_MINWEST,		offsetof(struct timezone, tz_minuteswest));
>     DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
>     BLANK();
> diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> index ddc63fd..d182a8d 100644
> --- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> @@ -79,7 +79,7 @@ PHDRS
>    */
>   VERSION
>   {
> -	LINUX_2.6 {
> +	LINUX_2.6.39 {
Do we really want to this version? Maybe 4.x is better?

Regards

Bamvor

>   	global:
>   		__kernel_rt_sigreturn;
>   		__kernel_gettimeofday;
> diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
> index efa79e8..a2d8a70 100644
> --- a/arch/arm64/kernel/vdso/gettimeofday.S
> +++ b/arch/arm64/kernel/vdso/gettimeofday.S
> @@ -25,6 +25,16 @@
>   #define NSEC_PER_SEC_LO16	0xca00
>   #define NSEC_PER_SEC_HI16	0x3b9a
>
> +#ifdef __LP64__
> +#define PTR_REG(n)	x##n
> +#define OFFSET(n)	n
> +#define DELOUSE(n)
> +#else
> +#define PTR_REG(n)	w##n
> +#define OFFSET(n)	COMPAT_##n
> +#define DELOUSE(n)	mov     w##n, w##n
> +#endif
> +
>   vdso_data	.req	x6
>   use_syscall	.req	w7
>   seqcnt		.req	w8
> @@ -51,6 +61,8 @@ seqcnt		.req	w8
>   /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
>   ENTRY(__kernel_gettimeofday)
>   	.cfi_startproc
> +	DELOUSE(0)
> +	DELOUSE(1)
>   	mov	x2, x30
>   	.cfi_register x30, x2
>
> @@ -68,7 +80,7 @@ ENTRY(__kernel_gettimeofday)
>   	mov	x13, #1000
>   	lsl	x13, x13, x12
>   	udiv	x11, x11, x13
> -	stp	x10, x11, [x0, #TVAL_TV_SEC]
> +	stp	PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
>   2:
>   	/* If tz is NULL, return 0. */
>   	cbz	x1, 3f
> @@ -88,6 +100,7 @@ ENDPROC(__kernel_gettimeofday)
>   /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
>   ENTRY(__kernel_clock_gettime)
>   	.cfi_startproc
> +	DELOUSE(1)
>   	cmp	w0, #CLOCK_REALTIME
>   	ccmp	w0, #CLOCK_MONOTONIC, #0x4, ne
>   	b.ne	2f
> @@ -159,7 +172,7 @@ ENTRY(__kernel_clock_gettime)
>
>   6:	/* Store to the user timespec. */
>   	lsr	x11, x11, x12
> -	stp	x10, x11, [x1, #TSPEC_TV_SEC]
> +	stp	PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
>   	mov	x0, xzr
>   	ret
>   7:
> @@ -174,6 +187,7 @@ ENDPROC(__kernel_clock_gettime)
>   /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
>   ENTRY(__kernel_clock_getres)
>   	.cfi_startproc
> +	DELOUSE(1)
>   	cmp	w0, #CLOCK_REALTIME
>   	ccmp	w0, #CLOCK_MONOTONIC, #0x4, ne
>   	b.ne	1f
> @@ -187,7 +201,7 @@ ENTRY(__kernel_clock_getres)
>   	ldr	x2, 6f
>   2:
>   	cbz	w1, 3f
> -	stp	xzr, x2, [x1]
> +	stp	PTR_REG(zr), PTR_REG(2), [x1]
>
>   3:	/* res == NULL. */
>   	mov	w0, wzr
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-06 12:37     ` Yury Norov
@ 2016-05-10  7:42       ` Zhangjian (Bamvor)
  2016-05-10  7:55         ` Zhangjian (Bamvor)
  2016-05-10  8:36         ` Arnd Bergmann
  0 siblings, 2 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-10  7:42 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel,
	linux-arch, linux-s390, Hanjun Guo, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, broonie, Andrew Pinski, schwab, schwidefsky,
	joseph, christoph.muellner, jijun (D), Zhangjian (Bamvor)

Hi, Yury

On 2016/5/6 20:37, Yury Norov wrote:
> On Fri, May 06, 2016 at 08:16:48PM +0800, Zhangjian (Bamvor) wrote:
>> Hi,
>>
>> On 2016/4/6 6:08, Yury Norov wrote:
>>> From: Andrew Pinski <apinski@cavium.com>
>>>
>>> Add a separate syscall-table for ILP32, which dispatches either to native
>>> LP64 system call implementation or to compat-syscalls, as appropriate.
>>>
>>> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
>>> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
>>> ---
>>>   arch/arm64/include/asm/unistd.h | 11 ++++++-
>>>   arch/arm64/kernel/Makefile      |  2 +-
>>>   arch/arm64/kernel/entry.S       | 12 +++++++-
>>>   arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
>>>   4 files changed, 87 insertions(+), 3 deletions(-)
>>>   create mode 100644 arch/arm64/kernel/sys_ilp32.c
>>>
>>> diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
>>> index 2971dea..5ea18ef 100644
>>> --- a/arch/arm64/include/asm/unistd.h
>>> +++ b/arch/arm64/include/asm/unistd.h
>>> @@ -13,9 +13,18 @@
>>>    * You should have received a copy of the GNU General Public License
>>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>    */
>>> +
>>> +#ifdef CONFIG_COMPAT
>>> +#define __ARCH_WANT_COMPAT_STAT64
>>> +#endif
>>> +
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +#define __ARCH_WANT_COMPAT_SYS_PREADV64
>>> +#define __ARCH_WANT_COMPAT_SYS_PWRITEV64
>>> +#endif
>>> +
>>>   #ifdef CONFIG_AARCH32_EL0
>>>   #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
>>> -#define __ARCH_WANT_COMPAT_STAT64
>>>   #define __ARCH_WANT_SYS_GETHOSTNAME
>>>   #define __ARCH_WANT_SYS_PAUSE
>>>   #define __ARCH_WANT_SYS_GETPGRP
>>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>>> index 9dfdf86..7aa65ea 100644
>>> --- a/arch/arm64/kernel/Makefile
>>> +++ b/arch/arm64/kernel/Makefile
>>> @@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
>>>   arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
>>>   					   sys_compat.o entry32.o		\
>>>   					   ../../arm/kernel/opcodes.o binfmt_elf32.o
>>> -arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
>>> +arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
>>>   arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
>>>   arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
>>>   arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
>>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>>> index cf4d1ae..1f7a145 100644
>>> --- a/arch/arm64/kernel/entry.S
>>> +++ b/arch/arm64/kernel/entry.S
>>> @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
>>>    */
>>>   	.align	6
>>>   el0_svc:
>>> -	adrp	stbl, sys_call_table		// load syscall table pointer
>>>   	uxtw	scno, w8			// syscall number in w8
>>>   	mov	sc_nr, #__NR_syscalls
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +	ldr	x16, [tsk, #TI_FLAGS]
>>> +	tbnz	x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
>>> +#endif
>>> +	adrp	stbl, sys_call_table		// load syscall table pointer
>>>   el0_svc_naked:					// compat entry point
>>>   	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
>>>   	enable_dbg_and_irq
>>> @@ -737,6 +741,12 @@ ni_sys:
>>>   	b	ret_fast_syscall
>>>   ENDPROC(el0_svc)
>>>
>>> +#ifdef CONFIG_ARM64_ILP32
>>> +el0_ilp32_svc:
>>> +	adrp	stbl, sys_call_ilp32_table // load syscall table pointer
>>> +	b el0_svc_naked
>>> +#endif
>>> +
>>>   	/*
>>>   	 * This is the really slow path.  We're going to be doing context
>>>   	 * switches, and waiting for our parent to respond.
>>> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
>>> new file mode 100644
>>> index 0000000..0996d8e
>>> --- /dev/null
>>> +++ b/arch/arm64/kernel/sys_ilp32.c
>>> @@ -0,0 +1,65 @@
>>> +/*
>>> + * AArch64- ILP32 specific system calls implementation
>>> + *
>>> + * Copyright (C) 2016 Cavium Inc.
>>> + * Author: Andrew Pinski <apinski@cavium.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>> + */
>>> +
>>> +#include <linux/compiler.h>
>>> +#include <linux/errno.h>
>>> +#include <linux/fs.h>
>>> +#include <linux/mm.h>
>>> +#include <linux/msg.h>
>>> +#include <linux/export.h>
>>> +#include <linux/sched.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/syscalls.h>
>>> +#include <linux/compat.h>
>>> +#include <asm-generic/syscalls.h>
>>> +
>>> +/* Using non-compat syscalls where necessary */
>>> +#define compat_sys_fadvise64_64        sys_fadvise64_64
>>> +#define compat_sys_fallocate           sys_fallocate
>>> +#define compat_sys_ftruncate64         sys_ftruncate
>>> +#define compat_sys_lookup_dcookie      sys_lookup_dcookie
>>> +#define compat_sys_pread64             sys_pread64
>>> +#define compat_sys_pwrite64            sys_pwrite64
>>> +#define compat_sys_readahead           sys_readahead
>>> +#define compat_sys_shmat               sys_shmat
>>> +#define compat_sys_sync_file_range     sys_sync_file_range
>>> +#define compat_sys_truncate64          sys_truncate
>>> +#define sys_llseek                     sys_lseek
>>> +#define sys_mmap2		       sys_mmap
>> I am a little bit confused here. We wrap the mmap to mmap2 in glibc
>> without shift the 4096 and We map mmap2 to mmap in kernel which
>> means we shift with the real page size. It works unless the
>> application want to mmap the offset bigger then 2G. In ILP32 app,
>> if the offset is bigger than 2G(e.g. 0xfb000000), it is a negative
>> number and extend to 64bit nagetive number in kernel
>> (0xfffffff fb000000). I add the "COMPAT_SYSCALL_WRAP6(mmap, ...)" in
>> kernel/compat_wrapper.c. But it is not works. I am not sure if it is
>> already sign extended in userspace.
>>
>> On the other hand, I read the code of mmap in arm and other
>> architecture. Usually, they will shift 4096 in userspace and shift
>> others in kernel if needed. Should we follow the similar ways or we
>> could call mmap_pgoff in glibc and do the shift according the real
>> page shift(getpages())?
>>
>> Thanks
>>
>> Bamvor
>>
>>
>
> Hi,
>
> AFAIR, here we don't shift offset, as it's 64-bit both in user-
> and kernel-space,
In your ilp32-2.22 branch, you wrapper mmap to mmap2 in which type of
offset is off_t. And off_t is 32bit in ilp32, correct?
"sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c"
/* mmap is provided by mmap as they are the same. */
void *__mmap (void *__addr, size_t __len, int __prot,
                      int __flags, int __fd, __off_t __offset)
{
    void *result;
    result = (void *)
      INLINE_SYSCALL (mmap2, 6, __addr,
                      __len, __prot, __flags, __fd, __offset);
    return result;
}
> and just pass it from user to kernel thru glibc
> with no changes.
>
> It definitely works, as there are many mappings made by linker and
> libc in 2G+ area, and there are no problems with them. This is a
> typical ILP32 application map:
Ok, the different is I am talking about the offset in mmap. I am NOT
talking about the map result.
If I run my test case with strace:
"strace -e trace=mmap ./mmap.arm64_ilp32 0xfb000000 0x1000", here is
the part of log:

1 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7721000
2 mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7557000
3 page size<0x1000>, offset is <0xfb000000>
4 mmap(NULL, 4096, PROT_READ, MAP_SHARED, 3, 0xfffffffffb000000) = -1 EINVAL (Invalid argument)
5 mmap of mmapfile failed

As you said, line 1 and 2 show that mmap could map above 2G. But it
is NOT what I want to discussion.
As I said, when I pass the offset above 2G(e.g. 0xfb0000000), we
could find that the actual offset pass to kernel is
0xfffffffffb000000(reference line 4).
It will fail if I map in /dev/mmem. It will not fail if the fd is
a normal file. But in both of case the offset is wrong.

Regards

Bamvor

> 00400000-00401000 r-xp 00000000 08:00 130400     /root/mykill
> 00410000-00411000 rwxp 00000000 08:00 130400     /root/mykill
> 00527000-00549000 rwxp 00000000 00:00 0          [heap]
> c6278000-c6298000 rwxp 00000000 00:00 0
> c6298000-c63d0000 r-xp 00000000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
> c63d0000-c63e0000 ---p 00138000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
> c63e0000-c63e2000 r-xp 00138000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
> c63e2000-c63e3000 rwxp 0013a000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
> c63e3000-c63e6000 rwxp 00000000 00:00 0
> c63e6000-c63fc000 r-xp 00000000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
> c63fc000-c640b000 ---p 00016000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
> c640b000-c640c000 r-xp 00015000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
> c640c000-c640d000 rwxp 00016000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
> c640d000-c640f000 rwxp 00000000 00:00 0
> c640f000-c642c000 r-xp 00000000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
> c6437000-c6439000 rwxp 00000000 00:00 0
> c6439000-c643a000 r--p 00000000 00:00 0          [vvar]
> c643a000-c643b000 r-xp 00000000 00:00 0          [vdso]
> c643b000-c643c000 r-xp 0001c000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
> c643c000-c643d000 rwxp 0001d000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
> ffe2d000-ffe4e000 rw-p 00000000 00:00 0          [stack]
>
>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10  7:42       ` Zhangjian (Bamvor)
@ 2016-05-10  7:55         ` Zhangjian (Bamvor)
  2016-05-10  8:36         ` Arnd Bergmann
  1 sibling, 0 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-10  7:55 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel,
	linux-arch, linux-s390, Hanjun Guo, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, broonie, Andrew Pinski, schwab, schwidefsky,
	joseph, christoph.muellner, jijun (D), Zhangjian (Bamvor)

Hi,

Sorry I forget to paste my test code:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>

#define TEMPFILE "mmapfile"

int main(int argc, char *argv[])
{
	int fd;
	void *addr;
	unsigned long offset;
	unsigned long size;

	if (argc == 3) {
		if (argv[1][0] == '0' && argv[1][1] == 'x')
			offset = strtoll(&argv[1][2], NULL, 16);
		else
			offset = atoi(argv[1]);

		if (argv[2][0] == '0' && argv[2][1] == 'x')
			size = strtoll(&argv[2][2], NULL, 16);
		else
			size = atoi(argv[2]);
	} else {
		exit(2);
	}

	printf("page size<0x%x>, offset is <0x%x>\n", size, offset);
//	if ((fd = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
//		fprintf(stderr, "opening %s failed\n", TEMPFILE);
//		exit(2);
//	}
	fd = open("/dev/mem", O_RDWR | O_SYNC);
	if (-1 == fd)
	{
		printf( "open /dev/mem fail!\n" );
		return 1;
	}

	//addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, offset);
	addr = mmap(0, size, PROT_READ, MAP_FILE | MAP_SHARED, fd, offset);
	if(addr == MAP_FAILED) {
		fprintf(stderr, "mmap of %s failed\n", TEMPFILE);
		exit(2);
	}
	printf("addr: <0x%x>\n", addr);

	return 0;
}

Regards

Bamvor

On 2016/5/10 15:42, Zhangjian (Bamvor) wrote:
> Hi, Yury
>
> On 2016/5/6 20:37, Yury Norov wrote:
>> On Fri, May 06, 2016 at 08:16:48PM +0800, Zhangjian (Bamvor) wrote:
>>> Hi,
>>>
>>> On 2016/4/6 6:08, Yury Norov wrote:
>>>> From: Andrew Pinski <apinski@cavium.com>
>>>>
>>>> Add a separate syscall-table for ILP32, which dispatches either to native
>>>> LP64 system call implementation or to compat-syscalls, as appropriate.
>>>>
>>>> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
>>>> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
>>>> ---
>>>>   arch/arm64/include/asm/unistd.h | 11 ++++++-
>>>>   arch/arm64/kernel/Makefile      |  2 +-
>>>>   arch/arm64/kernel/entry.S       | 12 +++++++-
>>>>   arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
>>>>   4 files changed, 87 insertions(+), 3 deletions(-)
>>>>   create mode 100644 arch/arm64/kernel/sys_ilp32.c
>>>>
>>>> diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
>>>> index 2971dea..5ea18ef 100644
>>>> --- a/arch/arm64/include/asm/unistd.h
>>>> +++ b/arch/arm64/include/asm/unistd.h
>>>> @@ -13,9 +13,18 @@
>>>>    * You should have received a copy of the GNU General Public License
>>>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>>    */
>>>> +
>>>> +#ifdef CONFIG_COMPAT
>>>> +#define __ARCH_WANT_COMPAT_STAT64
>>>> +#endif
>>>> +
>>>> +#ifdef CONFIG_ARM64_ILP32
>>>> +#define __ARCH_WANT_COMPAT_SYS_PREADV64
>>>> +#define __ARCH_WANT_COMPAT_SYS_PWRITEV64
>>>> +#endif
>>>> +
>>>>   #ifdef CONFIG_AARCH32_EL0
>>>>   #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
>>>> -#define __ARCH_WANT_COMPAT_STAT64
>>>>   #define __ARCH_WANT_SYS_GETHOSTNAME
>>>>   #define __ARCH_WANT_SYS_PAUSE
>>>>   #define __ARCH_WANT_SYS_GETPGRP
>>>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>>>> index 9dfdf86..7aa65ea 100644
>>>> --- a/arch/arm64/kernel/Makefile
>>>> +++ b/arch/arm64/kernel/Makefile
>>>> @@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
>>>>   arm64-obj-$(CONFIG_AARCH32_EL0)        += sys32.o kuser32.o signal32.o     \
>>>>                          sys_compat.o entry32.o        \
>>>>                          ../../arm/kernel/opcodes.o binfmt_elf32.o
>>>> -arm64-obj-$(CONFIG_ARM64_ILP32)        += binfmt_ilp32.o
>>>> +arm64-obj-$(CONFIG_ARM64_ILP32)        += binfmt_ilp32.o sys_ilp32.o
>>>>   arm64-obj-$(CONFIG_FUNCTION_TRACER)    += ftrace.o entry-ftrace.o
>>>>   arm64-obj-$(CONFIG_MODULES)        += arm64ksyms.o module.o
>>>>   arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)    += module-plts.o
>>>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>>>> index cf4d1ae..1f7a145 100644
>>>> --- a/arch/arm64/kernel/entry.S
>>>> +++ b/arch/arm64/kernel/entry.S
>>>> @@ -715,9 +715,13 @@ ENDPROC(ret_from_fork)
>>>>    */
>>>>       .align    6
>>>>   el0_svc:
>>>> -    adrp    stbl, sys_call_table        // load syscall table pointer
>>>>       uxtw    scno, w8            // syscall number in w8
>>>>       mov    sc_nr, #__NR_syscalls
>>>> +#ifdef CONFIG_ARM64_ILP32
>>>> +    ldr    x16, [tsk, #TI_FLAGS]
>>>> +    tbnz    x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
>>>> +#endif
>>>> +    adrp    stbl, sys_call_table        // load syscall table pointer
>>>>   el0_svc_naked:                    // compat entry point
>>>>       stp    x0, scno, [sp, #S_ORIG_X0]    // save the original x0 and syscall number
>>>>       enable_dbg_and_irq
>>>> @@ -737,6 +741,12 @@ ni_sys:
>>>>       b    ret_fast_syscall
>>>>   ENDPROC(el0_svc)
>>>>
>>>> +#ifdef CONFIG_ARM64_ILP32
>>>> +el0_ilp32_svc:
>>>> +    adrp    stbl, sys_call_ilp32_table // load syscall table pointer
>>>> +    b el0_svc_naked
>>>> +#endif
>>>> +
>>>>       /*
>>>>        * This is the really slow path.  We're going to be doing context
>>>>        * switches, and waiting for our parent to respond.
>>>> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
>>>> new file mode 100644
>>>> index 0000000..0996d8e
>>>> --- /dev/null
>>>> +++ b/arch/arm64/kernel/sys_ilp32.c
>>>> @@ -0,0 +1,65 @@
>>>> +/*
>>>> + * AArch64- ILP32 specific system calls implementation
>>>> + *
>>>> + * Copyright (C) 2016 Cavium Inc.
>>>> + * Author: Andrew Pinski <apinski@cavium.com>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License version 2 as
>>>> + * published by the Free Software Foundation.
>>>> + *
>>>> + * This program is distributed in the hope that it will be useful,
>>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>>> + * GNU General Public License for more details.
>>>> + *
>>>> + * You should have received a copy of the GNU General Public License
>>>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>> + */
>>>> +
>>>> +#include <linux/compiler.h>
>>>> +#include <linux/errno.h>
>>>> +#include <linux/fs.h>
>>>> +#include <linux/mm.h>
>>>> +#include <linux/msg.h>
>>>> +#include <linux/export.h>
>>>> +#include <linux/sched.h>
>>>> +#include <linux/slab.h>
>>>> +#include <linux/syscalls.h>
>>>> +#include <linux/compat.h>
>>>> +#include <asm-generic/syscalls.h>
>>>> +
>>>> +/* Using non-compat syscalls where necessary */
>>>> +#define compat_sys_fadvise64_64        sys_fadvise64_64
>>>> +#define compat_sys_fallocate           sys_fallocate
>>>> +#define compat_sys_ftruncate64         sys_ftruncate
>>>> +#define compat_sys_lookup_dcookie      sys_lookup_dcookie
>>>> +#define compat_sys_pread64             sys_pread64
>>>> +#define compat_sys_pwrite64            sys_pwrite64
>>>> +#define compat_sys_readahead           sys_readahead
>>>> +#define compat_sys_shmat               sys_shmat
>>>> +#define compat_sys_sync_file_range     sys_sync_file_range
>>>> +#define compat_sys_truncate64          sys_truncate
>>>> +#define sys_llseek                     sys_lseek
>>>> +#define sys_mmap2               sys_mmap
>>> I am a little bit confused here. We wrap the mmap to mmap2 in glibc
>>> without shift the 4096 and We map mmap2 to mmap in kernel which
>>> means we shift with the real page size. It works unless the
>>> application want to mmap the offset bigger then 2G. In ILP32 app,
>>> if the offset is bigger than 2G(e.g. 0xfb000000), it is a negative
>>> number and extend to 64bit nagetive number in kernel
>>> (0xfffffff fb000000). I add the "COMPAT_SYSCALL_WRAP6(mmap, ...)" in
>>> kernel/compat_wrapper.c. But it is not works. I am not sure if it is
>>> already sign extended in userspace.
>>>
>>> On the other hand, I read the code of mmap in arm and other
>>> architecture. Usually, they will shift 4096 in userspace and shift
>>> others in kernel if needed. Should we follow the similar ways or we
>>> could call mmap_pgoff in glibc and do the shift according the real
>>> page shift(getpages())?
>>>
>>> Thanks
>>>
>>> Bamvor
>>>
>>>
>>
>> Hi,
>>
>> AFAIR, here we don't shift offset, as it's 64-bit both in user-
>> and kernel-space,
> In your ilp32-2.22 branch, you wrapper mmap to mmap2 in which type of
> offset is off_t. And off_t is 32bit in ilp32, correct?
> "sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c"
> /* mmap is provided by mmap as they are the same. */
> void *__mmap (void *__addr, size_t __len, int __prot,
>                       int __flags, int __fd, __off_t __offset)
> {
>     void *result;
>     result = (void *)
>       INLINE_SYSCALL (mmap2, 6, __addr,
>                       __len, __prot, __flags, __fd, __offset);
>     return result;
> }
>> and just pass it from user to kernel thru glibc
>> with no changes.
>>
>> It definitely works, as there are many mappings made by linker and
>> libc in 2G+ area, and there are no problems with them. This is a
>> typical ILP32 application map:
> Ok, the different is I am talking about the offset in mmap. I am NOT
> talking about the map result.
> If I run my test case with strace:
> "strace -e trace=mmap ./mmap.arm64_ilp32 0xfb000000 0x1000", here is
> the part of log:
>
> 1 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7721000
> 2 mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7557000
> 3 page size<0x1000>, offset is <0xfb000000>
> 4 mmap(NULL, 4096, PROT_READ, MAP_SHARED, 3, 0xfffffffffb000000) = -1 EINVAL (Invalid argument)
> 5 mmap of mmapfile failed
>
> As you said, line 1 and 2 show that mmap could map above 2G. But it
> is NOT what I want to discussion.
> As I said, when I pass the offset above 2G(e.g. 0xfb0000000), we
> could find that the actual offset pass to kernel is
> 0xfffffffffb000000(reference line 4).
> It will fail if I map in /dev/mmem. It will not fail if the fd is
> a normal file. But in both of case the offset is wrong.
>
> Regards
>
> Bamvor
>
>> 00400000-00401000 r-xp 00000000 08:00 130400     /root/mykill
>> 00410000-00411000 rwxp 00000000 08:00 130400     /root/mykill
>> 00527000-00549000 rwxp 00000000 00:00 0          [heap]
>> c6278000-c6298000 rwxp 00000000 00:00 0
>> c6298000-c63d0000 r-xp 00000000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
>> c63d0000-c63e0000 ---p 00138000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
>> c63e0000-c63e2000 r-xp 00138000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
>> c63e2000-c63e3000 rwxp 0013a000 08:00 135293     /root/sys-root/libilp32/libc-2.22.so
>> c63e3000-c63e6000 rwxp 00000000 00:00 0
>> c63e6000-c63fc000 r-xp 00000000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
>> c63fc000-c640b000 ---p 00016000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
>> c640b000-c640c000 r-xp 00015000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
>> c640c000-c640d000 rwxp 00016000 08:00 135313     /root/sys-root/libilp32/libpthread-2.22.so
>> c640d000-c640f000 rwxp 00000000 00:00 0
>> c640f000-c642c000 r-xp 00000000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
>> c6437000-c6439000 rwxp 00000000 00:00 0
>> c6439000-c643a000 r--p 00000000 00:00 0          [vvar]
>> c643a000-c643b000 r-xp 00000000 00:00 0          [vdso]
>> c643b000-c643c000 r-xp 0001c000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
>> c643c000-c643d000 rwxp 0001d000 08:00 135288     /root/sys-root/libilp32/ld-2.22.so
>> ffe2d000-ffe4e000 rw-p 00000000 00:00 0          [stack]
>>
>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10  7:42       ` Zhangjian (Bamvor)
  2016-05-10  7:55         ` Zhangjian (Bamvor)
@ 2016-05-10  8:36         ` Arnd Bergmann
  2016-05-10  9:47           ` Zhangjian (Bamvor)
  1 sibling, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-10  8:36 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Zhangjian (Bamvor),
	Yury Norov, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Hanjun Guo, joseph, linux-arch, linux-s390,
	jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Tuesday 10 May 2016 15:42:07 Zhangjian wrote:
> On 2016/5/6 20:37, Yury Norov wrote:
> > On Fri, May 06, 2016 at 08:16:48PM +0800, Zhangjian (Bamvor) wrote:
> >
> > AFAIR, here we don't shift offset, as it's 64-bit both in user-
> > and kernel-space,
> In your ilp32-2.22 branch, you wrapper mmap to mmap2 in which type of
> offset is off_t. And off_t is 32bit in ilp32, correct?
> "sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c"
> /* mmap is provided by mmap as they are the same. */
> void *__mmap (void *__addr, size_t __len, int __prot,
>                       int __flags, int __fd, __off_t __offset)
> {
>     void *result;
>     result = (void *)
>       INLINE_SYSCALL (mmap2, 6, __addr,
>                       __len, __prot, __flags, __fd, __offset);
>     return result;
> }

__off_t should be 'long long' on new architectures, and map
to __kernel_loff_t.

Can you see how it is defined?

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10  8:36         ` Arnd Bergmann
@ 2016-05-10  9:47           ` Zhangjian (Bamvor)
  2016-05-10 11:48             ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-10  9:47 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Yury Norov, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Hanjun Guo, joseph, linux-arch, linux-s390,
	jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, bamvor >> Zhangjian (Bamvor)

Hi, Arnd

On 2016/5/10 16:36, Arnd Bergmann wrote:
> On Tuesday 10 May 2016 15:42:07 Zhangjian wrote:
>> On 2016/5/6 20:37, Yury Norov wrote:
>>> On Fri, May 06, 2016 at 08:16:48PM +0800, Zhangjian (Bamvor) wrote:
>>>
>>> AFAIR, here we don't shift offset, as it's 64-bit both in user-
>>> and kernel-space,
>> In your ilp32-2.22 branch, you wrapper mmap to mmap2 in which type of
>> offset is off_t. And off_t is 32bit in ilp32, correct?
>> "sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c"
>> /* mmap is provided by mmap as they are the same. */
>> void *__mmap (void *__addr, size_t __len, int __prot,
>>                        int __flags, int __fd, __off_t __offset)
>> {
>>      void *result;
>>      result = (void *)
>>        INLINE_SYSCALL (mmap2, 6, __addr,
>>                        __len, __prot, __flags, __fd, __offset);
>>      return result;
>> }
>
> __off_t should be 'long long' on new architectures, and map
> to __kernel_loff_t.
>
> Can you see how it is defined?
For kernel part, in "include/uapi/asm-generic/posix_types.h":
     #ifndef __kernel_long_t
     typedef long            __kernel_long_t;
     typedef unsigned long   __kernel_ulong_t;
     #endif
     typedef __kernel_long_t __kernel_off_t;
in "include/linux/types.h":
     typedef __kernel_off_t          off_t;

"include/uapi/asm-generic/posix_types.h" is uapi, we could not check
"ARCH_32BIT_OFF_T" here. Besides, the `__kernel_long_t` is long which
mean it is 32bit in ILP32. should we define something like x32?
     ```
     diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
     index 7985ff6..9baa8d3 100644
     --- a/arch/arm64/include/uapi/asm/posix_types.h
     +++ b/arch/arm64/include/uapi/asm/posix_types.h
     @@ -5,6 +5,9 @@ typedef unsigned short __kernel_old_uid_t;
      typedef unsigned short __kernel_old_gid_t;
       #define __kernel_old_uid_t __kernel_old_uid_t

      +typedef long long __kernel_long_t;
      +typedef unsigned long long __kernel_ulong_t;
      +
       #include <asm-generic/posix_types.h>

       #endif /*  __ASM_POSIX_TYPES_H */u
     ```
After this definition, the following kernel types is 64bit in ILP32:
     typedef __kernel_long_t         __kernel_suseconds_t;
     typedef __kernel_long_t __kernel_ssize_t;
     typedef __kernel_long_t __kernel_ptrdiff_t;
     typedef __kernel_long_t __kernel_off_t;
     typedef __kernel_long_t __kernel_time_t;
     typedef __kernel_long_t __kernel_clock_t;
     typedef __kernel_ulong_t __kernel_ino_t;
     typedef __kernel_ulong_t __kernel_size_t;

But it is not a generic way to define off_t to 64bit if
ARCH_32BIT_OFF_T is not defined. How about this one? We need to
define `__kernel_off_t` on all the old 32bit architecture like
arm:
```
diff --git a/arch/arm/include/uapi/asm/posix_types.h b/arch/arm/include/uapi/asm/posix_types.h
index d2de9cb..f9d065c 100644
--- a/arch/arm/include/uapi/asm/posix_types.h
+++ b/arch/arm/include/uapi/asm/posix_types.h
@@ -32,6 +32,9 @@ typedef unsigned short                __kernel_gid_t;
  typedef unsigned short         __kernel_old_dev_t;
  #define __kernel_old_dev_t __kernel_old_dev_t

+typedef __kernel_long_t        __kernel_off_t;
+#define __kernel_off_t
+
  #include <asm-generic/posix_types.h>

  #endif
```
And We could change the generic posix_types.h a little bit:
```
diff --git a/include/uapi/asm-generic/posix_types.h b/include/uapi/asm-generic/posix_types.h
index fe74fcc..7bbaf04 100644
--- a/include/uapi/asm-generic/posix_types.h
+++ b/include/uapi/asm-generic/posix_types.h
@@ -80,10 +80,13 @@ typedef struct {
  } __kernel_fsid_t;
  #endif

+#ifndef __kernel_off_t
+typedef long long __kernel_off_t;
+#endif
+
  /*
   * anything below here should be completely generic
   */
-typedef __kernel_long_t        __kernel_off_t;
  typedef long long      __kernel_loff_t;
  typedef __kernel_long_t        __kernel_time_t;
  typedef __kernel_long_t        __kernel_clock_t;
```

On the other hand, glibc define it own off_t in "bits/types.h":
     __STD_TYPE __OFF_T_TYPE __off_t;        /* Type of file sizes and offsets.  */
     __STD_TYPE __OFF64_T_TYPE __off64_t;    /* Type of file sizes and offsets (LFS).  */

in "sysdeps/unix/sysv/linux/aarch64/bits/typesizes.h":
     #define __OFF_T_TYPE            __SLONGWORD_TYPE
     #define __OFF64_T_TYPE          __SQUAD_TYPE

If we define off_t as 64bit in glibc:
     #define __OFF_T_TYPE           __SQUAD_TYPE

Should We need to align all the off_t syscall to 64bit syscall in
kernel?

Regards

Bamvor


> 	Arnd
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10  9:47           ` Zhangjian (Bamvor)
@ 2016-05-10 11:48             ` Arnd Bergmann
  2016-05-10 12:39               ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-10 11:48 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Zhangjian (Bamvor),
	linux-doc, Andrew Pinski, catalin.marinas, heiko.carstens,
	Yury Norov, Hanjun Guo, joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Tuesday 10 May 2016 17:47:26 Zhangjian wrote:
> On 2016/5/10 16:36, Arnd Bergmann wrote:
> > On Tuesday 10 May 2016 15:42:07 Zhangjian wrote:
> >> On 2016/5/6 20:37, Yury Norov wrote:
> 
> "include/uapi/asm-generic/posix_types.h" is uapi, we could not check
> "ARCH_32BIT_OFF_T" here. Besides, the `__kernel_long_t` is long which
> mean it is 32bit in ILP32. should we define something like x32?
>      ```
>      diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
>      index 7985ff6..9baa8d3 100644
>      --- a/arch/arm64/include/uapi/asm/posix_types.h
>      +++ b/arch/arm64/include/uapi/asm/posix_types.h

glibc does not use the definition of __kernel_off_t, it has its own
copy, so changing the kernel headers would do nothing.

>      @@ -5,6 +5,9 @@ typedef unsigned short __kernel_old_uid_t;
>       typedef unsigned short __kernel_old_gid_t;
>        #define __kernel_old_uid_t __kernel_old_uid_t
> 
>       +typedef long long __kernel_long_t;
>       +typedef unsigned long long __kernel_ulong_t;
>       +
>        #include <asm-generic/posix_types.h>
> 
>        #endif /*  __ASM_POSIX_TYPES_H */u
>      ```

This would break all sorts of things, because __kernel_long_t/__kernel_ulong_t
are not just used for off_t but also other things.

> 
> On the other hand, glibc define it own off_t in "bits/types.h":
>      __STD_TYPE __OFF_T_TYPE __off_t;        /* Type of file sizes and offsets.  */
>      __STD_TYPE __OFF64_T_TYPE __off64_t;    /* Type of file sizes and offsets (LFS).  */
> 
> in "sysdeps/unix/sysv/linux/aarch64/bits/typesizes.h":
>      #define __OFF_T_TYPE            __SLONGWORD_TYPE
>      #define __OFF64_T_TYPE          __SQUAD_TYPE
> 
> If we define off_t as 64bit in glibc:
>      #define __OFF_T_TYPE           __SQUAD_TYPE
> 
> Should We need to align all the off_t syscall to 64bit syscall in
> kernel?
> 

Yes, this is the change that I think we need to make, along with
the same change for __INO_T_TYPE and 

#define __OFF_T_MATCHES_OFF64_T        1
#define __INO_T_MATCHES_INO64_T        1

If I read the rest of the glibc headers right, that should be all we need
to ensure that both off_t and off64_t match the __kernel_loff_t based
syscalls.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10 11:48             ` Arnd Bergmann
@ 2016-05-10 12:39               ` Zhangjian (Bamvor)
  2016-05-10 12:50                 ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-10 12:39 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: linux-doc, Andrew Pinski, catalin.marinas, heiko.carstens,
	Yury Norov, Hanjun Guo, joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, Zhangjian (Bamvor)

Hi,

On 2016/5/10 19:48, Arnd Bergmann wrote:
> On Tuesday 10 May 2016 17:47:26 Zhangjian wrote:
>> On 2016/5/10 16:36, Arnd Bergmann wrote:
>>> On Tuesday 10 May 2016 15:42:07 Zhangjian wrote:
>>>> On 2016/5/6 20:37, Yury Norov wrote:
>>
>> "include/uapi/asm-generic/posix_types.h" is uapi, we could not check
>> "ARCH_32BIT_OFF_T" here. Besides, the `__kernel_long_t` is long which
>> mean it is 32bit in ILP32. should we define something like x32?
>>       ```
>>       diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
>>       index 7985ff6..9baa8d3 100644
>>       --- a/arch/arm64/include/uapi/asm/posix_types.h
>>       +++ b/arch/arm64/include/uapi/asm/posix_types.h
>
> glibc does not use the definition of __kernel_off_t, it has its own
> copy, so changing the kernel headers would do nothing.
Yes, I think so. I am puzzle that how do we ensure that all the new
32bit architecture will define off_t as 64bit after introduce
ARCH_32BIT_OFF_T and do not change any other code?
>
>>       @@ -5,6 +5,9 @@ typedef unsigned short __kernel_old_uid_t;
>>        typedef unsigned short __kernel_old_gid_t;
>>         #define __kernel_old_uid_t __kernel_old_uid_t
>>
>>        +typedef long long __kernel_long_t;
>>        +typedef unsigned long long __kernel_ulong_t;
>>        +
>>         #include <asm-generic/posix_types.h>
>>
>>         #endif /*  __ASM_POSIX_TYPES_H */u
>>       ```
>
> This would break all sorts of things, because __kernel_long_t/__kernel_ulong_t
> are not just used for off_t but also other things.
Yes. But if we do not change __kernel_long_t and __kernel_ulong_t, the
application of ilp32 will think size of long in kernel is 32bit. Is that
correct?
>
>>
>> On the other hand, glibc define it own off_t in "bits/types.h":
>>       __STD_TYPE __OFF_T_TYPE __off_t;        /* Type of file sizes and offsets.  */
>>       __STD_TYPE __OFF64_T_TYPE __off64_t;    /* Type of file sizes and offsets (LFS).  */
>>
>> in "sysdeps/unix/sysv/linux/aarch64/bits/typesizes.h":
>>       #define __OFF_T_TYPE            __SLONGWORD_TYPE
>>       #define __OFF64_T_TYPE          __SQUAD_TYPE
>>
>> If we define off_t as 64bit in glibc:
>>       #define __OFF_T_TYPE           __SQUAD_TYPE
>>
>> Should We need to align all the off_t syscall to 64bit syscall in
>> kernel?
>>
>
> Yes, this is the change that I think we need to make, along with
> the same change for __INO_T_TYPE and
>
> #define __OFF_T_MATCHES_OFF64_T        1
> #define __INO_T_MATCHES_INO64_T        1
>
> If I read the rest of the glibc headers right, that should be all we need
> to ensure that both off_t and off64_t match the __kernel_loff_t based
> syscalls.
Ok, I will test the ltp syscall test.
With this changes, the issue I mentioned should be fixed. But we still
use mmap2 syscall for ILP32 application when we pass the offset instead
of page offset. Is it correct?

Regards

Bamvor

>
> 	Arnd
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10 12:39               ` Zhangjian (Bamvor)
@ 2016-05-10 12:50                 ` Arnd Bergmann
  2016-05-11  2:04                   ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-10 12:50 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Tuesday 10 May 2016 20:39:41 Zhangjian wrote:
> Hi,
> 
> On 2016/5/10 19:48, Arnd Bergmann wrote:
> > On Tuesday 10 May 2016 17:47:26 Zhangjian wrote:
> >> On 2016/5/10 16:36, Arnd Bergmann wrote:
> >>> On Tuesday 10 May 2016 15:42:07 Zhangjian wrote:
> >>>> On 2016/5/6 20:37, Yury Norov wrote:
> >>
> >> "include/uapi/asm-generic/posix_types.h" is uapi, we could not check
> >> "ARCH_32BIT_OFF_T" here. Besides, the `__kernel_long_t` is long which
> >> mean it is 32bit in ILP32. should we define something like x32?
> >>       ```
> >>       diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
> >>       index 7985ff6..9baa8d3 100644
> >>       --- a/arch/arm64/include/uapi/asm/posix_types.h
> >>       +++ b/arch/arm64/include/uapi/asm/posix_types.h
> >
> > glibc does not use the definition of __kernel_off_t, it has its own
> > copy, so changing the kernel headers would do nothing.
> Yes, I think so. I am puzzle that how do we ensure that all the new
> 32bit architecture will define off_t as 64bit after introduce
> ARCH_32BIT_OFF_T and do not change any other code?

This is for historic reasons: we have two sets of system calls passing
file offsets: the original ones passing a 'long' are named e.g. lseek,
pread, pwrite, fadvise, ...

The replacement syscalls that pass a 'long long' __kernel_loff_t are only
available on 32-bit architectures and have different names, e.g. llseek,
pread64, pwrite64, fadvise64, ...

On 64-bit architectures, we only provide the first set, because
__kernel_off_t was already wide enough. On old 32-bit architectures
we have both, and on new 32-bit architectures we only have the second
set, which lets us use the same definitions on all 32-bit architectures.

> >>       @@ -5,6 +5,9 @@ typedef unsigned short __kernel_old_uid_t;
> >>        typedef unsigned short __kernel_old_gid_t;
> >>         #define __kernel_old_uid_t __kernel_old_uid_t
> >>
> >>        +typedef long long __kernel_long_t;
> >>        +typedef unsigned long long __kernel_ulong_t;
> >>        +
> >>         #include <asm-generic/posix_types.h>
> >>
> >>         #endif /*  __ASM_POSIX_TYPES_H */u
> >>       ```
> >
> > This would break all sorts of things, because __kernel_long_t/__kernel_ulong_t
> > are not just used for off_t but also other things.
> Yes. But if we do not change __kernel_long_t and __kernel_ulong_t, the
> application of ilp32 will think size of long in kernel is 32bit. Is that
> correct?

No, __kernel_long_t refers to the definition of 'long' in the kernel/user
ABI, not in the kernel (except on the x86-64 "x32" ABI, which is weird).

A 32-bit user space application must not care about how 'long' is defined
in the kernel, it should run on either 32-bit kernels or 64-bit kernels.
We don't have any plans to do an ilp32-mode kernel, but if we ever want
one, it must use the exact same ABI as the 64-bit kernel when running
ilp32 user space.

> >>
> >> On the other hand, glibc define it own off_t in "bits/types.h":
> >>       __STD_TYPE __OFF_T_TYPE __off_t;        /* Type of file sizes and offsets.  */
> >>       __STD_TYPE __OFF64_T_TYPE __off64_t;    /* Type of file sizes and offsets (LFS).  */
> >>
> >> in "sysdeps/unix/sysv/linux/aarch64/bits/typesizes.h":
> >>       #define __OFF_T_TYPE            __SLONGWORD_TYPE
> >>       #define __OFF64_T_TYPE          __SQUAD_TYPE
> >>
> >> If we define off_t as 64bit in glibc:
> >>       #define __OFF_T_TYPE           __SQUAD_TYPE
> >>
> >> Should We need to align all the off_t syscall to 64bit syscall in
> >> kernel?
> >>
> >
> > Yes, this is the change that I think we need to make, along with
> > the same change for __INO_T_TYPE and
> >
> > #define __OFF_T_MATCHES_OFF64_T        1
> > #define __INO_T_MATCHES_INO64_T        1
> >
> > If I read the rest of the glibc headers right, that should be all we need
> > to ensure that both off_t and off64_t match the __kernel_loff_t based
> > syscalls.
> Ok, I will test the ltp syscall test.
> With this changes, the issue I mentioned should be fixed. But we still
> use mmap2 syscall for ILP32 application when we pass the offset instead
> of page offset. Is it correct?

I don't remember. It's probably not important whether we have the shift
in there, as long as it's independent of the actual kernel page size and
user space and kernel agree on the calling conventions.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-10 12:50                 ` Arnd Bergmann
@ 2016-05-11  2:04                   ` Zhangjian (Bamvor)
  2016-05-11  8:04                     ` Yury Norov
  2016-05-11  8:09                     ` Arnd Bergmann
  0 siblings, 2 replies; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-11  2:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, Zhangjian (Bamvor)

Hi,

On 2016/5/10 20:50, Arnd Bergmann wrote:
> On Tuesday 10 May 2016 20:39:41 Zhangjian wrote:
>> Hi,
>>
>> On 2016/5/10 19:48, Arnd Bergmann wrote:
>>> On Tuesday 10 May 2016 17:47:26 Zhangjian wrote:
>>>> On 2016/5/10 16:36, Arnd Bergmann wrote:
>>>>> On Tuesday 10 May 2016 15:42:07 Zhangjian wrote:
>>>>>> On 2016/5/6 20:37, Yury Norov wrote:
>>>>
>>>> "include/uapi/asm-generic/posix_types.h" is uapi, we could not check
>>>> "ARCH_32BIT_OFF_T" here. Besides, the `__kernel_long_t` is long which
>>>> mean it is 32bit in ILP32. should we define something like x32?
>>>>        ```
>>>>        diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
>>>>        index 7985ff6..9baa8d3 100644
>>>>        --- a/arch/arm64/include/uapi/asm/posix_types.h
>>>>        +++ b/arch/arm64/include/uapi/asm/posix_types.h
>>>
>>> glibc does not use the definition of __kernel_off_t, it has its own
>>> copy, so changing the kernel headers would do nothing.
>> Yes, I think so. I am puzzle that how do we ensure that all the new
>> 32bit architecture will define off_t as 64bit after introduce
>> ARCH_32BIT_OFF_T and do not change any other code?
>
> This is for historic reasons: we have two sets of system calls passing
> file offsets: the original ones passing a 'long' are named e.g. lseek,
> pread, pwrite, fadvise, ...
>
> The replacement syscalls that pass a 'long long' __kernel_loff_t are only
> available on 32-bit architectures and have different names, e.g. llseek,
> pread64, pwrite64, fadvise64, ...
>
> On 64-bit architectures, we only provide the first set, because
> __kernel_off_t was already wide enough. On old 32-bit architectures
> we have both, and on new 32-bit architectures we only have the second
> set, which lets us use the same definitions on all 32-bit architectures.
>
>>>>        @@ -5,6 +5,9 @@ typedef unsigned short __kernel_old_uid_t;
>>>>         typedef unsigned short __kernel_old_gid_t;
>>>>          #define __kernel_old_uid_t __kernel_old_uid_t
>>>>
>>>>         +typedef long long __kernel_long_t;
>>>>         +typedef unsigned long long __kernel_ulong_t;
>>>>         +
>>>>          #include <asm-generic/posix_types.h>
>>>>
>>>>          #endif /*  __ASM_POSIX_TYPES_H */u
>>>>        ```
>>>
>>> This would break all sorts of things, because __kernel_long_t/__kernel_ulong_t
>>> are not just used for off_t but also other things.
>> Yes. But if we do not change __kernel_long_t and __kernel_ulong_t, the
>> application of ilp32 will think size of long in kernel is 32bit. Is that
>> correct?
>
> No, __kernel_long_t refers to the definition of 'long' in the kernel/user
> ABI, not in the kernel (except on the x86-64 "x32" ABI, which is weird).
Thanks, that is answer my question. I ask this because I saw the posix_types.h
for x32.
> A 32-bit user space application must not care about how 'long' is defined
> in the kernel, it should run on either 32-bit kernels or 64-bit kernels.
> We don't have any plans to do an ilp32-mode kernel, but if we ever want
> one, it must use the exact same ABI as the 64-bit kernel when running
> ilp32 user space.
>
>>>>
>>>> On the other hand, glibc define it own off_t in "bits/types.h":
>>>>        __STD_TYPE __OFF_T_TYPE __off_t;        /* Type of file sizes and offsets.  */
>>>>        __STD_TYPE __OFF64_T_TYPE __off64_t;    /* Type of file sizes and offsets (LFS).  */
>>>>
>>>> in "sysdeps/unix/sysv/linux/aarch64/bits/typesizes.h":
>>>>        #define __OFF_T_TYPE            __SLONGWORD_TYPE
>>>>        #define __OFF64_T_TYPE          __SQUAD_TYPE
>>>>
>>>> If we define off_t as 64bit in glibc:
>>>>        #define __OFF_T_TYPE           __SQUAD_TYPE
>>>>
>>>> Should We need to align all the off_t syscall to 64bit syscall in
>>>> kernel?
>>>>
>>>
>>> Yes, this is the change that I think we need to make, along with
>>> the same change for __INO_T_TYPE and
>>>
>>> #define __OFF_T_MATCHES_OFF64_T        1
>>> #define __INO_T_MATCHES_INO64_T        1
>>>
>>> If I read the rest of the glibc headers right, that should be all we need
>>> to ensure that both off_t and off64_t match the __kernel_loff_t based
>>> syscalls.
>> Ok, I will test the ltp syscall test.
>> With this changes, the issue I mentioned should be fixed. But we still
>> use mmap2 syscall for ILP32 application when we pass the offset instead
>> of page offset. Is it correct?
>
> I don't remember. It's probably not important whether we have the shift
> in there, as long as it's independent of the actual kernel page size and
> user space and kernel agree on the calling conventions.
Well. I am ok with where to shift the pages size because we get the same
result. I was just thinking if we should get rid of the name of mmap2 in our
ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
if they do not know the implementations.

Regards

Bamvor

>
> 	Arnd
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11  2:04                   ` Zhangjian (Bamvor)
@ 2016-05-11  8:04                     ` Yury Norov
  2016-05-11 10:55                       ` Arnd Bergmann
  2016-05-11  8:09                     ` Arnd Bergmann
  1 sibling, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-11  8:04 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Arnd Bergmann, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Hanjun Guo, joseph, linux-arch, linux-s390,
	jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Wed, May 11, 2016 at 10:04:16AM +0800, Zhangjian (Bamvor) wrote:
[...]

> >>Ok, I will test the ltp syscall test.
> >>With this changes, the issue I mentioned should be fixed. But we still
> >>use mmap2 syscall for ILP32 application when we pass the offset instead
> >>of page offset. Is it correct?
> >
> >I don't remember. It's probably not important whether we have the shift
> >in there, as long as it's independent of the actual kernel page size and
> >user space and kernel agree on the calling conventions.
> Well. I am ok with where to shift the pages size because we get the same
> result. I was just thinking if we should get rid of the name of mmap2 in our
> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> if they do not know the implementations.
> 

This is what generic unistd.h does. If you want to change it, you'd
change each arch that uses generic unistd.h.

> Regards
> 
> Bamvor
> 
> >
> >	Arnd
> >
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11  2:04                   ` Zhangjian (Bamvor)
  2016-05-11  8:04                     ` Yury Norov
@ 2016-05-11  8:09                     ` Arnd Bergmann
  2016-05-11 10:12                       ` Zhangjian (Bamvor)
  1 sibling, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-11  8:09 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
> > I don't remember. It's probably not important whether we have the shift
> > in there, as long as it's independent of the actual kernel page size and
> > user space and kernel agree on the calling conventions.
> Well. I am ok with where to shift the pages size because we get the same
> result. I was just thinking if we should get rid of the name of mmap2 in our
> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> if they do not know the implementations.

That is a good point: If the implementation matches the mmap() behavior rather than
mmap2(), we should rename the macro by doing

#undef __NR_mmap2
#define __NR_mmap 222

in the uapi/asm/unistd.h file for ilp32 mode. Alternatively we can keep the
__NR_mmap2 definition but then we need to pass the pgoff (value shifted by
12 bits) argument rather than the size in bytes.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11  8:09                     ` Arnd Bergmann
@ 2016-05-11 10:12                       ` Zhangjian (Bamvor)
  2016-05-11 11:16                         ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-11 10:12 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, Zhangjian (Bamvor)

Hi, Arnd

On 2016/5/11 16:09, Arnd Bergmann wrote:
 > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
 >>> I don't remember. It's probably not important whether we have the shift
 >>> in there, as long as it's independent of the actual kernel page size and
 >>> user space and kernel agree on the calling conventions.
 >> Well. I am ok with where to shift the pages size because we get the same
 >> result. I was just thinking if we should get rid of the name of mmap2 in our
 >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
 >> if they do not know the implementations.
 >
 > That is a good point: If the implementation matches the mmap() behavior rather than
 > mmap2(), we should rename the macro by doing
 >
 > #undef __NR_mmap2
 > #define __NR_mmap 222
 >
 > in the uapi/asm/unistd.h file for ilp32 mode.
Do you mean define the following things in kernel:
```
diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
index 1caadc2..3f79640 100644
--- a/arch/arm64/include/uapi/asm/unistd.h
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -14,3 +14,9 @@
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #include <asm-generic/unistd.h>
+
+#ifdef __ILP32__
+#undef __NR_mmap2
+#define __NR_mmap 222
+#endif /* #ifdef __ILP32__ */
+
```
Then glibc could call mmap instead of mmap2.
I could not try it now. Because after change off_t to 64bit in glibc, stat
is fail. I may need to revert the stat relative patch.

 > Alternatively we can keep the
 > __NR_mmap2 definition but then we need to pass the pgoff (value shifted by
 > 12 bits) argument rather than the size in bytes.
It means that we could reuse the existing code of mmap2 in kernel and glibc.
But we need to shift twice when kernel is 64k page.
It seems that the first method is more clear. Suggestion?

Regards

Bamvor
 >
 >   Arnd
 >

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11  8:04                     ` Yury Norov
@ 2016-05-11 10:55                       ` Arnd Bergmann
  2016-05-11 16:59                         ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-11 10:55 UTC (permalink / raw)
  To: Yury Norov
  Cc: Zhangjian (Bamvor),
	linux-doc, Andrew Pinski, catalin.marinas, heiko.carstens,
	Hanjun Guo, joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Wednesday 11 May 2016 11:04:38 Yury Norov wrote:
> On Wed, May 11, 2016 at 10:04:16AM +0800, Zhangjian (Bamvor) wrote:
> [...]
> 
> > >>Ok, I will test the ltp syscall test.
> > >>With this changes, the issue I mentioned should be fixed. But we still
> > >>use mmap2 syscall for ILP32 application when we pass the offset instead
> > >>of page offset. Is it correct?
> > >
> > >I don't remember. It's probably not important whether we have the shift
> > >in there, as long as it's independent of the actual kernel page size and
> > >user space and kernel agree on the calling conventions.
> > Well. I am ok with where to shift the pages size because we get the same
> > result. I was just thinking if we should get rid of the name of mmap2 in our
> > ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> > if they do not know the implementations.
> > 
> 
> This is what generic unistd.h does. If you want to change it, you'd
> change each arch that uses generic unistd.h.
> 

Generic unistd.h has this:

#ifdef __SYSCALL_COMPAT
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
#else
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
#endif

#define __NR3264_mmap 222
__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)


#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
#define __NR_mmap __NR3264_mmap
#else
#define __NR_mmap2 __NR3264_mmap
#endif

So by default we get __NR_mmap2 and sys_mmap2 on 32-bit ABIs, but
__NR_mmap and sys_mmap on 64-bit ABIs, as it should be.

The problem is that arch/arm64/kernel/sys_ilp32.c now overrides
this to use __NR_mmap2 with sys_mmap, so we have a mismatch. I think
we should either override both the implementation and the number,
or neither of them.

I think what happened is that you chose to override sys_mmap because
sys_mmap2 sometimes takes an off_t argument, however the kernel
just treats it as 'unsigned long', with a range of 44 bits for the
offset. Using sys_mmap with a __kernel_loff_t argument gives
us 64-bit range, but if we do that, I think it should be __NR_mmap.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11 10:12                       ` Zhangjian (Bamvor)
@ 2016-05-11 11:16                         ` Zhangjian (Bamvor)
  2016-05-11 14:50                           ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-11 11:16 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, Zhangjian (Bamvor)

Hi,

On 2016/5/11 18:12, Zhangjian (Bamvor) wrote:
> Hi, Arnd
>
> On 2016/5/11 16:09, Arnd Bergmann wrote:
>  > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
>  >>> I don't remember. It's probably not important whether we have the shift
>  >>> in there, as long as it's independent of the actual kernel page size and
>  >>> user space and kernel agree on the calling conventions.
>  >> Well. I am ok with where to shift the pages size because we get the same
>  >> result. I was just thinking if we should get rid of the name of mmap2 in our
>  >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
>  >> if they do not know the implementations.
>  >
>  > That is a good point: If the implementation matches the mmap() behavior rather than
>  > mmap2(), we should rename the macro by doing
>  >
>  > #undef __NR_mmap2
>  > #define __NR_mmap 222
>  >
>  > in the uapi/asm/unistd.h file for ilp32 mode.
> Do you mean define the following things in kernel:
> ```
> diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
> index 1caadc2..3f79640 100644
> --- a/arch/arm64/include/uapi/asm/unistd.h
> +++ b/arch/arm64/include/uapi/asm/unistd.h
> @@ -14,3 +14,9 @@
>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>    */
>   #include <asm-generic/unistd.h>
> +
> +#ifdef __ILP32__
> +#undef __NR_mmap2
> +#define __NR_mmap 222
> +#endif /* #ifdef __ILP32__ */
> +
> ```
> Then glibc could call mmap instead of mmap2.
> I could not try it now. Because after change off_t to 64bit in glibc, stat
> is fail. I may need to revert the stat relative patch.
After revert stat relative patch in glibc, mmap01-mmap14 success. But mmap16
success with segfault. I will investigate it later.

There is pointer and size_t in mmap, so, IIUC, we need to clear the top halves
of register by using COMPAT_SYSCALL_WRAP6. And after check the function in
arch/s390/kernel/compat_linux.c, I feel that we need to do the same thing for
pread64 and pwrite64.

But I got following error when I try to add
COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
size_t, count, loff_t, pos);
COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
size_t, count, loff_t, pos);

The error message:
kernel/compat_wrapper.c: In function 'compat_SyS_pread64':
include/linux/compiler.h:429:38: error: call to '__compiletime_assert_308' declared with attribute error: BUILD_BUG_ON failed: (sizeof(loff_t) > 4) && !__TYPE_IS_L(loff_t) && !__TYPE_IS_UL(loff_t) && !__TYPE_IS_PTR(loff_t)
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:412:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^
include/linux/compiler.h:429:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/bug.h:50:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^
include/linux/bug.h:74:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
^
include/linux/compat.h:749:2: note: in expansion of macro 'BUILD_BUG_ON'
BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \
^
include/linux/syscalls.h:38:23: note: in expansion of macro '__SC_COMPAT_CAST'
#define __MAP1(m,t,a) m(t,a)
^
include/linux/syscalls.h:39:35: note: in expansion of macro '__MAP1'
#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
^
include/linux/syscalls.h:40:35: note: in expansion of macro '__MAP2'
#define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
^
include/linux/syscalls.h:41:35: note: in expansion of macro '__MAP3'
#define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
^
include/linux/syscalls.h:44:22: note: in expansion of macro '__MAP4'
#define __MAP(n,...) __MAP##n(__VA_ARGS__)
^
include/linux/compat.h:777:19: note: in expansion of macro '__MAP'
return sys##name(__MAP(x, __SC_COMPAT_CAST, __VA_ARGS__)); \
^
include/linux/compat.h:735:41: note: in expansion of macro 'COMPAT_SYSCALL_WRAPx'
#define COMPAT_SYSCALL_WRAP4(name, ...) COMPAT_SYSCALL_WRAPx(4, _##name,\
^
kernel/compat_wrapper.c:307:1: note: in expansion of macro 'COMPAT_SYSCALL_WRAP4'
COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
^

Because the loff_t is not the long, unsigned long or pointer.

Regards

Bamvor
>  > Alternatively we can keep the
>  > __NR_mmap2 definition but then we need to pass the pgoff (value shifted by
>  > 12 bits) argument rather than the size in bytes.
> It means that we could reuse the existing code of mmap2 in kernel and glibc.
> But we need to shift twice when kernel is 64k page.
> It seems that the first method is more clear. Suggestion?
>
> Regards
>
> Bamvor
>  >
>  >   Arnd
>  >
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11 11:16                         ` Zhangjian (Bamvor)
@ 2016-05-11 14:50                           ` Arnd Bergmann
  2016-05-12  3:45                             ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-11 14:50 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Wednesday 11 May 2016 19:16:44 Zhangjian wrote:
> Hi,
> 
> On 2016/5/11 18:12, Zhangjian (Bamvor) wrote:
> > Hi, Arnd
> >
> > On 2016/5/11 16:09, Arnd Bergmann wrote:
> >  > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
> >  >>> I don't remember. It's probably not important whether we have the shift
> >  >>> in there, as long as it's independent of the actual kernel page size and
> >  >>> user space and kernel agree on the calling conventions.
> >  >> Well. I am ok with where to shift the pages size because we get the same
> >  >> result. I was just thinking if we should get rid of the name of mmap2 in our
> >  >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> >  >> if they do not know the implementations.
> >  >
> >  > That is a good point: If the implementation matches the mmap() behavior rather than
> >  > mmap2(), we should rename the macro by doing
> >  >
> >  > #undef __NR_mmap2
> >  > #define __NR_mmap 222
> >  >
> >  > in the uapi/asm/unistd.h file for ilp32 mode.
> > Do you mean define the following things in kernel:
> > ```
> > diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
> > index 1caadc2..3f79640 100644
> > --- a/arch/arm64/include/uapi/asm/unistd.h
> > +++ b/arch/arm64/include/uapi/asm/unistd.h
> > @@ -14,3 +14,9 @@
> >    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> >    */
> >   #include <asm-generic/unistd.h>
> > +
> > +#ifdef __ILP32__
> > +#undef __NR_mmap2
> > +#define __NR_mmap 222
> > +#endif /* #ifdef __ILP32__ */
> > +
> > ```
> > Then glibc could call mmap instead of mmap2.
> > I could not try it now. Because after change off_t to 64bit in glibc, stat
> > is fail. I may need to revert the stat relative patch.
> After revert stat relative patch in glibc, mmap01-mmap14 success. But mmap16
> success with segfault. I will investigate it later.
> 
> There is pointer and size_t in mmap, so, IIUC, we need to clear the top halves
> of register by using COMPAT_SYSCALL_WRAP6.

Correct, good catch!

> And after check the function in
> arch/s390/kernel/compat_linux.c, I feel that we need to do the same thing for
> pread64 and pwrite64.
> 

> But I got following error when I try to add
> COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
> size_t, count, loff_t, pos);
> COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
> size_t, count, loff_t, pos);
> 

Hmm, that is indeed tricky. I think COMPAT_SYSCALL_WRAP4 rightfully
refuses the loff_t argument here, as the common case is that this is
not possible.

Can you open-code this using a COMPAT_SYSCALL4 definition similar to what
arch/tile has, but without the merging of the two halves of the argument?

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11 10:55                       ` Arnd Bergmann
@ 2016-05-11 16:59                         ` Catalin Marinas
  2016-05-11 19:30                           ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-11 16:59 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Yury Norov, linux-doc, Andrew Pinski, heiko.carstens, Hanjun Guo,
	joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Zhangjian (Bamvor),
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Wed, May 11, 2016 at 12:55:01PM +0200, Arnd Bergmann wrote:
> On Wednesday 11 May 2016 11:04:38 Yury Norov wrote:
> > On Wed, May 11, 2016 at 10:04:16AM +0800, Zhangjian (Bamvor) wrote:
> > [...]
> > 
> > > >>Ok, I will test the ltp syscall test.
> > > >>With this changes, the issue I mentioned should be fixed. But we still
> > > >>use mmap2 syscall for ILP32 application when we pass the offset instead
> > > >>of page offset. Is it correct?
> > > >
> > > >I don't remember. It's probably not important whether we have the shift
> > > >in there, as long as it's independent of the actual kernel page size and
> > > >user space and kernel agree on the calling conventions.
> > > Well. I am ok with where to shift the pages size because we get the same
> > > result. I was just thinking if we should get rid of the name of mmap2 in our
> > > ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> > > if they do not know the implementations.
> > > 
> > 
> > This is what generic unistd.h does. If you want to change it, you'd
> > change each arch that uses generic unistd.h.
> 
> Generic unistd.h has this:
> 
> #ifdef __SYSCALL_COMPAT
> #define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
> #else
> #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
> #endif
> 
> #define __NR3264_mmap 222
> __SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
> 
> 
> #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
> #define __NR_mmap __NR3264_mmap
> #else
> #define __NR_mmap2 __NR3264_mmap
> #endif
> 
> So by default we get __NR_mmap2 and sys_mmap2 on 32-bit ABIs, but
> __NR_mmap and sys_mmap on 64-bit ABIs, as it should be.
> 
> The problem is that arch/arm64/kernel/sys_ilp32.c now overrides
> this to use __NR_mmap2 with sys_mmap, so we have a mismatch. I think
> we should either override both the implementation and the number,
> or neither of them.

I would vote for "neither of them" (so we use __NR_mmap2 and sys_mmap2)
to keep it close to new 32-bit architectures, even though we would have
some shifts by 12 in both glibc and kernel.

-- 
Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11 16:59                         ` Catalin Marinas
@ 2016-05-11 19:30                           ` Arnd Bergmann
  2016-05-12  9:17                             ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-11 19:30 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Yury Norov, linux-doc, Andrew Pinski, heiko.carstens, Hanjun Guo,
	joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Zhangjian (Bamvor),
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Wednesday 11 May 2016 17:59:01 Catalin Marinas wrote:
> On Wed, May 11, 2016 at 12:55:01PM +0200, Arnd Bergmann wrote:
> > On Wednesday 11 May 2016 11:04:38 Yury Norov wrote:
> > > On Wed, May 11, 2016 at 10:04:16AM +0800, Zhangjian (Bamvor) wrote:
> > > [...]
> > > 
> > > > >>Ok, I will test the ltp syscall test.
> > > > >>With this changes, the issue I mentioned should be fixed. But we still
> > > > >>use mmap2 syscall for ILP32 application when we pass the offset instead
> > > > >>of page offset. Is it correct?
> > > > >
> > > > >I don't remember. It's probably not important whether we have the shift
> > > > >in there, as long as it's independent of the actual kernel page size and
> > > > >user space and kernel agree on the calling conventions.
> > > > Well. I am ok with where to shift the pages size because we get the same
> > > > result. I was just thinking if we should get rid of the name of mmap2 in our
> > > > ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> > > > if they do not know the implementations.
> > > > 
> > > 
> > > This is what generic unistd.h does. If you want to change it, you'd
> > > change each arch that uses generic unistd.h.
> > 
> > Generic unistd.h has this:
> > 
> > #ifdef __SYSCALL_COMPAT
> > #define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
> > #else
> > #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
> > #endif
> > 
> > #define __NR3264_mmap 222
> > __SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
> > 
> > 
> > #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
> > #define __NR_mmap __NR3264_mmap
> > #else
> > #define __NR_mmap2 __NR3264_mmap
> > #endif
> > 
> > So by default we get __NR_mmap2 and sys_mmap2 on 32-bit ABIs, but
> > __NR_mmap and sys_mmap on 64-bit ABIs, as it should be.
> > 
> > The problem is that arch/arm64/kernel/sys_ilp32.c now overrides
> > this to use __NR_mmap2 with sys_mmap, so we have a mismatch. I think
> > we should either override both the implementation and the number,
> > or neither of them.
> 
> I would vote for "neither of them" (so we use __NR_mmap2 and sys_mmap2)
> to keep it close to new 32-bit architectures, even though we would have
> some shifts by 12 in both glibc and kernel.

I don't think the shifts are a problem, the main downside would be
the limit to 44 bits of file offsets (16TB files), but it's also
unclear if that is a practical problem at all. If it is, we run
into the same problem on all other 32-bit architectures too.

	Arnd

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (26 preceding siblings ...)
  2016-04-06  6:51 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 Geert Uytterhoeven
@ 2016-05-12  0:20 ` Yury Norov
  2016-05-12  9:19   ` Arnd Bergmann
  2016-05-12 13:35   ` Catalin Marinas
  2016-05-17 12:10 ` Szabolcs Nagy
  28 siblings, 2 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-12  0:20 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390

Hi,

I debugged preadv02 and pwritev02 failures and found very weird bug.
Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
of vector, and kernel reports successful read/write.

There are 2 problems:
1. How kernel allows such address to be passed to fs subsystem;
2. How fs successes to read/write at non-mapped, and in fact non-user
address.

I don't know the answer on 2'nd question, and it might be something
generic. But I investigated first problem.

The problem is that compat_rw_copy_check_uvector() uses access_ok() to
validate user address, and on arm64 it ends up with checking buffer
end against current_thread_info()->addr_limit.

current_thread_info()->addr_limit for ilp32, and most probably for
aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
It happens because on thread creation we call flush_old_exec() to set 
addr_limit, and completely ignore compat mode there.

This patch fixes it. It also fixes USER_DS macro to return different
values depending on compat.

This patch is enough to handle preadv02 and pwritev02, but problem #2
is still there.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h     | 1 +
 arch/arm64/include/asm/uaccess.h | 2 +-
 arch/arm64/kernel/binfmt_elf32.c | 1 +
 arch/arm64/kernel/binfmt_ilp32.c | 1 +
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 7a39683..6ba4952 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -146,6 +146,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
 do {						\
 	clear_thread_flag(TIF_32BIT_AARCH64);	\
 	clear_thread_flag(TIF_32BIT);		\
+	set_fs(TASK_SIZE_64);			\
 } while (0)
 
 #define ARCH_DLINFO							\
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 19cfdc5..3b0dd8d 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -51,7 +51,7 @@
 #define KERNEL_DS	(-1UL)
 #define get_ds()	(KERNEL_DS)
 
-#define USER_DS		TASK_SIZE_64
+#define USER_DS		TASK_SIZE
 #define get_fs()	(current_thread_info()->addr_limit)
 
 static inline void set_fs(mm_segment_t fs)
diff --git a/arch/arm64/kernel/binfmt_elf32.c b/arch/arm64/kernel/binfmt_elf32.c
index 5487872..2e8d9f3 100644
--- a/arch/arm64/kernel/binfmt_elf32.c
+++ b/arch/arm64/kernel/binfmt_elf32.c
@@ -12,6 +12,7 @@
 do {						\
 	clear_thread_flag(TIF_32BIT_AARCH64);	\
 	set_thread_flag(TIF_32BIT);		\
+	set_fs(TASK_SIZE_32);			\
 } while (0)
 
 #define COMPAT_ARCH_DLINFO
diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
index a934fd4..a8599c6 100644
--- a/arch/arm64/kernel/binfmt_ilp32.c
+++ b/arch/arm64/kernel/binfmt_ilp32.c
@@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
 do {									\
 	set_thread_flag(TIF_32BIT_AARCH64);				\
 	clear_thread_flag(TIF_32BIT);					\
+	set_fs(TASK_SIZE_32);						\
 } while (0)
 
 #undef ARCH_DLINFO
-- 
2.5.0

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11 14:50                           ` Arnd Bergmann
@ 2016-05-12  3:45                             ` Zhangjian (Bamvor)
  2016-05-12  8:24                               ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-12  3:45 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-doc, Andrew Pinski, catalin.marinas,
	heiko.carstens, Yury Norov, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, Zhangjian (Bamvor)

Hi, Arnd

On 2016/5/11 22:50, Arnd Bergmann wrote:
> On Wednesday 11 May 2016 19:16:44 Zhangjian wrote:
>> Hi,
>>
>> On 2016/5/11 18:12, Zhangjian (Bamvor) wrote:
>>> Hi, Arnd
>>>
>>> On 2016/5/11 16:09, Arnd Bergmann wrote:
>>>   > On Wednesday 11 May 2016 10:04:16 Zhangjian wrote:
>>>   >>> I don't remember. It's probably not important whether we have the shift
>>>   >>> in there, as long as it's independent of the actual kernel page size and
>>>   >>> user space and kernel agree on the calling conventions.
>>>   >> Well. I am ok with where to shift the pages size because we get the same
>>>   >> result. I was just thinking if we should get rid of the name of mmap2 in our
>>>   >> ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
>>>   >> if they do not know the implementations.
>>>   >
>>>   > That is a good point: If the implementation matches the mmap() behavior rather than
>>>   > mmap2(), we should rename the macro by doing
>>>   >
>>>   > #undef __NR_mmap2
>>>   > #define __NR_mmap 222
>>>   >
>>>   > in the uapi/asm/unistd.h file for ilp32 mode.
>>> Do you mean define the following things in kernel:
>>> ```
>>> diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
>>> index 1caadc2..3f79640 100644
>>> --- a/arch/arm64/include/uapi/asm/unistd.h
>>> +++ b/arch/arm64/include/uapi/asm/unistd.h
>>> @@ -14,3 +14,9 @@
>>>     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>     */
>>>    #include <asm-generic/unistd.h>
>>> +
>>> +#ifdef __ILP32__
>>> +#undef __NR_mmap2
>>> +#define __NR_mmap 222
>>> +#endif /* #ifdef __ILP32__ */
>>> +
>>> ```
>>> Then glibc could call mmap instead of mmap2.
>>> I could not try it now. Because after change off_t to 64bit in glibc, stat
>>> is fail. I may need to revert the stat relative patch.
>> After revert stat relative patch in glibc, mmap01-mmap14 success. But mmap16
>> success with segfault. I will investigate it later.
>>
>> There is pointer and size_t in mmap, so, IIUC, we need to clear the top halves
>> of register by using COMPAT_SYSCALL_WRAP6.
>
> Correct, good catch!
>
>> And after check the function in
>> arch/s390/kernel/compat_linux.c, I feel that we need to do the same thing for
>> pread64 and pwrite64.
>>
>
>> But I got following error when I try to add
>> COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
>> size_t, count, loff_t, pos);
>> COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
>> size_t, count, loff_t, pos);
>>
>
> Hmm, that is indeed tricky. I think COMPAT_SYSCALL_WRAP4 rightfully
> refuses the loff_t argument here, as the common case is that this is
> not possible.
It works if I apply the following patch, I defined the wrong `__TYPE_IS_xxx`
yesterday. Should we merge this into ILP32 series or send the compat.h
and syscalls.h individually? The current series of ILP32 is a little bit
long and hard to review.
diff --git a/include/linux/compat.h b/include/linux/compat.h
index ba6ebe0..22a9565 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -747,7 +747,8 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
  #ifndef __SC_COMPAT_CAST
  #define __SC_COMPAT_CAST(t, a) ({                                      \
         BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&              \
-                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));            \
+                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) &&           \
+                    !__TYPE_IS_LOFFT(t));                              \
         ((t) ((t)(-1) < 0 ? (s64)(s32)(a) : (u64)(u32)(a)));            \
  })
  #endif
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 6e57d9c..66eb85d 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -47,6 +47,7 @@
  #define __TYPE_IS_L(t) (__same_type((t)0, 0L))
  #define __TYPE_IS_UL(t)        (__same_type((t)0, 0UL))
  #define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL))
+#define __TYPE_IS_LOFFT(t)     (__same_type((t)0, (loff_t)0))
  #define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a
  #define __SC_CAST(t, a)        (t) a
  #define __SC_ARGS(t, a)        a
diff --git a/kernel/compat_wrapper.c b/kernel/compat_wrapper.c
index 98b68b8..28f02d0 100644
--- a/kernel/compat_wrapper.c
+++ b/kernel/compat_wrapper.c
@@ -304,3 +304,7 @@ COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len,
                      unsigned int, flags, struct sockaddr __user *, addr,
                      int, addr_len);
+COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
+                       size_t, count, loff_t, pos);
+COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
+                        size_t, count, loff_t, pos);
 >
 > Can you open-code this using a COMPAT_SYSCALL4 definition similar to what
 > arch/tile has, but without the merging of the two halves of the argument?
I am lost here. Tile do not use the wrapper, and it do not use the loff_t
either:
COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf,
                        size_t, count, u32, dummy, u32, low, u32, high)

Regards

Bamvor
> 	Arnd
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12  3:45                             ` Zhangjian (Bamvor)
@ 2016-05-12  8:24                               ` Yury Norov
  2016-05-12 12:52                                 ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-12  8:24 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Arnd Bergmann, linux-arm-kernel, linux-doc, Andrew Pinski,
	catalin.marinas, heiko.carstens, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Thu, May 12, 2016 at 11:45:53AM +0800, Zhangjian (Bamvor) wrote:

[...]

> >Hmm, that is indeed tricky. I think COMPAT_SYSCALL_WRAP4 rightfully
> >refuses the loff_t argument here, as the common case is that this is
> >not possible.
> It works if I apply the following patch, I defined the wrong `__TYPE_IS_xxx`
> yesterday. Should we merge this into ILP32 series or send the compat.h
> and syscalls.h individually? The current series of ILP32 is a little bit
> long and hard to review.
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index ba6ebe0..22a9565 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -747,7 +747,8 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
>  #ifndef __SC_COMPAT_CAST
>  #define __SC_COMPAT_CAST(t, a) ({                                      \
>         BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&              \
> -                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));            \
> +                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) &&           \
> +                    !__TYPE_IS_LOFFT(t));                              \

I think it's wrong, as loff_t is 64-bit in 32-bit userspace, and this
will clear meaningful data in top halve.

>         ((t) ((t)(-1) < 0 ? (s64)(s32)(a) : (u64)(u32)(a)));            \
>  })
>  #endif
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index 6e57d9c..66eb85d 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -47,6 +47,7 @@
>  #define __TYPE_IS_L(t) (__same_type((t)0, 0L))
>  #define __TYPE_IS_UL(t)        (__same_type((t)0, 0UL))
>  #define __TYPE_IS_LL(t) (__same_type((t)0, 0LL) || __same_type((t)0, 0ULL))
> +#define __TYPE_IS_LOFFT(t)     (__same_type((t)0, (loff_t)0))
>  #define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a
>  #define __SC_CAST(t, a)        (t) a
>  #define __SC_ARGS(t, a)        a
> diff --git a/kernel/compat_wrapper.c b/kernel/compat_wrapper.c
> index 98b68b8..28f02d0 100644
> --- a/kernel/compat_wrapper.c
> +++ b/kernel/compat_wrapper.c
> @@ -304,3 +304,7 @@ COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
>  COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len,
>                      unsigned int, flags, struct sockaddr __user *, addr,
>                      int, addr_len);
> +COMPAT_SYSCALL_WRAP4(pread64, unsigned int, fd, char __user *, buf,
> +                       size_t, count, loff_t, pos);
> +COMPAT_SYSCALL_WRAP4(pwrite64, unsigned int, fd, const char __user *, buf,
> +                        size_t, count, loff_t, pos);

For cases like this I think we should write wrappers by hands. In
unistd.h we can use __SC_WRAP, so they will work like wrappers
generated by COMPAT_SYSCALL_WRAPx() 

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-11 19:30                           ` Arnd Bergmann
@ 2016-05-12  9:17                             ` Catalin Marinas
  2016-05-12  9:21                               ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-12  9:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-doc, Andrew Pinski, heiko.carstens, Yury Norov, Hanjun Guo,
	joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Zhangjian (Bamvor),
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Wed, May 11, 2016 at 09:30:07PM +0200, Arnd Bergmann wrote:
> On Wednesday 11 May 2016 17:59:01 Catalin Marinas wrote:
> > On Wed, May 11, 2016 at 12:55:01PM +0200, Arnd Bergmann wrote:
> > > On Wednesday 11 May 2016 11:04:38 Yury Norov wrote:
> > > > On Wed, May 11, 2016 at 10:04:16AM +0800, Zhangjian (Bamvor) wrote:
> > > > [...]
> > > > 
> > > > > >>Ok, I will test the ltp syscall test.
> > > > > >>With this changes, the issue I mentioned should be fixed. But we still
> > > > > >>use mmap2 syscall for ILP32 application when we pass the offset instead
> > > > > >>of page offset. Is it correct?
> > > > > >
> > > > > >I don't remember. It's probably not important whether we have the shift
> > > > > >in there, as long as it's independent of the actual kernel page size and
> > > > > >user space and kernel agree on the calling conventions.
> > > > > Well. I am ok with where to shift the pages size because we get the same
> > > > > result. I was just thinking if we should get rid of the name of mmap2 in our
> > > > > ILP32 porting. Actually, it is mmap but we name it as mmap2. User may confused
> > > > > if they do not know the implementations.
> > > > > 
> > > > 
> > > > This is what generic unistd.h does. If you want to change it, you'd
> > > > change each arch that uses generic unistd.h.
> > > 
> > > Generic unistd.h has this:
> > > 
> > > #ifdef __SYSCALL_COMPAT
> > > #define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
> > > #else
> > > #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
> > > #endif
> > > 
> > > #define __NR3264_mmap 222
> > > __SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
> > > 
> > > 
> > > #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
> > > #define __NR_mmap __NR3264_mmap
> > > #else
> > > #define __NR_mmap2 __NR3264_mmap
> > > #endif
> > > 
> > > So by default we get __NR_mmap2 and sys_mmap2 on 32-bit ABIs, but
> > > __NR_mmap and sys_mmap on 64-bit ABIs, as it should be.
> > > 
> > > The problem is that arch/arm64/kernel/sys_ilp32.c now overrides
> > > this to use __NR_mmap2 with sys_mmap, so we have a mismatch. I think
> > > we should either override both the implementation and the number,
> > > or neither of them.
> > 
> > I would vote for "neither of them" (so we use __NR_mmap2 and sys_mmap2)
> > to keep it close to new 32-bit architectures, even though we would have
> > some shifts by 12 in both glibc and kernel.
> 
> I don't think the shifts are a problem, the main downside would be
> the limit to 44 bits of file offsets (16TB files), but it's also
> unclear if that is a practical problem at all. If it is, we run
> into the same problem on all other 32-bit architectures too.

I hope people are seriously thinking of moving to an LP64 ABI if they
have such large file offset needs.

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12  0:20 ` Yury Norov
@ 2016-05-12  9:19   ` Arnd Bergmann
  2016-05-12 10:30     ` Yury Norov
  2016-05-12 13:35   ` Catalin Marinas
  1 sibling, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-12  9:19 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, catalin.marinas, linux-kernel, linux-arch,
	linux-s390, pinskia, Prasun.Kapoor, heiko.carstens, linux-doc,
	Nathan_Lynch, agraf, klimov.linux, broonie, bamvor.zhangjian,
	schwab, schwidefsky, joseph, christoph.muellner

On Thursday 12 May 2016 03:20:00 Yury Norov wrote:
> 
> I debugged preadv02 and pwritev02 failures and found very weird bug.
> Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> of vector, and kernel reports successful read/write.
> 
> There are 2 problems:
> 1. How kernel allows such address to be passed to fs subsystem;
> 2. How fs successes to read/write at non-mapped, and in fact non-user
> address.
> 
> I don't know the answer on 2'nd question, and it might be something
> generic. But I investigated first problem.
> 
> The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> validate user address, and on arm64 it ends up with checking buffer
> end against current_thread_info()->addr_limit.
> 
> current_thread_info()->addr_limit for ilp32, and most probably for
> aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> It happens because on thread creation we call flush_old_exec() to set 
> addr_limit, and completely ignore compat mode there.
> 
> This patch fixes it. It also fixes USER_DS macro to return different
> values depending on compat.
> 
> This patch is enough to handle preadv02 and pwritev02, but problem #2
> is still there.
> 
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> 

Good catch!

Can you do a version of this patch that works on the current
mainline kernel and can be backported to fix aarch32 emulation?

For ilp32 mode, I think we can better fix arch/arm64/kernel/binfmt_ilp32.c
as it is introduced.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12  9:17                             ` Catalin Marinas
@ 2016-05-12  9:21                               ` Arnd Bergmann
  2016-05-12 12:49                                 ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-12  9:21 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-doc, Andrew Pinski, heiko.carstens, Yury Norov, Hanjun Guo,
	joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Zhangjian (Bamvor),
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Thursday 12 May 2016 10:17:58 Catalin Marinas wrote:
> On Wed, May 11, 2016 at 09:30:07PM +0200, Arnd Bergmann wrote:
> > On Wednesday 11 May 2016 17:59:01 Catalin Marinas wrote:
> > 
> > I don't think the shifts are a problem, the main downside would be
> > the limit to 44 bits of file offsets (16TB files), but it's also
> > unclear if that is a practical problem at all. If it is, we run
> > into the same problem on all other 32-bit architectures too.
> 
> I hope people are seriously thinking of moving to an LP64 ABI if they
> have such large file offset needs.

Good point. 44 bits of file size is certainly enough for mmap()
on a 32-bit task: you would only be able to map a very small fraction
of the file anyway, and if you want to map larger files, and should
move to 64-bit tasks long before this becomes a limitation.

	Arnd

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12  9:19   ` Arnd Bergmann
@ 2016-05-12 10:30     ` Yury Norov
  0 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-12 10:30 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-arch, linux-s390, pinskia, Prasun.Kapoor,
	catalin.marinas, broonie, linux-doc, heiko.carstens,
	linux-kernel, agraf, klimov.linux, bamvor.zhangjian, schwab,
	schwidefsky, Nathan_Lynch, joseph, christoph.muellner

On Thu, May 12, 2016 at 11:19:21AM +0200, Arnd Bergmann wrote:
> On Thursday 12 May 2016 03:20:00 Yury Norov wrote:
> > 
> > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > of vector, and kernel reports successful read/write.
> > 
> > There are 2 problems:
> > 1. How kernel allows such address to be passed to fs subsystem;
> > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > address.
> > 
> > I don't know the answer on 2'nd question, and it might be something
> > generic. But I investigated first problem.
> > 
> > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > validate user address, and on arm64 it ends up with checking buffer
> > end against current_thread_info()->addr_limit.
> > 
> > current_thread_info()->addr_limit for ilp32, and most probably for
> > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > It happens because on thread creation we call flush_old_exec() to set 
> > addr_limit, and completely ignore compat mode there.
> > 
> > This patch fixes it. It also fixes USER_DS macro to return different
> > values depending on compat.
> > 
> > This patch is enough to handle preadv02 and pwritev02, but problem #2
> > is still there.
> > 
> > Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> > 
> 
> Good catch!
> 
> Can you do a version of this patch that works on the current
> mainline kernel and can be backported to fix aarch32 emulation?
> 
> For ilp32 mode, I think we can better fix arch/arm64/kernel/binfmt_ilp32.c
> as it is introduced.
> 
> 	Arnd
> 

OK, will do

> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12  9:21                               ` Arnd Bergmann
@ 2016-05-12 12:49                                 ` Zhangjian (Bamvor)
  2016-05-12 13:06                                   ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-12 12:49 UTC (permalink / raw)
  To: Arnd Bergmann, Catalin Marinas
  Cc: linux-doc, Andrew Pinski, heiko.carstens, Yury Norov, Hanjun Guo,
	joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner, Zhangjian (Bamvor)

Hi,

On 2016/5/12 17:21, Arnd Bergmann wrote:
> On Thursday 12 May 2016 10:17:58 Catalin Marinas wrote:
>> On Wed, May 11, 2016 at 09:30:07PM +0200, Arnd Bergmann wrote:
>>> On Wednesday 11 May 2016 17:59:01 Catalin Marinas wrote:
>>>
>>> I don't think the shifts are a problem, the main downside would be
>>> the limit to 44 bits of file offsets (16TB files), but it's also
>>> unclear if that is a practical problem at all. If it is, we run
>>> into the same problem on all other 32-bit architectures too.
>>
>> I hope people are seriously thinking of moving to an LP64 ABI if they
>> have such large file offset needs.
>
> Good point. 44 bits of file size is certainly enough for mmap()
> on a 32-bit task: you would only be able to map a very small fraction
> of the file anyway, and if you want to map larger files, and should
> move to 64-bit tasks long before this becomes a limitation.
Hi,

I apply the following patch in order to make use of the REAL mmmap2. LTP
test pass in litle endian. mmap16 successful with segfault in big endian.

BTW, I saw the similar code in tile, mips, microblaze and s390 compat. Should
we merge these code into a common syscall wrapper?

kernel:
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index d85fe94..2cd72eb 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -41,7 +41,16 @@
  #define compat_sys_sync_file_range     sys_sync_file_range
  #define compat_sys_truncate64          sys_truncate
  #define sys_llseek                     sys_lseek
-#define sys_mmap2                     sys_mmap
+
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
+       unsigned long, prot, unsigned long, flags, unsigned long, fd,
+       unsigned long, pgoff)
+{
+       if (pgoff & (~PAGE_MASK >> 12))
+               return -EINVAL;
+
+       return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
+}

  asmlinkage long ilp32_sys_rt_sigreturn_wrapper(void);
  #define compat_sys_rt_sigreturn        ilp32_sys_rt_sigreturn_wrapper

glibc:
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap.c
index e69de29..f75e251 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap.c
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap.c
@@ -0,0 +1,2 @@
+#include <sysdeps/unix/sysv/linux/generic/wordsize-32/mmap.c>
+
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c
index c6c7f1d..6f1a141 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/mmap64.c
@@ -1,29 +1 @@
-#include <errno.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <string.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* mmap is provided by mmap as they are the same. */
-void *__mmap (void *__addr, size_t __len, int __prot,
-                    int __flags, int __fd, __off_t __offset)
-{
-   void *result;
-   result = (void *) INLINE_SYSCALL (mmap2, 6, __addr, __len, __prot, __flags,
-   return result;
-}
-/* mmap64 is provided by mmap as they are the same. */
-void *__mmap64 (void *__addr, size_t __len, int __prot,
-                    int __flags, int __fd, __off64_t __offset)
-{
-   void *result;
-   result = (void *)
-     INLINE_SYSCALL (mmap2, 6, __addr,
-                     __len, __prot, __flags, __fd, __offset);
-   return result;
-}
-weak_alias (__mmap, mmap)
-weak_alias (__mmap64, mmap64)
+#include <sysdeps/unix/sysv/linux/mmap64.c>

Regards

Bamvor
> 	Arnd
>

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12  8:24                               ` Yury Norov
@ 2016-05-12 12:52                                 ` Zhangjian (Bamvor)
  2016-05-12 12:59                                   ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-12 12:52 UTC (permalink / raw)
  To: Yury Norov
  Cc: Arnd Bergmann, linux-arm-kernel, linux-doc, Andrew Pinski,
	catalin.marinas, heiko.carstens, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner, Zhangjian (Bamvor)

Hi,

On 2016/5/12 16:24, Yury Norov wrote:
> On Thu, May 12, 2016 at 11:45:53AM +0800, Zhangjian (Bamvor) wrote:
>
> [...]
>
>>> Hmm, that is indeed tricky. I think COMPAT_SYSCALL_WRAP4 rightfully
>>> refuses the loff_t argument here, as the common case is that this is
>>> not possible.
>> It works if I apply the following patch, I defined the wrong `__TYPE_IS_xxx`
>> yesterday. Should we merge this into ILP32 series or send the compat.h
>> and syscalls.h individually? The current series of ILP32 is a little bit
>> long and hard to review.
>> diff --git a/include/linux/compat.h b/include/linux/compat.h
>> index ba6ebe0..22a9565 100644
>> --- a/include/linux/compat.h
>> +++ b/include/linux/compat.h
>> @@ -747,7 +747,8 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
>>   #ifndef __SC_COMPAT_CAST
>>   #define __SC_COMPAT_CAST(t, a) ({                                      \
>>          BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&              \
>> -                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));            \
>> +                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) &&           \
>> +                    !__TYPE_IS_LOFFT(t));                              \
>
> I think it's wrong, as loff_t is 64-bit in 32-bit userspace, and this
> will clear meaningful data in top halve.
Yes. It is my fault. The original thoughts is clear the up 32bit for size_t.
How should we skip the loff_t?

Regards

Bamvor

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12 12:52                                 ` Zhangjian (Bamvor)
@ 2016-05-12 12:59                                   ` Yury Norov
  0 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-12 12:59 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Arnd Bergmann, linux-arm-kernel, linux-doc, Andrew Pinski,
	catalin.marinas, heiko.carstens, Hanjun Guo, joseph, linux-arch,
	linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	Nathan_Lynch, linux-kernel, Andrew Pinski, schwidefsky,
	christoph.muellner

On Thu, May 12, 2016 at 08:52:46PM +0800, Zhangjian (Bamvor) wrote:
> Hi,
> 
> On 2016/5/12 16:24, Yury Norov wrote:
> >On Thu, May 12, 2016 at 11:45:53AM +0800, Zhangjian (Bamvor) wrote:
> >
> >[...]
> >
> >>>Hmm, that is indeed tricky. I think COMPAT_SYSCALL_WRAP4 rightfully
> >>>refuses the loff_t argument here, as the common case is that this is
> >>>not possible.
> >>It works if I apply the following patch, I defined the wrong `__TYPE_IS_xxx`
> >>yesterday. Should we merge this into ILP32 series or send the compat.h
> >>and syscalls.h individually? The current series of ILP32 is a little bit
> >>long and hard to review.
> >>diff --git a/include/linux/compat.h b/include/linux/compat.h
> >>index ba6ebe0..22a9565 100644
> >>--- a/include/linux/compat.h
> >>+++ b/include/linux/compat.h
> >>@@ -747,7 +747,8 @@ asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
> >>  #ifndef __SC_COMPAT_CAST
> >>  #define __SC_COMPAT_CAST(t, a) ({                                      \
> >>         BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) &&              \
> >>-                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t));            \
> >>+                    !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) &&           \
> >>+                    !__TYPE_IS_LOFFT(t));                              \
> >
> >I think it's wrong, as loff_t is 64-bit in 32-bit userspace, and this
> >will clear meaningful data in top halve.
> Yes. It is my fault. The original thoughts is clear the up 32bit for size_t.
> How should we skip the loff_t?
> 
> Regards
> 
> Bamvor

I already suggested:

For cases like this I think we should write wrappers by hands. In
unistd.h we can use __SC_WRAP, so they will work like wrappers
generated by COMPAT_SYSCALL_WRAPx()

Do you see any downsides?

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12 12:49                                 ` Zhangjian (Bamvor)
@ 2016-05-12 13:06                                   ` Arnd Bergmann
  2016-05-12 13:19                                     ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-12 13:06 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Catalin Marinas, linux-doc, Andrew Pinski, heiko.carstens,
	Yury Norov, Hanjun Guo, joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Thursday 12 May 2016 20:49:24 Zhangjian wrote:
> Hi,
> 
> On 2016/5/12 17:21, Arnd Bergmann wrote:
> > On Thursday 12 May 2016 10:17:58 Catalin Marinas wrote:
> >> On Wed, May 11, 2016 at 09:30:07PM +0200, Arnd Bergmann wrote:
> >>> On Wednesday 11 May 2016 17:59:01 Catalin Marinas wrote:
> >>>
> >>> I don't think the shifts are a problem, the main downside would be
> >>> the limit to 44 bits of file offsets (16TB files), but it's also
> >>> unclear if that is a practical problem at all. If it is, we run
> >>> into the same problem on all other 32-bit architectures too.
> >>
> >> I hope people are seriously thinking of moving to an LP64 ABI if they
> >> have such large file offset needs.
> >
> > Good point. 44 bits of file size is certainly enough for mmap()
> > on a 32-bit task: you would only be able to map a very small fraction
> > of the file anyway, and if you want to map larger files, and should
> > move to 64-bit tasks long before this becomes a limitation.
> Hi,
> 
> I apply the following patch in order to make use of the REAL mmmap2. LTP
> test pass in litle endian. mmap16 successful with segfault in big endian.
> 
> BTW, I saw the similar code in tile, mips, microblaze and s390 compat. Should
> we merge these code into a common syscall wrapper?

I think that's a good idea. The function used to be slightly different
for each architecture, but now it seems we have a significant number
of identical implementations that we could just merge them together
into one.

sys_mmap_pgoff was originally introduced as the common implementation
and it reduced the amount of duplication a lot, but as its units
are based on PAGE_SIZE rather than hardwired 4096 bytes, it's
not as useful.

> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> index d85fe94..2cd72eb 100644
> --- a/arch/arm64/kernel/sys_ilp32.c
> +++ b/arch/arm64/kernel/sys_ilp32.c
> @@ -41,7 +41,16 @@
>   #define compat_sys_sync_file_range     sys_sync_file_range
>   #define compat_sys_truncate64          sys_truncate
>   #define sys_llseek                     sys_lseek
> -#define sys_mmap2                     sys_mmap
> +
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> +       unsigned long, prot, unsigned long, flags, unsigned long, fd,
> +       unsigned long, pgoff)
> +{
> +       if (pgoff & (~PAGE_MASK >> 12))
> +               return -EINVAL;
> +
> +       return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
> +}
> 

Looks good to me.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12 13:06                                   ` Arnd Bergmann
@ 2016-05-12 13:19                                     ` Yury Norov
  2016-05-14 12:49                                       ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-12 13:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Zhangjian (Bamvor),
	Catalin Marinas, linux-doc, Andrew Pinski, heiko.carstens,
	Hanjun Guo, joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner

On Thu, May 12, 2016 at 03:06:39PM +0200, Arnd Bergmann wrote:
> On Thursday 12 May 2016 20:49:24 Zhangjian wrote:
> > Hi,
> > 
> > On 2016/5/12 17:21, Arnd Bergmann wrote:
> > > On Thursday 12 May 2016 10:17:58 Catalin Marinas wrote:
> > >> On Wed, May 11, 2016 at 09:30:07PM +0200, Arnd Bergmann wrote:
> > >>> On Wednesday 11 May 2016 17:59:01 Catalin Marinas wrote:
> > >>>
> > >>> I don't think the shifts are a problem, the main downside would be
> > >>> the limit to 44 bits of file offsets (16TB files), but it's also
> > >>> unclear if that is a practical problem at all. If it is, we run
> > >>> into the same problem on all other 32-bit architectures too.
> > >>
> > >> I hope people are seriously thinking of moving to an LP64 ABI if they
> > >> have such large file offset needs.
> > >
> > > Good point. 44 bits of file size is certainly enough for mmap()
> > > on a 32-bit task: you would only be able to map a very small fraction
> > > of the file anyway, and if you want to map larger files, and should
> > > move to 64-bit tasks long before this becomes a limitation.
> > Hi,
> > 
> > I apply the following patch in order to make use of the REAL mmmap2. LTP
> > test pass in litle endian. mmap16 successful with segfault in big endian.
> > 
> > BTW, I saw the similar code in tile, mips, microblaze and s390 compat. Should
> > we merge these code into a common syscall wrapper?
> 
> I think that's a good idea. The function used to be slightly different
> for each architecture, but now it seems we have a significant number
> of identical implementations that we could just merge them together
> into one.
> 
> sys_mmap_pgoff was originally introduced as the common implementation
> and it reduced the amount of duplication a lot, but as its units
> are based on PAGE_SIZE rather than hardwired 4096 bytes, it's
> not as useful.
> 

microblaze and mips (twice) are doing like this. And aarh32 as well,
in arch/arm64/kernel/entry32.S

In previous submissions it was a patch that shares aarch32 code to
ilp32. If we decided turn around again, I think, we'd pick up that patch.

The other option is to make this hack generic, as so many arches use it.

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12  0:20 ` Yury Norov
  2016-05-12  9:19   ` Arnd Bergmann
@ 2016-05-12 13:35   ` Catalin Marinas
  2016-05-12 13:44     ` Yury Norov
  1 sibling, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-12 13:35 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, heiko.carstens, linux-doc, Nathan_Lynch,
	agraf, klimov.linux, broonie, bamvor.zhangjian, schwab,
	schwidefsky, joseph, christoph.muellner

On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> I debugged preadv02 and pwritev02 failures and found very weird bug.
> Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> of vector, and kernel reports successful read/write.
> 
> There are 2 problems:
> 1. How kernel allows such address to be passed to fs subsystem;
> 2. How fs successes to read/write at non-mapped, and in fact non-user
> address.
> 
> I don't know the answer on 2'nd question, and it might be something
> generic. But I investigated first problem.
> 
> The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> validate user address, and on arm64 it ends up with checking buffer
> end against current_thread_info()->addr_limit.
> 
> current_thread_info()->addr_limit for ilp32, and most probably for
> aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> It happens because on thread creation we call flush_old_exec() to set 
> addr_limit, and completely ignore compat mode there.

I assume accesses beyond this address would fault anyway but I haven't
checked the code paths.

> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 7a39683..6ba4952 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -146,6 +146,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
>  do {						\
>  	clear_thread_flag(TIF_32BIT_AARCH64);	\
>  	clear_thread_flag(TIF_32BIT);		\
> +	set_fs(TASK_SIZE_64);			\
>  } while (0)

See below.

> diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
> index 19cfdc5..3b0dd8d 100644
> --- a/arch/arm64/include/asm/uaccess.h
> +++ b/arch/arm64/include/asm/uaccess.h
> @@ -51,7 +51,7 @@
>  #define KERNEL_DS	(-1UL)
>  #define get_ds()	(KERNEL_DS)
>  
> -#define USER_DS		TASK_SIZE_64
> +#define USER_DS		TASK_SIZE

I agree with this.

>  #define get_fs()	(current_thread_info()->addr_limit)
>  
>  static inline void set_fs(mm_segment_t fs)
> diff --git a/arch/arm64/kernel/binfmt_elf32.c b/arch/arm64/kernel/binfmt_elf32.c
> index 5487872..2e8d9f3 100644
> --- a/arch/arm64/kernel/binfmt_elf32.c
> +++ b/arch/arm64/kernel/binfmt_elf32.c
> @@ -12,6 +12,7 @@
>  do {						\
>  	clear_thread_flag(TIF_32BIT_AARCH64);	\
>  	set_thread_flag(TIF_32BIT);		\
> +	set_fs(TASK_SIZE_32);			\
>  } while (0)
>  
>  #define COMPAT_ARCH_DLINFO
> diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> index a934fd4..a8599c6 100644
> --- a/arch/arm64/kernel/binfmt_ilp32.c
> +++ b/arch/arm64/kernel/binfmt_ilp32.c
> @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
>  do {									\
>  	set_thread_flag(TIF_32BIT_AARCH64);				\
>  	clear_thread_flag(TIF_32BIT);					\
> +	set_fs(TASK_SIZE_32);						\
>  } while (0)

I don't think we need these two. AFAICT, flush_old_exec() takes care of
setting the USER_DS for the new thread.

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 13:35   ` Catalin Marinas
@ 2016-05-12 13:44     ` Yury Norov
  2016-05-12 14:07       ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-12 13:44 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, heiko.carstens, linux-doc, Nathan_Lynch,
	agraf, klimov.linux, broonie, bamvor.zhangjian, schwab,
	schwidefsky, joseph, christoph.muellner

On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > of vector, and kernel reports successful read/write.
> > 
> > There are 2 problems:
> > 1. How kernel allows such address to be passed to fs subsystem;
> > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > address.
> > 
> > I don't know the answer on 2'nd question, and it might be something
> > generic. But I investigated first problem.
> > 
> > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > validate user address, and on arm64 it ends up with checking buffer
> > end against current_thread_info()->addr_limit.
> > 
> > current_thread_info()->addr_limit for ilp32, and most probably for
> > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > It happens because on thread creation we call flush_old_exec() to set 
> > addr_limit, and completely ignore compat mode there.
> 
> I assume accesses beyond this address would fault anyway but I haven't
> checked the code paths.
> 
> > diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> > index 7a39683..6ba4952 100644
> > --- a/arch/arm64/include/asm/elf.h
> > +++ b/arch/arm64/include/asm/elf.h
> > @@ -146,6 +146,7 @@ typedef struct user_fpsimd_state elf_fpregset_t;
> >  do {						\
> >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> >  	clear_thread_flag(TIF_32BIT);		\
> > +	set_fs(TASK_SIZE_64);			\
> >  } while (0)
> 
> See below.
> 
> > diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
> > index 19cfdc5..3b0dd8d 100644
> > --- a/arch/arm64/include/asm/uaccess.h
> > +++ b/arch/arm64/include/asm/uaccess.h
> > @@ -51,7 +51,7 @@
> >  #define KERNEL_DS	(-1UL)
> >  #define get_ds()	(KERNEL_DS)
> >  
> > -#define USER_DS		TASK_SIZE_64
> > +#define USER_DS		TASK_SIZE
> 
> I agree with this.
> 
> >  #define get_fs()	(current_thread_info()->addr_limit)
> >  
> >  static inline void set_fs(mm_segment_t fs)
> > diff --git a/arch/arm64/kernel/binfmt_elf32.c b/arch/arm64/kernel/binfmt_elf32.c
> > index 5487872..2e8d9f3 100644
> > --- a/arch/arm64/kernel/binfmt_elf32.c
> > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > @@ -12,6 +12,7 @@
> >  do {						\
> >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> >  	set_thread_flag(TIF_32BIT);		\
> > +	set_fs(TASK_SIZE_32);			\
> >  } while (0)
> >  
> >  #define COMPAT_ARCH_DLINFO
> > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > index a934fd4..a8599c6 100644
> > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> >  do {									\
> >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> >  	clear_thread_flag(TIF_32BIT);					\
> > +	set_fs(TASK_SIZE_32);						\
> >  } while (0)
> 
> I don't think we need these two. AFAICT, flush_old_exec() takes care of
> setting the USER_DS for the new thread.

That's true, but USER_DS depends on personality which is not set yet
for new thread, as I wrote above. In fact, I tried correct USER_DS
only, and it doesn't work

> 
> -- 
> Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 13:44     ` Yury Norov
@ 2016-05-12 14:07       ` Catalin Marinas
  2016-05-12 14:20         ` Catalin Marinas
  2016-05-12 14:24         ` Yury Norov
  0 siblings, 2 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-05-12 14:07 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	Nathan_Lynch, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, joseph, schwab,
	schwidefsky, linux-arm-kernel, christoph.muellner

On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > of vector, and kernel reports successful read/write.
> > > 
> > > There are 2 problems:
> > > 1. How kernel allows such address to be passed to fs subsystem;
> > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > address.
> > > 
> > > I don't know the answer on 2'nd question, and it might be something
> > > generic. But I investigated first problem.
> > > 
> > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > validate user address, and on arm64 it ends up with checking buffer
> > > end against current_thread_info()->addr_limit.
> > > 
> > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > It happens because on thread creation we call flush_old_exec() to set 
> > > addr_limit, and completely ignore compat mode there.

[...]

> > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > @@ -12,6 +12,7 @@
> > >  do {						\
> > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > >  	set_thread_flag(TIF_32BIT);		\
> > > +	set_fs(TASK_SIZE_32);			\
> > >  } while (0)
> > >  
> > >  #define COMPAT_ARCH_DLINFO
> > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > index a934fd4..a8599c6 100644
> > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > >  do {									\
> > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > >  	clear_thread_flag(TIF_32BIT);					\
> > > +	set_fs(TASK_SIZE_32);						\
> > >  } while (0)
> > 
> > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > setting the USER_DS for the new thread.
> 
> That's true, but USER_DS depends on personality which is not set yet
> for new thread, as I wrote above. In fact, I tried correct USER_DS
> only, and it doesn't work

Ah, it looks like load_elf_binary() sets the personality after
flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
maximum 64-bit task value, so they should have a similar issue with
native 32-bit vs compat behaviour.

So what exactly is LTP complaining about? Is different error (like
EFAULT vs EINVAL) or not getting an error at all.

(I need to update my LTP, the preadv tests appeared in December last
year)

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 14:07       ` Catalin Marinas
@ 2016-05-12 14:20         ` Catalin Marinas
  2016-05-12 14:34           ` Yury Norov
  2016-05-12 14:24         ` Yury Norov
  1 sibling, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-12 14:20 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, linux-arm-kernel,
	schwab, schwidefsky, joseph, christoph.muellner

On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> > On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > > of vector, and kernel reports successful read/write.
> > > > 
> > > > There are 2 problems:
> > > > 1. How kernel allows such address to be passed to fs subsystem;
> > > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > > address.
> > > > 
> > > > I don't know the answer on 2'nd question, and it might be something
> > > > generic. But I investigated first problem.
> > > > 
> > > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > > validate user address, and on arm64 it ends up with checking buffer
> > > > end against current_thread_info()->addr_limit.
> > > > 
> > > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > > It happens because on thread creation we call flush_old_exec() to set 
> > > > addr_limit, and completely ignore compat mode there.
> 
> [...]
> 
> > > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > > @@ -12,6 +12,7 @@
> > > >  do {						\
> > > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > > >  	set_thread_flag(TIF_32BIT);		\
> > > > +	set_fs(TASK_SIZE_32);			\
> > > >  } while (0)
> > > >  
> > > >  #define COMPAT_ARCH_DLINFO
> > > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > > index a934fd4..a8599c6 100644
> > > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > > >  do {									\
> > > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > > >  	clear_thread_flag(TIF_32BIT);					\
> > > > +	set_fs(TASK_SIZE_32);						\
> > > >  } while (0)
> > > 
> > > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > > setting the USER_DS for the new thread.
> > 
> > That's true, but USER_DS depends on personality which is not set yet
> > for new thread, as I wrote above. In fact, I tried correct USER_DS
> > only, and it doesn't work
> 
> Ah, it looks like load_elf_binary() sets the personality after
> flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> maximum 64-bit task value, so they should have a similar issue with
> native 32-bit vs compat behaviour.

I think we have another problem. flush_old_exec() calls the arm64
flush_thread() where tls_thread_flush() checks for is_compat_task(). So
starting a 32-bit application from a 64-bit one not go on the correct
path.

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 14:07       ` Catalin Marinas
  2016-05-12 14:20         ` Catalin Marinas
@ 2016-05-12 14:24         ` Yury Norov
  2016-05-12 15:28           ` Catalin Marinas
  1 sibling, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-12 14:24 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	Nathan_Lynch, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, joseph, schwab,
	schwidefsky, linux-arm-kernel, christoph.muellner

On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> > On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > > of vector, and kernel reports successful read/write.
> > > > 
> > > > There are 2 problems:
> > > > 1. How kernel allows such address to be passed to fs subsystem;
> > > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > > address.
> > > > 
> > > > I don't know the answer on 2'nd question, and it might be something
> > > > generic. But I investigated first problem.
> > > > 
> > > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > > validate user address, and on arm64 it ends up with checking buffer
> > > > end against current_thread_info()->addr_limit.
> > > > 
> > > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > > It happens because on thread creation we call flush_old_exec() to set 
> > > > addr_limit, and completely ignore compat mode there.
> 
> [...]
> 
> > > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > > @@ -12,6 +12,7 @@
> > > >  do {						\
> > > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > > >  	set_thread_flag(TIF_32BIT);		\
> > > > +	set_fs(TASK_SIZE_32);			\
> > > >  } while (0)
> > > >  
> > > >  #define COMPAT_ARCH_DLINFO
> > > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > > index a934fd4..a8599c6 100644
> > > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > > >  do {									\
> > > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > > >  	clear_thread_flag(TIF_32BIT);					\
> > > > +	set_fs(TASK_SIZE_32);						\
> > > >  } while (0)
> > > 
> > > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > > setting the USER_DS for the new thread.
> > 
> > That's true, but USER_DS depends on personality which is not set yet
> > for new thread, as I wrote above. In fact, I tried correct USER_DS
> > only, and it doesn't work
> 
> Ah, it looks like load_elf_binary() sets the personality after
> flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> maximum 64-bit task value, so they should have a similar issue with
> native 32-bit vs compat behaviour.

Hmmm. If so, it means we'd introduce generic fix. It would be removing 
set_fs() from flush_old_exec() and appending it to load_elf_binary()
after SET_PERSONALITY(). But I think it should be agreed with other
arches developers. I've sent standalone patch for aarch64 (you in CC)
so let's move discussion there.

> So what exactly is LTP complaining about? Is different error (like
> EFAULT vs EINVAL) or not getting an error at all.
 
It should be EINVAL, but it succeed. The other problem is that
following fs routines does not complain on wrong address.

> (I need to update my LTP, the preadv tests appeared in December last
> year)
> 

preadv02 was extended with this testcase in April.

> -- 
> Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 14:20         ` Catalin Marinas
@ 2016-05-12 14:34           ` Yury Norov
  2016-05-12 14:54             ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-12 14:34 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, linux-arm-kernel,
	schwab, schwidefsky, joseph, christoph.muellner

On Thu, May 12, 2016 at 03:20:16PM +0100, Catalin Marinas wrote:
> On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> > On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> > > On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > > > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > > > of vector, and kernel reports successful read/write.
> > > > > 
> > > > > There are 2 problems:
> > > > > 1. How kernel allows such address to be passed to fs subsystem;
> > > > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > > > address.
> > > > > 
> > > > > I don't know the answer on 2'nd question, and it might be something
> > > > > generic. But I investigated first problem.
> > > > > 
> > > > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > > > validate user address, and on arm64 it ends up with checking buffer
> > > > > end against current_thread_info()->addr_limit.
> > > > > 
> > > > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > > > It happens because on thread creation we call flush_old_exec() to set 
> > > > > addr_limit, and completely ignore compat mode there.
> > 
> > [...]
> > 
> > > > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > > > @@ -12,6 +12,7 @@
> > > > >  do {						\
> > > > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > > > >  	set_thread_flag(TIF_32BIT);		\
> > > > > +	set_fs(TASK_SIZE_32);			\
> > > > >  } while (0)
> > > > >  
> > > > >  #define COMPAT_ARCH_DLINFO
> > > > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > index a934fd4..a8599c6 100644
> > > > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > > > >  do {									\
> > > > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > > > >  	clear_thread_flag(TIF_32BIT);					\
> > > > > +	set_fs(TASK_SIZE_32);						\
> > > > >  } while (0)
> > > > 
> > > > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > > > setting the USER_DS for the new thread.
> > > 
> > > That's true, but USER_DS depends on personality which is not set yet
> > > for new thread, as I wrote above. In fact, I tried correct USER_DS
> > > only, and it doesn't work
> > 
> > Ah, it looks like load_elf_binary() sets the personality after
> > flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> > maximum 64-bit task value, so they should have a similar issue with
> > native 32-bit vs compat behaviour.
> 
> I think we have another problem. flush_old_exec() calls the arm64
> flush_thread() where tls_thread_flush() checks for is_compat_task(). So
> starting a 32-bit application from a 64-bit one not go on the correct
> path.

As per now, all native, aarch32 and ilp32 tasks can exec() any
binaries they need. Are you think it's wrong? If so, how we coild run
first compat application (maybe shell), it there are only lp64 tasks
on the system?

> 
> -- 
> Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 14:34           ` Yury Norov
@ 2016-05-12 14:54             ` Catalin Marinas
  2016-05-12 15:27               ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-12 14:54 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	Nathan_Lynch, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, joseph, schwab,
	schwidefsky, linux-arm-kernel, christoph.muellner

On Thu, May 12, 2016 at 05:34:15PM +0300, Yury Norov wrote:
> On Thu, May 12, 2016 at 03:20:16PM +0100, Catalin Marinas wrote:
> > On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> > > On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> > > > On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > > > > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > > > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > > > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > > > > of vector, and kernel reports successful read/write.
> > > > > > 
> > > > > > There are 2 problems:
> > > > > > 1. How kernel allows such address to be passed to fs subsystem;
> > > > > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > > > > address.
> > > > > > 
> > > > > > I don't know the answer on 2'nd question, and it might be something
> > > > > > generic. But I investigated first problem.
> > > > > > 
> > > > > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > > > > validate user address, and on arm64 it ends up with checking buffer
> > > > > > end against current_thread_info()->addr_limit.
> > > > > > 
> > > > > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > > > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > > > > It happens because on thread creation we call flush_old_exec() to set 
> > > > > > addr_limit, and completely ignore compat mode there.
> > > 
> > > [...]
> > > 
> > > > > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > > > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > > > > @@ -12,6 +12,7 @@
> > > > > >  do {						\
> > > > > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > > > > >  	set_thread_flag(TIF_32BIT);		\
> > > > > > +	set_fs(TASK_SIZE_32);			\
> > > > > >  } while (0)
> > > > > >  
> > > > > >  #define COMPAT_ARCH_DLINFO
> > > > > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > > index a934fd4..a8599c6 100644
> > > > > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > > > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > > > > >  do {									\
> > > > > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > > > > >  	clear_thread_flag(TIF_32BIT);					\
> > > > > > +	set_fs(TASK_SIZE_32);						\
> > > > > >  } while (0)
> > > > > 
> > > > > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > > > > setting the USER_DS for the new thread.
> > > > 
> > > > That's true, but USER_DS depends on personality which is not set yet
> > > > for new thread, as I wrote above. In fact, I tried correct USER_DS
> > > > only, and it doesn't work
> > > 
> > > Ah, it looks like load_elf_binary() sets the personality after
> > > flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> > > maximum 64-bit task value, so they should have a similar issue with
> > > native 32-bit vs compat behaviour.
> > 
> > I think we have another problem. flush_old_exec() calls the arm64
> > flush_thread() where tls_thread_flush() checks for is_compat_task(). So
> > starting a 32-bit application from a 64-bit one not go on the correct
> > path.
> 
> As per now, all native, aarch32 and ilp32 tasks can exec() any
> binaries they need.

And that's correct.

> Are you think it's wrong? If so, how we coild run
> first compat application (maybe shell), it there are only lp64 tasks
> on the system?

What I meant is that we rely on flush_old_exec() to initialise the TLS
register for the compat task but it currently depends on what the parent
is. I think tls_thread_flush() should actually drop the is_compat_task()
thread and always initialise all the TLS registers.

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 14:54             ` Catalin Marinas
@ 2016-05-12 15:27               ` Yury Norov
  0 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-12 15:27 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	Nathan_Lynch, linux-doc, heiko.carstens, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, joseph, schwab,
	schwidefsky, linux-arm-kernel, christoph.muellner

On Thu, May 12, 2016 at 03:54:03PM +0100, Catalin Marinas wrote:
> On Thu, May 12, 2016 at 05:34:15PM +0300, Yury Norov wrote:
> > On Thu, May 12, 2016 at 03:20:16PM +0100, Catalin Marinas wrote:
> > > On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> > > > On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> > > > > On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > > > > > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > > > > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > > > > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > > > > > of vector, and kernel reports successful read/write.
> > > > > > > 
> > > > > > > There are 2 problems:
> > > > > > > 1. How kernel allows such address to be passed to fs subsystem;
> > > > > > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > > > > > address.
> > > > > > > 
> > > > > > > I don't know the answer on 2'nd question, and it might be something
> > > > > > > generic. But I investigated first problem.
> > > > > > > 
> > > > > > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > > > > > validate user address, and on arm64 it ends up with checking buffer
> > > > > > > end against current_thread_info()->addr_limit.
> > > > > > > 
> > > > > > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > > > > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > > > > > It happens because on thread creation we call flush_old_exec() to set 
> > > > > > > addr_limit, and completely ignore compat mode there.
> > > > 
> > > > [...]
> > > > 
> > > > > > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > > > > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > > > > > @@ -12,6 +12,7 @@
> > > > > > >  do {						\
> > > > > > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > > > > > >  	set_thread_flag(TIF_32BIT);		\
> > > > > > > +	set_fs(TASK_SIZE_32);			\
> > > > > > >  } while (0)
> > > > > > >  
> > > > > > >  #define COMPAT_ARCH_DLINFO
> > > > > > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > > > index a934fd4..a8599c6 100644
> > > > > > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > > > > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > > > > > >  do {									\
> > > > > > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > > > > > >  	clear_thread_flag(TIF_32BIT);					\
> > > > > > > +	set_fs(TASK_SIZE_32);						\
> > > > > > >  } while (0)
> > > > > > 
> > > > > > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > > > > > setting the USER_DS for the new thread.
> > > > > 
> > > > > That's true, but USER_DS depends on personality which is not set yet
> > > > > for new thread, as I wrote above. In fact, I tried correct USER_DS
> > > > > only, and it doesn't work
> > > > 
> > > > Ah, it looks like load_elf_binary() sets the personality after
> > > > flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> > > > maximum 64-bit task value, so they should have a similar issue with
> > > > native 32-bit vs compat behaviour.
> > > 
> > > I think we have another problem. flush_old_exec() calls the arm64
> > > flush_thread() where tls_thread_flush() checks for is_compat_task(). So
> > > starting a 32-bit application from a 64-bit one not go on the correct
> > > path.
> > 
> > As per now, all native, aarch32 and ilp32 tasks can exec() any
> > binaries they need.
> 
> And that's correct.
> 
> > Are you think it's wrong? If so, how we coild run
> > first compat application (maybe shell), it there are only lp64 tasks
> > on the system?
> 
> What I meant is that we rely on flush_old_exec() to initialise the TLS
> register for the compat task but it currently depends on what the parent
> is. I think tls_thread_flush() should actually drop the is_compat_task()
> thread and always initialise all the TLS registers.
> 

OK. I'll do it in v2.

> -- 
> Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 14:24         ` Yury Norov
@ 2016-05-12 15:28           ` Catalin Marinas
  2016-05-13  8:11             ` Zhangjian (Bamvor)
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-12 15:28 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, linux-kernel, agraf,
	klimov.linux, broonie, bamvor.zhangjian, linux-arm-kernel,
	schwab, schwidefsky, joseph, christoph.muellner

On Thu, May 12, 2016 at 05:24:57PM +0300, Yury Norov wrote:
> On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> > On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> > > On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> > > > On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > > > > I debugged preadv02 and pwritev02 failures and found very weird bug.
> > > > > Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > > > > of vector, and kernel reports successful read/write.
> > > > > 
> > > > > There are 2 problems:
> > > > > 1. How kernel allows such address to be passed to fs subsystem;
> > > > > 2. How fs successes to read/write at non-mapped, and in fact non-user
> > > > > address.
> > > > > 
> > > > > I don't know the answer on 2'nd question, and it might be something
> > > > > generic. But I investigated first problem.
> > > > > 
> > > > > The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> > > > > validate user address, and on arm64 it ends up with checking buffer
> > > > > end against current_thread_info()->addr_limit.
> > > > > 
> > > > > current_thread_info()->addr_limit for ilp32, and most probably for
> > > > > aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> > > > > It happens because on thread creation we call flush_old_exec() to set 
> > > > > addr_limit, and completely ignore compat mode there.
> > 
> > [...]
> > 
> > > > > --- a/arch/arm64/kernel/binfmt_elf32.c
> > > > > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > > > > @@ -12,6 +12,7 @@
> > > > >  do {						\
> > > > >  	clear_thread_flag(TIF_32BIT_AARCH64);	\
> > > > >  	set_thread_flag(TIF_32BIT);		\
> > > > > +	set_fs(TASK_SIZE_32);			\
> > > > >  } while (0)
> > > > >  
> > > > >  #define COMPAT_ARCH_DLINFO
> > > > > diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > index a934fd4..a8599c6 100644
> > > > > --- a/arch/arm64/kernel/binfmt_ilp32.c
> > > > > +++ b/arch/arm64/kernel/binfmt_ilp32.c
> > > > > @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
> > > > >  do {									\
> > > > >  	set_thread_flag(TIF_32BIT_AARCH64);				\
> > > > >  	clear_thread_flag(TIF_32BIT);					\
> > > > > +	set_fs(TASK_SIZE_32);						\
> > > > >  } while (0)
> > > > 
> > > > I don't think we need these two. AFAICT, flush_old_exec() takes care of
> > > > setting the USER_DS for the new thread.
> > > 
> > > That's true, but USER_DS depends on personality which is not set yet
> > > for new thread, as I wrote above. In fact, I tried correct USER_DS
> > > only, and it doesn't work
> > 
> > Ah, it looks like load_elf_binary() sets the personality after
> > flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> > maximum 64-bit task value, so they should have a similar issue with
> > native 32-bit vs compat behaviour.
> 
> Hmmm. If so, it means we'd introduce generic fix. It would be removing 
> set_fs() from flush_old_exec() and appending it to load_elf_binary()
> after SET_PERSONALITY(). But I think it should be agreed with other
> arches developers.

The set_fs() in flush_old_exec() is probably fine, it may be meant to
re-set the USER_DS for the old thread.

It appears that at least powerpc and x86 don't have different USER_DS
setting for native and compat, so moving the set_fs() call further down
would not make any difference for them, nor will it fix the preadv02 LTP
test (if it fails for them, I haven't checked).

> I've sent standalone patch for aarch64 (you in CC) so let's move
> discussion there.

I've seen the patch but we would lose some discussion history here. I
think we should continue this thread and just summarise the conclusion
in reply to the other patch. This thread is also available on
linux-arch, in case other architecture maintainers follow it.

> > So what exactly is LTP complaining about? Is different error (like
> > EFAULT vs EINVAL) or not getting an error at all.
>  
> It should be EINVAL, but it succeed. The other problem is that
> following fs routines does not complain on wrong address.

I see. The test asks the kernel to write a single byte (out of maximum
64) to the user address 0xffffffff. In the absence of the access_ok()
check, this operation succeeds. If the preadv syscall gets 2 bytes as
the count, then it would fail with EFAULT.

While it's not really a bug, I agree that for matching the native 32-bit
behavior (basically for other syscalls like those involving vfs_read()),
the simplest fix would be to have a dynamic USER_DS.

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-12 15:28           ` Catalin Marinas
@ 2016-05-13  8:11             ` Zhangjian (Bamvor)
  2016-05-13  9:28               ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Zhangjian (Bamvor) @ 2016-05-13  8:11 UTC (permalink / raw)
  To: Catalin Marinas, Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	heiko.carstens, linux-doc, Nathan_Lynch, linux-kernel, agraf,
	klimov.linux, broonie, linux-arm-kernel, schwab, schwidefsky,
	joseph, christoph.muellner, Zhangjian (Bamvor),
	Kefeng Wang

Hi,

On 2016/5/12 23:28, Catalin Marinas wrote:
> On Thu, May 12, 2016 at 05:24:57PM +0300, Yury Norov wrote:
>> On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
>>> On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
>>>> On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
>>>>> On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
>>>>>> I debugged preadv02 and pwritev02 failures and found very weird bug.
>>>>>> Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
>>>>>> of vector, and kernel reports successful read/write.
>>>>>>
>>>>>> There are 2 problems:
>>>>>> 1. How kernel allows such address to be passed to fs subsystem;
>>>>>> 2. How fs successes to read/write at non-mapped, and in fact non-user
>>>>>> address.
>>>>>>
>>>>>> I don't know the answer on 2'nd question, and it might be something
>>>>>> generic. But I investigated first problem.
>>>>>>
>>>>>> The problem is that compat_rw_copy_check_uvector() uses access_ok() to
>>>>>> validate user address, and on arm64 it ends up with checking buffer
>>>>>> end against current_thread_info()->addr_limit.
>>>>>>
>>>>>> current_thread_info()->addr_limit for ilp32, and most probably for
>>>>>> aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
>>>>>> It happens because on thread creation we call flush_old_exec() to set
>>>>>> addr_limit, and completely ignore compat mode there.
>>>
>>> [...]
>>>
>>>>>> --- a/arch/arm64/kernel/binfmt_elf32.c
>>>>>> +++ b/arch/arm64/kernel/binfmt_elf32.c
>>>>>> @@ -12,6 +12,7 @@
>>>>>>   do {						\
>>>>>>   	clear_thread_flag(TIF_32BIT_AARCH64);	\
>>>>>>   	set_thread_flag(TIF_32BIT);		\
>>>>>> +	set_fs(TASK_SIZE_32);			\
>>>>>>   } while (0)
>>>>>>
>>>>>>   #define COMPAT_ARCH_DLINFO
>>>>>> diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
>>>>>> index a934fd4..a8599c6 100644
>>>>>> --- a/arch/arm64/kernel/binfmt_ilp32.c
>>>>>> +++ b/arch/arm64/kernel/binfmt_ilp32.c
>>>>>> @@ -59,6 +59,7 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
>>>>>>   do {									\
>>>>>>   	set_thread_flag(TIF_32BIT_AARCH64);				\
>>>>>>   	clear_thread_flag(TIF_32BIT);					\
>>>>>> +	set_fs(TASK_SIZE_32);						\
>>>>>>   } while (0)
>>>>>
>>>>> I don't think we need these two. AFAICT, flush_old_exec() takes care of
>>>>> setting the USER_DS for the new thread.
>>>>
>>>> That's true, but USER_DS depends on personality which is not set yet
>>>> for new thread, as I wrote above. In fact, I tried correct USER_DS
>>>> only, and it doesn't work
>>>
>>> Ah, it looks like load_elf_binary() sets the personality after
>>> flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
>>> maximum 64-bit task value, so they should have a similar issue with
>>> native 32-bit vs compat behaviour.
>>
>> Hmmm. If so, it means we'd introduce generic fix. It would be removing
>> set_fs() from flush_old_exec() and appending it to load_elf_binary()
>> after SET_PERSONALITY(). But I think it should be agreed with other
>> arches developers.
>
> The set_fs() in flush_old_exec() is probably fine, it may be meant to
> re-set the USER_DS for the old thread.
>
> It appears that at least powerpc and x86 don't have different USER_DS
> setting for native and compat, so moving the set_fs() call further down
> would not make any difference for them, nor will it fix the preadv02 LTP
> test (if it fails for them, I haven't checked).
>
>> I've sent standalone patch for aarch64 (you in CC) so let's move
>> discussion there.
>
> I've seen the patch but we would lose some discussion history here. I
> think we should continue this thread and just summarise the conclusion
> in reply to the other patch. This thread is also available on
> linux-arch, in case other architecture maintainers follow it.
>
>>> So what exactly is LTP complaining about? Is different error (like
>>> EFAULT vs EINVAL) or not getting an error at all.
>>
>> It should be EINVAL, but it succeed. The other problem is that
>> following fs routines does not complain on wrong address.
>
> I see. The test asks the kernel to write a single byte (out of maximum
> 64) to the user address 0xffffffff.
What address We should set for this limitation, TASK_SIZE or STACK_TOP?
It is same for 64bit application. But STACK_TOP(0xffff0000) is below
TASK_SIZE in 32bit application. The address above STACK_TOP is preserved
for 32bit application.

Regards

Bamvor

 > In the absence of the access_ok()
> check, this operation succeeds. If the preadv syscall gets 2 bytes as
> the count, then it would fail with EFAULT.
>
> While it's not really a bug, I agree that for matching the native 32-bit
> behavior (basically for other syscalls like those involving vfs_read()),
> the simplest fix would be to have a dynamic USER_DS.



>

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-13  8:11             ` Zhangjian (Bamvor)
@ 2016-05-13  9:28               ` Catalin Marinas
  2016-05-13 10:51                 ` Yury Norov
  2016-05-13 13:32                 ` Catalin Marinas
  0 siblings, 2 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-05-13  9:28 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Yury Norov, linux-arch, linux-s390, Kefeng Wang, arnd, pinskia,
	Prasun.Kapoor, Nathan_Lynch, linux-doc, heiko.carstens,
	linux-kernel, agraf, klimov.linux, broonie, joseph, schwab,
	schwidefsky, linux-arm-kernel, christoph.muellner

On Fri, May 13, 2016 at 04:11:23PM +0800, Zhangjian (Bamvor) wrote:
> On 2016/5/12 23:28, Catalin Marinas wrote:
> >On Thu, May 12, 2016 at 05:24:57PM +0300, Yury Norov wrote:
> >>On Thu, May 12, 2016 at 03:07:35PM +0100, Catalin Marinas wrote:
> >>>On Thu, May 12, 2016 at 04:44:31PM +0300, Yury Norov wrote:
> >>>>On Thu, May 12, 2016 at 02:35:34PM +0100, Catalin Marinas wrote:
> >>>>>On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> >>>>>>I debugged preadv02 and pwritev02 failures and found very weird bug.
> >>>>>>Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> >>>>>>of vector, and kernel reports successful read/write.
> >>>>>>
> >>>>>>There are 2 problems:
> >>>>>>1. How kernel allows such address to be passed to fs subsystem;
> >>>>>>2. How fs successes to read/write at non-mapped, and in fact non-user
> >>>>>>address.
> >>>>>>
> >>>>>>I don't know the answer on 2'nd question, and it might be something
> >>>>>>generic. But I investigated first problem.
> >>>>>>
> >>>>>>The problem is that compat_rw_copy_check_uvector() uses access_ok() to
> >>>>>>validate user address, and on arm64 it ends up with checking buffer
> >>>>>>end against current_thread_info()->addr_limit.
> >>>>>>
> >>>>>>current_thread_info()->addr_limit for ilp32, and most probably for
> >>>>>>aarch32 is equal to aarch64 one, and so adress_ok() doesn't fail.
> >>>>>>It happens because on thread creation we call flush_old_exec() to set
> >>>>>>addr_limit, and completely ignore compat mode there.
[...]
> >>>>That's true, but USER_DS depends on personality which is not set yet
> >>>>for new thread, as I wrote above. In fact, I tried correct USER_DS
> >>>>only, and it doesn't work
> >>>
> >>>Ah, it looks like load_elf_binary() sets the personality after
> >>>flush_old_exec(). Looking at powerpc and x86, they set USER_DS to the
> >>>maximum 64-bit task value, so they should have a similar issue with
> >>>native 32-bit vs compat behaviour.
[...]
> >>>So what exactly is LTP complaining about? Is different error (like
> >>>EFAULT vs EINVAL) or not getting an error at all.
> >>
> >>It should be EINVAL, but it succeed. The other problem is that
> >>following fs routines does not complain on wrong address.
> >
> >I see. The test asks the kernel to write a single byte (out of maximum
> >64) to the user address 0xffffffff.
> 
> What address We should set for this limitation, TASK_SIZE or STACK_TOP?
> It is same for 64bit application. But STACK_TOP(0xffff0000) is below
> TASK_SIZE in 32bit application. The address above STACK_TOP is preserved
> for 32bit application.

The discussion is mainly around whether USER_DS for 32-bit compat apps
should be the same as USER_DS for native 32-bit apps. Even for native
32-bit kernels, we don't use STACK_TOP as addr_limit. A read/write from
0xffffffff would fail in both cases anyway. I think the LTP test doesn't
even try to access such memory but only to probe the range validity (I
haven't managed to build the latest LTP yet).

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-13  9:28               ` Catalin Marinas
@ 2016-05-13 10:51                 ` Yury Norov
  2016-05-13 11:03                   ` Catalin Marinas
  2016-05-13 13:32                 ` Catalin Marinas
  1 sibling, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-13 10:51 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Zhangjian (Bamvor),
	linux-arch, linux-s390, Kefeng Wang, arnd, pinskia,
	Prasun.Kapoor, heiko.carstens, broonie, linux-doc, Nathan_Lynch,
	linux-kernel, agraf, klimov.linux, linux-arm-kernel, schwab,
	schwidefsky, joseph, christoph.muellner

On Fri, May 13, 2016 at 09:28:03AM +0000, Catalin Marinas wrote:
> 
> The discussion is mainly around whether USER_DS for 32-bit compat apps
> should be the same as USER_DS for native 32-bit apps. Even for native
> 32-bit kernels, we don't use STACK_TOP as addr_limit. A read/write from
> 0xffffffff would fail in both cases anyway. I think the LTP test doesn't
> even try to access such memory but only to probe the range validity (I
> haven't managed to build the latest LTP yet).

This fix lets me build it (on top of 7b3ef3b0b)
Of course, it's not 'official'. :)

---
 testcases/kernel/syscalls/fstatat/fstatat01.c  | 1 +
 testcases/kernel/syscalls/preadv/preadv.h      | 1 +
 testcases/kernel/syscalls/pwritev/pwritev.h    | 1 +
 testcases/kernel/syscalls/request_key/Makefile | 2 +-
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/testcases/kernel/syscalls/fstatat/fstatat01.c b/testcases/kernel/syscalls/fstatat/fstatat01.c
index 128f6dd..6e23c9e 100644
--- a/testcases/kernel/syscalls/fstatat/fstatat01.c
+++ b/testcases/kernel/syscalls/fstatat/fstatat01.c
@@ -59,6 +59,7 @@ static const char *filenames[TEST_CASES];
 static const int expected_errno[] = { 0, 0, ENOTDIR, EBADF, EINVAL, 0 };
 static const int flags[] = { 0, 0, 0, 0, 9999, 0 };
 
+#define HAVE_FSTATAT
 #if !defined(HAVE_FSTATAT)
 #if (__NR_fstatat64 > 0)
 int fstatat(int dirfd, const char *filename, struct stat64 *statbuf, int flags)
diff --git a/testcases/kernel/syscalls/preadv/preadv.h b/testcases/kernel/syscalls/preadv/preadv.h
index f3ac30d..b001389 100644
--- a/testcases/kernel/syscalls/preadv/preadv.h
+++ b/testcases/kernel/syscalls/preadv/preadv.h
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "linux_syscall_numbers.h"
 
+#define HAVE_PREADV
 #if !defined(HAVE_PREADV)
 int preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
diff --git a/testcases/kernel/syscalls/pwritev/pwritev.h b/testcases/kernel/syscalls/pwritev/pwritev.h
index ae9d999..2a4d188 100644
--- a/testcases/kernel/syscalls/pwritev/pwritev.h
+++ b/testcases/kernel/syscalls/pwritev/pwritev.h
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "linux_syscall_numbers.h"
 
+#define HAVE_PWRITEV
 #if !defined(HAVE_PWRITEV)
 int pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
 {
diff --git a/testcases/kernel/syscalls/request_key/Makefile b/testcases/kernel/syscalls/request_key/Makefile
index 9add429..2e8a37c 100644
--- a/testcases/kernel/syscalls/request_key/Makefile
+++ b/testcases/kernel/syscalls/request_key/Makefile
@@ -19,6 +19,6 @@ top_srcdir		?= ../../../..
 
 include $(top_srcdir)/include/mk/testcases.mk
 
-LDLIBS		+= $(KEYUTILS_LIBS)
+LDLIBS		+= $(lkeyutils)
 
 include $(top_srcdir)/include/mk/generic_leaf_target.mk
-- 
2.5.0


> 
> -- 
> Catalin
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-13 10:51                 ` Yury Norov
@ 2016-05-13 11:03                   ` Catalin Marinas
  0 siblings, 0 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-05-13 11:03 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, Kefeng Wang, arnd, pinskia,
	Prasun.Kapoor, Nathan_Lynch, linux-doc, heiko.carstens,
	linux-kernel, agraf, klimov.linux, broonie, Zhangjian (Bamvor),
	joseph, schwab, schwidefsky, linux-arm-kernel,
	christoph.muellner

On Fri, May 13, 2016 at 01:51:15PM +0300, Yury Norov wrote:
> On Fri, May 13, 2016 at 09:28:03AM +0000, Catalin Marinas wrote:
> > The discussion is mainly around whether USER_DS for 32-bit compat apps
> > should be the same as USER_DS for native 32-bit apps. Even for native
> > 32-bit kernels, we don't use STACK_TOP as addr_limit. A read/write from
> > 0xffffffff would fail in both cases anyway. I think the LTP test doesn't
> > even try to access such memory but only to probe the range validity (I
> > haven't managed to build the latest LTP yet).
> 
> This fix lets me build it (on top of 7b3ef3b0b)
> Of course, it's not 'official'. :)
[...]
> --- a/testcases/kernel/syscalls/fstatat/fstatat01.c
> +++ b/testcases/kernel/syscalls/fstatat/fstatat01.c
> @@ -59,6 +59,7 @@ static const char *filenames[TEST_CASES];
>  static const int expected_errno[] = { 0, 0, ENOTDIR, EBADF, EINVAL, 0 };
>  static const int flags[] = { 0, 0, 0, 0, 9999, 0 };
>  
> +#define HAVE_FSTATAT
>  #if !defined(HAVE_FSTATAT)
>  #if (__NR_fstatat64 > 0)
>  int fstatat(int dirfd, const char *filename, struct stat64 *statbuf, int flags)
> diff --git a/testcases/kernel/syscalls/preadv/preadv.h b/testcases/kernel/syscalls/preadv/preadv.h
> index f3ac30d..b001389 100644
> --- a/testcases/kernel/syscalls/preadv/preadv.h
> +++ b/testcases/kernel/syscalls/preadv/preadv.h
> @@ -21,6 +21,7 @@
>  #include "config.h"
>  #include "linux_syscall_numbers.h"
>  
> +#define HAVE_PREADV
>  #if !defined(HAVE_PREADV)
>  int preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
>  {
> diff --git a/testcases/kernel/syscalls/pwritev/pwritev.h b/testcases/kernel/syscalls/pwritev/pwritev.h
> index ae9d999..2a4d188 100644
> --- a/testcases/kernel/syscalls/pwritev/pwritev.h
> +++ b/testcases/kernel/syscalls/pwritev/pwritev.h
> @@ -21,6 +21,7 @@
>  #include "config.h"
>  #include "linux_syscall_numbers.h"
>  
> +#define HAVE_PWRITEV
>  #if !defined(HAVE_PWRITEV)
>  int pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
>  {

I didn't need any of these defines as they are automatically generated
in include/config.h for AArch32. However, I need to run autoreconf to
generate the configure script prior to building (archlinuxarm
filesystem)

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-13  9:28               ` Catalin Marinas
  2016-05-13 10:51                 ` Yury Norov
@ 2016-05-13 13:32                 ` Catalin Marinas
  1 sibling, 0 replies; 135+ messages in thread
From: Catalin Marinas @ 2016-05-13 13:32 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: linux-arch, linux-s390, Kefeng Wang, arnd, pinskia,
	Prasun.Kapoor, heiko.carstens, broonie, linux-doc, Nathan_Lynch,
	linux-kernel, agraf, klimov.linux, Yury Norov, linux-arm-kernel,
	schwab, schwidefsky, joseph, christoph.muellner

On Fri, May 13, 2016 at 09:28:03AM +0000, Catalin Marinas wrote:
> > >>>>>On Thu, May 12, 2016 at 03:20:00AM +0300, Yury Norov wrote:
> > >>>>>>I debugged preadv02 and pwritev02 failures and found very weird bug.
> > >>>>>>Test passes {iovec_base = 0xffffffff, iovec_len = 64} as one element
> > >>>>>>of vector, and kernel reports successful read/write.
[...]
> The discussion is mainly around whether USER_DS for 32-bit compat apps
> should be the same as USER_DS for native 32-bit apps. Even for native
> 32-bit kernels, we don't use STACK_TOP as addr_limit. A read/write from
> 0xffffffff would fail in both cases anyway. I think the LTP test doesn't
> even try to access such memory but only to probe the range validity (I
> haven't managed to build the latest LTP yet).

OK, so I managed to get the latest LTP (tag 20160510) built for AArch32
but the preadv02 does not fail:

-----------------------------
# uname -m
aarch64

# file ./testcases/bin/preadv02
./testcases/bin/preadv02: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=98066291426e1d3ee49d8504ce2a5bd721ab7fe8, not stripped

# ./testcases/bin/preadv02
preadv02.c:97: PASS: preadv() failed as expected: EINVAL
preadv02.c:97: PASS: preadv() failed as expected: EINVAL
preadv02.c:97: PASS: preadv() failed as expected: EINVAL
preadv02.c:97: PASS: preadv() failed as expected: EFAULT
preadv02.c:97: PASS: preadv() failed as expected: EBADF
preadv02.c:97: PASS: preadv() failed as expected: EBADF
preadv02.c:97: PASS: preadv() failed as expected: EISDIR
preadv02.c:97: PASS: preadv() failed as expected: ESPIPE

Summary:
passed   8
failed   0
skipped  0
warnings 0
-----------------------------

It's the 4th test above which passes iovec_base as -1 and expects
EFAULT. However, it seems to get the expected error. I guess that even
if access_ok() passes, the access to that location by the kernel would
fail since there isn't anything mapped.

With ILP32, however, STACK_TOP is TASK_SIZE and you may have the address
mapped already. I still think the USER_DS fix is useful, though I need
another way to check that it's actually a fix.

-- 
Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-12 13:19                                     ` Yury Norov
@ 2016-05-14 12:49                                       ` Yury Norov
  0 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-14 12:49 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Zhangjian (Bamvor),
	Catalin Marinas, linux-doc, Andrew Pinski, heiko.carstens,
	Hanjun Guo, joseph, linux-arch, linux-s390, jijun (D),
	Prasun.Kapoor, schwab, agraf, pinskia, klimov.linux, broonie,
	linux-arm-kernel, Nathan_Lynch, linux-kernel, Andrew Pinski,
	schwidefsky, christoph.muellner, jan.dakinevich

On Thu, May 12, 2016 at 04:19:48PM +0300, Yury Norov wrote:

[...]

> > I think that's a good idea. The function used to be slightly different
> > for each architecture, but now it seems we have a significant number
> > of identical implementations that we could just merge them together
> > into one.
> > 
> > sys_mmap_pgoff was originally introduced as the common implementation
> > and it reduced the amount of duplication a lot, but as its units
> > are based on PAGE_SIZE rather than hardwired 4096 bytes, it's
> > not as useful.
> > 
> 
> microblaze and mips (twice) are doing like this. And aarh32 as well,
> in arch/arm64/kernel/entry32.S
> 
> In previous submissions it was a patch that shares aarch32 code to
> ilp32. If we decided turn around again, I think, we'd pick up that patch.
> 
> The other option is to make this hack generic, as so many arches use it.

Hi again,

I picked up that old patch from Jan, and found that it doesn't delouse
addr and length, which is wrong for ilp32. So now I think we'd pick
Bamvor version.

Jan's patch (rebased) is attached for reference.

Yury.


>From 02ad258662c40d457ac041634e67e1cbdbb800f3 Mon Sep 17 00:00:00 2001
From: Jan Dakinevich <jan.dakinevich@gmail.com>
Date: Tue, 3 Nov 2015 02:30:41 +0300
Subject: ilp32: common 32-bit wrappers

Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 9dfdf86..2319042 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -30,6 +30,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
 arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
+arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
diff --git a/arch/arm64/kernel/entry32-common.S b/arch/arm64/kernel/entry32-common.S
new file mode 100644
index 0000000..1a0abe3
--- /dev/null
+++ b/arch/arm64/kernel/entry32-common.S
@@ -0,0 +1,23 @@
+#include <linux/linkage.h>
+#include <linux/const.h>
+
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/errno.h>
+#include <asm/page.h>
+
+/*
+ * Note: off_4k (w5) is always in units of 4K. If we can't do the
+ * requested offset because it is not page-aligned, we return -EINVAL.
+ */
+ENTRY(compat_sys_mmap2_wrapper)
+#if PAGE_SHIFT > 12
+	tst	w5, #~PAGE_MASK >> 12
+	b.ne	1f
+	lsr	w5, w5, #PAGE_SHIFT - 12
+#endif
+	b	sys_mmap_pgoff
+1:	mov	x0, #-EINVAL
+	ret
+ENDPROC(compat_sys_mmap2_wrapper)
+
diff --git a/arch/arm64/kernel/entry32.S b/arch/arm64/kernel/entry32.S
index f332d5d..58cb5b0 100644
--- a/arch/arm64/kernel/entry32.S
+++ b/arch/arm64/kernel/entry32.S
@@ -55,21 +55,6 @@ ENTRY(compat_sys_fstatfs64_wrapper)
 ENDPROC(compat_sys_fstatfs64_wrapper)
 
 /*
- * Note: off_4k (w5) is always in units of 4K. If we can't do the
- * requested offset because it is not page-aligned, we return -EINVAL.
- */
-ENTRY(compat_sys_mmap2_wrapper)
-#if PAGE_SHIFT > 12
-	tst	w5, #~PAGE_MASK >> 12
-	b.ne	1f
-	lsr	w5, w5, #PAGE_SHIFT - 12
-#endif
-	b	sys_mmap_pgoff
-1:	mov	x0, #-EINVAL
-	ret
-ENDPROC(compat_sys_mmap2_wrapper)
-
-/*
  * Wrappers for AArch32 syscalls that either take 64-bit parameters
  * in registers or that take 32-bit parameters which require sign
  * extension.

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
                     ` (2 preceding siblings ...)
  2016-05-06 12:16   ` Zhangjian (Bamvor)
@ 2016-05-14 15:03   ` Yury Norov
  2016-05-16 17:06     ` Catalin Marinas
  3 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-14 15:03 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: schwidefsky, heiko.carstens, pinskia, Prasun.Kapoor, schwab,
	Nathan_Lynch, agraf, klimov.linux, broonie, joseph,
	christoph.muellner, bamvor.zhangjian, linux-doc, linux-arch,
	linux-s390, Andrew Pinski, Andrew Pinski

So, after all discussions, this patch is looking like this.

Changes:
 - assembler part reworked to be more clear, as Catalin recommended;
 - mmap now points to mmap2, as in 1st versions (suggested by Bamvor),
   and ilp32 wrapper delouses required arguments;
 - pread64 and pwrite64 wrappers introduced to delouse args as well;
 - removed unneeded #undefs;

Did I miss something?

diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 2971dea..5ea18ef 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,9 +13,18 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+
+#ifdef CONFIG_COMPAT
+#define __ARCH_WANT_COMPAT_STAT64
+#endif
+
+#ifdef CONFIG_ARM64_ILP32
+#define __ARCH_WANT_COMPAT_SYS_PREADV64
+#define __ARCH_WANT_COMPAT_SYS_PWRITEV64
+#endif
+
 #ifdef CONFIG_AARCH32_EL0
 #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
-#define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 9dfdf86..7aa65ea 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,7 +28,7 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
-arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_ARM64_MODULE_PLTS)	+= module-plts.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index cf4d1ae..0f651bc 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -500,6 +500,7 @@ el0_svc_compat:
 	 * AArch32 syscall handling
 	 */
 	adrp	stbl, compat_sys_call_table	// load compat syscall table pointer
+	ldr     x16, [tsk, #TI_FLAGS]
 	uxtw	scno, w7			// syscall number in w7 (r7)
 	mov     sc_nr, #__NR_compat_syscalls
 	b	el0_svc_naked
@@ -716,15 +717,20 @@ ENDPROC(ret_from_fork)
 	.align	6
 el0_svc:
 	adrp	stbl, sys_call_table		// load syscall table pointer
+	ldr	x16, [tsk, #TI_FLAGS]
 	uxtw	scno, w8			// syscall number in w8
 	mov	sc_nr, #__NR_syscalls
+#ifdef CONFIG_ARM64_ILP32
+	adrp	x17, sys_call_ilp32_table	// load ilp32 syscall table pointer
+	tst	x16, #_TIF_32BIT_AARCH64
+	csel    stbl, stbl, x17, eq		// We are using ILP32
+#endif
 el0_svc_naked:					// compat entry point
 	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
 	enable_dbg_and_irq
 	ct_user_exit 1
 
-	ldr	x16, [tsk, #TI_FLAGS]		// check for syscall hooks
-	tst	x16, #_TIF_SYSCALL_WORK
+	tst	x16, #_TIF_SYSCALL_WORK		// check for syscall hooks
 	b.ne	__sys_trace
 	cmp     scno, sc_nr                     // check upper syscall limit
 	b.hs	ni_sys
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
new file mode 100644
index 0000000..64db612
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,84 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2016 Cavium Inc.
+ * Author: Andrew Pinski <apinski@cavium.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define __SYSCALL_COMPAT
+
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/msg.h>
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+#include <asm-generic/syscalls.h>
+
+/* Using non-compat syscalls where necessary */
+#define compat_sys_fadvise64_64        sys_fadvise64_64
+#define compat_sys_fallocate           sys_fallocate
+#define compat_sys_ftruncate64         sys_ftruncate
+#define compat_sys_lookup_dcookie      sys_lookup_dcookie
+#define compat_sys_readahead           sys_readahead
+#define compat_sys_shmat               sys_shmat
+#define compat_sys_sync_file_range     sys_sync_file_range
+#define compat_sys_truncate64          sys_truncate
+#define sys_llseek                     sys_lseek
+
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
+       unsigned long, prot, unsigned long, flags, unsigned long, fd,
+       unsigned long, pgoff)
+{
+       if (pgoff & (~PAGE_MASK >> 12))
+               return -EINVAL;
+
+       return sys_mmap_pgoff((compat_uptr_t) addr, (compat_size_t) len,
+		       (int) prot, (int) flags, (int) fd,
+		       pgoff >> (PAGE_SHIFT-12));
+}
+
+COMPAT_SYSCALL_DEFINE4(pread64, unsigned int, fd, compat_uptr_t __user *, ubuf,
+		       compat_size_t, count, off_t, offset)
+{
+	return sys_pread64(fd, (char *) ubuf, count, offset);
+}
+
+COMPAT_SYSCALL_DEFINE4(pwrite64, unsigned int, fd, compat_uptr_t __user *, ubuf,
+		       compat_size_t, count, off_t, offset)
+{
+	return sys_pwrite64(fd, (char *) ubuf, count, offset);
+}
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#undef __SC_WRAP
+
+#define __SYSCALL(nr, sym)	[nr] = sym,
+#define __SC_WRAP(nr, sym)	[nr] = compat_##sym,
+
+/*
+ * The sys_call_ilp32_table array must be 4K aligned to be accessible from
+ * kernel/entry.S.
+ */
+void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = {
+	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-14 15:03   ` Yury Norov
@ 2016-05-16 17:06     ` Catalin Marinas
  2016-05-17 19:05       ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-16 17:06 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, heiko.carstens, linux-doc, Nathan_Lynch,
	agraf, klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwab, schwidefsky, joseph, christoph.muellner

On Sat, May 14, 2016 at 06:03:52PM +0300, Yury Norov wrote:
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> +       unsigned long, prot, unsigned long, flags, unsigned long, fd,
> +       unsigned long, pgoff)

To avoid the types confusion we could add __SC_WRAP to mmap2 in unistd.h
and use COMPAT_SYSCALL_DEFINE6 here (together with compat_ptr_t etc.).

> +{
> +       if (pgoff & (~PAGE_MASK >> 12))
> +               return -EINVAL;
> +
> +       return sys_mmap_pgoff((compat_uptr_t) addr, (compat_size_t) len,
> +		       (int) prot, (int) flags, (int) fd,
> +		       pgoff >> (PAGE_SHIFT-12));

Then we wouldn't need the explicit casting here.

> +}
> +
> +COMPAT_SYSCALL_DEFINE4(pread64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> +		       compat_size_t, count, off_t, offset)
> +{
> +	return sys_pread64(fd, (char *) ubuf, count, offset);
> +}
> +
> +COMPAT_SYSCALL_DEFINE4(pwrite64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> +		       compat_size_t, count, off_t, offset)
> +{
> +	return sys_pwrite64(fd, (char *) ubuf, count, offset);

Nitpick: no space between cast type and variable name: (char *)ubuf, ...

We can also make these functions static as they are not used outside
this file.

-- 
Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
                   ` (27 preceding siblings ...)
  2016-05-12  0:20 ` Yury Norov
@ 2016-05-17 12:10 ` Szabolcs Nagy
  2016-05-17 15:37   ` Arnd Bergmann
  2016-05-17 15:40   ` Joseph Myers
  28 siblings, 2 replies; 135+ messages in thread
From: Szabolcs Nagy @ 2016-05-17 12:10 UTC (permalink / raw)
  To: Yury Norov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: nd, linux-arch, linux-s390, pinskia, Prasun.Kapoor, schwab,
	broonie, linux-doc, heiko.carstens, agraf, klimov.linux,
	bamvor.zhangjian, schwidefsky, Nathan_Lynch, joseph,
	christoph.muellner, GNU C Library

On 05/04/16 23:08, Yury Norov wrote:
> This version is rebased on kernel v4.6-rc2, and has fixes in signal subsystem.
> It works with updated glibc [1] (though very draft), and tested with LTP.
> 
> It was tested on QEMU and ThunderX machines. No major difference found.
> This is RFC because ILP32 is not tested in big-endian mode.
> 
>  v3: https://lkml.org/lkml/2014/9/3/704
>  v4: https://lkml.org/lkml/2015/4/13/691
>  v5: https://lkml.org/lkml/2015/9/29/911
> 
>  v6:
>  - time_t, __kenel_off_t and other types turned to be 32-bit
>    for compatibility reasons (after v5 discussion);

i added libc-alpha to cc, the thread is at
https://lkml.org/lkml/2016/4/5/872
or http://thread.gmane.org/gmane.linux.kernel.cross-arch/31449

the kernel position seems to be that the aarch64 ilp32 syscall abi
will follow regular 32bit abis (apart from signal context and ptrace
related things and syscalls will take 64bit arguments).

i think the reasoning is that this allows legacy (non-64bit-safe)
software to use this abi on aarch64 without trouble.

i think this design should be ok for glibc.

there are some interop issues between processes following different abis
(e.g. shared mutexes, abi specific file formats, lib paths,..) which apply,
but i assume it is no different from existing 32bit vs 64bit issues.

the 32bit time_t and off_t are ugly and i wonder if 32bit __kernel_off_t
is really necessary. (i don't see where that is changed: it is supposed
to be __kernel_long_t which is 64bit).

i think even legacy software should be able to deal with 64bit off_t,
so we could avoid having two sets of filesystem apis or is 64bit-only
off_t more work to do in linux/glibc?

>  - related changes applied to ILP32 syscall table and handlers;
>  - ILP32 VDSO code excluded. It's not mandatory, and caused questions
>    during review process. We definitely make sure we will follow up
>    with a VDSO later on because it is needed for performance reasons;
>  - fixed build issues with different combinations of AARCH32 / ILP32
>    enabling in config;
>  - ILP32 TLS bug fixed;
>  - entry32-common.S introduced to hold wrappers needed for both ILP32
>    and AARCH32_EL0;
>  - documentation updated according to latest changes;
>  - rebased to the current head;
>  - coding style re-checked;
>  - ILP32 syscall table turned around.
> 
>    rfc3:
>  - all structures and system calls are just like AARCH32 ones now. with 2
>    exceptions: syscalls that take 64-bit parameter in 2 32-bit regosters
>    are replaced with LP64 version; struct rt_sigframe is constructed both
>    from LP64 and AARCH32 fields to be consistent with AARCH64 register set;
>  - documentation rewritten accordingly;
>  - common code for all 3 ABIs is moved to separated files for easy use,
>    new headers and objects are introduced, incl: is_compat.h, thread_bits.h,
>    signal_common.h, signal32_common.h.
>  - ILP32 VDSO code restored, Nathans comments are addressed;
>  - patch "arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl" removed, as
>    Arnd suggested general solution for IPC_64 problem.
> 
>    rfc4:
>  - sys_ilp32.c syscall list is fixed according to comments;
>  - binfmt_elf32.c and binfmt_ilp32.c are introduced to host the code handling
>    corresponding formats;
>  - statfs64, fstsatfs64 and mmap wrappers are removed;
>  - rebased on v4.4-rc8 + http://www.spinics.net/lists/kernel/msg2151759.html
> 
>  rfc5:
>  - addressed rfc4 comments;
>  - turned s390 compat wrappers to be generic and applied it to arm64/ilp32.
>    Heiko Carsten and Martin Schwidefsky added to CC as s390 maintainers.
> 
>  rfc6:
>  - glibc follows new ABI, [1];
>  - significant rework for signal subsystem (patches 21, 23) - struct ucontext
>    is now corresponds user representation;
>  - compat wrappers and 32-bit off_t patchsets are joined with this patchset,
>    as for now ilp32 is the only user for them;
>  - moved to kernel v4.6-rc2;
>  - few minor bugfixes.
> 
> [1] https://github.com/norov/glibc/tree/new-api
> 
> Andrew Pinski (7):
>   arm64: ensure the kernel is compiled for LP64
>   arm64: rename COMPAT to AARCH32_EL0 in Kconfig
>   arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
>     instead
>   arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
>   arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
>     it
>   arm64: ilp32: introduce ilp32-specific handlers for sigframe and
>     ucontext
>   arm64:ilp32: add ARM64_ILP32 to Kconfig
> 
> Bamvor Jian Zhang (1):
>   arm64: compat: change config dependences to aarch32
> 
> Philipp Tomsich (1):
>   arm64:ilp32: add vdso-ilp32 and use for signal return
> 
> Yury Norov (16):
>   all: syscall wrappers: add documentation
>   all: introduce COMPAT_WRAPPER option and enable it for s390
>   all: s390: move wrapper infrastructure to generic headers
>   all: s390: move compat_wrappers.c from arch/s390/kernel to kernel/
>   all: wrap needed syscalls in generic unistd
>   compat ABI: use non-compat openat and open_by_handle_at variants
>   32-bit ABI: introduce ARCH_32BIT_OFF_T config option
>   arm64: ilp32: add documentation on the ILP32 ABI for ARM64
>   thread: move thread bits accessors to separated file
>   arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
>   arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
>   arm64: introduce binfmt_elf32.c
>   arm64: ilp32: introduce binfmt_ilp32.c
>   arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32
>   arm64: signal: share lp64 signal routines to ilp32
>   arm64: signal32: move ilp32 and aarch32 common code to separated file
> 
>  Documentation/adding-syscalls.txt             |  32 +++
>  Documentation/arm64/ilp32.txt                 |  13 ++
>  arch/Kconfig                                  |   8 +
>  arch/arc/Kconfig                              |   1 +
>  arch/arm/Kconfig                              |   1 +
>  arch/arm64/Kconfig                            |  17 +-
>  arch/arm64/Makefile                           |   5 +
>  arch/arm64/include/asm/compat.h               |  19 +-
>  arch/arm64/include/asm/elf.h                  |  35 +---
>  arch/arm64/include/asm/fpsimd.h               |   2 +-
>  arch/arm64/include/asm/ftrace.h               |   2 +-
>  arch/arm64/include/asm/hwcap.h                |   6 +-
>  arch/arm64/include/asm/is_compat.h            |  84 ++++++++
>  arch/arm64/include/asm/memory.h               |   3 +-
>  arch/arm64/include/asm/processor.h            |  11 +-
>  arch/arm64/include/asm/ptrace.h               |   2 +-
>  arch/arm64/include/asm/signal32.h             |   6 +-
>  arch/arm64/include/asm/signal32_common.h      |  25 +++
>  arch/arm64/include/asm/signal_common.h        |  33 +++
>  arch/arm64/include/asm/signal_ilp32.h         |  34 ++++
>  arch/arm64/include/asm/syscall.h              |   2 +-
>  arch/arm64/include/asm/thread_info.h          |   3 +-
>  arch/arm64/include/asm/unistd.h               |  11 +-
>  arch/arm64/include/asm/unistd32.h             |   2 +-
>  arch/arm64/include/asm/vdso.h                 |   6 +
>  arch/arm64/include/uapi/asm/bitsperlong.h     |   9 +-
>  arch/arm64/kernel/Makefile                    |  12 +-
>  arch/arm64/kernel/asm-offsets.c               |   2 +-
>  arch/arm64/kernel/binfmt_elf32.c              |  33 +++
>  arch/arm64/kernel/binfmt_ilp32.c              |  91 +++++++++
>  arch/arm64/kernel/cpufeature.c                |   8 +-
>  arch/arm64/kernel/cpuinfo.c                   |   4 +-
>  arch/arm64/kernel/entry.S                     |  18 +-
>  arch/arm64/kernel/entry_ilp32.S               |  23 +++
>  arch/arm64/kernel/head.S                      |   2 +-
>  arch/arm64/kernel/hw_breakpoint.c             |  10 +-
>  arch/arm64/kernel/perf_regs.c                 |   2 +-
>  arch/arm64/kernel/process.c                   |   7 +-
>  arch/arm64/kernel/ptrace.c                    |  67 ++++++-
>  arch/arm64/kernel/signal.c                    | 100 ++++++----
>  arch/arm64/kernel/signal32.c                  |  85 --------
>  arch/arm64/kernel/signal32_common.c           | 115 +++++++++++
>  arch/arm64/kernel/signal_ilp32.c              | 192 ++++++++++++++++++
>  arch/arm64/kernel/sys32.c                     |   1 +
>  arch/arm64/kernel/sys_ilp32.c                 |  68 +++++++
>  arch/arm64/kernel/traps.c                     |   5 +-
>  arch/arm64/kernel/vdso-ilp32/.gitignore       |   2 +
>  arch/arm64/kernel/vdso-ilp32/Makefile         |  72 +++++++
>  arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S     |  33 +++
>  arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S |  95 +++++++++
>  arch/arm64/kernel/vdso.c                      |  65 ++++--
>  arch/blackfin/Kconfig                         |   1 +
>  arch/cris/Kconfig                             |   1 +
>  arch/frv/Kconfig                              |   1 +
>  arch/h8300/Kconfig                            |   1 +
>  arch/hexagon/Kconfig                          |   1 +
>  arch/m32r/Kconfig                             |   1 +
>  arch/m68k/Kconfig                             |   1 +
>  arch/metag/Kconfig                            |   1 +
>  arch/microblaze/Kconfig                       |   1 +
>  arch/mips/Kconfig                             |   1 +
>  arch/mn10300/Kconfig                          |   1 +
>  arch/nios2/Kconfig                            |   1 +
>  arch/openrisc/Kconfig                         |   1 +
>  arch/parisc/Kconfig                           |   1 +
>  arch/powerpc/Kconfig                          |   1 +
>  arch/s390/Kconfig                             |   1 +
>  arch/s390/include/asm/compat.h                |  17 +-
>  arch/s390/kernel/Makefile                     |   2 +-
>  arch/s390/kernel/compat_linux.c               |   4 +
>  arch/s390/kernel/compat_wrapper.c             | 180 -----------------
>  arch/score/Kconfig                            |   1 +
>  arch/sh/Kconfig                               |   1 +
>  arch/sparc/Kconfig                            |   1 +
>  arch/tile/Kconfig                             |   1 +
>  arch/tile/kernel/compat.c                     |   3 +
>  arch/unicore32/Kconfig                        |   1 +
>  arch/x86/Kconfig                              |   1 +
>  arch/x86/um/Kconfig                           |   1 +
>  arch/xtensa/Kconfig                           |   1 +
>  drivers/clocksource/arm_arch_timer.c          |   2 +-
>  include/linux/compat.h                        | 277 ++++++++++++++++++++++++++
>  include/linux/fcntl.h                         |   2 +-
>  include/linux/ptrace.h                        |   6 +
>  include/linux/syscalls.h                      |  57 +-----
>  include/linux/syscalls_structs.h              |  60 ++++++
>  include/linux/thread_bits.h                   |  55 +++++
>  include/linux/thread_info.h                   |  44 +---
>  include/uapi/asm-generic/unistd.h             | 231 ++++++++++-----------
>  kernel/Makefile                               |   1 +
>  kernel/compat_wrapper.c                       | 175 ++++++++++++++++
>  kernel/ptrace.c                               |  10 +-
>  92 files changed, 1997 insertions(+), 637 deletions(-)
>  create mode 100644 Documentation/arm64/ilp32.txt
>  create mode 100644 arch/arm64/include/asm/is_compat.h
>  create mode 100644 arch/arm64/include/asm/signal32_common.h
>  create mode 100644 arch/arm64/include/asm/signal_common.h
>  create mode 100644 arch/arm64/include/asm/signal_ilp32.h
>  create mode 100644 arch/arm64/kernel/binfmt_elf32.c
>  create mode 100644 arch/arm64/kernel/binfmt_ilp32.c
>  create mode 100644 arch/arm64/kernel/entry_ilp32.S
>  create mode 100644 arch/arm64/kernel/signal32_common.c
>  create mode 100644 arch/arm64/kernel/signal_ilp32.c
>  create mode 100644 arch/arm64/kernel/sys_ilp32.c
>  create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
>  create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
>  create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
>  create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
>  delete mode 100644 arch/s390/kernel/compat_wrapper.c
>  create mode 100644 include/linux/syscalls_structs.h
>  create mode 100644 include/linux/thread_bits.h
>  create mode 100644 kernel/compat_wrapper.c
> 

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-17 12:10 ` Szabolcs Nagy
@ 2016-05-17 15:37   ` Arnd Bergmann
  2016-05-17 15:45     ` Joseph Myers
  2016-05-17 15:40   ` Joseph Myers
  1 sibling, 1 reply; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-17 15:37 UTC (permalink / raw)
  To: Szabolcs Nagy
  Cc: Yury Norov, catalin.marinas, linux-arm-kernel, linux-kernel, nd,
	linux-arch, linux-s390, pinskia, Prasun.Kapoor, schwab, broonie,
	linux-doc, heiko.carstens, agraf, klimov.linux, bamvor.zhangjian,
	schwidefsky, Nathan_Lynch, joseph, christoph.muellner,
	GNU C Library

On Tuesday 17 May 2016 13:10:53 Szabolcs Nagy wrote:
> On 05/04/16 23:08, Yury Norov wrote:
> > This version is rebased on kernel v4.6-rc2, and has fixes in signal subsystem.
> > It works with updated glibc [1] (though very draft), and tested with LTP.
> > 
> > It was tested on QEMU and ThunderX machines. No major difference found.
> > This is RFC because ILP32 is not tested in big-endian mode.
> > 
> >  v3: https://lkml.org/lkml/2014/9/3/704
> >  v4: https://lkml.org/lkml/2015/4/13/691
> >  v5: https://lkml.org/lkml/2015/9/29/911
> > 
> >  v6:
> >  - time_t, __kenel_off_t and other types turned to be 32-bit
> >    for compatibility reasons (after v5 discussion);
> 
> i added libc-alpha to cc, the thread is at
> https://lkml.org/lkml/2016/4/5/872
> or http://thread.gmane.org/gmane.linux.kernel.cross-arch/31449
> 
> the kernel position seems to be that the aarch64 ilp32 syscall abi
> will follow regular 32bit abis (apart from signal context and ptrace
> related things and syscalls will take 64bit arguments).
> 
> i think the reasoning is that this allows legacy (non-64bit-safe)
> software to use this abi on aarch64 without trouble.
> 
> i think this design should be ok for glibc.
> 
> there are some interop issues between processes following different abis
> (e.g. shared mutexes, abi specific file formats, lib paths,..) which apply,
> but i assume it is no different from existing 32bit vs 64bit issues.
> 
> the 32bit time_t and off_t are ugly and i wonder if 32bit __kernel_off_t
> is really necessary. (i don't see where that is changed: it is supposed
> to be __kernel_long_t which is 64bit).

__kernel_off_t and __kernel_ino_t are always 'long' and 'unsigned long'
for historic reasons, but they are not used at all on modern architectures.
We could add a few lines with #ifdef to the kernel headers to hide the
definition on architectures that don't use them, but that seems pointless
given that glibc just defines its own version.

For time_t, I'm working on the same thing in the long run: there will
be a 64 bit __kernel_time64_t that is always used on all architectures,
and a __kernel_time_t that is provided for backwards compatibility
with old libc on architectures that started out having it.

__kernel_long_t should not be 64 bit on 32-bit architectures, it is the
size of the 'long' type in the ABI and defining it as 'long long' on
x32 keeps causing problems that we should not add on new architectures.

> i think even legacy software should be able to deal with 64bit off_t,
> so we could avoid having two sets of filesystem apis or is 64bit-only
> off_t more work to do in linux/glibc?

All architectures that got merged in the last 10 years only support
64-bit __kernel_loff_t in the kernel but not __kernel_off_t, this
includes arc, c6x, h8300, hexagon, metag, nios2, openrisc, tile and
unicore32. However, glibc implements 32-bit off_t on top of the
64-bit syscall interfaces. I believe this was done to keep the code
looking more like the older 32-bit architectures.

I think it has become easier to override now and we just need to
update sysdeps/unix/sysv/linux/generic/bits/typesizes.h to set

#define __INO64_T_TYPE          __UQUAD_TYPE
#define __OFF64_T_TYPE          __UQUAD_TYPE
#define __OFF_T_MATCHES_OFF64_T        1
#define __INO_T_MATCHES_INO64_T        1

for new architectures (obviously not the ones that already use the
32-bit types). I haven't tries this, so there may be other things
that are required.

	Arnd

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-17 12:10 ` Szabolcs Nagy
  2016-05-17 15:37   ` Arnd Bergmann
@ 2016-05-17 15:40   ` Joseph Myers
  1 sibling, 0 replies; 135+ messages in thread
From: Joseph Myers @ 2016-05-17 15:40 UTC (permalink / raw)
  To: Szabolcs Nagy
  Cc: Yury Norov, arnd, catalin.marinas, linux-arm-kernel,
	linux-kernel, nd, linux-arch, linux-s390, pinskia, Prasun.Kapoor,
	schwab, broonie, linux-doc, heiko.carstens, agraf, klimov.linux,
	bamvor.zhangjian, schwidefsky, Nathan_Lynch, christoph.muellner,
	GNU C Library

On Tue, 17 May 2016, Szabolcs Nagy wrote:

> i think even legacy software should be able to deal with 64bit off_t,
> so we could avoid having two sets of filesystem apis or is 64bit-only
> off_t more work to do in linux/glibc?

wordsize-64 directories generally expect 64-bit interfaces.  wordsize-32 
directories generally expect that there are two sets of filesystem APIs 
which are not aliased (at the userspace level - the versions for the 
generic syscall API deal with setting EOVERFLOW in userspace as needed).

The "wordsize" concept is not wonderfully well-defined and could do with 
being split up into multiple better-defined concepts, but that's obvious 
something pretty tricky to get right, involving a very careful analysis of 
the existing code.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-17 15:37   ` Arnd Bergmann
@ 2016-05-17 15:45     ` Joseph Myers
  2016-05-17 16:02       ` Andreas Schwab
  0 siblings, 1 reply; 135+ messages in thread
From: Joseph Myers @ 2016-05-17 15:45 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Szabolcs Nagy, Yury Norov, catalin.marinas, linux-arm-kernel,
	linux-kernel, nd, linux-arch, linux-s390, pinskia, Prasun.Kapoor,
	schwab, broonie, linux-doc, heiko.carstens, agraf, klimov.linux,
	bamvor.zhangjian, schwidefsky, Nathan_Lynch, christoph.muellner,
	GNU C Library

On Tue, 17 May 2016, Arnd Bergmann wrote:

> I think it has become easier to override now and we just need to
> update sysdeps/unix/sysv/linux/generic/bits/typesizes.h to set
> 
> #define __INO64_T_TYPE          __UQUAD_TYPE
> #define __OFF64_T_TYPE          __UQUAD_TYPE
> #define __OFF_T_MATCHES_OFF64_T        1
> #define __INO_T_MATCHES_INO64_T        1
> 
> for new architectures (obviously not the ones that already use the
> 32-bit types). I haven't tries this, so there may be other things
> that are required.

I think more than that would be needed to get struct stat to match and get 
things aliased for that (which is presumably desirable).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-17 15:45     ` Joseph Myers
@ 2016-05-17 16:02       ` Andreas Schwab
  2016-05-17 22:45         ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Andreas Schwab @ 2016-05-17 16:02 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Arnd Bergmann, Szabolcs Nagy, Yury Norov, catalin.marinas,
	linux-arm-kernel, linux-kernel, nd, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, broonie, linux-doc, heiko.carstens,
	agraf, klimov.linux, bamvor.zhangjian, schwidefsky, Nathan_Lynch,
	christoph.muellner, GNU C Library

Joseph Myers <joseph@codesourcery.com> writes:

> On Tue, 17 May 2016, Arnd Bergmann wrote:
>
>> I think it has become easier to override now and we just need to
>> update sysdeps/unix/sysv/linux/generic/bits/typesizes.h to set
>> 
>> #define __INO64_T_TYPE          __UQUAD_TYPE
>> #define __OFF64_T_TYPE          __UQUAD_TYPE
>> #define __OFF_T_MATCHES_OFF64_T        1
>> #define __INO_T_MATCHES_INO64_T        1
>> 
>> for new architectures (obviously not the ones that already use the
>> 32-bit types). I haven't tries this, so there may be other things
>> that are required.
>
> I think more than that would be needed to get struct stat to match and get 
> things aliased for that (which is presumably desirable).

Looking at sysdeps/unix/sysv/linux/generic/bits/stat.h, there is at
least blkcnt_t that differs between stat and stat64.  And you probably
want to alias statfs and statfs64 as well, ie. fs{blk,fil}cnt_t.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-16 17:06     ` Catalin Marinas
@ 2016-05-17 19:05       ` Yury Norov
  2016-05-18 11:21         ` Catalin Marinas
  0 siblings, 1 reply; 135+ messages in thread
From: Yury Norov @ 2016-05-17 19:05 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, heiko.carstens, linux-doc, Nathan_Lynch,
	agraf, klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwab, schwidefsky, joseph, christoph.muellner

On Mon, May 16, 2016 at 06:06:05PM +0100, Catalin Marinas wrote:
> On Sat, May 14, 2016 at 06:03:52PM +0300, Yury Norov wrote:
> > +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> > +       unsigned long, prot, unsigned long, flags, unsigned long, fd,
> > +       unsigned long, pgoff)
> 
> To avoid the types confusion we could add __SC_WRAP to mmap2 in unistd.h
> and use COMPAT_SYSCALL_DEFINE6 here (together with compat_ptr_t etc.).
> 
> > +{
> > +       if (pgoff & (~PAGE_MASK >> 12))
> > +               return -EINVAL;
> > +
> > +       return sys_mmap_pgoff((compat_uptr_t) addr, (compat_size_t) len,
> > +		       (int) prot, (int) flags, (int) fd,
> > +		       pgoff >> (PAGE_SHIFT-12));
> 
> Then we wouldn't need the explicit casting here.

See below

> 
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE4(pread64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> > +		       compat_size_t, count, off_t, offset)
> > +{
> > +	return sys_pread64(fd, (char *) ubuf, count, offset);
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE4(pwrite64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> > +		       compat_size_t, count, off_t, offset)
> > +{
> > +	return sys_pwrite64(fd, (char *) ubuf, count, offset);
> 
> Nitpick: no space between cast type and variable name: (char *)ubuf, ...

I think it's really a matter of taste. I prefer to have a space, and
there's no solid rule in coding style.

And there are 13032 insertions of my version vs 35030 of yours:
~/work/linux$ git grep ' \*)[a-zA-Z]'|wc -l
35030
~/work/linux$ git grep ' \*) [a-zA-Z]'|wc -l
13032

Of course, I will change it if you insist.

> We can also make these functions static as they are not used outside
> this file.

If it's OK, we can use just compat_sys_xxx() instead of
COMPAT_SYSCALL_DEFINEx(xxx), and for mmap2 we'll not need to change 
_SYSCALL to _SC_WRAP in unistd.h that way.

> > -- 
> Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-05-17 16:02       ` Andreas Schwab
@ 2016-05-17 22:45         ` Arnd Bergmann
  0 siblings, 0 replies; 135+ messages in thread
From: Arnd Bergmann @ 2016-05-17 22:45 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: Joseph Myers, Szabolcs Nagy, Yury Norov, catalin.marinas,
	linux-arm-kernel, linux-kernel, nd, linux-arch, linux-s390,
	pinskia, Prasun.Kapoor, broonie, linux-doc, heiko.carstens,
	agraf, klimov.linux, bamvor.zhangjian, schwidefsky, Nathan_Lynch,
	christoph.muellner, GNU C Library

On Tuesday 17 May 2016 18:02:36 Andreas Schwab wrote:
> Joseph Myers <joseph@codesourcery.com> writes:
> 
> > On Tue, 17 May 2016, Arnd Bergmann wrote:
> >
> >> I think it has become easier to override now and we just need to
> >> update sysdeps/unix/sysv/linux/generic/bits/typesizes.h to set
> >> 
> >> #define __INO64_T_TYPE          __UQUAD_TYPE
> >> #define __OFF64_T_TYPE          __UQUAD_TYPE
> >> #define __OFF_T_MATCHES_OFF64_T        1
> >> #define __INO_T_MATCHES_INO64_T        1
> >> 
> >> for new architectures (obviously not the ones that already use the
> >> 32-bit types). I haven't tries this, so there may be other things
> >> that are required.
> >
> > I think more than that would be needed to get struct stat to match and get 
> > things aliased for that (which is presumably desirable).
> 
> Looking at sysdeps/unix/sysv/linux/generic/bits/stat.h, there is at
> least blkcnt_t that differs between stat and stat64.  And you probably
> want to alias statfs and statfs64 as well, ie. fs{blk,fil}cnt_t.

Makes sense. Indeed that is a bit more work than I hoped, in particular
if we have to audit the uses of __WORDSIZE as well.

	Arnd

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-17 19:05       ` Yury Norov
@ 2016-05-18 11:21         ` Catalin Marinas
  2016-05-18 17:58           ` Yury Norov
  0 siblings, 1 reply; 135+ messages in thread
From: Catalin Marinas @ 2016-05-18 11:21 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	Nathan_Lynch, joseph, linux-doc, heiko.carstens, linux-kernel,
	agraf, klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwab, schwidefsky, linux-arm-kernel,
	christoph.muellner

On Tue, May 17, 2016 at 10:05:26PM +0300, Yury Norov wrote:
> On Mon, May 16, 2016 at 06:06:05PM +0100, Catalin Marinas wrote:
> > On Sat, May 14, 2016 at 06:03:52PM +0300, Yury Norov wrote:
> > > +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> > > +       unsigned long, prot, unsigned long, flags, unsigned long, fd,
> > > +       unsigned long, pgoff)
> > 
> > To avoid the types confusion we could add __SC_WRAP to mmap2 in unistd.h
> > and use COMPAT_SYSCALL_DEFINE6 here (together with compat_ptr_t etc.).
> > 
> > > +{
> > > +       if (pgoff & (~PAGE_MASK >> 12))
> > > +               return -EINVAL;
> > > +
> > > +       return sys_mmap_pgoff((compat_uptr_t) addr, (compat_size_t) len,
> > > +		       (int) prot, (int) flags, (int) fd,
> > > +		       pgoff >> (PAGE_SHIFT-12));
> > 
> > Then we wouldn't need the explicit casting here.
> 
> See below
> 
> > > +}
> > > +
> > > +COMPAT_SYSCALL_DEFINE4(pread64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> > > +		       compat_size_t, count, off_t, offset)
> > > +{
> > > +	return sys_pread64(fd, (char *) ubuf, count, offset);
> > > +}
> > > +
> > > +COMPAT_SYSCALL_DEFINE4(pwrite64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> > > +		       compat_size_t, count, off_t, offset)
> > > +{
> > > +	return sys_pwrite64(fd, (char *) ubuf, count, offset);
> > 
> > Nitpick: no space between cast type and variable name: (char *)ubuf, ...
> 
> I think it's really a matter of taste. I prefer to have a space, and
> there's no solid rule in coding style.
> 
> And there are 13032 insertions of my version vs 35030 of yours:
> ~/work/linux$ git grep ' \*)[a-zA-Z]'|wc -l
> 35030
> ~/work/linux$ git grep ' \*) [a-zA-Z]'|wc -l
> 13032
> 
> Of course, I will change it if you insist.

Not really, I thought it's covered by CodingStyle but it doesn't seem
to.

> > We can also make these functions static as they are not used outside
> > this file.
> 
> If it's OK, we can use just compat_sys_xxx() instead of
> COMPAT_SYSCALL_DEFINEx(xxx),

I got lost in macros, what difference would COMPAT_SYSCALL_DEFINE vs
compat_sys_*() make? Is this the delouse stuff?

> and for mmap2 we'll not need to change _SYSCALL to _SC_WRAP in
> unistd.h that way.

Looking at the generic unistd.h, adding _SC_WRAP for sys_mmap2 is
indeed not easy:

#define __NR3264_mmap 222
__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)

So defining a compat_sys_mmap2() would work but I think you'd also need:

#define sys_mmap2	compat_sys_mmap2()

-- 
Catalin

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

* Re: [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-05-18 11:21         ` Catalin Marinas
@ 2016-05-18 17:58           ` Yury Norov
  0 siblings, 0 replies; 135+ messages in thread
From: Yury Norov @ 2016-05-18 17:58 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arch, linux-s390, arnd, pinskia, Prasun.Kapoor,
	Nathan_Lynch, joseph, linux-doc, heiko.carstens, linux-kernel,
	agraf, klimov.linux, Andrew Pinski, broonie, bamvor.zhangjian,
	Andrew Pinski, schwab, schwidefsky, linux-arm-kernel,
	christoph.muellner

On Wed, May 18, 2016 at 12:21:46PM +0100, Catalin Marinas wrote:
> On Tue, May 17, 2016 at 10:05:26PM +0300, Yury Norov wrote:
> > On Mon, May 16, 2016 at 06:06:05PM +0100, Catalin Marinas wrote:
> > > On Sat, May 14, 2016 at 06:03:52PM +0300, Yury Norov wrote:
> > > > +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> > > > +       unsigned long, prot, unsigned long, flags, unsigned long, fd,
> > > > +       unsigned long, pgoff)
> > > 
> > > To avoid the types confusion we could add __SC_WRAP to mmap2 in unistd.h
> > > and use COMPAT_SYSCALL_DEFINE6 here (together with compat_ptr_t etc.).
> > > 
> > > > +{
> > > > +       if (pgoff & (~PAGE_MASK >> 12))
> > > > +               return -EINVAL;
> > > > +
> > > > +       return sys_mmap_pgoff((compat_uptr_t) addr, (compat_size_t) len,
> > > > +		       (int) prot, (int) flags, (int) fd,
> > > > +		       pgoff >> (PAGE_SHIFT-12));
> > > 
> > > Then we wouldn't need the explicit casting here.
> > 
> > See below
> > 
> > > > +}
> > > > +
> > > > +COMPAT_SYSCALL_DEFINE4(pread64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> > > > +		       compat_size_t, count, off_t, offset)
> > > > +{
> > > > +	return sys_pread64(fd, (char *) ubuf, count, offset);
> > > > +}
> > > > +
> > > > +COMPAT_SYSCALL_DEFINE4(pwrite64, unsigned int, fd, compat_uptr_t __user *, ubuf,
> > > > +		       compat_size_t, count, off_t, offset)
> > > > +{
> > > > +	return sys_pwrite64(fd, (char *) ubuf, count, offset);
> > > 
> > > Nitpick: no space between cast type and variable name: (char *)ubuf, ...
> > 
> > I think it's really a matter of taste. I prefer to have a space, and
> > there's no solid rule in coding style.
> > 
> > And there are 13032 insertions of my version vs 35030 of yours:
> > ~/work/linux$ git grep ' \*)[a-zA-Z]'|wc -l
> > 35030
> > ~/work/linux$ git grep ' \*) [a-zA-Z]'|wc -l
> > 13032
> > 
> > Of course, I will change it if you insist.
> 
> Not really, I thought it's covered by CodingStyle but it doesn't seem
> to.
> 
> > > We can also make these functions static as they are not used outside
> > > this file.
> > 
> > If it's OK, we can use just compat_sys_xxx() instead of
> > COMPAT_SYSCALL_DEFINEx(xxx),
> 
> I got lost in macros, what difference would COMPAT_SYSCALL_DEFINE vs
> compat_sys_*() make? Is this the delouse stuff?
> 

Hmm... I looked again. It seems that COMPAT delouses all arguments,
including off_t, and that's what we try to avoid. So we *should* use
naked functions. 

include/linux/compat.h:
53 #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
54         asmlinkage long compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))\
55              __attribute__((alias(__stringify(compat_SyS##name))));  \
56         static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
57         asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__));\
58         asmlinkage long compat_SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))\
59         { \
60                 return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
61         } \
62         static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))


> > and for mmap2 we'll not need to change _SYSCALL to _SC_WRAP in
> > unistd.h that way.
> 
> Looking at the generic unistd.h, adding _SC_WRAP for sys_mmap2 is
> indeed not easy:
> 
> #define __NR3264_mmap 222
> __SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
> 
> So defining a compat_sys_mmap2() would work but I think you'd also need:
> 

> #define sys_mmap2	compat_sys_mmap2()

OK.

> 
> -- 
> Catalin

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-08  2:49 ` Andrew Pinski
@ 2016-04-09  2:42   ` Arnd Bergmann
  0 siblings, 0 replies; 135+ messages in thread
From: Arnd Bergmann @ 2016-04-09  2:42 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Adam Borowski, LKML, Geert Uytterhoeven, Catalin Marinas,
	linux-arm-kernel, Martin Schwidefsky, Heiko Carstens,
	Prasun Kapoor, Andreas Schwab, Nathan Lynch, Alexander Graf,
	Alexey Klimov, Mark Brown, Joseph S. Myers, christoph.muellner,
	Zhangjian (Bamvor),
	linux-doc, Linux-Arch, linux-s390, Yury Norov

On Friday 08 April 2016, Andrew Pinski wrote:
> On Thu, Apr 7, 2016 at 5:18 AM, Adam Borowski <kilobyte@angband.pl> wrote:
> > On Wed, 6 Apr 2016, Geert Uytterhoeven wrote:
> >> On Wed, Apr 6, 2016 at 12:08 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> >>>  v6:
> >>>  - time_t, __kenel_off_t and other types turned to be 32-bit
> >>>    for compatibility reasons (after v5 discussion);
> >
> > Introducing a new arch today with y2038 problems is not a good idea.
> > Linus said so with appropriately pointy words in 2011.

This was before we made the decision to fix the y2038 problem for all
architectures.

> This is the third time we had this discussion on time_t for ILP32.  I
> had originally it as 32bit, then Catalin suggested I change it to
> 64bit and then Arnd (with his work for 2038 issue on 32bit arch) said
> ILP32 should match all other 32bit targets and the other 64bit time_t
> be fixed by the current work he was working on.  Now you are
> suggesting we change it again.
> Arnd can you please comment more on why we want 32bit time_t instead
> of the 64bit one?  I Know there was some POSIX (or was it C90)
> violation but I suspect there is an easy way to workaround this inside
> the kernel but the discussion to move over to 32bit time_t was already
> made by the time I started to look into that.

x32 still runs into new problems today, and will continue to have problems
with newly added drivers that pass time_t (or other __kernel_long_t) arguments
through ioctl.

To avoid having to audit every new driver for interfaces that behave
differently based on the __kernel_long_t definition, arm64 is not following
the same route as x86 here and instead uses the normal 32-bit ABI like
any other architecture. This means we use 32-bit time_t, aio_context_t,
size_t and clock_t and share the system call implementation with the
compat handling for arm (aarch32) mode.

Once we have the interfaces for 64-bit time_t in place in the kernel,
we will be able to rebuild glibc on all 32-bit architectures including
arm and arm64/ilp32 that way.

The POSIX and C99 incompatibility you mention is about struct timespec,
which uses 'long' as the type for the tv_nsec member. This is vaguely
related to the issue of 64-bit time_t, but is not the reason for
starting out with 32-bit time_t for the new ABI here.

[side note:
How to precisely handle tv_nsec on 32-bit architectures is still an open
issue that will have to be solved when we nail down the new system call
interfaces:
The issue specifically is what happens when the upper half of the
second 64-bit word in struct timespec argument passed into a system
call is nonzero: the normal 64-bit syscalls must return an error,
while the 32-bit user space expects the kernel to ignore the upper bits.
This means something between the application and the native system call
has to clear the bits, and this can either be done by copying the
data inside of glibc (as done on x32) or by adding an extra system
call entry point in the kernel.]

> >> We're already closer to the (future) y2038 than to the (past) introduction of
> >> LP64...
> >>
> >> These unfixable legacy applications have been spreading through x32 to
> >> the shiny new arm64 server architecture (does ppc64el also have an ILP32 mode,
> >> or is it planned)? Lots of resources are spent on maintaining the status quo,
> >> instead of on fixing the real problems.
> >
> > As an x32 (userland) porter, I can tell you that time_t!=long _did_ cause
> > non-trivial amounts of work.  But that work is already done (at least in
> > Debian), so you might as well benefit from it.
> 
> There is actually private code out there which uses timespec and
> timeval to pass time over the wire; yes I know bad coding style and
> all but they did it that way.  This is code which was working for x86
> and we are porting it to ARM64; a data center code by the way; not
> some networking code even.  This means they have not ported the code
> to fully 64bit yet and they might never.

This code will run into the same problem on arm64/ilp32 when built against
a future libc implementation that defines time_t as 64-bit, but at least
the glibc maintainers so far plan to leave this as a per-application
option for the forseeable future: even on a system that uses 64-bit time_t
in user space and kernel by default, you should be able to build an
application using a 32-bit time_t.

	Arnd

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
  2016-04-07 12:18 Adam Borowski
@ 2016-04-08  2:49 ` Andrew Pinski
  2016-04-09  2:42   ` Arnd Bergmann
  0 siblings, 1 reply; 135+ messages in thread
From: Andrew Pinski @ 2016-04-08  2:49 UTC (permalink / raw)
  To: Adam Borowski
  Cc: LKML, Geert Uytterhoeven, Arnd Bergmann, Catalin Marinas,
	linux-arm-kernel, Martin Schwidefsky, Heiko Carstens,
	Prasun Kapoor, Andreas Schwab, Nathan Lynch, Alexander Graf,
	Alexey Klimov, Mark Brown, Joseph S. Myers, christoph.muellner,
	Zhangjian (Bamvor),
	linux-doc, Linux-Arch, linux-s390, Yury Norov

On Thu, Apr 7, 2016 at 5:18 AM, Adam Borowski <kilobyte@angband.pl> wrote:
> On Wed, 6 Apr 2016, Geert Uytterhoeven wrote:
>> On Wed, Apr 6, 2016 at 12:08 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
>>>  v6:
>>>  - time_t, __kenel_off_t and other types turned to be 32-bit
>>>    for compatibility reasons (after v5 discussion);
>
> Introducing a new arch today with y2038 problems is not a good idea.
> Linus said so with appropriately pointy words in 2011.

This is the third time we had this discussion on time_t for ILP32.  I
had originally it as 32bit, then Catalin suggested I change it to
64bit and then Arnd (with his work for 2038 issue on 32bit arch) said
ILP32 should match all other 32bit targets and the other 64bit time_t
be fixed by the current work he was working on.  Now you are
suggesting we change it again.
Arnd can you please comment more on why we want 32bit time_t instead
of the 64bit one?  I Know there was some POSIX (or was it C90)
violation but I suspect there is an easy way to workaround this inside
the kernel but the discussion to move over to 32bit time_t was already
made by the time I started to look into that.

>
>> What makes you think these "applications that can’t readily be migrated to LP64
>> because they were written assuming an ILP32 data model, and that will never
>> become suitable for a LP64 data model and will remain locked into ILP32
>> operating environments" are more likely to be fixed for y2038 later, than for
>> LP64 now?
>
> Such broken applications already have plenty of bogus architecture detection
> code so you need porting anyway...

I don't disagree here; just see below ...

>
>> We're already closer to the (future) y2038 than to the (past) introduction of
>> LP64...
>>
>> These unfixable legacy applications have been spreading through x32 to
>> the shiny new arm64 server architecture (does ppc64el also have an ILP32 mode,
>> or is it planned)? Lots of resources are spent on maintaining the status quo,
>> instead of on fixing the real problems.
>
> As an x32 (userland) porter, I can tell you that time_t!=long _did_ cause
> non-trivial amounts of work.  But that work is already done (at least in
> Debian), so you might as well benefit from it.

There is actually private code out there which uses timespec and
timeval to pass time over the wire; yes I know bad coding style and
all but they did it that way.  This is code which was working for x86
and we are porting it to ARM64; a data center code by the way; not
some networking code even.  This means they have not ported the code
to fully 64bit yet and they might never.

Thanks,
Andrew

>
>
> --
> A tit a day keeps the vet away.

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

* Re: [RFC6 PATCH v6 00/21] ILP32 for ARM64
@ 2016-04-07 12:18 Adam Borowski
  2016-04-08  2:49 ` Andrew Pinski
  0 siblings, 1 reply; 135+ messages in thread
From: Adam Borowski @ 2016-04-07 12:18 UTC (permalink / raw)
  To: linux-kernel
  Cc: Geert Uytterhoeven, Arnd Bergmann, Catalin Marinas,
	linux-arm-kernel, Martin Schwidefsky, Heiko Carstens,
	Andrew Pinski, Prasun Kapoor, Andreas Schwab, Nathan Lynch,
	Alexander Graf, Alexey Klimov, Mark Brown, Joseph S. Myers,
	christoph.muellner, bamvor.zhangjian, linux-doc, Linux-Arch,
	linux-s390, Yury Norov

On Wed, 6 Apr 2016, Geert Uytterhoeven wrote:
> On Wed, Apr 6, 2016 at 12:08 AM, Yury Norov <ynorov@caviumnetworks.com> wrote:
>>  v6:
>>  - time_t, __kenel_off_t and other types turned to be 32-bit
>>    for compatibility reasons (after v5 discussion);

Introducing a new arch today with y2038 problems is not a good idea.
Linus said so with appropriately pointy words in 2011.

> What makes you think these "applications that can’t readily be migrated to LP64
> because they were written assuming an ILP32 data model, and that will never
> become suitable for a LP64 data model and will remain locked into ILP32
> operating environments" are more likely to be fixed for y2038 later, than for
> LP64 now?

Such broken applications already have plenty of bogus architecture detection
code so you need porting anyway...

> We're already closer to the (future) y2038 than to the (past) introduction of
> LP64...
>
> These unfixable legacy applications have been spreading through x32 to
> the shiny new arm64 server architecture (does ppc64el also have an ILP32 mode,
> or is it planned)? Lots of resources are spent on maintaining the status quo,
> instead of on fixing the real problems.
          
As an x32 (userland) porter, I can tell you that time_t!=long _did_ cause
non-trivial amounts of work.  But that work is already done (at least in
Debian), so you might as well benefit from it.


-- 
A tit a day keeps the vet away.

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

end of thread, other threads:[~2016-05-18 17:59 UTC | newest]

Thread overview: 135+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-05 22:08 [RFC6 PATCH v6 00/21] ILP32 for ARM64 Yury Norov
2016-04-05 22:08 ` [PATCH 01/25] all: syscall wrappers: add documentation Yury Norov
2016-04-05 22:08 ` [PATCH 02/25] all: introduce COMPAT_WRAPPER option and enable it for s390 Yury Norov
2016-04-05 22:08 ` [PATCH 03/25] all: s390: move wrapper infrastructure to generic headers Yury Norov
2016-04-05 22:08 ` [PATCH 04/25] all: s390: move compat_wrappers.c from arch/s390/kernel to kernel/ Yury Norov
2016-04-05 22:08 ` [PATCH 05/25] all: wrap needed syscalls in generic unistd Yury Norov
2016-04-05 22:08 ` [PATCH 06/25] compat ABI: use non-compat openat and open_by_handle_at variants Yury Norov
2016-04-05 22:08 ` [PATCH 07/25] 32-bit ABI: introduce ARCH_32BIT_OFF_T config option Yury Norov
2016-04-05 22:08 ` [PATCH 08/25] arm64: ilp32: add documentation on the ILP32 ABI for ARM64 Yury Norov
2016-04-05 22:08 ` [PATCH 09/25] arm64: ensure the kernel is compiled for LP64 Yury Norov
2016-04-05 22:08 ` [PATCH 10/25] arm64: rename COMPAT to AARCH32_EL0 in Kconfig Yury Norov
2016-04-14  3:20   ` Zhangjian (Bamvor)
2016-04-22 15:28     ` Catalin Marinas
2016-04-05 22:08 ` [PATCH 11/25] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Yury Norov
2016-04-05 22:08 ` [PATCH 12/25] arm64: compat: change config dependences to aarch32 Yury Norov
2016-04-22 15:58   ` Catalin Marinas
2016-04-22 21:59     ` Yury Norov
2016-04-23  2:33       ` Zhangjian (Bamvor)
2016-04-05 22:08 ` [PATCH 13/25] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64 Yury Norov
2016-04-05 22:08 ` [PATCH 14/25] thread: move thread bits accessors to separated file Yury Norov
2016-04-05 22:08 ` [PATCH 15/25] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat) Yury Norov
2016-05-06 12:02   ` Zhangjian (Bamvor)
2016-04-05 22:08 ` [PATCH 16/25] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64 Yury Norov
2016-04-05 22:08 ` [PATCH 17/25] arm64: introduce binfmt_elf32.c Yury Norov
2016-04-05 22:08 ` [PATCH 18/25] arm64: ilp32: introduce binfmt_ilp32.c Yury Norov
2016-04-22 16:51   ` Catalin Marinas
2016-04-22 17:41     ` Arnd Bergmann
2016-04-05 22:08 ` [PATCH 19/25] arm64: ptrace: handle ptrace_request differently for aarch32 and ilp32 Yury Norov
2016-04-22 17:10   ` Catalin Marinas
2016-04-22 21:40     ` Yury Norov
2016-04-25 16:57       ` Catalin Marinas
2016-04-05 22:08 ` [PATCH 20/25] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
2016-04-25 17:26   ` Catalin Marinas
2016-04-25 18:19     ` Yury Norov
2016-04-25 18:47       ` Yury Norov
2016-04-26 10:08         ` Catalin Marinas
2016-04-26 16:57   ` Catalin Marinas
2016-04-28 19:19     ` Yury Norov
2016-04-28 20:43       ` Arnd Bergmann
2016-04-28 22:21         ` Yury Norov
2016-04-28 22:43           ` Arnd Bergmann
2016-04-29 13:13             ` Yury Norov
2016-04-29 15:45               ` Arnd Bergmann
2016-05-06 12:16   ` Zhangjian (Bamvor)
2016-05-06 12:37     ` Yury Norov
2016-05-10  7:42       ` Zhangjian (Bamvor)
2016-05-10  7:55         ` Zhangjian (Bamvor)
2016-05-10  8:36         ` Arnd Bergmann
2016-05-10  9:47           ` Zhangjian (Bamvor)
2016-05-10 11:48             ` Arnd Bergmann
2016-05-10 12:39               ` Zhangjian (Bamvor)
2016-05-10 12:50                 ` Arnd Bergmann
2016-05-11  2:04                   ` Zhangjian (Bamvor)
2016-05-11  8:04                     ` Yury Norov
2016-05-11 10:55                       ` Arnd Bergmann
2016-05-11 16:59                         ` Catalin Marinas
2016-05-11 19:30                           ` Arnd Bergmann
2016-05-12  9:17                             ` Catalin Marinas
2016-05-12  9:21                               ` Arnd Bergmann
2016-05-12 12:49                                 ` Zhangjian (Bamvor)
2016-05-12 13:06                                   ` Arnd Bergmann
2016-05-12 13:19                                     ` Yury Norov
2016-05-14 12:49                                       ` Yury Norov
2016-05-11  8:09                     ` Arnd Bergmann
2016-05-11 10:12                       ` Zhangjian (Bamvor)
2016-05-11 11:16                         ` Zhangjian (Bamvor)
2016-05-11 14:50                           ` Arnd Bergmann
2016-05-12  3:45                             ` Zhangjian (Bamvor)
2016-05-12  8:24                               ` Yury Norov
2016-05-12 12:52                                 ` Zhangjian (Bamvor)
2016-05-12 12:59                                   ` Yury Norov
2016-05-14 15:03   ` Yury Norov
2016-05-16 17:06     ` Catalin Marinas
2016-05-17 19:05       ` Yury Norov
2016-05-18 11:21         ` Catalin Marinas
2016-05-18 17:58           ` Yury Norov
2016-04-05 22:08 ` [PATCH 21/25] arm64: signal: share lp64 signal routines to ilp32 Yury Norov
2016-04-05 22:08 ` [PATCH 22/25] arm64: signal32: move ilp32 and aarch32 common code to separated file Yury Norov
2016-04-05 22:08 ` [PATCH 23/25] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Yury Norov
2016-04-05 22:08 ` [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov
2016-04-13  9:19   ` Zhangjian (Bamvor)
2016-04-13 15:55     ` Yury Norov
2016-05-03 12:49       ` Zhangjian (Bamvor)
2016-04-29 16:01   ` Catalin Marinas
2016-04-29 17:30     ` Arnd Bergmann
2016-05-03  9:00       ` Catalin Marinas
2016-05-03  9:05         ` Arnd Bergmann
2016-05-03 11:07           ` Zhangjian (Bamvor)
2016-05-03 12:41             ` Zhangjian (Bamvor)
2016-05-04 21:49               ` Yury Norov
2016-05-04 23:23                 ` Andrew Pinski
2016-05-05  2:24                   ` Zhangjian (Bamvor)
2016-05-05  6:40                     ` Andrew Pinski
2016-05-06 14:00                       ` Yury Norov
2016-05-09 10:07                         ` Zhangjian (Bamvor)
2016-05-05  8:22               ` Yury Norov
2016-04-05 22:08 ` [PATCH 25/25] arm64:ilp32: add ARM64_ILP32 to Kconfig Yury Norov
2016-04-29 16:03   ` Catalin Marinas
2016-04-29 16:08     ` Yury Norov
2016-04-29 16:14       ` Catalin Marinas
2016-04-29 16:26         ` Yury Norov
2016-04-05 22:44 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 - LTP results Yury Norov
2016-04-23  3:37   ` Zhangjian (Bamvor)
2016-04-27  7:30     ` Andrew Pinski
2016-04-27 21:15       ` Andrew Pinski
2016-04-28 12:16         ` Zhangjian (Bamvor)
2016-04-06  6:51 ` [RFC6 PATCH v6 00/21] ILP32 for ARM64 Geert Uytterhoeven
2016-04-06 12:29   ` Yury Norov
2016-04-07 12:28     ` Geert Uytterhoeven
2016-05-12  0:20 ` Yury Norov
2016-05-12  9:19   ` Arnd Bergmann
2016-05-12 10:30     ` Yury Norov
2016-05-12 13:35   ` Catalin Marinas
2016-05-12 13:44     ` Yury Norov
2016-05-12 14:07       ` Catalin Marinas
2016-05-12 14:20         ` Catalin Marinas
2016-05-12 14:34           ` Yury Norov
2016-05-12 14:54             ` Catalin Marinas
2016-05-12 15:27               ` Yury Norov
2016-05-12 14:24         ` Yury Norov
2016-05-12 15:28           ` Catalin Marinas
2016-05-13  8:11             ` Zhangjian (Bamvor)
2016-05-13  9:28               ` Catalin Marinas
2016-05-13 10:51                 ` Yury Norov
2016-05-13 11:03                   ` Catalin Marinas
2016-05-13 13:32                 ` Catalin Marinas
2016-05-17 12:10 ` Szabolcs Nagy
2016-05-17 15:37   ` Arnd Bergmann
2016-05-17 15:45     ` Joseph Myers
2016-05-17 16:02       ` Andreas Schwab
2016-05-17 22:45         ` Arnd Bergmann
2016-05-17 15:40   ` Joseph Myers
2016-04-07 12:18 Adam Borowski
2016-04-08  2:49 ` Andrew Pinski
2016-04-09  2:42   ` Arnd Bergmann

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).