All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC3 PATCH v6 00/20] ILP32 for ARM64
@ 2015-12-15 21:42 ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

This is still RFC because we have no glibc yet, that correspnds new ABI
introduced here. And so we cannot run tests. LP64 and AARCH32 tests show
no regression though.

  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.


Andrew Pinski (9):
  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: share HWCAP between LP64 and ILP32
  arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
  arm64:ilp32: support core dump generation for ILP32
  arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
    it
  arm64:ilp32: add ARM64_ILP32 to Kconfig

Jan Dakinevich (1):
  arm64: ilp32: share aarch32 syscall wrappers to ilp32

Philipp Tomsich (2):
  arm64:ilp32: add vdso-ilp32 and use for signal return
  arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for
    ILP32

Yury Norov (8):
  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: signal: wrap struct ucontext, fp and lr with struct sigframe
  arm64: signal: move ilp32 and lp64 common code to separated file
  arm64: signal32: move ilp32 and aarch32 common code to separated file
  arm64: ilp32: introduce ilp32-specific handlers for sigframe

 Documentation/arm64/ilp32.txt                 |  17 +++
 arch/arm64/Kconfig                            |  12 ++
 arch/arm64/Makefile                           |   5 +
 arch/arm64/include/asm/compat.h               |  19 +--
 arch/arm64/include/asm/elf.h                  | 118 +++++++++++++++--
 arch/arm64/include/asm/fpsimd.h               |   2 +-
 arch/arm64/include/asm/hwcap.h                |  12 +-
 arch/arm64/include/asm/is_compat.h            |  86 +++++++++++++
 arch/arm64/include/asm/memory.h               |   3 +-
 arch/arm64/include/asm/processor.h            |  16 ++-
 arch/arm64/include/asm/ptrace.h               |   2 +-
 arch/arm64/include/asm/signal32.h             |   6 +-
 arch/arm64/include/asm/signal32_common.h      |  30 +++++
 arch/arm64/include/asm/signal_common.h        |  39 ++++++
 arch/arm64/include/asm/signal_ilp32.h         |  38 ++++++
 arch/arm64/include/asm/thread_info.h          |   3 +-
 arch/arm64/include/asm/unistd.h               |  13 +-
 arch/arm64/include/asm/vdso.h                 |   4 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |   9 +-
 arch/arm64/kernel/Makefile                    |  11 +-
 arch/arm64/kernel/asm-offsets.c               |   2 +-
 arch/arm64/kernel/entry.S                     |  18 ++-
 arch/arm64/kernel/entry32-common.S            |  37 ++++++
 arch/arm64/kernel/entry32.S                   |  29 -----
 arch/arm64/kernel/entry_ilp32.S               |  32 +++++
 arch/arm64/kernel/head.S                      |   2 +-
 arch/arm64/kernel/hw_breakpoint.c             |   6 +-
 arch/arm64/kernel/perf_regs.c                 |   2 +-
 arch/arm64/kernel/process.c                   |   5 +-
 arch/arm64/kernel/ptrace.c                    |  48 ++++---
 arch/arm64/kernel/signal.c                    | 176 +++-----------------------
 arch/arm64/kernel/signal32.c                  |  85 -------------
 arch/arm64/kernel/signal32_common.c           | 116 +++++++++++++++++
 arch/arm64/kernel/signal_common.c             | 174 +++++++++++++++++++++++++
 arch/arm64/kernel/signal_ilp32.c              | 126 ++++++++++++++++++
 arch/arm64/kernel/sys_ilp32.c                 |  77 +++++++++++
 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 ++++++++--
 include/linux/thread_bits.h                   |  57 +++++++++
 include/linux/thread_info.h                   |  44 +------
 44 files changed, 1343 insertions(+), 410 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/entry32-common.S
 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_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
 create mode 100644 include/linux/thread_bits.h

-- 
2.5.0


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

* [RFC3 PATCH v6 00/20] ILP32 for ARM64
@ 2015-12-15 21:42 ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

This is still RFC because we have no glibc yet, that correspnds new ABI
introduced here. And so we cannot run tests. LP64 and AARCH32 tests show
no regression though.

  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.


Andrew Pinski (9):
  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: share HWCAP between LP64 and ILP32
  arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
  arm64:ilp32: support core dump generation for ILP32
  arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
    it
  arm64:ilp32: add ARM64_ILP32 to Kconfig

Jan Dakinevich (1):
  arm64: ilp32: share aarch32 syscall wrappers to ilp32

Philipp Tomsich (2):
  arm64:ilp32: add vdso-ilp32 and use for signal return
  arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for
    ILP32

Yury Norov (8):
  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: signal: wrap struct ucontext, fp and lr with struct sigframe
  arm64: signal: move ilp32 and lp64 common code to separated file
  arm64: signal32: move ilp32 and aarch32 common code to separated file
  arm64: ilp32: introduce ilp32-specific handlers for sigframe

 Documentation/arm64/ilp32.txt                 |  17 +++
 arch/arm64/Kconfig                            |  12 ++
 arch/arm64/Makefile                           |   5 +
 arch/arm64/include/asm/compat.h               |  19 +--
 arch/arm64/include/asm/elf.h                  | 118 +++++++++++++++--
 arch/arm64/include/asm/fpsimd.h               |   2 +-
 arch/arm64/include/asm/hwcap.h                |  12 +-
 arch/arm64/include/asm/is_compat.h            |  86 +++++++++++++
 arch/arm64/include/asm/memory.h               |   3 +-
 arch/arm64/include/asm/processor.h            |  16 ++-
 arch/arm64/include/asm/ptrace.h               |   2 +-
 arch/arm64/include/asm/signal32.h             |   6 +-
 arch/arm64/include/asm/signal32_common.h      |  30 +++++
 arch/arm64/include/asm/signal_common.h        |  39 ++++++
 arch/arm64/include/asm/signal_ilp32.h         |  38 ++++++
 arch/arm64/include/asm/thread_info.h          |   3 +-
 arch/arm64/include/asm/unistd.h               |  13 +-
 arch/arm64/include/asm/vdso.h                 |   4 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |   9 +-
 arch/arm64/kernel/Makefile                    |  11 +-
 arch/arm64/kernel/asm-offsets.c               |   2 +-
 arch/arm64/kernel/entry.S                     |  18 ++-
 arch/arm64/kernel/entry32-common.S            |  37 ++++++
 arch/arm64/kernel/entry32.S                   |  29 -----
 arch/arm64/kernel/entry_ilp32.S               |  32 +++++
 arch/arm64/kernel/head.S                      |   2 +-
 arch/arm64/kernel/hw_breakpoint.c             |   6 +-
 arch/arm64/kernel/perf_regs.c                 |   2 +-
 arch/arm64/kernel/process.c                   |   5 +-
 arch/arm64/kernel/ptrace.c                    |  48 ++++---
 arch/arm64/kernel/signal.c                    | 176 +++-----------------------
 arch/arm64/kernel/signal32.c                  |  85 -------------
 arch/arm64/kernel/signal32_common.c           | 116 +++++++++++++++++
 arch/arm64/kernel/signal_common.c             | 174 +++++++++++++++++++++++++
 arch/arm64/kernel/signal_ilp32.c              | 126 ++++++++++++++++++
 arch/arm64/kernel/sys_ilp32.c                 |  77 +++++++++++
 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 ++++++++--
 include/linux/thread_bits.h                   |  57 +++++++++
 include/linux/thread_info.h                   |  44 +------
 44 files changed, 1343 insertions(+), 410 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/entry32-common.S
 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_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
 create mode 100644 include/linux/thread_bits.h

-- 
2.5.0

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

* [PATCH v6 01/20] arm64: ilp32: add documentation on the ILP32 ABI for ARM64
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

Based on Andrew Pinski's patch-series.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 Documentation/arm64/ilp32.txt | 17 +++++++++++++++++
 1 file changed, 17 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..ad3a48e
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,17 @@
+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 sigframe, taken from lp64 to
+handle AARCH64 register set.
+
+Syscalls openat and open_by_handle_at are as non-compat as, it's
+temporary solution. There is expected global refactoring for all
+platforms.
+
-- 
2.5.0


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

* [PATCH v6 01/20] arm64: ilp32: add documentation on the ILP32 ABI for ARM64
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

Based on Andrew Pinski's patch-series.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 Documentation/arm64/ilp32.txt | 17 +++++++++++++++++
 1 file changed, 17 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..ad3a48e
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,17 @@
+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 sigframe, taken from lp64 to
+handle AARCH64 register set.
+
+Syscalls openat and open_by_handle_at are as non-compat as, it's
+temporary solution. There is expected global refactoring for all
+platforms.
+
-- 
2.5.0

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

* [PATCH v6 02/20] arm64: ensure the kernel is compiled for LP64
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

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).

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/Makefile | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index d10b5d4..432b69a 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -29,14 +29,19 @@ endif
 KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr)
 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] 156+ messages in thread

* [PATCH v6 02/20] arm64: ensure the kernel is compiled for LP64
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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).

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/Makefile | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index d10b5d4..432b69a 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -29,14 +29,19 @@ endif
 KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr)
 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] 156+ messages in thread

* [PATCH v6 03/20] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/Kconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 07d1811..4753d435 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -679,6 +679,11 @@ menu "Userspace binary formats"
 source "fs/Kconfig.binfmt"
 
 config COMPAT
+	def_bool y
+	depends on AARCH32_EL0
+	select COMPAT_BINFMT_ELF
+
+config AARCH32_EL0
 	bool "Kernel support for 32-bit EL0"
 	depends on !ARM64_64K_PAGES || EXPERT
 	select COMPAT_BINFMT_ELF
-- 
2.5.0


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

* [PATCH v6 03/20] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrew Pinski <apinski@cavium.com>

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/Kconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 07d1811..4753d435 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -679,6 +679,11 @@ menu "Userspace binary formats"
 source "fs/Kconfig.binfmt"
 
 config COMPAT
+	def_bool y
+	depends on AARCH32_EL0
+	select COMPAT_BINFMT_ELF
+
+config AARCH32_EL0
 	bool "Kernel support for 32-bit EL0"
 	depends on !ARM64_64K_PAGES || EXPERT
 	select COMPAT_BINFMT_ELF
-- 
2.5.0

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

* [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h       | 11 ++++++++---
 arch/arm64/include/asm/fpsimd.h    |  2 +-
 arch/arm64/include/asm/processor.h |  4 ++--
 arch/arm64/include/asm/ptrace.h    |  2 +-
 arch/arm64/include/asm/signal32.h  |  6 ++++--
 arch/arm64/include/asm/unistd.h    |  7 +++++--
 arch/arm64/kernel/Makefile         |  2 +-
 arch/arm64/kernel/asm-offsets.c    |  2 +-
 arch/arm64/kernel/entry.S          |  6 +++---
 arch/arm64/kernel/head.S           |  2 +-
 arch/arm64/kernel/ptrace.c         | 27 ++++++++++++++++++++-------
 arch/arm64/kernel/traps.c          |  2 +-
 arch/arm64/kernel/vdso.c           |  4 ++--
 13 files changed, 50 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..d255764 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -166,14 +166,16 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
+#ifdef CONFIG_AARCH32_EL0
+
 /* AArch32 registers. */
-#define COMPAT_ELF_NGREG		18
+#define COMPAT_A32_ELF_NGREG		18
 typedef unsigned int			compat_elf_greg_t;
-typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_ELF_NGREG];
+typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
 
 /* AArch32 EABI. */
 #define EF_ARM_EABI_MASK		0xff000000
-#define compat_elf_check_arch(x)	(((x)->e_machine == EM_ARM) && \
+#define compat_a32_elf_check_arch(x)	(((x)->e_machine == EM_ARM) && \
 					 ((x)->e_flags & EF_ARM_EABI_MASK))
 
 #define compat_start_thread		compat_start_thread
@@ -183,6 +185,9 @@ extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 				      int uses_interp);
 #define compat_arch_setup_additional_pages \
 					aarch32_setup_vectors_page
+#endif
+
+#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
 
 #endif /* CONFIG_COMPAT */
 
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/processor.h b/arch/arm64/include/asm/processor.h
index 98f3235..ff4abec 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -79,7 +79,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;
@@ -88,7 +88,7 @@ struct thread_struct {
 	struct debug_info	debug;		/* debugging */
 };
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define task_user_tls(t)						\
 ({									\
 	unsigned long *__tls;						\
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 536274e..1059b3f 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -120,7 +120,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..e6216ef 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,9 +13,8 @@
  * 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
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
@@ -26,7 +25,9 @@
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #define __ARCH_WANT_SYS_FORK
 #define __ARCH_WANT_SYS_VFORK
+#endif
 
+#ifdef CONFIG_COMPAT
 /*
  * Compat syscall numbers used by the AArch64 kernel.
  */
@@ -44,6 +45,8 @@
 #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 
+#define __ARCH_WANT_COMPAT_STAT64
+
 #define __NR_compat_syscalls		390
 #endif
 
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 22dc9bc..1470332 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,7 +20,7 @@ arm64-obj-y		:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   cpufeature.o alternative.o cacheinfo.o		\
 			   smp.o smp_spin_table.o topology.o
 
-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 8d89cf8..e3bcf77 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -51,7 +51,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/entry.S b/arch/arm64/kernel/entry.S
index 4306c93..52be5c8 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -212,7 +212,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
@@ -252,7 +252,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)
@@ -414,7 +414,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 90d09ed..d11d0b2 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -519,7 +519,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 1971f49..2a39b5d 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -76,7 +76,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())
@@ -651,7 +651,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 {
@@ -853,7 +853,7 @@ static int compat_tls_set(struct task_struct *target,
 static const struct user_regset aarch32_regsets[] = {
 	[REGSET_COMPAT_GPR] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = COMPAT_ELF_NGREG,
+		.n = COMPAT_A32_ELF_NGREG,
 		.size = sizeof(compat_elf_greg_t),
 		.align = sizeof(compat_elf_greg_t),
 		.get = compat_gpr_get,
@@ -877,7 +877,7 @@ static const struct user_regset_view user_aarch32_view = {
 static const struct user_regset aarch32_ptrace_regsets[] = {
 	[REGSET_GPR] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = COMPAT_ELF_NGREG,
+		.n = COMPAT_A32_ELF_NGREG,
 		.size = sizeof(compat_elf_greg_t),
 		.align = sizeof(compat_elf_greg_t),
 		.get = compat_gpr_get,
@@ -1109,7 +1109,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,
+long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
 	unsigned long addr = caddr;
@@ -1186,11 +1186,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#else /* !CONFIG_AARCH32_EL0 */
+#define compat_a32_arch_ptrace(child, request, caddr, cdata) (-1)
+#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)
+{
+	if (is_compat_task())
+		return compat_a32_arch_ptrace(child, request, caddr, cdata);
+	return compat_ptrace_request(child, request, caddr, cdata);
+}
+#endif
+
 
 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 f93aae5..9ce9894 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -363,7 +363,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];
 
-- 
2.5.0


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

* [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrew Pinski <apinski@cavium.com>

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h       | 11 ++++++++---
 arch/arm64/include/asm/fpsimd.h    |  2 +-
 arch/arm64/include/asm/processor.h |  4 ++--
 arch/arm64/include/asm/ptrace.h    |  2 +-
 arch/arm64/include/asm/signal32.h  |  6 ++++--
 arch/arm64/include/asm/unistd.h    |  7 +++++--
 arch/arm64/kernel/Makefile         |  2 +-
 arch/arm64/kernel/asm-offsets.c    |  2 +-
 arch/arm64/kernel/entry.S          |  6 +++---
 arch/arm64/kernel/head.S           |  2 +-
 arch/arm64/kernel/ptrace.c         | 27 ++++++++++++++++++++-------
 arch/arm64/kernel/traps.c          |  2 +-
 arch/arm64/kernel/vdso.c           |  4 ++--
 13 files changed, 50 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..d255764 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -166,14 +166,16 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
+#ifdef CONFIG_AARCH32_EL0
+
 /* AArch32 registers. */
-#define COMPAT_ELF_NGREG		18
+#define COMPAT_A32_ELF_NGREG		18
 typedef unsigned int			compat_elf_greg_t;
-typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_ELF_NGREG];
+typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
 
 /* AArch32 EABI. */
 #define EF_ARM_EABI_MASK		0xff000000
-#define compat_elf_check_arch(x)	(((x)->e_machine == EM_ARM) && \
+#define compat_a32_elf_check_arch(x)	(((x)->e_machine == EM_ARM) && \
 					 ((x)->e_flags & EF_ARM_EABI_MASK))
 
 #define compat_start_thread		compat_start_thread
@@ -183,6 +185,9 @@ extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 				      int uses_interp);
 #define compat_arch_setup_additional_pages \
 					aarch32_setup_vectors_page
+#endif
+
+#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
 
 #endif /* CONFIG_COMPAT */
 
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/processor.h b/arch/arm64/include/asm/processor.h
index 98f3235..ff4abec 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -79,7 +79,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;
@@ -88,7 +88,7 @@ struct thread_struct {
 	struct debug_info	debug;		/* debugging */
 };
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define task_user_tls(t)						\
 ({									\
 	unsigned long *__tls;						\
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 536274e..1059b3f 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -120,7 +120,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..e6216ef 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,9 +13,8 @@
  * 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
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
@@ -26,7 +25,9 @@
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #define __ARCH_WANT_SYS_FORK
 #define __ARCH_WANT_SYS_VFORK
+#endif
 
+#ifdef CONFIG_COMPAT
 /*
  * Compat syscall numbers used by the AArch64 kernel.
  */
@@ -44,6 +45,8 @@
 #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
 #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
 
+#define __ARCH_WANT_COMPAT_STAT64
+
 #define __NR_compat_syscalls		390
 #endif
 
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 22dc9bc..1470332 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,7 +20,7 @@ arm64-obj-y		:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   cpufeature.o alternative.o cacheinfo.o		\
 			   smp.o smp_spin_table.o topology.o
 
-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 8d89cf8..e3bcf77 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -51,7 +51,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/entry.S b/arch/arm64/kernel/entry.S
index 4306c93..52be5c8 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -212,7 +212,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
@@ -252,7 +252,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)
@@ -414,7 +414,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 90d09ed..d11d0b2 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -519,7 +519,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 1971f49..2a39b5d 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -76,7 +76,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())
@@ -651,7 +651,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 {
@@ -853,7 +853,7 @@ static int compat_tls_set(struct task_struct *target,
 static const struct user_regset aarch32_regsets[] = {
 	[REGSET_COMPAT_GPR] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = COMPAT_ELF_NGREG,
+		.n = COMPAT_A32_ELF_NGREG,
 		.size = sizeof(compat_elf_greg_t),
 		.align = sizeof(compat_elf_greg_t),
 		.get = compat_gpr_get,
@@ -877,7 +877,7 @@ static const struct user_regset_view user_aarch32_view = {
 static const struct user_regset aarch32_ptrace_regsets[] = {
 	[REGSET_GPR] = {
 		.core_note_type = NT_PRSTATUS,
-		.n = COMPAT_ELF_NGREG,
+		.n = COMPAT_A32_ELF_NGREG,
 		.size = sizeof(compat_elf_greg_t),
 		.align = sizeof(compat_elf_greg_t),
 		.get = compat_gpr_get,
@@ -1109,7 +1109,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,
+long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
 	unsigned long addr = caddr;
@@ -1186,11 +1186,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#else /* !CONFIG_AARCH32_EL0 */
+#define compat_a32_arch_ptrace(child, request, caddr, cdata) (-1)
+#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)
+{
+	if (is_compat_task())
+		return compat_a32_arch_ptrace(child, request, caddr, cdata);
+	return compat_ptrace_request(child, request, caddr, cdata);
+}
+#endif
+
 
 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 f93aae5..9ce9894 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -363,7 +363,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];
 
-- 
2.5.0

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

* [PATCH v6 05/20] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski

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.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <apinski@cavium.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] 156+ messages in thread

* [PATCH v6 05/20] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <apinski@cavium.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] 156+ messages in thread

* [PATCH v6 06/20] thread: move thread bits accessors to separated file
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

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 | 57 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/thread_info.h | 44 +---------------------------------
 2 files changed, 58 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..8d1e3be
--- /dev/null
+++ b/include/linux/thread_bits.h
@@ -0,0 +1,57 @@
+
+/* thread_bits.h: common low-level thread bits accessors */
+
+#ifndef _LINUX_THREAD_BITS_H
+#define _LINUX_THREAD_BITS_H
+
+#ifdef __KERNEL__
+#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 /* __KERNEL_  */
+#endif /* _LINUX_THREAD_BITS_H */
+
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index ff307b5..c905fec 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__
 
@@ -61,47 +60,6 @@ extern long do_no_restart_syscall(struct restart_block *parm);
 # define THREADINFO_GFP		(GFP_KERNEL | __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] 156+ messages in thread

* [PATCH v6 06/20] thread: move thread bits accessors to separated file
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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 | 57 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/thread_info.h | 44 +---------------------------------
 2 files changed, 58 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..8d1e3be
--- /dev/null
+++ b/include/linux/thread_bits.h
@@ -0,0 +1,57 @@
+
+/* thread_bits.h: common low-level thread bits accessors */
+
+#ifndef _LINUX_THREAD_BITS_H
+#define _LINUX_THREAD_BITS_H
+
+#ifdef __KERNEL__
+#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 /* __KERNEL_  */
+#endif /* _LINUX_THREAD_BITS_H */
+
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index ff307b5..c905fec 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__
 
@@ -61,47 +60,6 @@ extern long do_no_restart_syscall(struct restart_block *parm);
 # define THREADINFO_GFP		(GFP_KERNEL | __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] 156+ messages in thread

* [PATCH v6 07/20] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	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 invlude 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.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/compat.h      | 19 ++---------
 arch/arm64/include/asm/elf.h         |  3 +-
 arch/arm64/include/asm/is_compat.h   | 62 ++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/memory.h      |  3 +-
 arch/arm64/include/asm/processor.h   |  5 +--
 arch/arm64/include/asm/thread_info.h |  2 +-
 arch/arm64/kernel/hw_breakpoint.c    |  6 ++--
 arch/arm64/kernel/perf_regs.c        |  2 +-
 arch/arm64/kernel/process.c          |  5 ++-
 arch/arm64/kernel/ptrace.c           | 11 +++----
 arch/arm64/kernel/signal.c           |  4 +--
 arch/arm64/kernel/traps.c            |  3 +-
 12 files changed, 87 insertions(+), 38 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 7fbed69..8e40dec 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -25,6 +25,8 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 
+#include <asm/is_compat.h>
+
 #define COMPAT_USER_HZ		100
 #ifdef __AARCH64EB__
 #define COMPAT_UTS_MACHINE	"armv8b\0\0"
@@ -299,23 +301,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 d255764..8786ca5 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -16,6 +16,7 @@
 #ifndef __ASM_ELF_H
 #define __ASM_ELF_H
 
+#include <asm/is_compat.h>
 #include <asm/hwcap.h>
 
 /*
@@ -149,7 +150,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 /* 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
diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
new file mode 100644
index 0000000..476db90
--- /dev/null
+++ b/arch/arm64/include/asm/is_compat.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Cavium Inc.
+ *
+ * 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
+#ifdef __KERNEL__
+#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 /* __KERNEL__ */
+#endif /* __ASM_IS_COMPAT_H */
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 6b4c3ad..ea4b10d 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -25,6 +25,7 @@
 #include <linux/const.h>
 #include <linux/types.h>
 #include <asm/sizes.h>
+#include <asm/is_compat.h>
 
 /*
  * Allow for constants defined here to be used from assembly code
@@ -58,7 +59,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 ff4abec..f1ba514 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -29,6 +29,7 @@
 
 #include <linux/string.h>
 
+#include <asm/is_compat.h>
 #include <asm/fpsimd.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/pgtable-hwdef.h>
@@ -39,7 +40,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
@@ -92,7 +93,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/thread_info.h b/arch/arm64/include/asm/thread_info.h
index dcd06d1..7d03565 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -110,7 +110,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_SWITCH_MM		23	/* deferred switch_mm */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index bba85c8..917f6e1 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -420,7 +420,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_task()) {
+		if (is_a32_compat_task()) {
 			if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
 			    info->ctrl.len != ARM_BREAKPOINT_LEN_4)
 				return -EINVAL;
@@ -477,7 +477,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	 * AArch32 tasks expect some simple alignment fixups, so emulate
 	 * that here.
 	 */
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
 			alignment_mask = 0x7;
 		else
@@ -664,7 +664,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 223b093..e109f49 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,7 +45,6 @@
 #include <linux/personality.h>
 #include <linux/notifier.h>
 
-#include <asm/compat.h>
 #include <asm/cacheflush.h>
 #include <asm/fpsimd.h>
 #include <asm/mmu_context.h>
@@ -259,7 +258,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)
@@ -296,7 +295,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 2a39b5d..816b432 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>
@@ -79,7 +78,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) {
@@ -1194,7 +1193,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		return compat_a32_arch_ptrace(child, request, caddr, cdata);
 	return compat_ptrace_request(child, request, caddr, cdata);
 }
@@ -1210,9 +1209,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;
@@ -1239,7 +1238,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;
 
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index e18c48c..65baaef 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 9ce9894..0afab39 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>
@@ -365,7 +366,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] 156+ messages in thread

* [PATCH v6 07/20] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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 invlude 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.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/compat.h      | 19 ++---------
 arch/arm64/include/asm/elf.h         |  3 +-
 arch/arm64/include/asm/is_compat.h   | 62 ++++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/memory.h      |  3 +-
 arch/arm64/include/asm/processor.h   |  5 +--
 arch/arm64/include/asm/thread_info.h |  2 +-
 arch/arm64/kernel/hw_breakpoint.c    |  6 ++--
 arch/arm64/kernel/perf_regs.c        |  2 +-
 arch/arm64/kernel/process.c          |  5 ++-
 arch/arm64/kernel/ptrace.c           | 11 +++----
 arch/arm64/kernel/signal.c           |  4 +--
 arch/arm64/kernel/traps.c            |  3 +-
 12 files changed, 87 insertions(+), 38 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 7fbed69..8e40dec 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -25,6 +25,8 @@
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 
+#include <asm/is_compat.h>
+
 #define COMPAT_USER_HZ		100
 #ifdef __AARCH64EB__
 #define COMPAT_UTS_MACHINE	"armv8b\0\0"
@@ -299,23 +301,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 d255764..8786ca5 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -16,6 +16,7 @@
 #ifndef __ASM_ELF_H
 #define __ASM_ELF_H
 
+#include <asm/is_compat.h>
 #include <asm/hwcap.h>
 
 /*
@@ -149,7 +150,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 /* 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
diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
new file mode 100644
index 0000000..476db90
--- /dev/null
+++ b/arch/arm64/include/asm/is_compat.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 Cavium Inc.
+ *
+ * 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
+#ifdef __KERNEL__
+#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 /* __KERNEL__ */
+#endif /* __ASM_IS_COMPAT_H */
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 6b4c3ad..ea4b10d 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -25,6 +25,7 @@
 #include <linux/const.h>
 #include <linux/types.h>
 #include <asm/sizes.h>
+#include <asm/is_compat.h>
 
 /*
  * Allow for constants defined here to be used from assembly code
@@ -58,7 +59,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 ff4abec..f1ba514 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -29,6 +29,7 @@
 
 #include <linux/string.h>
 
+#include <asm/is_compat.h>
 #include <asm/fpsimd.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/pgtable-hwdef.h>
@@ -39,7 +40,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
@@ -92,7 +93,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/thread_info.h b/arch/arm64/include/asm/thread_info.h
index dcd06d1..7d03565 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -110,7 +110,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_SWITCH_MM		23	/* deferred switch_mm */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index bba85c8..917f6e1 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -420,7 +420,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_task()) {
+		if (is_a32_compat_task()) {
 			if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
 			    info->ctrl.len != ARM_BREAKPOINT_LEN_4)
 				return -EINVAL;
@@ -477,7 +477,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	 * AArch32 tasks expect some simple alignment fixups, so emulate
 	 * that here.
 	 */
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
 			alignment_mask = 0x7;
 		else
@@ -664,7 +664,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 223b093..e109f49 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,7 +45,6 @@
 #include <linux/personality.h>
 #include <linux/notifier.h>
 
-#include <asm/compat.h>
 #include <asm/cacheflush.h>
 #include <asm/fpsimd.h>
 #include <asm/mmu_context.h>
@@ -259,7 +258,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)
@@ -296,7 +295,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 2a39b5d..816b432 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>
@@ -79,7 +78,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) {
@@ -1194,7 +1193,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			compat_ulong_t caddr, compat_ulong_t cdata)
 {
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		return compat_a32_arch_ptrace(child, request, caddr, cdata);
 	return compat_ptrace_request(child, request, caddr, cdata);
 }
@@ -1210,9 +1209,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;
@@ -1239,7 +1238,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;
 
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index e18c48c..65baaef 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 9ce9894..0afab39 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>
@@ -365,7 +366,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] 156+ messages in thread

* [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/is_compat.h   | 30 +++++++++++++++++++++++++++---
 arch/arm64/include/asm/thread_info.h |  1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
index 476db90..89b1f65 100644
--- a/arch/arm64/include/asm/is_compat.h
+++ b/arch/arm64/include/asm/is_compat.h
@@ -36,7 +36,6 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 #else
 
 static inline int is_a32_compat_task(void)
-
 {
 	return 0;
 }
@@ -45,14 +44,39 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 {
 	return 0;
 }
-
 #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 7d03565..e72de74 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -112,6 +112,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SINGLESTEP		21
 #define TIF_32BIT		22	/* AARCH32 process */
 #define TIF_SWITCH_MM		23	/* deferred switch_mm */
+#define TIF_32BIT_AARCH64	24	/* 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] 156+ messages in thread

* [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/is_compat.h   | 30 +++++++++++++++++++++++++++---
 arch/arm64/include/asm/thread_info.h |  1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
index 476db90..89b1f65 100644
--- a/arch/arm64/include/asm/is_compat.h
+++ b/arch/arm64/include/asm/is_compat.h
@@ -36,7 +36,6 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 #else
 
 static inline int is_a32_compat_task(void)
-
 {
 	return 0;
 }
@@ -45,14 +44,39 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 {
 	return 0;
 }
-
 #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 7d03565..e72de74 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -112,6 +112,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SINGLESTEP		21
 #define TIF_32BIT		22	/* AARCH32 process */
 #define TIF_SWITCH_MM		23	/* deferred switch_mm */
+#define TIF_32BIT_AARCH64	24	/* 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] 156+ messages in thread

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/hwcap.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 0ad7351..1e5361e 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -47,9 +47,17 @@
 #define ELF_HWCAP		(elf_hwcap)
 
 #ifdef CONFIG_COMPAT
-#define COMPAT_ELF_HWCAP	(compat_elf_hwcap)
-#define COMPAT_ELF_HWCAP2	(compat_elf_hwcap2)
 extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
+#define COMPAT_ELF_HWCAP	\
+	(is_a32_compat_task()	\
+	  ? compat_elf_hwcap	\
+	  : elf_hwcap)
+
+#define COMPAT_ELF_HWCAP2	\
+	(is_a32_compat_task()	\
+	  ? compat_elf_hwcap2	\
+	  : 0)
+
 #endif
 
 extern unsigned long elf_hwcap;
-- 
2.5.0


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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrew Pinski <apinski@cavium.com>

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/hwcap.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 0ad7351..1e5361e 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -47,9 +47,17 @@
 #define ELF_HWCAP		(elf_hwcap)
 
 #ifdef CONFIG_COMPAT
-#define COMPAT_ELF_HWCAP	(compat_elf_hwcap)
-#define COMPAT_ELF_HWCAP2	(compat_elf_hwcap2)
 extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
+#define COMPAT_ELF_HWCAP	\
+	(is_a32_compat_task()	\
+	  ? compat_elf_hwcap	\
+	  : elf_hwcap)
+
+#define COMPAT_ELF_HWCAP2	\
+	(is_a32_compat_task()	\
+	  ? compat_elf_hwcap2	\
+	  : 0)
+
 #endif
 
 extern unsigned long elf_hwcap;
-- 
2.5.0

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

* [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

If we have both ILP32 and AARCH32 compiled in, we need use the non compat start
thread for ILP32.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/processor.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index f1ba514..e365280 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -124,6 +124,13 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc,
 static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 				       unsigned long sp)
 {
+#ifdef CONFIG_ARM64_ILP32
+	/* ILP32 threads are started the same way as LP64 threads. */
+	if (is_ilp32_compat_task()) {
+		start_thread(regs, pc, sp);
+		return;
+	}
+#endif
 	start_thread_common(regs, pc);
 	regs->pstate = COMPAT_PSR_MODE_USR;
 	if (pc & 1)
-- 
2.5.0


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

* [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrew Pinski <apinski@cavium.com>

If we have both ILP32 and AARCH32 compiled in, we need use the non compat start
thread for ILP32.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/processor.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index f1ba514..e365280 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -124,6 +124,13 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc,
 static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 				       unsigned long sp)
 {
+#ifdef CONFIG_ARM64_ILP32
+	/* ILP32 threads are started the same way as LP64 threads. */
+	if (is_ilp32_compat_task()) {
+		start_thread(regs, pc, sp);
+		return;
+	}
+#endif
 	start_thread_common(regs, pc);
 	regs->pstate = COMPAT_PSR_MODE_USR;
 	if (pc & 1)
-- 
2.5.0

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

* [PATCH v6 11/20] arm64:ilp32: support core dump generation for ILP32
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski

From: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>

This patch supports core dumping on ILP32.
We need a few extra macros (COMPAT_PR_REG_SIZE and COMPAT_PRSTATUS_SIZE) due
to size differences of the register sets.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h | 104 ++++++++++++++++++++++++++++++++++++++-----
 arch/arm64/kernel/ptrace.c   |  12 ++---
 2 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 8786ca5..4e2e3c0 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -135,7 +135,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 {									\
@@ -167,12 +171,15 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
+extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
+				      int uses_interp);
+
 #ifdef CONFIG_AARCH32_EL0
 
 /* AArch32 registers. */
 #define COMPAT_A32_ELF_NGREG		18
-typedef unsigned int			compat_elf_greg_t;
-typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
+typedef unsigned int			compat_a32_elf_greg_t;
+typedef compat_a32_elf_greg_t		compat_a32_elf_gregset_t[COMPAT_A32_ELF_NGREG];
 
 /* AArch32 EABI. */
 #define EF_ARM_EABI_MASK		0xff000000
@@ -180,15 +187,92 @@ typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_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_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
+#define COMPAT_A32_SET_PERSONALITY(ex)		\
+do {						\
+	clear_thread_flag(TIF_32BIT_AARCH64);	\
+	set_thread_flag(TIF_32BIT);		\
+} while (0)
+#define COMPAT_A32_ARCH_DLINFO		do {} while (0)
+
+#else
+
+typedef elf_greg_t			compat_elf_greg_t;
+typedef elf_gregset_t			compat_elf_gregset_t;
+#define compat_a32_elf_check_arch(x)	0
+#define COMPAT_A32_SET_PERSONALITY(ex)	do {} while (0)
+#define COMPAT_A32_ARCH_DLINFO		do {} while (0)
+#endif
+
+/*
+ * If ILP32 is turned on, we want to define the compat_elf_greg_t to the non compat
+ * one and define PR_REG_SIZE/PRSTATUS_SIZE/SET_PR_FPVALID so we pick up the correct
+ * ones for AARCH32. Note also the definition of the macros have to be correct for
+ * LP64 as this file is included in the standard binfmt_elf.c.
+ */
+#ifdef CONFIG_ARM64_ILP32
+typedef elf_greg_t			compat_elf_greg_t;
+typedef elf_gregset_t			compat_elf_gregset_t;
+#ifdef CONFIG_AARCH32_EL0
+#define PR_REG_SIZE(S)			(is_a32_compat_task() \
+						? sizeof(compat_a32_elf_gregset_t) \
+						: sizeof(elf_gregset_t))
+#endif
+
+/*
+ * struct elf_prstatus is defined in include/uapi/linux/elfcore.h,
+ * and has different sise for supported ABIs
+ */
+#define PRSTATUS_SIZE(S)		(is_a32_compat_task() ? 124 : (is_ilp32_compat_task() ? 352 : 392))
+
+#define SET_PR_FPVALID(S, V)							\
+do {										\
+	*(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE((S)->pr_reg)) = (V);	\
+} while (0)
+#else
+typedef compat_a32_elf_greg_t compat_elf_greg_t;
+typedef compat_a32_elf_gregset_t compat_elf_gregset_t;
+#endif
+
+#ifdef CONFIG_ARM64_ILP32
+#define compat_ilp32_elf_check_arch(x) ((x)->e_machine == EM_AARCH64)
+#define COMPAT_ILP32_SET_PERSONALITY(ex)	\
+do {						\
+	set_thread_flag(TIF_32BIT_AARCH64);	\
+	clear_thread_flag(TIF_32BIT);		\
+} while (0)
+#define COMPAT_ILP32_ARCH_DLINFO					\
+do {									\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
+		    (elf_addr_t)(long)current->mm->context.vdso);	\
+} while (0)
+#else
+#define compat_ilp32_elf_check_arch(x) 0
+#define COMPAT_ILP32_SET_PERSONALITY(ex)	do {} while (0)
+#define COMPAT_ILP32_ARCH_DLINFO		do {} while (0)
 #endif
 
-#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
+#define compat_elf_check_arch(x)	(compat_a32_elf_check_arch(x) || compat_ilp32_elf_check_arch(x))
+#define COMPAT_SET_PERSONALITY(ex)			\
+do {							\
+	if (compat_a32_elf_check_arch(&ex))		\
+		COMPAT_A32_SET_PERSONALITY(ex);		\
+	else						\
+		COMPAT_ILP32_SET_PERSONALITY(ex);	\
+} while (0)
+
+/* ILP32 uses the "LP64-like" vdso pages */
+#define compat_arch_setup_additional_pages	\
+	(is_a32_compat_task()			\
+	 ? &aarch32_setup_vectors_page		\
+	 : &(arch_setup_additional_pages))
+
+#define COMPAT_ARCH_DLINFO			\
+do {						\
+	if (is_a32_compat_task())		\
+		COMPAT_A32_ARCH_DLINFO;		\
+	else					\
+		COMPAT_ILP32_ARCH_DLINFO;	\
+} while (0)
 
 #endif /* CONFIG_COMPAT */
 
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 816b432..a9d07a9 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -853,8 +853,8 @@ static const struct user_regset aarch32_regsets[] = {
 	[REGSET_COMPAT_GPR] = {
 		.core_note_type = NT_PRSTATUS,
 		.n = COMPAT_A32_ELF_NGREG,
-		.size = sizeof(compat_elf_greg_t),
-		.align = sizeof(compat_elf_greg_t),
+		.size = sizeof(compat_a32_elf_greg_t),
+		.align = sizeof(compat_a32_elf_greg_t),
 		.get = compat_gpr_get,
 		.set = compat_gpr_set
 	},
@@ -945,7 +945,7 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
 		tmp = tsk->mm->start_data;
 	else if (off == COMPAT_PT_TEXT_END_ADDR)
 		tmp = tsk->mm->end_code;
-	else if (off < sizeof(compat_elf_gregset_t))
+	else if (off < sizeof(compat_a32_elf_gregset_t))
 		return copy_regset_to_user(tsk, &user_aarch32_view,
 					   REGSET_COMPAT_GPR, off,
 					   sizeof(compat_ulong_t), ret);
@@ -966,7 +966,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
 	if (off & 3 || off >= COMPAT_USER_SZ)
 		return -EIO;
 
-	if (off >= sizeof(compat_elf_gregset_t))
+	if (off >= sizeof(compat_a32_elf_gregset_t))
 		return 0;
 
 	set_fs(KERNEL_DS);
@@ -1129,7 +1129,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 			ret = copy_regset_to_user(child,
 						  &user_aarch32_view,
 						  REGSET_COMPAT_GPR,
-						  0, sizeof(compat_elf_gregset_t),
+						  0, sizeof(compat_a32_elf_gregset_t),
 						  datap);
 			break;
 
@@ -1137,7 +1137,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 			ret = copy_regset_from_user(child,
 						    &user_aarch32_view,
 						    REGSET_COMPAT_GPR,
-						    0, sizeof(compat_elf_gregset_t),
+						    0, sizeof(compat_a32_elf_gregset_t),
 						    datap);
 			break;
 
-- 
2.5.0


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

* [PATCH v6 11/20] arm64:ilp32: support core dump generation for ILP32
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>

This patch supports core dumping on ILP32.
We need a few extra macros (COMPAT_PR_REG_SIZE and COMPAT_PRSTATUS_SIZE) due
to size differences of the register sets.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h | 104 ++++++++++++++++++++++++++++++++++++++-----
 arch/arm64/kernel/ptrace.c   |  12 ++---
 2 files changed, 100 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 8786ca5..4e2e3c0 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -135,7 +135,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 {									\
@@ -167,12 +171,15 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
 
+extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
+				      int uses_interp);
+
 #ifdef CONFIG_AARCH32_EL0
 
 /* AArch32 registers. */
 #define COMPAT_A32_ELF_NGREG		18
-typedef unsigned int			compat_elf_greg_t;
-typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
+typedef unsigned int			compat_a32_elf_greg_t;
+typedef compat_a32_elf_greg_t		compat_a32_elf_gregset_t[COMPAT_A32_ELF_NGREG];
 
 /* AArch32 EABI. */
 #define EF_ARM_EABI_MASK		0xff000000
@@ -180,15 +187,92 @@ typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_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_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
+#define COMPAT_A32_SET_PERSONALITY(ex)		\
+do {						\
+	clear_thread_flag(TIF_32BIT_AARCH64);	\
+	set_thread_flag(TIF_32BIT);		\
+} while (0)
+#define COMPAT_A32_ARCH_DLINFO		do {} while (0)
+
+#else
+
+typedef elf_greg_t			compat_elf_greg_t;
+typedef elf_gregset_t			compat_elf_gregset_t;
+#define compat_a32_elf_check_arch(x)	0
+#define COMPAT_A32_SET_PERSONALITY(ex)	do {} while (0)
+#define COMPAT_A32_ARCH_DLINFO		do {} while (0)
+#endif
+
+/*
+ * If ILP32 is turned on, we want to define the compat_elf_greg_t to the non compat
+ * one and define PR_REG_SIZE/PRSTATUS_SIZE/SET_PR_FPVALID so we pick up the correct
+ * ones for AARCH32. Note also the definition of the macros have to be correct for
+ * LP64 as this file is included in the standard binfmt_elf.c.
+ */
+#ifdef CONFIG_ARM64_ILP32
+typedef elf_greg_t			compat_elf_greg_t;
+typedef elf_gregset_t			compat_elf_gregset_t;
+#ifdef CONFIG_AARCH32_EL0
+#define PR_REG_SIZE(S)			(is_a32_compat_task() \
+						? sizeof(compat_a32_elf_gregset_t) \
+						: sizeof(elf_gregset_t))
+#endif
+
+/*
+ * struct elf_prstatus is defined in include/uapi/linux/elfcore.h,
+ * and has different sise for supported ABIs
+ */
+#define PRSTATUS_SIZE(S)		(is_a32_compat_task() ? 124 : (is_ilp32_compat_task() ? 352 : 392))
+
+#define SET_PR_FPVALID(S, V)							\
+do {										\
+	*(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE((S)->pr_reg)) = (V);	\
+} while (0)
+#else
+typedef compat_a32_elf_greg_t compat_elf_greg_t;
+typedef compat_a32_elf_gregset_t compat_elf_gregset_t;
+#endif
+
+#ifdef CONFIG_ARM64_ILP32
+#define compat_ilp32_elf_check_arch(x) ((x)->e_machine == EM_AARCH64)
+#define COMPAT_ILP32_SET_PERSONALITY(ex)	\
+do {						\
+	set_thread_flag(TIF_32BIT_AARCH64);	\
+	clear_thread_flag(TIF_32BIT);		\
+} while (0)
+#define COMPAT_ILP32_ARCH_DLINFO					\
+do {									\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
+		    (elf_addr_t)(long)current->mm->context.vdso);	\
+} while (0)
+#else
+#define compat_ilp32_elf_check_arch(x) 0
+#define COMPAT_ILP32_SET_PERSONALITY(ex)	do {} while (0)
+#define COMPAT_ILP32_ARCH_DLINFO		do {} while (0)
 #endif
 
-#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
+#define compat_elf_check_arch(x)	(compat_a32_elf_check_arch(x) || compat_ilp32_elf_check_arch(x))
+#define COMPAT_SET_PERSONALITY(ex)			\
+do {							\
+	if (compat_a32_elf_check_arch(&ex))		\
+		COMPAT_A32_SET_PERSONALITY(ex);		\
+	else						\
+		COMPAT_ILP32_SET_PERSONALITY(ex);	\
+} while (0)
+
+/* ILP32 uses the "LP64-like" vdso pages */
+#define compat_arch_setup_additional_pages	\
+	(is_a32_compat_task()			\
+	 ? &aarch32_setup_vectors_page		\
+	 : &(arch_setup_additional_pages))
+
+#define COMPAT_ARCH_DLINFO			\
+do {						\
+	if (is_a32_compat_task())		\
+		COMPAT_A32_ARCH_DLINFO;		\
+	else					\
+		COMPAT_ILP32_ARCH_DLINFO;	\
+} while (0)
 
 #endif /* CONFIG_COMPAT */
 
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 816b432..a9d07a9 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -853,8 +853,8 @@ static const struct user_regset aarch32_regsets[] = {
 	[REGSET_COMPAT_GPR] = {
 		.core_note_type = NT_PRSTATUS,
 		.n = COMPAT_A32_ELF_NGREG,
-		.size = sizeof(compat_elf_greg_t),
-		.align = sizeof(compat_elf_greg_t),
+		.size = sizeof(compat_a32_elf_greg_t),
+		.align = sizeof(compat_a32_elf_greg_t),
 		.get = compat_gpr_get,
 		.set = compat_gpr_set
 	},
@@ -945,7 +945,7 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
 		tmp = tsk->mm->start_data;
 	else if (off == COMPAT_PT_TEXT_END_ADDR)
 		tmp = tsk->mm->end_code;
-	else if (off < sizeof(compat_elf_gregset_t))
+	else if (off < sizeof(compat_a32_elf_gregset_t))
 		return copy_regset_to_user(tsk, &user_aarch32_view,
 					   REGSET_COMPAT_GPR, off,
 					   sizeof(compat_ulong_t), ret);
@@ -966,7 +966,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
 	if (off & 3 || off >= COMPAT_USER_SZ)
 		return -EIO;
 
-	if (off >= sizeof(compat_elf_gregset_t))
+	if (off >= sizeof(compat_a32_elf_gregset_t))
 		return 0;
 
 	set_fs(KERNEL_DS);
@@ -1129,7 +1129,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 			ret = copy_regset_to_user(child,
 						  &user_aarch32_view,
 						  REGSET_COMPAT_GPR,
-						  0, sizeof(compat_elf_gregset_t),
+						  0, sizeof(compat_a32_elf_gregset_t),
 						  datap);
 			break;
 
@@ -1137,7 +1137,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
 			ret = copy_regset_from_user(child,
 						    &user_aarch32_view,
 						    REGSET_COMPAT_GPR,
-						    0, sizeof(compat_elf_gregset_t),
+						    0, sizeof(compat_a32_elf_gregset_t),
 						    datap);
 			break;
 
-- 
2.5.0

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	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.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/unistd.h |  6 ++++
 arch/arm64/kernel/Makefile      |  1 +
 arch/arm64/kernel/entry.S       | 12 +++++++-
 arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 1 deletion(-)
 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 e6216ef..230db54 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,6 +13,12 @@
  * 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_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_SYS_GETHOSTNAME
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 1470332..8787347 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,6 +24,7 @@ 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
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 52be5c8..bcd921a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -664,9 +664,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
@@ -686,6 +690,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..8ce79db
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,65 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2015 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>
+
+/* 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_sigaltstack         sys_sigaltstack
+#define compat_sys_sync_file_range     sys_sync_file_range
+#define compat_sys_truncate64          sys_truncate
+#define sys_llseek                     sys_lseek
+
+#define compat_sys_open_by_handle_at   sys_open_by_handle_at
+#define compat_sys_openat              sys_openat
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#undef __SC_COMP
+#undef __SC_3264
+#undef __SC_COMP_3264
+
+#define __SYSCALL_COMPAT
+#define __SYSCALL(nr, sym)	[nr] = 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] 156+ messages in thread

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/unistd.h |  6 ++++
 arch/arm64/kernel/Makefile      |  1 +
 arch/arm64/kernel/entry.S       | 12 +++++++-
 arch/arm64/kernel/sys_ilp32.c   | 65 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 1 deletion(-)
 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 e6216ef..230db54 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,6 +13,12 @@
  * 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_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_SYS_GETHOSTNAME
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 1470332..8787347 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,6 +24,7 @@ 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
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 52be5c8..bcd921a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -664,9 +664,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
@@ -686,6 +690,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..8ce79db
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,65 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2015 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>
+
+/* 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_sigaltstack         sys_sigaltstack
+#define compat_sys_sync_file_range     sys_sync_file_range
+#define compat_sys_truncate64          sys_truncate
+#define sys_llseek                     sys_lseek
+
+#define compat_sys_open_by_handle_at   sys_open_by_handle_at
+#define compat_sys_openat              sys_openat
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#undef __SC_COMP
+#undef __SC_3264
+#undef __SC_COMP_3264
+
+#define __SYSCALL_COMPAT
+#define __SYSCALL(nr, sym)	[nr] = 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] 156+ messages in thread

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

From: Jan Dakinevich <jan.dakinevich@gmail.com>

statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
ilp32 to workaround some issues. Here we create common file to share aarch32
workarounds to with ilp32 code.

Reviewed-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com>
---
 arch/arm64/kernel/Makefile         |  1 +
 arch/arm64/kernel/entry32-common.S | 37 +++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/entry32.S        | 29 -----------------------------
 arch/arm64/kernel/sys_ilp32.c      |  9 +++++++++
 4 files changed, 47 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm64/kernel/entry32-common.S

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 8787347..837d730 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,6 +25,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   ../../arm/kernel/opcodes.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
+arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm64/kernel/entry32-common.S b/arch/arm64/kernel/entry32-common.S
new file mode 100644
index 0000000..2ad5912
--- /dev/null
+++ b/arch/arm64/kernel/entry32-common.S
@@ -0,0 +1,37 @@
+#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>
+
+ENTRY(compat_sys_statfs64_wrapper)
+	mov	w3, #84
+	cmp	w1, #88
+	csel	w1, w3, w1, eq
+	b	compat_sys_statfs64
+ENDPROC(compat_sys_statfs64_wrapper)
+
+ENTRY(compat_sys_fstatfs64_wrapper)
+	mov	w3, #84
+	cmp	w1, #88
+	csel	w1, w3, w1, eq
+	b	compat_sys_fstatfs64
+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)
+
diff --git a/arch/arm64/kernel/entry32.S b/arch/arm64/kernel/entry32.S
index f332d5d..8026129 100644
--- a/arch/arm64/kernel/entry32.S
+++ b/arch/arm64/kernel/entry32.S
@@ -40,35 +40,6 @@ ENTRY(compat_sys_rt_sigreturn_wrapper)
 	b	compat_sys_rt_sigreturn
 ENDPROC(compat_sys_rt_sigreturn_wrapper)
 
-ENTRY(compat_sys_statfs64_wrapper)
-	mov	w3, #84
-	cmp	w1, #88
-	csel	w1, w3, w1, eq
-	b	compat_sys_statfs64
-ENDPROC(compat_sys_statfs64_wrapper)
-
-ENTRY(compat_sys_fstatfs64_wrapper)
-	mov	w3, #84
-	cmp	w1, #88
-	csel	w1, w3, w1, eq
-	b	compat_sys_fstatfs64
-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
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index 8ce79db..c282fa2 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -45,6 +45,15 @@
 #define compat_sys_open_by_handle_at   sys_open_by_handle_at
 #define compat_sys_openat              sys_openat
 
+asmlinkage long compat_sys_mmap2_wrapper(void);
+#define sys_mmap2                      compat_sys_mmap2_wrapper
+
+asmlinkage long compat_sys_fstatfs64_wrapper(void);
+#define compat_sys_fstatfs64    compat_sys_fstatfs64_wrapper
+
+asmlinkage long compat_sys_statfs64_wrapper(void);
+#define compat_sys_statfs64             compat_sys_statfs64_wrapper
+
 #include <asm/syscall.h>
 
 #undef __SYSCALL
-- 
2.5.0


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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jan Dakinevich <jan.dakinevich@gmail.com>

statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
ilp32 to workaround some issues. Here we create common file to share aarch32
workarounds to with ilp32 code.

Reviewed-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Signed-off-by: Jan Dakinevich <jan.dakinevich@gmail.com>
---
 arch/arm64/kernel/Makefile         |  1 +
 arch/arm64/kernel/entry32-common.S | 37 +++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/entry32.S        | 29 -----------------------------
 arch/arm64/kernel/sys_ilp32.c      |  9 +++++++++
 4 files changed, 47 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm64/kernel/entry32-common.S

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 8787347..837d730 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,6 +25,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   ../../arm/kernel/opcodes.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
+arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm64/kernel/entry32-common.S b/arch/arm64/kernel/entry32-common.S
new file mode 100644
index 0000000..2ad5912
--- /dev/null
+++ b/arch/arm64/kernel/entry32-common.S
@@ -0,0 +1,37 @@
+#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>
+
+ENTRY(compat_sys_statfs64_wrapper)
+	mov	w3, #84
+	cmp	w1, #88
+	csel	w1, w3, w1, eq
+	b	compat_sys_statfs64
+ENDPROC(compat_sys_statfs64_wrapper)
+
+ENTRY(compat_sys_fstatfs64_wrapper)
+	mov	w3, #84
+	cmp	w1, #88
+	csel	w1, w3, w1, eq
+	b	compat_sys_fstatfs64
+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)
+
diff --git a/arch/arm64/kernel/entry32.S b/arch/arm64/kernel/entry32.S
index f332d5d..8026129 100644
--- a/arch/arm64/kernel/entry32.S
+++ b/arch/arm64/kernel/entry32.S
@@ -40,35 +40,6 @@ ENTRY(compat_sys_rt_sigreturn_wrapper)
 	b	compat_sys_rt_sigreturn
 ENDPROC(compat_sys_rt_sigreturn_wrapper)
 
-ENTRY(compat_sys_statfs64_wrapper)
-	mov	w3, #84
-	cmp	w1, #88
-	csel	w1, w3, w1, eq
-	b	compat_sys_statfs64
-ENDPROC(compat_sys_statfs64_wrapper)
-
-ENTRY(compat_sys_fstatfs64_wrapper)
-	mov	w3, #84
-	cmp	w1, #88
-	csel	w1, w3, w1, eq
-	b	compat_sys_fstatfs64
-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
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index 8ce79db..c282fa2 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -45,6 +45,15 @@
 #define compat_sys_open_by_handle_at   sys_open_by_handle_at
 #define compat_sys_openat              sys_openat
 
+asmlinkage long compat_sys_mmap2_wrapper(void);
+#define sys_mmap2                      compat_sys_mmap2_wrapper
+
+asmlinkage long compat_sys_fstatfs64_wrapper(void);
+#define compat_sys_fstatfs64    compat_sys_fstatfs64_wrapper
+
+asmlinkage long compat_sys_statfs64_wrapper(void);
+#define compat_sys_statfs64             compat_sys_statfs64_wrapper
+
 #include <asm/syscall.h>
 
 #undef __SYSCALL
-- 
2.5.0

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

* [PATCH v6 14/20] arm64: signal: wrap struct ucontext, fp and lr with struct sigframe
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

It helps to move common code for lp64 and ilp32 to separated header.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/kernel/signal.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 65baaef..20dca65 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -35,14 +35,18 @@
 #include <asm/signal32.h>
 #include <asm/vdso.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)
@@ -93,7 +97,7 @@ 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;
@@ -145,10 +149,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,7 +166,7 @@ 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;
@@ -230,13 +234,13 @@ static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
 }
 
 static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
-			 void __user *frame, int usig)
+			 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 +261,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] 156+ messages in thread

* [PATCH v6 14/20] arm64: signal: wrap struct ucontext, fp and lr with struct sigframe
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

It helps to move common code for lp64 and ilp32 to separated header.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/kernel/signal.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 65baaef..20dca65 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -35,14 +35,18 @@
 #include <asm/signal32.h>
 #include <asm/vdso.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)
@@ -93,7 +97,7 @@ 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;
@@ -145,10 +149,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,7 +166,7 @@ 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;
@@ -230,13 +234,13 @@ static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
 }
 
 static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
-			 void __user *frame, int usig)
+			 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 +261,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] 156+ messages in thread

* [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

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 |  39 ++++++++
 arch/arm64/kernel/Makefile             |   2 +-
 arch/arm64/kernel/signal.c             | 154 +----------------------------
 arch/arm64/kernel/signal_common.c      | 174 +++++++++++++++++++++++++++++++++
 4 files changed, 215 insertions(+), 154 deletions(-)
 create mode 100644 arch/arm64/include/asm/signal_common.h
 create mode 100644 arch/arm64/kernel/signal_common.c

diff --git a/arch/arm64/include/asm/signal_common.h b/arch/arm64/include/asm/signal_common.h
new file mode 100644
index 0000000..2fb3997
--- /dev/null
+++ b/arch/arm64/include/asm/signal_common.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 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>
+
+struct sigframe {
+	struct ucontext uc;
+	u64 fp;
+	u64 lr;
+};
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx);
+int restore_fpsimd_context(struct fpsimd_context __user *ctx);
+int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set);
+int restore_sigframe(struct pt_regs *regs, struct sigframe __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/Makefile b/arch/arm64/kernel/Makefile
index 837d730..94b8b84 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -18,7 +18,7 @@ arm64-obj-y		:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o	\
 			   return_address.o cpuinfo.o cpu_errata.o		\
 			   cpufeature.o alternative.o cacheinfo.o		\
-			   smp.o smp_spin_table.o topology.o
+			   smp.o smp_spin_table.o topology.o signal_common.o
 
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 20dca65..4b8efe5 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -33,13 +33,7 @@
 #include <asm/unistd.h>
 #include <asm/fpsimd.h>
 #include <asm/signal32.h>
-#include <asm/vdso.h>
-
-struct sigframe {
-	struct ucontext uc;
-	u64 fp;
-	u64 lr;
-};
+#include <asm/signal_common.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -49,87 +43,6 @@ struct rt_sigframe {
 	struct sigframe sig;
 };
 
-static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
-{
-	struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
-	int err;
-
-	/* dump the hardware registers to the fpsimd_state structure */
-	fpsimd_preserve_current_state();
-
-	/* copy the FP and status/control registers */
-	err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));
-	__put_user_error(fpsimd->fpsr, &ctx->fpsr, err);
-	__put_user_error(fpsimd->fpcr, &ctx->fpcr, err);
-
-	/* copy the magic/size information */
-	__put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err);
-	__put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err);
-
-	return err ? -EFAULT : 0;
-}
-
-static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
-{
-	struct fpsimd_state fpsimd;
-	__u32 magic, size;
-	int err = 0;
-
-	/* check the magic/size information */
-	__get_user_error(magic, &ctx->head.magic, err);
-	__get_user_error(size, &ctx->head.size, err);
-	if (err)
-		return -EFAULT;
-	if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
-		return -EINVAL;
-
-	/* copy the FP and status/control registers */
-	err = __copy_from_user(fpsimd.vregs, ctx->vregs,
-			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
-	__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
-
-	/* load the hardware registers from the fpsimd_state structure */
-	if (!err)
-		fpsimd_update_current_state(&fpsimd);
-
-	return err ? -EFAULT : 0;
-}
-
-static int restore_sigframe(struct pt_regs *regs,
-			    struct sigframe __user *sf)
-{
-	sigset_t set;
-	int i, err;
-	void *aux = sf->uc.uc_mcontext.__reserved;
-
-	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
-	if (err == 0)
-		set_current_blocked(&set);
-
-	for (i = 0; i < 31; i++)
-		__get_user_error(regs->regs[i], &sf->uc.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);
-
-	/*
-	 * Avoid sys_rt_sigreturn() restarting.
-	 */
-	regs->syscallno = ~0UL;
-
-	err |= !valid_user_regs(&regs->user_regs);
-
-	if (err == 0) {
-		struct fpsimd_context *fpsimd_ctx =
-			container_of(aux, struct fpsimd_context, head);
-		err |= restore_fpsimd_context(fpsimd_ctx);
-	}
-
-	return err;
-}
-
 asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
@@ -166,53 +79,6 @@ badframe:
 	return 0;
 }
 
-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;
-
-	/* 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);
-
-	for (i = 0; i < 31; i++)
-		__put_user_error(regs->regs[i], &sf->uc.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);
-
-	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
-
-	if (err == 0) {
-		struct fpsimd_context *fpsimd_ctx =
-			container_of(aux, struct fpsimd_context, head);
-		err |= preserve_fpsimd_context(fpsimd_ctx);
-		aux += sizeof(*fpsimd_ctx);
-	}
-
-	/* fault information, if valid */
-	if (current->thread.fault_code) {
-		struct esr_context *esr_ctx =
-			container_of(aux, struct esr_context, head);
-		__put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
-		__put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
-		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
-		aux += sizeof(*esr_ctx);
-	}
-
-	/* set the "end" magic */
-	end = aux;
-	__put_user_error(0, &end->magic, err);
-	__put_user_error(0, &end->size, err);
-
-	return err;
-}
-
 static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
 					       struct pt_regs *regs)
 {
@@ -233,24 +99,6 @@ 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, off_t sigframe_off, int usig)
-{
-	__sigrestore_t sigtramp;
-
-	regs->regs[0] = usig;
-	regs->sp = (unsigned long)frame;
-	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)
-		sigtramp = ka->sa.sa_restorer;
-	else
-		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
-
-	regs->regs[30] = (unsigned long)sigtramp;
-}
-
 static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 			  struct pt_regs *regs)
 {
diff --git a/arch/arm64/kernel/signal_common.c b/arch/arm64/kernel/signal_common.c
new file mode 100644
index 0000000..7043e5c
--- /dev/null
+++ b/arch/arm64/kernel/signal_common.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 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/>.
+ */
+
+#include <linux/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/fpsimd.h>
+#include <asm/vdso.h>
+#include <asm/signal_common.h>
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
+{
+	struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
+	int err;
+
+	/* dump the hardware registers to the fpsimd_state structure */
+	fpsimd_preserve_current_state();
+
+	/* copy the FP and status/control registers */
+	err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));
+	__put_user_error(fpsimd->fpsr, &ctx->fpsr, err);
+	__put_user_error(fpsimd->fpcr, &ctx->fpcr, err);
+
+	/* copy the magic/size information */
+	__put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err);
+	__put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err);
+
+	return err ? -EFAULT : 0;
+}
+
+int restore_fpsimd_context(struct fpsimd_context __user *ctx)
+{
+	struct fpsimd_state fpsimd;
+	__u32 magic, size;
+	int err = 0;
+
+	/* check the magic/size information */
+	__get_user_error(magic, &ctx->head.magic, err);
+	__get_user_error(size, &ctx->head.size, err);
+	if (err)
+		return -EFAULT;
+	if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
+		return -EINVAL;
+
+	/* copy the FP and status/control registers */
+	err = __copy_from_user(fpsimd.vregs, ctx->vregs,
+			       sizeof(fpsimd.vregs));
+	__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
+	__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
+
+	/* load the hardware registers from the fpsimd_state structure */
+	if (!err)
+		fpsimd_update_current_state(&fpsimd);
+
+	return err ? -EFAULT : 0;
+}
+
+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;
+
+	/* 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);
+
+	for (i = 0; i < 31; i++)
+		__put_user_error(regs->regs[i], &sf->uc.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);
+
+	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
+
+	if (err == 0) {
+		struct fpsimd_context *fpsimd_ctx =
+			container_of(aux, struct fpsimd_context, head);
+		err |= preserve_fpsimd_context(fpsimd_ctx);
+		aux += sizeof(*fpsimd_ctx);
+	}
+
+	/* fault information, if valid */
+	if (current->thread.fault_code) {
+		struct esr_context *esr_ctx =
+			container_of(aux, struct esr_context, head);
+		__put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
+		__put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
+		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
+		aux += sizeof(*esr_ctx);
+	}
+
+	/* set the "end" magic */
+	end = aux;
+	__put_user_error(0, &end->magic, err);
+	__put_user_error(0, &end->size, err);
+
+	return err;
+}
+
+int restore_sigframe(struct pt_regs *regs,
+			    struct sigframe __user *sf)
+{
+	sigset_t set;
+	int i, err;
+	void *aux = sf->uc.uc_mcontext.__reserved;
+
+	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
+	if (err == 0)
+		set_current_blocked(&set);
+
+	for (i = 0; i < 31; i++)
+		__get_user_error(regs->regs[i], &sf->uc.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);
+
+	/*
+	 * Avoid sys_rt_sigreturn() restarting.
+	 */
+	regs->syscallno = ~0UL;
+
+	err |= !valid_user_regs(&regs->user_regs);
+
+	if (err == 0) {
+		struct fpsimd_context *fpsimd_ctx =
+			container_of(aux, struct fpsimd_context, head);
+		err |= restore_fpsimd_context(fpsimd_ctx);
+	}
+
+	return err;
+}
+
+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 + sigframe_off + offsetof(struct sigframe, fp);
+	regs->pc = (unsigned long)ka->sa.sa_handler;
+
+	if (ka->sa.sa_flags & SA_RESTORER)
+		sigtramp = ka->sa.sa_restorer;
+#ifdef CONFIG_ARM64_ILP32
+	else if (is_ilp32_compat_task())
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
+#endif
+	else
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
+
+	regs->regs[30] = (unsigned long)sigtramp;
+}
+
-- 
2.5.0


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

* [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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 |  39 ++++++++
 arch/arm64/kernel/Makefile             |   2 +-
 arch/arm64/kernel/signal.c             | 154 +----------------------------
 arch/arm64/kernel/signal_common.c      | 174 +++++++++++++++++++++++++++++++++
 4 files changed, 215 insertions(+), 154 deletions(-)
 create mode 100644 arch/arm64/include/asm/signal_common.h
 create mode 100644 arch/arm64/kernel/signal_common.c

diff --git a/arch/arm64/include/asm/signal_common.h b/arch/arm64/include/asm/signal_common.h
new file mode 100644
index 0000000..2fb3997
--- /dev/null
+++ b/arch/arm64/include/asm/signal_common.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 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>
+
+struct sigframe {
+	struct ucontext uc;
+	u64 fp;
+	u64 lr;
+};
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx);
+int restore_fpsimd_context(struct fpsimd_context __user *ctx);
+int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set);
+int restore_sigframe(struct pt_regs *regs, struct sigframe __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/Makefile b/arch/arm64/kernel/Makefile
index 837d730..94b8b84 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -18,7 +18,7 @@ arm64-obj-y		:= debug-monitors.o entry.o irq.o fpsimd.o		\
 			   hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o	\
 			   return_address.o cpuinfo.o cpu_errata.o		\
 			   cpufeature.o alternative.o cacheinfo.o		\
-			   smp.o smp_spin_table.o topology.o
+			   smp.o smp_spin_table.o topology.o signal_common.o
 
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 20dca65..4b8efe5 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -33,13 +33,7 @@
 #include <asm/unistd.h>
 #include <asm/fpsimd.h>
 #include <asm/signal32.h>
-#include <asm/vdso.h>
-
-struct sigframe {
-	struct ucontext uc;
-	u64 fp;
-	u64 lr;
-};
+#include <asm/signal_common.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -49,87 +43,6 @@ struct rt_sigframe {
 	struct sigframe sig;
 };
 
-static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
-{
-	struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
-	int err;
-
-	/* dump the hardware registers to the fpsimd_state structure */
-	fpsimd_preserve_current_state();
-
-	/* copy the FP and status/control registers */
-	err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));
-	__put_user_error(fpsimd->fpsr, &ctx->fpsr, err);
-	__put_user_error(fpsimd->fpcr, &ctx->fpcr, err);
-
-	/* copy the magic/size information */
-	__put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err);
-	__put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err);
-
-	return err ? -EFAULT : 0;
-}
-
-static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
-{
-	struct fpsimd_state fpsimd;
-	__u32 magic, size;
-	int err = 0;
-
-	/* check the magic/size information */
-	__get_user_error(magic, &ctx->head.magic, err);
-	__get_user_error(size, &ctx->head.size, err);
-	if (err)
-		return -EFAULT;
-	if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
-		return -EINVAL;
-
-	/* copy the FP and status/control registers */
-	err = __copy_from_user(fpsimd.vregs, ctx->vregs,
-			       sizeof(fpsimd.vregs));
-	__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
-	__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
-
-	/* load the hardware registers from the fpsimd_state structure */
-	if (!err)
-		fpsimd_update_current_state(&fpsimd);
-
-	return err ? -EFAULT : 0;
-}
-
-static int restore_sigframe(struct pt_regs *regs,
-			    struct sigframe __user *sf)
-{
-	sigset_t set;
-	int i, err;
-	void *aux = sf->uc.uc_mcontext.__reserved;
-
-	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
-	if (err == 0)
-		set_current_blocked(&set);
-
-	for (i = 0; i < 31; i++)
-		__get_user_error(regs->regs[i], &sf->uc.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);
-
-	/*
-	 * Avoid sys_rt_sigreturn() restarting.
-	 */
-	regs->syscallno = ~0UL;
-
-	err |= !valid_user_regs(&regs->user_regs);
-
-	if (err == 0) {
-		struct fpsimd_context *fpsimd_ctx =
-			container_of(aux, struct fpsimd_context, head);
-		err |= restore_fpsimd_context(fpsimd_ctx);
-	}
-
-	return err;
-}
-
 asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
@@ -166,53 +79,6 @@ badframe:
 	return 0;
 }
 
-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;
-
-	/* 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);
-
-	for (i = 0; i < 31; i++)
-		__put_user_error(regs->regs[i], &sf->uc.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);
-
-	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
-
-	if (err == 0) {
-		struct fpsimd_context *fpsimd_ctx =
-			container_of(aux, struct fpsimd_context, head);
-		err |= preserve_fpsimd_context(fpsimd_ctx);
-		aux += sizeof(*fpsimd_ctx);
-	}
-
-	/* fault information, if valid */
-	if (current->thread.fault_code) {
-		struct esr_context *esr_ctx =
-			container_of(aux, struct esr_context, head);
-		__put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
-		__put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
-		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
-		aux += sizeof(*esr_ctx);
-	}
-
-	/* set the "end" magic */
-	end = aux;
-	__put_user_error(0, &end->magic, err);
-	__put_user_error(0, &end->size, err);
-
-	return err;
-}
-
 static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
 					       struct pt_regs *regs)
 {
@@ -233,24 +99,6 @@ 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, off_t sigframe_off, int usig)
-{
-	__sigrestore_t sigtramp;
-
-	regs->regs[0] = usig;
-	regs->sp = (unsigned long)frame;
-	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)
-		sigtramp = ka->sa.sa_restorer;
-	else
-		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
-
-	regs->regs[30] = (unsigned long)sigtramp;
-}
-
 static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 			  struct pt_regs *regs)
 {
diff --git a/arch/arm64/kernel/signal_common.c b/arch/arm64/kernel/signal_common.c
new file mode 100644
index 0000000..7043e5c
--- /dev/null
+++ b/arch/arm64/kernel/signal_common.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 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/>.
+ */
+
+#include <linux/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/fpsimd.h>
+#include <asm/vdso.h>
+#include <asm/signal_common.h>
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
+{
+	struct fpsimd_state *fpsimd = &current->thread.fpsimd_state;
+	int err;
+
+	/* dump the hardware registers to the fpsimd_state structure */
+	fpsimd_preserve_current_state();
+
+	/* copy the FP and status/control registers */
+	err = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));
+	__put_user_error(fpsimd->fpsr, &ctx->fpsr, err);
+	__put_user_error(fpsimd->fpcr, &ctx->fpcr, err);
+
+	/* copy the magic/size information */
+	__put_user_error(FPSIMD_MAGIC, &ctx->head.magic, err);
+	__put_user_error(sizeof(struct fpsimd_context), &ctx->head.size, err);
+
+	return err ? -EFAULT : 0;
+}
+
+int restore_fpsimd_context(struct fpsimd_context __user *ctx)
+{
+	struct fpsimd_state fpsimd;
+	__u32 magic, size;
+	int err = 0;
+
+	/* check the magic/size information */
+	__get_user_error(magic, &ctx->head.magic, err);
+	__get_user_error(size, &ctx->head.size, err);
+	if (err)
+		return -EFAULT;
+	if (magic != FPSIMD_MAGIC || size != sizeof(struct fpsimd_context))
+		return -EINVAL;
+
+	/* copy the FP and status/control registers */
+	err = __copy_from_user(fpsimd.vregs, ctx->vregs,
+			       sizeof(fpsimd.vregs));
+	__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);
+	__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);
+
+	/* load the hardware registers from the fpsimd_state structure */
+	if (!err)
+		fpsimd_update_current_state(&fpsimd);
+
+	return err ? -EFAULT : 0;
+}
+
+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;
+
+	/* 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);
+
+	for (i = 0; i < 31; i++)
+		__put_user_error(regs->regs[i], &sf->uc.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);
+
+	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
+
+	if (err == 0) {
+		struct fpsimd_context *fpsimd_ctx =
+			container_of(aux, struct fpsimd_context, head);
+		err |= preserve_fpsimd_context(fpsimd_ctx);
+		aux += sizeof(*fpsimd_ctx);
+	}
+
+	/* fault information, if valid */
+	if (current->thread.fault_code) {
+		struct esr_context *esr_ctx =
+			container_of(aux, struct esr_context, head);
+		__put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
+		__put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
+		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
+		aux += sizeof(*esr_ctx);
+	}
+
+	/* set the "end" magic */
+	end = aux;
+	__put_user_error(0, &end->magic, err);
+	__put_user_error(0, &end->size, err);
+
+	return err;
+}
+
+int restore_sigframe(struct pt_regs *regs,
+			    struct sigframe __user *sf)
+{
+	sigset_t set;
+	int i, err;
+	void *aux = sf->uc.uc_mcontext.__reserved;
+
+	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
+	if (err == 0)
+		set_current_blocked(&set);
+
+	for (i = 0; i < 31; i++)
+		__get_user_error(regs->regs[i], &sf->uc.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);
+
+	/*
+	 * Avoid sys_rt_sigreturn() restarting.
+	 */
+	regs->syscallno = ~0UL;
+
+	err |= !valid_user_regs(&regs->user_regs);
+
+	if (err == 0) {
+		struct fpsimd_context *fpsimd_ctx =
+			container_of(aux, struct fpsimd_context, head);
+		err |= restore_fpsimd_context(fpsimd_ctx);
+	}
+
+	return err;
+}
+
+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 + sigframe_off + offsetof(struct sigframe, fp);
+	regs->pc = (unsigned long)ka->sa.sa_handler;
+
+	if (ka->sa.sa_flags & SA_RESTORER)
+		sigtramp = ka->sa.sa_restorer;
+#ifdef CONFIG_ARM64_ILP32
+	else if (is_ilp32_compat_task())
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
+#endif
+	else
+		sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
+
+	regs->regs[30] = (unsigned long)sigtramp;
+}
+
-- 
2.5.0

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

* [PATCH v6 16/20] arm64: signal32: move ilp32 and aarch32 common code to separated file
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal32_common.h |  30 ++++++++
 arch/arm64/kernel/Makefile               |   2 +-
 arch/arm64/kernel/signal32.c             |  85 ----------------------
 arch/arm64/kernel/signal32_common.c      | 116 +++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 86 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..37a3a3c
--- /dev/null
+++ b/arch/arm64/include/asm/signal32_common.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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_SIGNAL32_COMMON_H
+#define __ASM_SIGNAL32_COMMON_H
+
+#ifdef __KERNEL__
+
+#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 /* __KERNEL__ */
+#endif /* __ASM_SIGNAL32_COMMON_H */
+
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 94b8b84..f90fb08 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,7 +25,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   ../../arm/kernel/opcodes.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
-arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o
+arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o signal32_common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 71ef6dc..2a69815 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 explicitely 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..446c7c0
--- /dev/null
+++ b/arch/arm64/kernel/signal32_common.c
@@ -0,0 +1,116 @@
+/*
+ * Based on arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 Cavium Metworks.
+ * 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 explicitely 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] 156+ messages in thread

* [PATCH v6 16/20] arm64: signal32: move ilp32 and aarch32 common code to separated file
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal32_common.h |  30 ++++++++
 arch/arm64/kernel/Makefile               |   2 +-
 arch/arm64/kernel/signal32.c             |  85 ----------------------
 arch/arm64/kernel/signal32_common.c      | 116 +++++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 86 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..37a3a3c
--- /dev/null
+++ b/arch/arm64/include/asm/signal32_common.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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_SIGNAL32_COMMON_H
+#define __ASM_SIGNAL32_COMMON_H
+
+#ifdef __KERNEL__
+
+#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 /* __KERNEL__ */
+#endif /* __ASM_SIGNAL32_COMMON_H */
+
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 94b8b84..f90fb08 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,7 +25,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   ../../arm/kernel/opcodes.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
-arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o
+arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o signal32_common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
 arm64-obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 71ef6dc..2a69815 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 explicitely 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..446c7c0
--- /dev/null
+++ b/arch/arm64/kernel/signal32_common.c
@@ -0,0 +1,116 @@
+/*
+ * Based on arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2015 Cavium Metworks.
+ * 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 explicitely 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] 156+ messages in thread

* [PATCH v6 17/20] arm64: ilp32: introduce ilp32-specific handlers for sigframe
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

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

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal_ilp32.h |  38 ++++++++++
 arch/arm64/kernel/Makefile            |   2 +-
 arch/arm64/kernel/entry_ilp32.S       |  32 +++++++++
 arch/arm64/kernel/signal.c            |   3 +
 arch/arm64/kernel/signal_ilp32.c      | 126 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/sys_ilp32.c         |   3 +
 6 files changed, 203 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..81e1909
--- /dev/null
+++ b/arch/arm64/include/asm/signal_ilp32.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 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_ILP32_H
+#define __ASM_SIGNAL_ILP32_H
+
+#ifdef __KERNEL__
+#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 /* __KERNEL__ */
+#endif /* __ASM_SIGNAL_ILP32_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index f90fb08..f92e707 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,7 +24,7 @@ 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
-arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= signal_ilp32.o sys_ilp32.o entry_ilp32.o
 arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o signal32_common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
diff --git a/arch/arm64/kernel/entry_ilp32.S b/arch/arm64/kernel/entry_ilp32.S
new file mode 100644
index 0000000..424060f
--- /dev/null
+++ b/arch/arm64/kernel/entry_ilp32.S
@@ -0,0 +1,32 @@
+/*
+ * ILP32 system call wrappers
+ *
+ * Copyright (C) 2015 Cavium Networks.
+ * Author: 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/linkage.h>
+#include <linux/const.h>
+
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/errno.h>
+#include <asm/page.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 4b8efe5..d67a9b8 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -34,6 +34,7 @@
 #include <asm/fpsimd.h>
 #include <asm/signal32.h>
 #include <asm/signal_common.h>
+#include <asm/signal_ilp32.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -153,6 +154,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..d38434b
--- /dev/null
+++ b/arch/arm64/kernel/signal_ilp32.c
@@ -0,0 +1,126 @@
+/*
+ * Based on arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 2015 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_rt_sigframe {
+	struct compat_siginfo info;
+	struct sigframe sig;
+};
+
+asmlinkage int 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 64-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_sigframe(regs, &frame->sig))
+		goto badframe;
+
+	if (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;
+
+	__put_user_error(0, &frame->sig.uc.uc_flags, err);
+	__put_user_error(NULL, &frame->sig.uc.uc_link, err);
+
+	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,
+			offsetof(struct ilp32_rt_sigframe, sig), usig);
+		if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+			err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
+			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 c282fa2..1882bb3 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -54,6 +54,9 @@ asmlinkage long compat_sys_fstatfs64_wrapper(void);
 asmlinkage long compat_sys_statfs64_wrapper(void);
 #define compat_sys_statfs64             compat_sys_statfs64_wrapper
 
+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] 156+ messages in thread

* [PATCH v6 17/20] arm64: ilp32: introduce ilp32-specific handlers for sigframe
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/include/asm/signal_ilp32.h |  38 ++++++++++
 arch/arm64/kernel/Makefile            |   2 +-
 arch/arm64/kernel/entry_ilp32.S       |  32 +++++++++
 arch/arm64/kernel/signal.c            |   3 +
 arch/arm64/kernel/signal_ilp32.c      | 126 ++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/sys_ilp32.c         |   3 +
 6 files changed, 203 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..81e1909
--- /dev/null
+++ b/arch/arm64/include/asm/signal_ilp32.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 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_ILP32_H
+#define __ASM_SIGNAL_ILP32_H
+
+#ifdef __KERNEL__
+#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 /* __KERNEL__ */
+#endif /* __ASM_SIGNAL_ILP32_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index f90fb08..f92e707 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,7 +24,7 @@ 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
-arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= signal_ilp32.o sys_ilp32.o entry_ilp32.o
 arm64-obj-$(CONFIG_COMPAT)		+= entry32-common.o signal32_common.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
diff --git a/arch/arm64/kernel/entry_ilp32.S b/arch/arm64/kernel/entry_ilp32.S
new file mode 100644
index 0000000..424060f
--- /dev/null
+++ b/arch/arm64/kernel/entry_ilp32.S
@@ -0,0 +1,32 @@
+/*
+ * ILP32 system call wrappers
+ *
+ * Copyright (C) 2015 Cavium Networks.
+ * Author: 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/linkage.h>
+#include <linux/const.h>
+
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/errno.h>
+#include <asm/page.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 4b8efe5..d67a9b8 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -34,6 +34,7 @@
 #include <asm/fpsimd.h>
 #include <asm/signal32.h>
 #include <asm/signal_common.h>
+#include <asm/signal_ilp32.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -153,6 +154,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..d38434b
--- /dev/null
+++ b/arch/arm64/kernel/signal_ilp32.c
@@ -0,0 +1,126 @@
+/*
+ * Based on arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 2015 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_rt_sigframe {
+	struct compat_siginfo info;
+	struct sigframe sig;
+};
+
+asmlinkage int 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 64-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_sigframe(regs, &frame->sig))
+		goto badframe;
+
+	if (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;
+
+	__put_user_error(0, &frame->sig.uc.uc_flags, err);
+	__put_user_error(NULL, &frame->sig.uc.uc_link, err);
+
+	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,
+			offsetof(struct ilp32_rt_sigframe, sig), usig);
+		if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+			err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
+			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 c282fa2..1882bb3 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -54,6 +54,9 @@ asmlinkage long compat_sys_fstatfs64_wrapper(void);
 asmlinkage long compat_sys_statfs64_wrapper(void);
 #define compat_sys_statfs64             compat_sys_statfs64_wrapper
 
+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] 156+ messages in thread

* [PATCH v6 18/20] arm64:ilp32: add vdso-ilp32 and use for signal return
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

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                 |  4 ++
 arch/arm64/kernel/Makefile                    |  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                      | 61 ++++++++++++++---
 7 files changed, 262 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..84050c6 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -29,6 +29,10 @@
 
 #include <generated/vdso-offsets.h>
 
+#ifdef CONFIG_ARM64_ILP32
+#include <generated/vdso-ilp32-offsets.h>
+#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 f92e707..2ef91c2 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -40,6 +40,7 @@ arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.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
@@ -47,3 +48,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/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] 156+ messages in thread

* [PATCH v6 18/20] arm64:ilp32: add vdso-ilp32 and use for signal return
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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                 |  4 ++
 arch/arm64/kernel/Makefile                    |  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                      | 61 ++++++++++++++---
 7 files changed, 262 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..84050c6 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -29,6 +29,10 @@
 
 #include <generated/vdso-offsets.h>
 
+#ifdef CONFIG_ARM64_ILP32
+#include <generated/vdso-ilp32-offsets.h>
+#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 f92e707..2ef91c2 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -40,6 +40,7 @@ arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.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
@@ -47,3 +48,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/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] 156+ messages in thread

* [PATCH v6 19/20] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski

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

To make life for tools (such as gdb) easier when dealing with ILP32 processes,
we report a proper subarchitecture for ILP32 in the ELF auxiliary vectors.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 4e2e3c0..1fc6b48 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -164,9 +164,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 #ifdef CONFIG_COMPAT
 
 #ifdef __AARCH64EB__
-#define COMPAT_ELF_PLATFORM		("v8b")
+#define COMPAT_ELF_PLATFORM		(is_ilp32_compat_task() ? "aarch64_be:ilp32" : "v8b")
 #else
-#define COMPAT_ELF_PLATFORM		("v8l")
+#define COMPAT_ELF_PLATFORM		(is_ilp32_compat_task() ? "aarch64:ilp32" : "v8l")
 #endif
 
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
-- 
2.5.0


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

* [PATCH v6 19/20] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

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

To make life for tools (such as gdb) easier when dealing with ILP32 processes,
we report a proper subarchitecture for ILP32 in the ELF auxiliary vectors.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/include/asm/elf.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 4e2e3c0..1fc6b48 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -164,9 +164,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 #ifdef CONFIG_COMPAT
 
 #ifdef __AARCH64EB__
-#define COMPAT_ELF_PLATFORM		("v8b")
+#define COMPAT_ELF_PLATFORM		(is_ilp32_compat_task() ? "aarch64_be:ilp32" : "v8b")
 #else
-#define COMPAT_ELF_PLATFORM		("v8l")
+#define COMPAT_ELF_PLATFORM		(is_ilp32_compat_task() ? "aarch64:ilp32" : "v8l")
 #endif
 
 #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
-- 
2.5.0

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

* [PATCH v6 20/20] arm64:ilp32: add ARM64_ILP32 to Kconfig
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-15 21:42   ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: ynorov, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

From: Andrew Pinski <apinski@cavium.com>

This patch adds the config option for ILP32.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/Kconfig | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4753d435..deec37a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -680,7 +680,7 @@ source "fs/Kconfig.binfmt"
 
 config COMPAT
 	def_bool y
-	depends on AARCH32_EL0
+	depends on AARCH32_EL0 || ARM64_ILP32
 	select COMPAT_BINFMT_ELF
 
 config AARCH32_EL0
@@ -702,6 +702,13 @@ config AARCH32_EL0
 
 	  If you want to execute 32-bit userspace applications, say Y.
 
+config ARM64_ILP32
+	bool "Kernel support for ILP32"
+	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] 156+ messages in thread

* [PATCH v6 20/20] arm64:ilp32: add ARM64_ILP32 to Kconfig
@ 2015-12-15 21:42   ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-15 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

From: Andrew Pinski <apinski@cavium.com>

This patch adds the config option for ILP32.

Reviewed-by: David Daney <ddaney@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>
Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
---
 arch/arm64/Kconfig | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4753d435..deec37a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -680,7 +680,7 @@ source "fs/Kconfig.binfmt"
 
 config COMPAT
 	def_bool y
-	depends on AARCH32_EL0
+	depends on AARCH32_EL0 || ARM64_ILP32
 	select COMPAT_BINFMT_ELF
 
 config AARCH32_EL0
@@ -702,6 +702,13 @@ config AARCH32_EL0
 
 	  If you want to execute 32-bit userspace applications, say Y.
 
+config ARM64_ILP32
+	bool "Kernel support for ILP32"
+	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] 156+ messages in thread

* Re: [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-16 15:50     ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 15:50 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, Andrew Pinski, jan.dakinevich, Andrew Pinski,
	ddaney.cavm, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Wednesday 16 December 2015 00:42:36 Yury Norov wrote:
> +#ifdef CONFIG_ARM64_ILP32
> +       /* ILP32 threads are started the same way as LP64 threads. */
> +       if (is_ilp32_compat_task()) {
> +               start_thread(regs, pc, sp);
> +               return;
> +       }
> +#endif
> 

Just a small style comment, but I think you can just leave out the #ifdef,
as is_ilp32_compat_task() will already return false if that is disabled.

	Arnd

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

* [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
@ 2015-12-16 15:50     ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 December 2015 00:42:36 Yury Norov wrote:
> +#ifdef CONFIG_ARM64_ILP32
> +       /* ILP32 threads are started the same way as LP64 threads. */
> +       if (is_ilp32_compat_task()) {
> +               start_thread(regs, pc, sp);
> +               return;
> +       }
> +#endif
> 

Just a small style comment, but I think you can just leave out the #ifdef,
as is_ilp32_compat_task() will already return false if that is disabled.

	Arnd

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

* Re: [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-16 15:54     ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 15:54 UTC (permalink / raw)
  To: Yury Norov
  Cc: catalin.marinas, linux-arm-kernel, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, Nathan_Lynch, agraf, klimov.linux,
	broonie, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner, Andrew Pinski,
	Andrew Pinski

On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> 
>  #ifdef CONFIG_COMPAT
> -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
>  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> +#define COMPAT_ELF_HWCAP       \
> +       (is_a32_compat_task()   \
> +         ? compat_elf_hwcap    \
> +         : elf_hwcap)
> +
> +#define COMPAT_ELF_HWCAP2      \
> +       (is_a32_compat_task()   \
> +         ? compat_elf_hwcap2   \
> +         : 0)
> +
>  #endif
>  
> 

I'm trying to understand how this is used. Are you compiling
fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?

Would it be easier to use a separate arch/arm64/kernel/binfmt_elf32.c
as a copy of fs/compat_binfmt_elf.c, with all the right macros defined
for ilp32 mode in there?

	Arnd

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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-16 15:54     ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> 
>  #ifdef CONFIG_COMPAT
> -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
>  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> +#define COMPAT_ELF_HWCAP       \
> +       (is_a32_compat_task()   \
> +         ? compat_elf_hwcap    \
> +         : elf_hwcap)
> +
> +#define COMPAT_ELF_HWCAP2      \
> +       (is_a32_compat_task()   \
> +         ? compat_elf_hwcap2   \
> +         : 0)
> +
>  #endif
>  
> 

I'm trying to understand how this is used. Are you compiling
fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?

Would it be easier to use a separate arch/arm64/kernel/binfmt_elf32.c
as a copy of fs/compat_binfmt_elf.c, with all the right macros defined
for ilp32 mode in there?

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-16 16:07     ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 16:07 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, Andrew Pinski, jan.dakinevich, Andrew Pinski,
	ddaney.cavm, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Wednesday 16 December 2015 00:42:38 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
> +#define compat_sys_sigaltstack         sys_sigaltstack
> +#define compat_sys_sync_file_range     sys_sync_file_range
> +#define compat_sys_truncate64          sys_truncate
> +#define sys_llseek                     sys_lseek
> +
> +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> +#define compat_sys_openat              sys_openat

Very nice and short list now!

I've double-checked all calls and the only one I'm not sure about is
sys_sigaltstack. Did we discuss that one earlier?
My first guess would be that it's easier to use the compat
version of that.

I would probably also group sys_shmat with sys_openat, because it's
different from the other ones in the first block as this is not
about passing 64-bit arguments as registers, but instead it's about
the behavior of the system call.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-16 16:07     ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 16:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 December 2015 00:42:38 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
> +#define compat_sys_sigaltstack         sys_sigaltstack
> +#define compat_sys_sync_file_range     sys_sync_file_range
> +#define compat_sys_truncate64          sys_truncate
> +#define sys_llseek                     sys_lseek
> +
> +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> +#define compat_sys_openat              sys_openat

Very nice and short list now!

I've double-checked all calls and the only one I'm not sure about is
sys_sigaltstack. Did we discuss that one earlier?
My first guess would be that it's easier to use the compat
version of that.

I would probably also group sys_shmat with sys_openat, because it's
different from the other ones in the first block as this is not
about passing 64-bit arguments as registers, but instead it's about
the behavior of the system call.

	Arnd

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

* Re: [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-16 16:08     ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 16:08 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wednesday 16 December 2015 00:42:41 Yury Norov wrote:
> +               sigtramp = ka->sa.sa_restorer;
> +#ifdef CONFIG_ARM64_ILP32
> +       else if (is_ilp32_compat_task())
> +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> +#endif
> +       else
> +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> 

This is another case where I think it's more readable to remove the #ifdef,
with no change in behavior.

	Arnd

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

* [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
@ 2015-12-16 16:08     ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 16:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 December 2015 00:42:41 Yury Norov wrote:
> +               sigtramp = ka->sa.sa_restorer;
> +#ifdef CONFIG_ARM64_ILP32
> +       else if (is_ilp32_compat_task())
> +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> +#endif
> +       else
> +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> 

This is another case where I think it's more readable to remove the #ifdef,
with no change in behavior.

	Arnd

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

* Re: [RFC3 PATCH v6 00/20] ILP32 for ARM64
  2015-12-15 21:42 ` Yury Norov
@ 2015-12-16 16:24   ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 16:24 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wednesday 16 December 2015 00:42:26 Yury Norov wrote:
> This is still RFC because we have no glibc yet, that correspnds new ABI
> introduced here. And so we cannot run tests. LP64 and AARCH32 tests show
> no regression though.
> 
>   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.

Hi Yury,

This version looks very good overall, thanks for addressing all my previous
comments!

I've commented on a few things, but it's mostly about style, and there
are no show-stoppers. Please reply to my questions about the binfmt_elf.c,
I must be missing something here as I can't even find which patch adds
support for the new ELF32 executable format.

Regarding my sys_sigaltstack comment, I've looked at the compat handling
in kernel/signal.c and see that it's really ugly. Is that the reason
you didn't want to use it? I think it's a good idea to clean that up
so we don't need the get_fs()/set_fs() hack, but that can be done
independent from your series and would benefit all 32-bit compat handling.

	Arnd

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

* [RFC3 PATCH v6 00/20] ILP32 for ARM64
@ 2015-12-16 16:24   ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 December 2015 00:42:26 Yury Norov wrote:
> This is still RFC because we have no glibc yet, that correspnds new ABI
> introduced here. And so we cannot run tests. LP64 and AARCH32 tests show
> no regression though.
> 
>   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.

Hi Yury,

This version looks very good overall, thanks for addressing all my previous
comments!

I've commented on a few things, but it's mostly about style, and there
are no show-stoppers. Please reply to my questions about the binfmt_elf.c,
I must be missing something here as I can't even find which patch adds
support for the new ELF32 executable format.

Regarding my sys_sigaltstack comment, I've looked at the compat handling
in kernel/signal.c and see that it's really ugly. Is that the reason
you didn't want to use it? I think it's a good idea to clean that up
so we don't need the get_fs()/set_fs() hack, but that can be done
independent from your series and would benefit all 32-bit compat handling.

	Arnd

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

* Re: [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-16 15:54     ` Arnd Bergmann
@ 2015-12-16 16:58       ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-16 16:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Yury Norov, pinskia, Prasun.Kapoor, Nathan_Lynch, linux-kernel,
	agraf, Andrew Pinski, klimov.linux, Andrew Pinski, broonie,
	jan.dakinevich, joseph, ddaney.cavm, schwab, bamvor.zhangjian,
	philipp.tomsich, linux-arm-kernel, christoph.muellner

On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > 
> >  #ifdef CONFIG_COMPAT
> > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > +#define COMPAT_ELF_HWCAP       \
> > +       (is_a32_compat_task()   \
> > +         ? compat_elf_hwcap    \
> > +         : elf_hwcap)
> > +
> > +#define COMPAT_ELF_HWCAP2      \
> > +       (is_a32_compat_task()   \
> > +         ? compat_elf_hwcap2   \
> > +         : 0)
> > +
> >  #endif
> 
> I'm trying to understand how this is used. Are you compiling
> fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?

It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
are evaluated every time a new ELF file is loaded. We do a similar trick
with COMPAT_SET_PERSONALITY in patch 11.

-- 
Catalin

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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-16 16:58       ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-16 16:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > 
> >  #ifdef CONFIG_COMPAT
> > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > +#define COMPAT_ELF_HWCAP       \
> > +       (is_a32_compat_task()   \
> > +         ? compat_elf_hwcap    \
> > +         : elf_hwcap)
> > +
> > +#define COMPAT_ELF_HWCAP2      \
> > +       (is_a32_compat_task()   \
> > +         ? compat_elf_hwcap2   \
> > +         : 0)
> > +
> >  #endif
> 
> I'm trying to understand how this is used. Are you compiling
> fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?

It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
are evaluated every time a new ELF file is loaded. We do a similar trick
with COMPAT_SET_PERSONALITY in patch 11.

-- 
Catalin

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

* Re: [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-16 16:58       ` Catalin Marinas
@ 2015-12-16 17:19         ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-16 17:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, pinskia, Prasun.Kapoor, schwab, broonie,
	Nathan_Lynch, agraf, linux-kernel, klimov.linux, Andrew Pinski,
	Yury Norov, jan.dakinevich, Andrew Pinski, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 04:58:20PM +0000, Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> > On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > > 
> > >  #ifdef CONFIG_COMPAT
> > > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> > >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > > +#define COMPAT_ELF_HWCAP       \
> > > +       (is_a32_compat_task()   \
> > > +         ? compat_elf_hwcap    \
> > > +         : elf_hwcap)
> > > +
> > > +#define COMPAT_ELF_HWCAP2      \
> > > +       (is_a32_compat_task()   \
> > > +         ? compat_elf_hwcap2   \
> > > +         : 0)
> > > +
> > >  #endif
> > 
> > I'm trying to understand how this is used. Are you compiling
> > fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?
> 
> It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
> i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
> are evaluated every time a new ELF file is loaded. We do a similar trick
> with COMPAT_SET_PERSONALITY in patch 11.

IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
go beyond bit 31. The above may need to look something like:

#define COMPAT_ELF_HWCAP	\
	(is_a32_compat_task()	\
	 ? compat_elf_hwcap	\
	 : (u32)elf_hwcap)

#define COMPAT_ELF_HWCAP2	\
	(is_a32_compat_task()	\
	 ? compat_elf_hwcap2	\
	 : (u32)(elf_hwcap >> 32))

-- 
Catalin

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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-16 17:19         ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-16 17:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 04:58:20PM +0000, Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> > On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > > 
> > >  #ifdef CONFIG_COMPAT
> > > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> > >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > > +#define COMPAT_ELF_HWCAP       \
> > > +       (is_a32_compat_task()   \
> > > +         ? compat_elf_hwcap    \
> > > +         : elf_hwcap)
> > > +
> > > +#define COMPAT_ELF_HWCAP2      \
> > > +       (is_a32_compat_task()   \
> > > +         ? compat_elf_hwcap2   \
> > > +         : 0)
> > > +
> > >  #endif
> > 
> > I'm trying to understand how this is used. Are you compiling
> > fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?
> 
> It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
> i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
> are evaluated every time a new ELF file is loaded. We do a similar trick
> with COMPAT_SET_PERSONALITY in patch 11.

IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
go beyond bit 31. The above may need to look something like:

#define COMPAT_ELF_HWCAP	\
	(is_a32_compat_task()	\
	 ? compat_elf_hwcap	\
	 : (u32)elf_hwcap)

#define COMPAT_ELF_HWCAP2	\
	(is_a32_compat_task()	\
	 ? compat_elf_hwcap2	\
	 : (u32)(elf_hwcap >> 32))

-- 
Catalin

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

* Re: [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-16 17:19         ` Catalin Marinas
@ 2015-12-16 19:17           ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 19:17 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, pinskia, Prasun.Kapoor, schwab, broonie,
	Nathan_Lynch, agraf, linux-kernel, klimov.linux, Andrew Pinski,
	Yury Norov, jan.dakinevich, Andrew Pinski, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

On Wednesday 16 December 2015 17:19:05 Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 04:58:20PM +0000, Catalin Marinas wrote:
> > On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> > > On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > > > 
> > > >  #ifdef CONFIG_COMPAT
> > > > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > > > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> > > >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > > > +#define COMPAT_ELF_HWCAP       \
> > > > +       (is_a32_compat_task()   \
> > > > +         ? compat_elf_hwcap    \
> > > > +         : elf_hwcap)
> > > > +
> > > > +#define COMPAT_ELF_HWCAP2      \
> > > > +       (is_a32_compat_task()   \
> > > > +         ? compat_elf_hwcap2   \
> > > > +         : 0)
> > > > +
> > > >  #endif
> > > 
> > > I'm trying to understand how this is used. Are you compiling
> > > fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?
> > 
> > It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
> > i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
> > are evaluated every time a new ELF file is loaded. We do a similar trick
> > with COMPAT_SET_PERSONALITY in patch 11.

Ok, I see. I've also looked at other architectures, and found that
MIPS does it the way I thought it would be

git grep -w binfmt_elf.c
arch/mips/kernel/binfmt_elfn32.c:#include "../../../fs/binfmt_elf.c"
arch/mips/kernel/binfmt_elfo32.c:#include "../../../fs/binfmt_elf.c"

I still think doing the same for arm64 would result in more maintainable
code, because it completely separates the two different formats into
separate files. We'd obviously leave the existing compat handling as
it is, and just add one more file, not do both of them separately as
MIPS does.

Do you see any downsides of that approach?

> IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
> elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
> go beyond bit 31. The above may need to look something like:
> 
> #define COMPAT_ELF_HWCAP        \
>         (is_a32_compat_task()   \
>          ? compat_elf_hwcap     \
>          : (u32)elf_hwcap)
> 
> #define COMPAT_ELF_HWCAP2       \
>         (is_a32_compat_task()   \
>          ? compat_elf_hwcap2    \
>          : (u32)(elf_hwcap >> 32))

Yes, interesting find.

	Arnd

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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-16 19:17           ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-16 19:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 December 2015 17:19:05 Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 04:58:20PM +0000, Catalin Marinas wrote:
> > On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> > > On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > > > 
> > > >  #ifdef CONFIG_COMPAT
> > > > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > > > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> > > >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > > > +#define COMPAT_ELF_HWCAP       \
> > > > +       (is_a32_compat_task()   \
> > > > +         ? compat_elf_hwcap    \
> > > > +         : elf_hwcap)
> > > > +
> > > > +#define COMPAT_ELF_HWCAP2      \
> > > > +       (is_a32_compat_task()   \
> > > > +         ? compat_elf_hwcap2   \
> > > > +         : 0)
> > > > +
> > > >  #endif
> > > 
> > > I'm trying to understand how this is used. Are you compiling
> > > fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?
> > 
> > It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
> > i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
> > are evaluated every time a new ELF file is loaded. We do a similar trick
> > with COMPAT_SET_PERSONALITY in patch 11.

Ok, I see. I've also looked at other architectures, and found that
MIPS does it the way I thought it would be

git grep -w binfmt_elf.c
arch/mips/kernel/binfmt_elfn32.c:#include "../../../fs/binfmt_elf.c"
arch/mips/kernel/binfmt_elfo32.c:#include "../../../fs/binfmt_elf.c"

I still think doing the same for arm64 would result in more maintainable
code, because it completely separates the two different formats into
separate files. We'd obviously leave the existing compat handling as
it is, and just add one more file, not do both of them separately as
MIPS does.

Do you see any downsides of that approach?

> IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
> elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
> go beyond bit 31. The above may need to look something like:
> 
> #define COMPAT_ELF_HWCAP        \
>         (is_a32_compat_task()   \
>          ? compat_elf_hwcap     \
>          : (u32)elf_hwcap)
> 
> #define COMPAT_ELF_HWCAP2       \
>         (is_a32_compat_task()   \
>          ? compat_elf_hwcap2    \
>          : (u32)(elf_hwcap >> 32))

Yes, interesting find.

	Arnd

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

* Re: [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-16 19:17           ` Arnd Bergmann
@ 2015-12-17 10:54             ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 10:54 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: bamvor.zhangjian, pinskia, Prasun.Kapoor, schwab, joseph,
	Nathan_Lynch, agraf, linux-kernel, klimov.linux, Andrew Pinski,
	broonie, Yury Norov, Andrew Pinski, ddaney.cavm, jan.dakinevich,
	philipp.tomsich, linux-arm-kernel, christoph.muellner

On Wed, Dec 16, 2015 at 08:17:25PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 17:19:05 Catalin Marinas wrote:
> > On Wed, Dec 16, 2015 at 04:58:20PM +0000, Catalin Marinas wrote:
> > > On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> > > > On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > > > > 
> > > > >  #ifdef CONFIG_COMPAT
> > > > > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > > > > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> > > > >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > > > > +#define COMPAT_ELF_HWCAP       \
> > > > > +       (is_a32_compat_task()   \
> > > > > +         ? compat_elf_hwcap    \
> > > > > +         : elf_hwcap)
> > > > > +
> > > > > +#define COMPAT_ELF_HWCAP2      \
> > > > > +       (is_a32_compat_task()   \
> > > > > +         ? compat_elf_hwcap2   \
> > > > > +         : 0)
> > > > > +
> > > > >  #endif
> > > > 
> > > > I'm trying to understand how this is used. Are you compiling
> > > > fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?
> > > 
> > > It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
> > > i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
> > > are evaluated every time a new ELF file is loaded. We do a similar trick
> > > with COMPAT_SET_PERSONALITY in patch 11.
> 
> Ok, I see. I've also looked at other architectures, and found that
> MIPS does it the way I thought it would be
> 
> git grep -w binfmt_elf.c
> arch/mips/kernel/binfmt_elfn32.c:#include "../../../fs/binfmt_elf.c"
> arch/mips/kernel/binfmt_elfo32.c:#include "../../../fs/binfmt_elf.c"
> 
> I still think doing the same for arm64 would result in more maintainable
> code, because it completely separates the two different formats into
> separate files. We'd obviously leave the existing compat handling as
> it is, and just add one more file, not do both of them separately as
> MIPS does.

It will probably simplify some of the code like setting personality,
COMPAT_ELF_HWCAP, elf_check_arch.

> Do you see any downsides of that approach?

Not really. execve may take just a little bit longer to search the right
binfmt but that's lost in the noise anyway, the execve operation itself
is expensive.

AFAICT, the main decision on choosing the ELF binfmt comes from
elf_check_arch() and sizeof(struct elf_phdr). The ILP32 would use the
EM_AARCH64 class but a smaller struct elf_phdr (with 32-bit members). So
there won't be any confusion with the AArch32 (compat) and AArch64
(native) binfmt elf loaders.

> > IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
> > elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
> > go beyond bit 31. The above may need to look something like:
> > 
> > #define COMPAT_ELF_HWCAP        \
> >         (is_a32_compat_task()   \
> >          ? compat_elf_hwcap     \
> >          : (u32)elf_hwcap)
> > 
> > #define COMPAT_ELF_HWCAP2       \
> >         (is_a32_compat_task()   \
> >          ? compat_elf_hwcap2    \
> >          : (u32)(elf_hwcap >> 32))
> 
> Yes, interesting find.

BTW, we need to make sure this series (primarily the ABI) is big-endian
safe. I know it is not targeted at this initially but given that the
reason for doing it is legacy networking code, I wouldn't be surprised
if someone asks for BE at some point in the future.

-- 
Catalin

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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-17 10:54             ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 10:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 08:17:25PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 17:19:05 Catalin Marinas wrote:
> > On Wed, Dec 16, 2015 at 04:58:20PM +0000, Catalin Marinas wrote:
> > > On Wed, Dec 16, 2015 at 04:54:34PM +0100, Arnd Bergmann wrote:
> > > > On Wednesday 16 December 2015 00:42:35 Yury Norov wrote:
> > > > > 
> > > > >  #ifdef CONFIG_COMPAT
> > > > > -#define COMPAT_ELF_HWCAP       (compat_elf_hwcap)
> > > > > -#define COMPAT_ELF_HWCAP2      (compat_elf_hwcap2)
> > > > >  extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
> > > > > +#define COMPAT_ELF_HWCAP       \
> > > > > +       (is_a32_compat_task()   \
> > > > > +         ? compat_elf_hwcap    \
> > > > > +         : elf_hwcap)
> > > > > +
> > > > > +#define COMPAT_ELF_HWCAP2      \
> > > > > +       (is_a32_compat_task()   \
> > > > > +         ? compat_elf_hwcap2   \
> > > > > +         : 0)
> > > > > +
> > > > >  #endif
> > > > 
> > > > I'm trying to understand how this is used. Are you compiling
> > > > fs/compat_binfmt_elf.c twice to handle both 32-bit ELF types?
> > > 
> > > It's the same compat_binfmt_elf.c which handles all 32-bit ELF types,
> > > i.e. AArch32 and A64/ILP32. The above macros are not constants, so they
> > > are evaluated every time a new ELF file is loaded. We do a similar trick
> > > with COMPAT_SET_PERSONALITY in patch 11.
> 
> Ok, I see. I've also looked at other architectures, and found that
> MIPS does it the way I thought it would be
> 
> git grep -w binfmt_elf.c
> arch/mips/kernel/binfmt_elfn32.c:#include "../../../fs/binfmt_elf.c"
> arch/mips/kernel/binfmt_elfo32.c:#include "../../../fs/binfmt_elf.c"
> 
> I still think doing the same for arm64 would result in more maintainable
> code, because it completely separates the two different formats into
> separate files. We'd obviously leave the existing compat handling as
> it is, and just add one more file, not do both of them separately as
> MIPS does.

It will probably simplify some of the code like setting personality,
COMPAT_ELF_HWCAP, elf_check_arch.

> Do you see any downsides of that approach?

Not really. execve may take just a little bit longer to search the right
binfmt but that's lost in the noise anyway, the execve operation itself
is expensive.

AFAICT, the main decision on choosing the ELF binfmt comes from
elf_check_arch() and sizeof(struct elf_phdr). The ILP32 would use the
EM_AARCH64 class but a smaller struct elf_phdr (with 32-bit members). So
there won't be any confusion with the AArch32 (compat) and AArch64
(native) binfmt elf loaders.

> > IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
> > elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
> > go beyond bit 31. The above may need to look something like:
> > 
> > #define COMPAT_ELF_HWCAP        \
> >         (is_a32_compat_task()   \
> >          ? compat_elf_hwcap     \
> >          : (u32)elf_hwcap)
> > 
> > #define COMPAT_ELF_HWCAP2       \
> >         (is_a32_compat_task()   \
> >          ? compat_elf_hwcap2    \
> >          : (u32)(elf_hwcap >> 32))
> 
> Yes, interesting find.

BTW, we need to make sure this series (primarily the ABI) is big-endian
safe. I know it is not targeted at this initially but given that the
reason for doing it is legacy networking code, I wouldn't be surprised
if someone asks for BE at some point in the future.

-- 
Catalin

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

* Re: [PATCH v6 03/20] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-17 11:23     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 11:23 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, Andrew Pinski, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:29AM +0300, Yury Norov wrote:
> From: Andrew Pinski <apinski@cavium.com>
> 
> Reviewed-by: David Daney <ddaney@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>
> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>

I already asked here to add a long patch description:

http://article.gmane.org/gmane.linux.kernel/2099414

-- 
Catalin

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

* [PATCH v6 03/20] arm64: rename COMPAT to AARCH32_EL0 in Kconfig
@ 2015-12-17 11:23     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:29AM +0300, Yury Norov wrote:
> From: Andrew Pinski <apinski@cavium.com>
> 
> Reviewed-by: David Daney <ddaney@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>
> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>

I already asked here to add a long patch description:

http://article.gmane.org/gmane.linux.kernel/2099414

-- 
Catalin

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

* Re: [PATCH v6 07/20] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-17 11:38     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 11:38 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:33AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
> new file mode 100644
> index 0000000..476db90
> --- /dev/null
> +++ b/arch/arm64/include/asm/is_compat.h
> @@ -0,0 +1,62 @@
> +/*
> + * Copyright (C) 2015 Cavium Inc.

Moving code around and changing function names doesn't exactly mean a
change in copyright (though it's not that much code).

> + *
> + * 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
> +#ifdef __KERNEL__

Nitpick: I thought we no longer need __KERNEL__ for non-uapi header files.

-- 
Catalin

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

* [PATCH v6 07/20] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
@ 2015-12-17 11:38     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:33AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
> new file mode 100644
> index 0000000..476db90
> --- /dev/null
> +++ b/arch/arm64/include/asm/is_compat.h
> @@ -0,0 +1,62 @@
> +/*
> + * Copyright (C) 2015 Cavium Inc.

Moving code around and changing function names doesn't exactly mean a
change in copyright (though it's not that much code).

> + *
> + * 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
> +#ifdef __KERNEL__

Nitpick: I thought we no longer need __KERNEL__ for non-uapi header files.

-- 
Catalin

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

* Re: [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
  2015-12-15 21:42   ` [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} " Yury Norov
@ 2015-12-17 11:41     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 11:41 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> Reviewed-by: David Daney <ddaney@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>
> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>

Long description missing.

> diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
> index 476db90..89b1f65 100644
> --- a/arch/arm64/include/asm/is_compat.h
> +++ b/arch/arm64/include/asm/is_compat.h
> @@ -36,7 +36,6 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  #else
>  
>  static inline int is_a32_compat_task(void)
> -
>  {
>  	return 0;
>  }

You should move this to the previous patch.

> @@ -45,14 +44,39 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  {
>  	return 0;
>  }
> -
>  #endif /* CONFIG_AARCH32_EL0 */

Maybe this one as well, though I like an empty line before the last
#endif (i.e. drop this hunk).

-- 
Catalin

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

* [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
@ 2015-12-17 11:41     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 11:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> Reviewed-by: David Daney <ddaney@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>
> Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>

Long description missing.

> diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
> index 476db90..89b1f65 100644
> --- a/arch/arm64/include/asm/is_compat.h
> +++ b/arch/arm64/include/asm/is_compat.h
> @@ -36,7 +36,6 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  #else
>  
>  static inline int is_a32_compat_task(void)
> -
>  {
>  	return 0;
>  }

You should move this to the previous patch.

> @@ -45,14 +44,39 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  {
>  	return 0;
>  }
> -
>  #endif /* CONFIG_AARCH32_EL0 */

Maybe this one as well, though I like an empty line before the last
#endif (i.e. drop this hunk).

-- 
Catalin

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

* Re: [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
  2015-12-17 10:54             ` Catalin Marinas
@ 2015-12-17 13:56               ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-17 13:56 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: bamvor.zhangjian, pinskia, Prasun.Kapoor, schwab, joseph,
	Nathan_Lynch, agraf, linux-kernel, klimov.linux, Andrew Pinski,
	broonie, Yury Norov, Andrew Pinski, ddaney.cavm, jan.dakinevich,
	philipp.tomsich, linux-arm-kernel, christoph.muellner

On Thursday 17 December 2015 10:54:47 Catalin Marinas wrote:
> > > IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
> > > elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
> > > go beyond bit 31. The above may need to look something like:
> > > 
> > > #define COMPAT_ELF_HWCAP        \
> > >         (is_a32_compat_task()   \
> > >          ? compat_elf_hwcap     \
> > >          : (u32)elf_hwcap)
> > > 
> > > #define COMPAT_ELF_HWCAP2       \
> > >         (is_a32_compat_task()   \
> > >          ? compat_elf_hwcap2    \
> > >          : (u32)(elf_hwcap >> 32))
> > 
> > Yes, interesting find.
> 
> BTW, we need to make sure this series (primarily the ABI) is big-endian
> safe. I know it is not targeted at this initially but given that the
> reason for doing it is legacy networking code, I wouldn't be surprised
> if someone asks for BE at some point in the future.

Yes, I'm sure that will be needed.

	Arnd

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

* [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32
@ 2015-12-17 13:56               ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-17 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 17 December 2015 10:54:47 Catalin Marinas wrote:
> > > IIUC, we may have a problem with this. elf_hwcap is 64-bit long while
> > > elf_info[n] is 32-bit (Elf32_Addr), so we truncate AT_HWCAP if we ever
> > > go beyond bit 31. The above may need to look something like:
> > > 
> > > #define COMPAT_ELF_HWCAP        \
> > >         (is_a32_compat_task()   \
> > >          ? compat_elf_hwcap     \
> > >          : (u32)elf_hwcap)
> > > 
> > > #define COMPAT_ELF_HWCAP2       \
> > >         (is_a32_compat_task()   \
> > >          ? compat_elf_hwcap2    \
> > >          : (u32)(elf_hwcap >> 32))
> > 
> > Yes, interesting find.
> 
> BTW, we need to make sure this series (primarily the ABI) is big-endian
> safe. I know it is not targeted at this initially but given that the
> reason for doing it is legacy networking code, I wouldn't be surprised
> if someone asks for BE at some point in the future.

Yes, I'm sure that will be needed.

	Arnd

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

* Re: [PATCH v6 11/20] arm64:ilp32: support core dump generation for ILP32
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-17 14:05     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 14:05 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:37AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 8786ca5..4e2e3c0 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
[...]
> +/*
> + * struct elf_prstatus is defined in include/uapi/linux/elfcore.h,
> + * and has different sise for supported ABIs
> + */
> +#define PRSTATUS_SIZE(S)		(is_a32_compat_task() ? 124 : (is_ilp32_compat_task() ? 352 : 392))

It's the *third* time I ask this: can you not use some sizeof instead of
the magic numbers?

-- 
Catalin

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

* [PATCH v6 11/20] arm64:ilp32: support core dump generation for ILP32
@ 2015-12-17 14:05     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:37AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 8786ca5..4e2e3c0 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
[...]
> +/*
> + * struct elf_prstatus is defined in include/uapi/linux/elfcore.h,
> + * and has different sise for supported ABIs
> + */
> +#define PRSTATUS_SIZE(S)		(is_a32_compat_task() ? 124 : (is_ilp32_compat_task() ? 352 : 392))

It's the *third* time I ask this: can you not use some sizeof instead of
the magic numbers?

-- 
Catalin

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-17 14:38     ` Andreas Schwab
  -1 siblings, 0 replies; 156+ messages in thread
From: Andreas Schwab @ 2015-12-17 14:38 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel, pinskia,
	Prasun.Kapoor, Nathan_Lynch, agraf, klimov.linux, broonie,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

Yury Norov <ynorov@caviumnetworks.com> writes:

> From: Jan Dakinevich <jan.dakinevich@gmail.com>
>
> statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and

Typo: s/fstat64/fstatfs64/

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] 156+ messages in thread

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-17 14:38     ` Andreas Schwab
  0 siblings, 0 replies; 156+ messages in thread
From: Andreas Schwab @ 2015-12-17 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

Yury Norov <ynorov@caviumnetworks.com> writes:

> From: Jan Dakinevich <jan.dakinevich@gmail.com>
>
> statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and

Typo: s/fstat64/fstatfs64/

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab at 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] 156+ messages in thread

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-17 18:27     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 18:27 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, Andrew Pinski, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:38AM +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

I initially thought this should be sys_ftruncate64 (or a wrapper to pass
small == 0) but we rely on sys_openat to set O_LARGEFILE.

arch/arm has ftruncate and ftruncate64, but it looks like we route both
via sys_ftruncate(). The difference is the "small" argument which
imposes a limit on the length without O_LARGEFILE, so we may have a bug
here.

> +#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

I wonder whether we need wrappers (actually, not only for these but
sys_read etc.). These functions take either a pointer or a size_t
argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
kernel. Can we guarantee that user space zeros the top 32-bit of the
arguments passed here?

With compat/AArch32, this is guaranteed by the kernel since EL0 won't be
able to touch the top part but here I'm not entirely sure. As long as
user space used Wn registers for 32-bit types, we are probably fine (the
architecture guarantees the top 32-bit zeroing following a MOV, LDR etc.
instruction into a Wn register). We just need to mention this in the ABI
document (ilp32.txt).

> +#define compat_sys_sigaltstack         sys_sigaltstack

I think Arnd is right here in using the compat function. The stack_t
would differ between LP64 and ILP32. compat_sys_sigaltstack() uses
compat_user_stack_pointer() but this should work correctly as it checks
pt_regs for the right mode.

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

I think this makes sense since we have 64-bit registers.

> +
> +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> +#define compat_sys_openat              sys_openat

So using sys_openat() forces O_LARGEFILE and we don't have a problem
with (f)truncate. We may have an issue with AArch32 compat though.

-- 
Catalin

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-17 18:27     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-17 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:38AM +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

I initially thought this should be sys_ftruncate64 (or a wrapper to pass
small == 0) but we rely on sys_openat to set O_LARGEFILE.

arch/arm has ftruncate and ftruncate64, but it looks like we route both
via sys_ftruncate(). The difference is the "small" argument which
imposes a limit on the length without O_LARGEFILE, so we may have a bug
here.

> +#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

I wonder whether we need wrappers (actually, not only for these but
sys_read etc.). These functions take either a pointer or a size_t
argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
kernel. Can we guarantee that user space zeros the top 32-bit of the
arguments passed here?

With compat/AArch32, this is guaranteed by the kernel since EL0 won't be
able to touch the top part but here I'm not entirely sure. As long as
user space used Wn registers for 32-bit types, we are probably fine (the
architecture guarantees the top 32-bit zeroing following a MOV, LDR etc.
instruction into a Wn register). We just need to mention this in the ABI
document (ilp32.txt).

> +#define compat_sys_sigaltstack         sys_sigaltstack

I think Arnd is right here in using the compat function. The stack_t
would differ between LP64 and ILP32. compat_sys_sigaltstack() uses
compat_user_stack_pointer() but this should work correctly as it checks
pt_regs for the right mode.

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

I think this makes sense since we have 64-bit registers.

> +
> +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> +#define compat_sys_openat              sys_openat

So using sys_openat() forces O_LARGEFILE and we don't have a problem
with (f)truncate. We may have an issue with AArch32 compat though.

-- 
Catalin

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-17 18:27     ` Catalin Marinas
@ 2015-12-17 20:10       ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-17 20:10 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Yury Norov, linux-arm-kernel, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, Andrew Pinski, jan.dakinevich, Andrew Pinski,
	ddaney.cavm, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:

> > +#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
> 
> I wonder whether we need wrappers (actually, not only for these but
> sys_read etc.). These functions take either a pointer or a size_t
> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> kernel. Can we guarantee that user space zeros the top 32-bit of the
> arguments passed here?

I'm pretty sure that is safe. I haven't read the calling conventions
specification for arm64 ilp32, but usually all function arguments are
passed as 64-bit registers with proper sign-extend or zero-extend.

Most other syscalls rely on this behavior too, not just the ones that
are being modified here.

> With compat/AArch32, this is guaranteed by the kernel since EL0 won't be
> able to touch the top part but here I'm not entirely sure. As long as
> user space used Wn registers for 32-bit types, we are probably fine (the
> architecture guarantees the top 32-bit zeroing following a MOV, LDR etc.
> instruction into a Wn register). We just need to mention this in the ABI
> document (ilp32.txt).

I think the aarch32 case is actually the hard one, because it has to
worry about explicitly sign-extending 32-bit arguments (signed int or
signed long) that might be negative, e.g. user space passes -1 
as 0xffffffff, which the kernel entry turns into 0x00000000ffffffff
when it should use 0xffffffffffffffff. The COMPAT_SYSCALL_DEFINEx
macros take care of this.

> > +
> > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> > +#define compat_sys_openat              sys_openat
> 
> So using sys_openat() forces O_LARGEFILE and we don't have a problem
> with (f)truncate. We may have an issue with AArch32 compat though.

aarch32 uses the correct compat functions in asm/unistd32.h

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-17 20:10       ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-17 20:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:

> > +#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
> 
> I wonder whether we need wrappers (actually, not only for these but
> sys_read etc.). These functions take either a pointer or a size_t
> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> kernel. Can we guarantee that user space zeros the top 32-bit of the
> arguments passed here?

I'm pretty sure that is safe. I haven't read the calling conventions
specification for arm64 ilp32, but usually all function arguments are
passed as 64-bit registers with proper sign-extend or zero-extend.

Most other syscalls rely on this behavior too, not just the ones that
are being modified here.

> With compat/AArch32, this is guaranteed by the kernel since EL0 won't be
> able to touch the top part but here I'm not entirely sure. As long as
> user space used Wn registers for 32-bit types, we are probably fine (the
> architecture guarantees the top 32-bit zeroing following a MOV, LDR etc.
> instruction into a Wn register). We just need to mention this in the ABI
> document (ilp32.txt).

I think the aarch32 case is actually the hard one, because it has to
worry about explicitly sign-extending 32-bit arguments (signed int or
signed long) that might be negative, e.g. user space passes -1 
as 0xffffffff, which the kernel entry turns into 0x00000000ffffffff
when it should use 0xffffffffffffffff. The COMPAT_SYSCALL_DEFINEx
macros take care of this.

> > +
> > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> > +#define compat_sys_openat              sys_openat
> 
> So using sys_openat() forces O_LARGEFILE and we don't have a problem
> with (f)truncate. We may have an issue with AArch32 compat though.

aarch32 uses the correct compat functions in asm/unistd32.h

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-17 20:10       ` Arnd Bergmann
@ 2015-12-17 20:14         ` Andrew Pinski
  -1 siblings, 0 replies; 156+ messages in thread
From: Andrew Pinski @ 2015-12-17 20:14 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Catalin Marinas, Yury Norov, linux-arm-kernel, LKML, Kapoor,
	Prasun, Andreas Schwab, broonie, Nathan Lynch, Alexander Graf,
	Alexey Klimov, Jan Dakinevich, Andrew Pinski, David Daney,
	Zhangjian (Bamvor),
	Philipp Tomsich, Joseph S. Myers, christoph.muellner

On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
>> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
>
>> > +#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
>>
>> I wonder whether we need wrappers (actually, not only for these but
>> sys_read etc.). These functions take either a pointer or a size_t
>> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
>> kernel. Can we guarantee that user space zeros the top 32-bit of the
>> arguments passed here?
>
> I'm pretty sure that is safe. I haven't read the calling conventions
> specification for arm64 ilp32, but usually all function arguments are
> passed as 64-bit registers with proper sign-extend or zero-extend.

Well (just like LP64 on AARCH64), when passing a 32bit value to a
function, the upper 32bits are undefined.  I ran into this when I was
debugging the GCC go library on ILP32 (though reproduced with pure C
code) and the assembly functions inside glibc where pointers are
passed with the upper 32bits as undefined.
So we have an issue if called with syscall function or using pure
assembly to create the syscall functions (which glibc does).

Thanks,
Andrew

>
> Most other syscalls rely on this behavior too, not just the ones that
> are being modified here.
>
>> With compat/AArch32, this is guaranteed by the kernel since EL0 won't be
>> able to touch the top part but here I'm not entirely sure. As long as
>> user space used Wn registers for 32-bit types, we are probably fine (the
>> architecture guarantees the top 32-bit zeroing following a MOV, LDR etc.
>> instruction into a Wn register). We just need to mention this in the ABI
>> document (ilp32.txt).
>
> I think the aarch32 case is actually the hard one, because it has to
> worry about explicitly sign-extending 32-bit arguments (signed int or
> signed long) that might be negative, e.g. user space passes -1
> as 0xffffffff, which the kernel entry turns into 0x00000000ffffffff
> when it should use 0xffffffffffffffff. The COMPAT_SYSCALL_DEFINEx
> macros take care of this.
>
>> > +
>> > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
>> > +#define compat_sys_openat              sys_openat
>>
>> So using sys_openat() forces O_LARGEFILE and we don't have a problem
>> with (f)truncate. We may have an issue with AArch32 compat though.
>
> aarch32 uses the correct compat functions in asm/unistd32.h
>
>         Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-17 20:14         ` Andrew Pinski
  0 siblings, 0 replies; 156+ messages in thread
From: Andrew Pinski @ 2015-12-17 20:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
>> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
>
>> > +#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
>>
>> I wonder whether we need wrappers (actually, not only for these but
>> sys_read etc.). These functions take either a pointer or a size_t
>> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
>> kernel. Can we guarantee that user space zeros the top 32-bit of the
>> arguments passed here?
>
> I'm pretty sure that is safe. I haven't read the calling conventions
> specification for arm64 ilp32, but usually all function arguments are
> passed as 64-bit registers with proper sign-extend or zero-extend.

Well (just like LP64 on AARCH64), when passing a 32bit value to a
function, the upper 32bits are undefined.  I ran into this when I was
debugging the GCC go library on ILP32 (though reproduced with pure C
code) and the assembly functions inside glibc where pointers are
passed with the upper 32bits as undefined.
So we have an issue if called with syscall function or using pure
assembly to create the syscall functions (which glibc does).

Thanks,
Andrew

>
> Most other syscalls rely on this behavior too, not just the ones that
> are being modified here.
>
>> With compat/AArch32, this is guaranteed by the kernel since EL0 won't be
>> able to touch the top part but here I'm not entirely sure. As long as
>> user space used Wn registers for 32-bit types, we are probably fine (the
>> architecture guarantees the top 32-bit zeroing following a MOV, LDR etc.
>> instruction into a Wn register). We just need to mention this in the ABI
>> document (ilp32.txt).
>
> I think the aarch32 case is actually the hard one, because it has to
> worry about explicitly sign-extending 32-bit arguments (signed int or
> signed long) that might be negative, e.g. user space passes -1
> as 0xffffffff, which the kernel entry turns into 0x00000000ffffffff
> when it should use 0xffffffffffffffff. The COMPAT_SYSCALL_DEFINEx
> macros take care of this.
>
>> > +
>> > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
>> > +#define compat_sys_openat              sys_openat
>>
>> So using sys_openat() forces O_LARGEFILE and we don't have a problem
>> with (f)truncate. We may have an issue with AArch32 compat though.
>
> aarch32 uses the correct compat functions in asm/unistd32.h
>
>         Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-17 20:14         ` Andrew Pinski
@ 2015-12-17 20:50           ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-17 20:50 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Catalin Marinas, Yury Norov, linux-arm-kernel, LKML, Kapoor,
	Prasun, Andreas Schwab, broonie, Nathan Lynch, Alexander Graf,
	Alexey Klimov, Jan Dakinevich, Andrew Pinski, David Daney,
	Zhangjian (Bamvor),
	Philipp Tomsich, Joseph S. Myers, christoph.muellner

On Thursday 17 December 2015 12:14:20 Andrew Pinski wrote:
> On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> >> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
> >
> >> > +#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
> >>
> >> I wonder whether we need wrappers (actually, not only for these but
> >> sys_read etc.). These functions take either a pointer or a size_t
> >> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> >> kernel. Can we guarantee that user space zeros the top 32-bit of the
> >> arguments passed here?
> >
> > I'm pretty sure that is safe. I haven't read the calling conventions
> > specification for arm64 ilp32, but usually all function arguments are
> > passed as 64-bit registers with proper sign-extend or zero-extend.
> 
> Well (just like LP64 on AARCH64), when passing a 32bit value to a
> function, the upper 32bits are undefined.  I ran into this when I was
> debugging the GCC go library on ILP32 (though reproduced with pure C
> code) and the assembly functions inside glibc where pointers are
> passed with the upper 32bits as undefined.
> So we have an issue if called with syscall function or using pure
> assembly to create the syscall functions (which glibc does).

Ok, I see :-(

So the calling conventions avoid the problem of being able to set
the upper bits from malicious user space when the kernel assumes they
are zeroed out (we had security bugs in this area, before we introduced
SYSCALL_DEFINEx()), but it means that we need wrappers around each
syscall that takes an argument that is different length between user
and kernel space (as Catalin guessed). arch/s390 has the same problem and
works around it with code in arch/s390/kernel/compat_wrapper.c, while
other architectures (at least powerpc, x86 and tile IIRC, don't know much
about mips, parisc and sparc) don't have the problem because of their
calling conventions.

This also means that we cannot work around it in glibc at all, because
we have to be able to handle malicious user space, so it has to be
done in the kernel using something similar to what s390 does.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-17 20:50           ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-17 20:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 17 December 2015 12:14:20 Andrew Pinski wrote:
> On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> >> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
> >
> >> > +#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
> >>
> >> I wonder whether we need wrappers (actually, not only for these but
> >> sys_read etc.). These functions take either a pointer or a size_t
> >> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> >> kernel. Can we guarantee that user space zeros the top 32-bit of the
> >> arguments passed here?
> >
> > I'm pretty sure that is safe. I haven't read the calling conventions
> > specification for arm64 ilp32, but usually all function arguments are
> > passed as 64-bit registers with proper sign-extend or zero-extend.
> 
> Well (just like LP64 on AARCH64), when passing a 32bit value to a
> function, the upper 32bits are undefined.  I ran into this when I was
> debugging the GCC go library on ILP32 (though reproduced with pure C
> code) and the assembly functions inside glibc where pointers are
> passed with the upper 32bits as undefined.
> So we have an issue if called with syscall function or using pure
> assembly to create the syscall functions (which glibc does).

Ok, I see :-(

So the calling conventions avoid the problem of being able to set
the upper bits from malicious user space when the kernel assumes they
are zeroed out (we had security bugs in this area, before we introduced
SYSCALL_DEFINEx()), but it means that we need wrappers around each
syscall that takes an argument that is different length between user
and kernel space (as Catalin guessed). arch/s390 has the same problem and
works around it with code in arch/s390/kernel/compat_wrapper.c, while
other architectures (at least powerpc, x86 and tile IIRC, don't know much
about mips, parisc and sparc) don't have the problem because of their
calling conventions.

This also means that we cannot work around it in glibc at all, because
we have to be able to handle malicious user space, so it has to be
done in the kernel using something similar to what s390 does.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-17 20:14         ` Andrew Pinski
@ 2015-12-18 11:42           ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-18 11:42 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Arnd Bergmann, Joseph S. Myers, Kapoor, Prasun, broonie,
	Nathan Lynch, LKML, Alexander Graf, Alexey Klimov, Yury Norov,
	Jan Dakinevich, Andrew Pinski, David Daney, Andreas Schwab,
	Zhangjian (Bamvor),
	Philipp Tomsich, linux-arm-kernel, christoph.muellner,
	Marcus Shawcroft

(cc'ing Marcus for more insight on the tools side)

On Thu, Dec 17, 2015 at 12:14:20PM -0800, Andrew Pinski wrote:
> On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> >> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
> >
> >> > +#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
> >>
> >> I wonder whether we need wrappers (actually, not only for these but
> >> sys_read etc.). These functions take either a pointer or a size_t
> >> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> >> kernel. Can we guarantee that user space zeros the top 32-bit of the
> >> arguments passed here?
> >
> > I'm pretty sure that is safe. I haven't read the calling conventions
> > specification for arm64 ilp32, but usually all function arguments are
> > passed as 64-bit registers with proper sign-extend or zero-extend.
> 
> Well (just like LP64 on AARCH64), when passing a 32bit value to a
> function, the upper 32bits are undefined.  I ran into this when I was
> debugging the GCC go library on ILP32 (though reproduced with pure C
> code) and the assembly functions inside glibc where pointers are
> passed with the upper 32bits as undefined.
> So we have an issue if called with syscall function or using pure
> assembly to create the syscall functions (which glibc does).

I think the ILP32 syscall ABI should follow the PCS convention where the
top 32-bit of a register is not guaranteed 0 when the size of the
argument is 32-bit. So take the read(2) syscall:

	ssize_t read(int fd, void *buf, size_t count);

>From the ILP32 code perspective, void * and size_t are both 32-bit. It
would call into the kernel leaving the top 32-bit as undefined (if we
follow the PCS). Normally, calling a function with the same size
arguments is not a problem since the compiler generates the callee code
accordingly. However, we route the syscall directly into the native
sys_read() where void * and size_t are 64-bit with the top 32-bit left
undefined.

We have three options here:

1. Always follow PCS convention across user/kernel call and add wrappers
   in the kernel (preferred)

2. Follow the PCS up to glibc and get glibc to zero the top part (not
   always safe with hand-written assembly, though we already do this for
   AArch32 where the PCS only specifies 4 arguments in registers, the
   rest go on the stack)

3. Follow the PCS up to glibc but always pass syscall arguments in W
   registers, like AArch32 compat support (the least preferred option,
   the only advantage is a single wrapper for all syscalls but it would
   be doing unnecessary zeroing even for syscalls where it isn't needed)

My preference, as stated above, is (1). You can write the wrappers in C
directly and let the compiler upgrade the types when calling the native
syscall. But any other option would be fine (take some inspiration from
other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
for all functions that we need to wrap, it would have been easier (so we
need to add them but probably in the arch/arm64 code).

-- 
Catalin

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-18 11:42           ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-18 11:42 UTC (permalink / raw)
  To: linux-arm-kernel

(cc'ing Marcus for more insight on the tools side)

On Thu, Dec 17, 2015 at 12:14:20PM -0800, Andrew Pinski wrote:
> On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> >> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
> >
> >> > +#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
> >>
> >> I wonder whether we need wrappers (actually, not only for these but
> >> sys_read etc.). These functions take either a pointer or a size_t
> >> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> >> kernel. Can we guarantee that user space zeros the top 32-bit of the
> >> arguments passed here?
> >
> > I'm pretty sure that is safe. I haven't read the calling conventions
> > specification for arm64 ilp32, but usually all function arguments are
> > passed as 64-bit registers with proper sign-extend or zero-extend.
> 
> Well (just like LP64 on AARCH64), when passing a 32bit value to a
> function, the upper 32bits are undefined.  I ran into this when I was
> debugging the GCC go library on ILP32 (though reproduced with pure C
> code) and the assembly functions inside glibc where pointers are
> passed with the upper 32bits as undefined.
> So we have an issue if called with syscall function or using pure
> assembly to create the syscall functions (which glibc does).

I think the ILP32 syscall ABI should follow the PCS convention where the
top 32-bit of a register is not guaranteed 0 when the size of the
argument is 32-bit. So take the read(2) syscall:

	ssize_t read(int fd, void *buf, size_t count);

>From the ILP32 code perspective, void * and size_t are both 32-bit. It
would call into the kernel leaving the top 32-bit as undefined (if we
follow the PCS). Normally, calling a function with the same size
arguments is not a problem since the compiler generates the callee code
accordingly. However, we route the syscall directly into the native
sys_read() where void * and size_t are 64-bit with the top 32-bit left
undefined.

We have three options here:

1. Always follow PCS convention across user/kernel call and add wrappers
   in the kernel (preferred)

2. Follow the PCS up to glibc and get glibc to zero the top part (not
   always safe with hand-written assembly, though we already do this for
   AArch32 where the PCS only specifies 4 arguments in registers, the
   rest go on the stack)

3. Follow the PCS up to glibc but always pass syscall arguments in W
   registers, like AArch32 compat support (the least preferred option,
   the only advantage is a single wrapper for all syscalls but it would
   be doing unnecessary zeroing even for syscalls where it isn't needed)

My preference, as stated above, is (1). You can write the wrappers in C
directly and let the compiler upgrade the types when calling the native
syscall. But any other option would be fine (take some inspiration from
other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
for all functions that we need to wrap, it would have been easier (so we
need to add them but probably in the arch/arm64 code).

-- 
Catalin

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-18 11:42           ` Catalin Marinas
@ 2015-12-18 12:47             ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-18 12:47 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Andrew Pinski, Joseph S. Myers, Kapoor, Prasun, broonie,
	Nathan Lynch, LKML, Alexander Graf, Alexey Klimov, Yury Norov,
	Jan Dakinevich, Andrew Pinski, David Daney, Andreas Schwab,
	Zhangjian (Bamvor),
	Philipp Tomsich, linux-arm-kernel, christoph.muellner,
	Marcus Shawcroft

On Friday 18 December 2015 11:42:19 Catalin Marinas wrote:
> On Thu, Dec 17, 2015 at 12:14:20PM -0800, Andrew Pinski wrote:
> > Well (just like LP64 on AARCH64), when passing a 32bit value to a
> > function, the upper 32bits are undefined.  I ran into this when I was
> > debugging the GCC go library on ILP32 (though reproduced with pure C
> > code) and the assembly functions inside glibc where pointers are
> > passed with the upper 32bits as undefined.
> > So we have an issue if called with syscall function or using pure
> > assembly to create the syscall functions (which glibc does).
> 
> I think the ILP32 syscall ABI should follow the PCS convention where the
> top 32-bit of a register is not guaranteed 0 when the size of the
> argument is 32-bit. So take the read(2) syscall:
> 
>         ssize_t read(int fd, void *buf, size_t count);
> 
> From the ILP32 code perspective, void * and size_t are both 32-bit. It
> would call into the kernel leaving the top 32-bit as undefined (if we
> follow the PCS). Normally, calling a function with the same size
> arguments is not a problem since the compiler generates the callee code
> accordingly. However, we route the syscall directly into the native
> sys_read() where void * and size_t are 64-bit with the top 32-bit left
> undefined.
> 
> We have three options here:
> 
> 1. Always follow PCS convention across user/kernel call and add wrappers
>    in the kernel (preferred)

Yes, I also think this is best.

> 2. Follow the PCS up to glibc and get glibc to zero the top part (not
>    always safe with hand-written assembly, though we already do this for
>    AArch32 where the PCS only specifies 4 arguments in registers, the
>    rest go on the stack)

I assume this needs special handling for syscalls with 64-bit arguments
in both glibc and kernel.

> 3. Follow the PCS up to glibc but always pass syscall arguments in W
>    registers, like AArch32 compat support (the least preferred option,
>    the only advantage is a single wrapper for all syscalls but it would
>    be doing unnecessary zeroing even for syscalls where it isn't needed)

This would mean we cannot pass 64-bit arguments in registers, right?
 
> My preference, as stated above, is (1). You can write the wrappers in C
> directly and let the compiler upgrade the types when calling the native
> syscall. But any other option would be fine (take some inspiration from
> other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
> for all functions that we need to wrap, it would have been easier (so we
> need to add them but probably in the arch/arm64 code).

It would be nice to have that code architecture-independent, so we can
share it with s390 and only need to update one place when new syscalls
get added.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-18 12:47             ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-18 12:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 18 December 2015 11:42:19 Catalin Marinas wrote:
> On Thu, Dec 17, 2015 at 12:14:20PM -0800, Andrew Pinski wrote:
> > Well (just like LP64 on AARCH64), when passing a 32bit value to a
> > function, the upper 32bits are undefined.  I ran into this when I was
> > debugging the GCC go library on ILP32 (though reproduced with pure C
> > code) and the assembly functions inside glibc where pointers are
> > passed with the upper 32bits as undefined.
> > So we have an issue if called with syscall function or using pure
> > assembly to create the syscall functions (which glibc does).
> 
> I think the ILP32 syscall ABI should follow the PCS convention where the
> top 32-bit of a register is not guaranteed 0 when the size of the
> argument is 32-bit. So take the read(2) syscall:
> 
>         ssize_t read(int fd, void *buf, size_t count);
> 
> From the ILP32 code perspective, void * and size_t are both 32-bit. It
> would call into the kernel leaving the top 32-bit as undefined (if we
> follow the PCS). Normally, calling a function with the same size
> arguments is not a problem since the compiler generates the callee code
> accordingly. However, we route the syscall directly into the native
> sys_read() where void * and size_t are 64-bit with the top 32-bit left
> undefined.
> 
> We have three options here:
> 
> 1. Always follow PCS convention across user/kernel call and add wrappers
>    in the kernel (preferred)

Yes, I also think this is best.

> 2. Follow the PCS up to glibc and get glibc to zero the top part (not
>    always safe with hand-written assembly, though we already do this for
>    AArch32 where the PCS only specifies 4 arguments in registers, the
>    rest go on the stack)

I assume this needs special handling for syscalls with 64-bit arguments
in both glibc and kernel.

> 3. Follow the PCS up to glibc but always pass syscall arguments in W
>    registers, like AArch32 compat support (the least preferred option,
>    the only advantage is a single wrapper for all syscalls but it would
>    be doing unnecessary zeroing even for syscalls where it isn't needed)

This would mean we cannot pass 64-bit arguments in registers, right?
 
> My preference, as stated above, is (1). You can write the wrappers in C
> directly and let the compiler upgrade the types when calling the native
> syscall. But any other option would be fine (take some inspiration from
> other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
> for all functions that we need to wrap, it would have been easier (so we
> need to add them but probably in the arch/arm64 code).

It would be nice to have that code architecture-independent, so we can
share it with s390 and only need to update one place when new syscalls
get added.

	Arnd

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

* Re: [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
  2015-12-16 16:08     ` Arnd Bergmann
@ 2015-12-18 13:48       ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 13:48 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wed, Dec 16, 2015 at 05:08:35PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:42:41 Yury Norov wrote:
> > +               sigtramp = ka->sa.sa_restorer;
> > +#ifdef CONFIG_ARM64_ILP32
> > +       else if (is_ilp32_compat_task())
> > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> > +#endif
> > +       else
> > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> > 
> 
> This is another case where I think it's more readable to remove the #ifdef,
> with no change in behavior.
> 
> 	Arnd

No actually. symbol sigtramp_ilp32 is declared in
arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S

And so it does not exist if CONFIG_ARM64_ILP32 is not set.

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

* [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
@ 2015-12-18 13:48       ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 05:08:35PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:42:41 Yury Norov wrote:
> > +               sigtramp = ka->sa.sa_restorer;
> > +#ifdef CONFIG_ARM64_ILP32
> > +       else if (is_ilp32_compat_task())
> > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> > +#endif
> > +       else
> > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> > 
> 
> This is another case where I think it's more readable to remove the #ifdef,
> with no change in behavior.
> 
> 	Arnd

No actually. symbol sigtramp_ilp32 is declared in
arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S

And so it does not exist if CONFIG_ARM64_ILP32 is not set.

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-17 14:38     ` Andreas Schwab
@ 2015-12-18 13:49       ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 13:49 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel, pinskia,
	Prasun.Kapoor, Nathan_Lynch, agraf, klimov.linux, broonie,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Thu, Dec 17, 2015 at 03:38:16PM +0100, Andreas Schwab wrote:
> Yury Norov <ynorov@caviumnetworks.com> writes:
> 
> > From: Jan Dakinevich <jan.dakinevich@gmail.com>
> >
> > statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
> 
> Typo: s/fstat64/fstatfs64/
> 
> Andreas.

Thank you.

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-18 13:49       ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 17, 2015 at 03:38:16PM +0100, Andreas Schwab wrote:
> Yury Norov <ynorov@caviumnetworks.com> writes:
> 
> > From: Jan Dakinevich <jan.dakinevich@gmail.com>
> >
> > statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
> 
> Typo: s/fstat64/fstatfs64/
> 
> Andreas.

Thank you.

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

* Re: [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
  2015-12-16 15:50     ` Arnd Bergmann
@ 2015-12-18 13:57       ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 13:57 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, Andrew Pinski, jan.dakinevich, Andrew Pinski,
	ddaney.cavm, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Wed, Dec 16, 2015 at 04:50:18PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:42:36 Yury Norov wrote:
> > +#ifdef CONFIG_ARM64_ILP32
> > +       /* ILP32 threads are started the same way as LP64 threads. */
> > +       if (is_ilp32_compat_task()) {
> > +               start_thread(regs, pc, sp);
> > +               return;
> > +       }
> > +#endif
> > 
> 
> Just a small style comment, but I think you can just leave out the #ifdef,
> as is_ilp32_compat_task() will already return false if that is disabled.
> 
> 	Arnd

Missed it, thank you.

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

* [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
@ 2015-12-18 13:57       ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 04:50:18PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 December 2015 00:42:36 Yury Norov wrote:
> > +#ifdef CONFIG_ARM64_ILP32
> > +       /* ILP32 threads are started the same way as LP64 threads. */
> > +       if (is_ilp32_compat_task()) {
> > +               start_thread(regs, pc, sp);
> > +               return;
> > +       }
> > +#endif
> > 
> 
> Just a small style comment, but I think you can just leave out the #ifdef,
> as is_ilp32_compat_task() will already return false if that is disabled.
> 
> 	Arnd

Missed it, thank you.

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

* Re: [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
  2015-12-18 13:48       ` Yury Norov
@ 2015-12-18 14:09         ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-18 14:09 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arm-kernel, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Friday 18 December 2015 16:48:55 Yury Norov wrote:
> On Wed, Dec 16, 2015 at 05:08:35PM +0100, Arnd Bergmann wrote:
> > On Wednesday 16 December 2015 00:42:41 Yury Norov wrote:
> > > +               sigtramp = ka->sa.sa_restorer;
> > > +#ifdef CONFIG_ARM64_ILP32
> > > +       else if (is_ilp32_compat_task())
> > > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> > > +#endif
> > > +       else
> > > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> > > 
> > 
> > This is another case where I think it's more readable to remove the #ifdef,
> > with no change in behavior.
> > 
> >       Arnd
> 
> No actually. symbol sigtramp_ilp32 is declared in
> arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> 
> And so it does not exist if CONFIG_ARM64_ILP32 is not set.

You only need the declaration of that symbol, the compiler's dead code
elimination will ensure that no symbol reference is generated when 
the condition is always false at compile time.

	Arnd

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

* [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
@ 2015-12-18 14:09         ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-18 14:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 18 December 2015 16:48:55 Yury Norov wrote:
> On Wed, Dec 16, 2015 at 05:08:35PM +0100, Arnd Bergmann wrote:
> > On Wednesday 16 December 2015 00:42:41 Yury Norov wrote:
> > > +               sigtramp = ka->sa.sa_restorer;
> > > +#ifdef CONFIG_ARM64_ILP32
> > > +       else if (is_ilp32_compat_task())
> > > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
> > > +#endif
> > > +       else
> > > +               sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
> > > 
> > 
> > This is another case where I think it's more readable to remove the #ifdef,
> > with no change in behavior.
> > 
> >       Arnd
> 
> No actually. symbol sigtramp_ilp32 is declared in
> arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> 
> And so it does not exist if CONFIG_ARM64_ILP32 is not set.

You only need the declaration of that symbol, the compiler's dead code
elimination will ensure that no symbol reference is generated when 
the condition is always false at compile time.

	Arnd

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

* Re: [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
  2015-12-17 11:41     ` Catalin Marinas
@ 2015-12-18 14:11       ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 14:11 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Thu, Dec 17, 2015 at 11:41:53AM +0000, Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> > Reviewed-by: David Daney <ddaney@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>
> > Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> 
> Long description missing.

Hi, Catalin,

I think this patch (and patch #3 too) is trivial, and
explanation in patch name is clear enougth. So, I just do not
understand what else to explain here. Could you point me, and then I
will do it.

> 
> > diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
> > index 476db90..89b1f65 100644
> > --- a/arch/arm64/include/asm/is_compat.h
> > +++ b/arch/arm64/include/asm/is_compat.h
> > @@ -36,7 +36,6 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
> >  #else
> >  
> >  static inline int is_a32_compat_task(void)
> > -
> >  {
> >  	return 0;
> >  }
> 
> You should move this to the previous patch.
> 
> > @@ -45,14 +44,39 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
> >  {
> >  	return 0;
> >  }
> > -
> >  #endif /* CONFIG_AARCH32_EL0 */
> 
> Maybe this one as well, though I like an empty line before the last
> #endif (i.e. drop this hunk).

It's just dirt, I'll clean it. Thank you.

Yury.

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

* [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
@ 2015-12-18 14:11       ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 14:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 17, 2015 at 11:41:53AM +0000, Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> > Reviewed-by: David Daney <ddaney@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>
> > Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> 
> Long description missing.

Hi, Catalin,

I think this patch (and patch #3 too) is trivial, and
explanation in patch name is clear enougth. So, I just do not
understand what else to explain here. Could you point me, and then I
will do it.

> 
> > diff --git a/arch/arm64/include/asm/is_compat.h b/arch/arm64/include/asm/is_compat.h
> > index 476db90..89b1f65 100644
> > --- a/arch/arm64/include/asm/is_compat.h
> > +++ b/arch/arm64/include/asm/is_compat.h
> > @@ -36,7 +36,6 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
> >  #else
> >  
> >  static inline int is_a32_compat_task(void)
> > -
> >  {
> >  	return 0;
> >  }
> 
> You should move this to the previous patch.
> 
> > @@ -45,14 +44,39 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
> >  {
> >  	return 0;
> >  }
> > -
> >  #endif /* CONFIG_AARCH32_EL0 */
> 
> Maybe this one as well, though I like an empty line before the last
> #endif (i.e. drop this hunk).

It's just dirt, I'll clean it. Thank you.

Yury.

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

* Re: [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
  2015-12-18 14:11       ` Yury Norov
@ 2015-12-18 14:44         ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 14:44 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, linux-kernel,
	agraf, klimov.linux, Andrew Pinski, broonie, jan.dakinevich,
	joseph, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	linux-arm-kernel, christoph.muellner

On Fri, Dec 18, 2015 at 05:11:12PM +0300, Yury Norov wrote:
> On Thu, Dec 17, 2015 at 11:41:53AM +0000, Catalin Marinas wrote:
> > On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> > > Reviewed-by: David Daney <ddaney@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>
> > > Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> > 
> > Long description missing.
> 
> Hi, Catalin,
> 
> I think this patch (and patch #3 too) is trivial, and
> explanation in patch name is clear enougth. So, I just do not
> understand what else to explain here. Could you point me, and then I
> will do it.
> 

Is it OK?

arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64

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 this. This patch is
preparation for following patches in ilp32 patchset.

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

* [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
@ 2015-12-18 14:44         ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-18 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 18, 2015 at 05:11:12PM +0300, Yury Norov wrote:
> On Thu, Dec 17, 2015 at 11:41:53AM +0000, Catalin Marinas wrote:
> > On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> > > Reviewed-by: David Daney <ddaney@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>
> > > Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> > 
> > Long description missing.
> 
> Hi, Catalin,
> 
> I think this patch (and patch #3 too) is trivial, and
> explanation in patch name is clear enougth. So, I just do not
> understand what else to explain here. Could you point me, and then I
> will do it.
> 

Is it OK?

arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64

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 this. This patch is
preparation for following patches in ilp32 patchset.

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

* Re: [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
  2015-12-18 14:44         ` Yury Norov
@ 2015-12-21 17:42           ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-21 17:42 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, linux-kernel,
	agraf, klimov.linux, Andrew Pinski, broonie, jan.dakinevich,
	linux-arm-kernel, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Fri, Dec 18, 2015 at 05:44:37PM +0300, Yury Norov wrote:
> On Fri, Dec 18, 2015 at 05:11:12PM +0300, Yury Norov wrote:
> > On Thu, Dec 17, 2015 at 11:41:53AM +0000, Catalin Marinas wrote:
> > > On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> > > > Reviewed-by: David Daney <ddaney@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>
> > > > Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> > > 
> > > Long description missing.
> > 
> > Hi, Catalin,
> > 
> > I think this patch (and patch #3 too) is trivial, and
> > explanation in patch name is clear enougth. So, I just do not
> > understand what else to explain here. Could you point me, and then I
> > will do it.
> > 
> 
> Is it OK?
> 
> arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
> 
> 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 this. This patch is
> preparation for following patches in ilp32 patchset.

It looks fine to me.

-- 
Catalin

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

* [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} and TIF_32BIT_AARCH64
@ 2015-12-21 17:42           ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-21 17:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 18, 2015 at 05:44:37PM +0300, Yury Norov wrote:
> On Fri, Dec 18, 2015 at 05:11:12PM +0300, Yury Norov wrote:
> > On Thu, Dec 17, 2015 at 11:41:53AM +0000, Catalin Marinas wrote:
> > > On Wed, Dec 16, 2015 at 12:42:34AM +0300, Yury Norov wrote:
> > > > Reviewed-by: David Daney <ddaney@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>
> > > > Signed-off-by: Andrew Pinski <Andrew.Pinski@caviumnetworks.com>
> > > 
> > > Long description missing.
> > 
> > Hi, Catalin,
> > 
> > I think this patch (and patch #3 too) is trivial, and
> > explanation in patch name is clear enougth. So, I just do not
> > understand what else to explain here. Could you point me, and then I
> > will do it.
> > 
> 
> Is it OK?
> 
> arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
> 
> 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 this. This patch is
> preparation for following patches in ilp32 patchset.

It looks fine to me.

-- 
Catalin

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-18 12:47             ` Arnd Bergmann
@ 2015-12-21 18:31               ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-21 18:31 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Zhangjian (Bamvor),
	Andrew Pinski, Kapoor, Prasun, Andreas Schwab, Nathan Lynch,
	LKML, Alexander Graf, Alexey Klimov, broonie, Yury Norov,
	Andrew Pinski, David Daney, Jan Dakinevich, Philipp Tomsich,
	Marcus Shawcroft, Joseph S. Myers, christoph.muellner

On Fri, Dec 18, 2015 at 01:47:55PM +0100, Arnd Bergmann wrote:
> On Friday 18 December 2015 11:42:19 Catalin Marinas wrote:
> > On Thu, Dec 17, 2015 at 12:14:20PM -0800, Andrew Pinski wrote:
> > > Well (just like LP64 on AARCH64), when passing a 32bit value to a
> > > function, the upper 32bits are undefined.  I ran into this when I was
> > > debugging the GCC go library on ILP32 (though reproduced with pure C
> > > code) and the assembly functions inside glibc where pointers are
> > > passed with the upper 32bits as undefined.
> > > So we have an issue if called with syscall function or using pure
> > > assembly to create the syscall functions (which glibc does).
> > 
> > I think the ILP32 syscall ABI should follow the PCS convention where the
> > top 32-bit of a register is not guaranteed 0 when the size of the
> > argument is 32-bit. So take the read(2) syscall:
> > 
> >         ssize_t read(int fd, void *buf, size_t count);
> > 
> > From the ILP32 code perspective, void * and size_t are both 32-bit. It
> > would call into the kernel leaving the top 32-bit as undefined (if we
> > follow the PCS). Normally, calling a function with the same size
> > arguments is not a problem since the compiler generates the callee code
> > accordingly. However, we route the syscall directly into the native
> > sys_read() where void * and size_t are 64-bit with the top 32-bit left
> > undefined.
> > 
> > We have three options here:
> > 
> > 1. Always follow PCS convention across user/kernel call and add wrappers
> >    in the kernel (preferred)
> 
> Yes, I also think this is best.
> 
> > 2. Follow the PCS up to glibc and get glibc to zero the top part (not
> >    always safe with hand-written assembly, though we already do this for
> >    AArch32 where the PCS only specifies 4 arguments in registers, the
> >    rest go on the stack)
> 
> I assume this needs special handling for syscalls with 64-bit arguments
> in both glibc and kernel.

I think glibc only should suffice, if it is its responsibility to zero
the top 32-bit part.

> > 3. Follow the PCS up to glibc but always pass syscall arguments in W
> >    registers, like AArch32 compat support (the least preferred option,
> >    the only advantage is a single wrapper for all syscalls but it would
> >    be doing unnecessary zeroing even for syscalls where it isn't needed)
> 
> This would mean we cannot pass 64-bit arguments in registers, right?

Not in a single register but two (like we do on AArch32).

> > My preference, as stated above, is (1). You can write the wrappers in C
> > directly and let the compiler upgrade the types when calling the native
> > syscall. But any other option would be fine (take some inspiration from
> > other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
> > for all functions that we need to wrap, it would have been easier (so we
> > need to add them but probably in the arch/arm64 code).
> 
> It would be nice to have that code architecture-independent, so we can
> share it with s390 and only need to update one place when new syscalls
> get added.

We could indeed move things like:

COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)

to the core code and share them between s390 and arm64/ILP32. So let's
stick to option 1.

-- 
Catalin

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-21 18:31               ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-21 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 18, 2015 at 01:47:55PM +0100, Arnd Bergmann wrote:
> On Friday 18 December 2015 11:42:19 Catalin Marinas wrote:
> > On Thu, Dec 17, 2015 at 12:14:20PM -0800, Andrew Pinski wrote:
> > > Well (just like LP64 on AARCH64), when passing a 32bit value to a
> > > function, the upper 32bits are undefined.  I ran into this when I was
> > > debugging the GCC go library on ILP32 (though reproduced with pure C
> > > code) and the assembly functions inside glibc where pointers are
> > > passed with the upper 32bits as undefined.
> > > So we have an issue if called with syscall function or using pure
> > > assembly to create the syscall functions (which glibc does).
> > 
> > I think the ILP32 syscall ABI should follow the PCS convention where the
> > top 32-bit of a register is not guaranteed 0 when the size of the
> > argument is 32-bit. So take the read(2) syscall:
> > 
> >         ssize_t read(int fd, void *buf, size_t count);
> > 
> > From the ILP32 code perspective, void * and size_t are both 32-bit. It
> > would call into the kernel leaving the top 32-bit as undefined (if we
> > follow the PCS). Normally, calling a function with the same size
> > arguments is not a problem since the compiler generates the callee code
> > accordingly. However, we route the syscall directly into the native
> > sys_read() where void * and size_t are 64-bit with the top 32-bit left
> > undefined.
> > 
> > We have three options here:
> > 
> > 1. Always follow PCS convention across user/kernel call and add wrappers
> >    in the kernel (preferred)
> 
> Yes, I also think this is best.
> 
> > 2. Follow the PCS up to glibc and get glibc to zero the top part (not
> >    always safe with hand-written assembly, though we already do this for
> >    AArch32 where the PCS only specifies 4 arguments in registers, the
> >    rest go on the stack)
> 
> I assume this needs special handling for syscalls with 64-bit arguments
> in both glibc and kernel.

I think glibc only should suffice, if it is its responsibility to zero
the top 32-bit part.

> > 3. Follow the PCS up to glibc but always pass syscall arguments in W
> >    registers, like AArch32 compat support (the least preferred option,
> >    the only advantage is a single wrapper for all syscalls but it would
> >    be doing unnecessary zeroing even for syscalls where it isn't needed)
> 
> This would mean we cannot pass 64-bit arguments in registers, right?

Not in a single register but two (like we do on AArch32).

> > My preference, as stated above, is (1). You can write the wrappers in C
> > directly and let the compiler upgrade the types when calling the native
> > syscall. But any other option would be fine (take some inspiration from
> > other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
> > for all functions that we need to wrap, it would have been easier (so we
> > need to add them but probably in the arch/arm64 code).
> 
> It would be nice to have that code architecture-independent, so we can
> share it with s390 and only need to update one place when new syscalls
> get added.

We could indeed move things like:

COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)

to the core code and share them between s390 and arm64/ILP32. So let's
stick to option 1.

-- 
Catalin

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-18 12:47             ` Arnd Bergmann
@ 2015-12-21 18:39               ` Dr. Philipp Tomsich
  -1 siblings, 0 replies; 156+ messages in thread
From: Dr. Philipp Tomsich @ 2015-12-21 18:39 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Catalin Marinas, Andrew Pinski, Joseph S. Myers, Kapoor, Prasun,
	broonie, Nathan Lynch, LKML, Alexander Graf, Alexey Klimov,
	Yury Norov, Jan Dakinevich, Andrew Pinski, David Daney,
	Andreas Schwab, Zhangjian (Bamvor),
	linux-arm-kernel, Christoph Müllner, Marcus Shawcroft


> On 18 Dec 2015, at 13:47, Arnd Bergmann <arnd@arndb.de> wrote:
> 
>> 3. Follow the PCS up to glibc but always pass syscall arguments in W
>>   registers, like AArch32 compat support (the least preferred option,
>>   the only advantage is a single wrapper for all syscalls but it would
>>   be doing unnecessary zeroing even for syscalls where it isn't needed)
> 
> This would mean we cannot pass 64-bit arguments in registers, right?

Note that there’s no 32bit registers (the ‘w’-form always refers to the lower
32bits of a 64bit register, with implicit zero-extension)… and load/store
instructions always use the full base-register (‘x’-form) for address calculation.
I.e. a load/store would inadvertently pickup “random garbage” in the upper 
32bits, if no explicit zero-extension is applied.

In other words: all zero-extensions for 32bit arguments should be explicit
on the kernel side.

Regards,
Philipp.


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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-21 18:39               ` Dr. Philipp Tomsich
  0 siblings, 0 replies; 156+ messages in thread
From: Dr. Philipp Tomsich @ 2015-12-21 18:39 UTC (permalink / raw)
  To: linux-arm-kernel


> On 18 Dec 2015, at 13:47, Arnd Bergmann <arnd@arndb.de> wrote:
> 
>> 3. Follow the PCS up to glibc but always pass syscall arguments in W
>>   registers, like AArch32 compat support (the least preferred option,
>>   the only advantage is a single wrapper for all syscalls but it would
>>   be doing unnecessary zeroing even for syscalls where it isn't needed)
> 
> This would mean we cannot pass 64-bit arguments in registers, right?

Note that there?s no 32bit registers (the ?w?-form always refers to the lower
32bits of a 64bit register, with implicit zero-extension)? and load/store
instructions always use the full base-register (?x?-form) for address calculation.
I.e. a load/store would inadvertently pickup ?random garbage? in the upper 
32bits, if no explicit zero-extension is applied.

In other words: all zero-extensions for 32bit arguments should be explicit
on the kernel side.

Regards,
Philipp.

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-21 18:39               ` Dr. Philipp Tomsich
@ 2015-12-21 22:13                 ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-21 22:13 UTC (permalink / raw)
  To: Dr. Philipp Tomsich
  Cc: Catalin Marinas, Andrew Pinski, Joseph S. Myers, Kapoor, Prasun,
	broonie, Nathan Lynch, LKML, Alexander Graf, Alexey Klimov,
	Yury Norov, Jan Dakinevich, Andrew Pinski, David Daney,
	Andreas Schwab, Zhangjian (Bamvor),
	linux-arm-kernel, Christoph Müllner, Marcus Shawcroft

On Monday 21 December 2015, Dr. Philipp Tomsich wrote:
> 
> > On 18 Dec 2015, at 13:47, Arnd Bergmann <arnd@arndb.de> wrote:
> > 
> >> 3. Follow the PCS up to glibc but always pass syscall arguments in W
> >>   registers, like AArch32 compat support (the least preferred option,
> >>   the only advantage is a single wrapper for all syscalls but it would
> >>   be doing unnecessary zeroing even for syscalls where it isn't needed)
> > 
> > This would mean we cannot pass 64-bit arguments in registers, right?
> 
> Note that there’s no 32bit registers (the ‘w’-form always refers to the lower
> 32bits of a 64bit register, with implicit zero-extension)… and load/store
> instructions always use the full base-register (‘x’-form) for address calculation.
> I.e. a load/store would inadvertently pickup “random garbage” in the upper 
> 32bits, if no explicit zero-extension is applied.
> 
> In other words: all zero-extensions for 32bit arguments should be explicit
> on the kernel side.

I think that is what Catalin meant with the single wrapper in the description:
the kernel always zeroes out the upper 32 bits in the initial trap, and then
we only need to do sign-extensions for the few cases that need it, and pass 64-bit
arguments in two lower halves. In contrast, approach 1 adds a separate wrapper
for each syscall that takes care of both sign-extending where necessary and
zero-extending all othe 32-bit arguments but not the 64-bit arguments.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-21 22:13                 ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-21 22:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 21 December 2015, Dr. Philipp Tomsich wrote:
> 
> > On 18 Dec 2015, at 13:47, Arnd Bergmann <arnd@arndb.de> wrote:
> > 
> >> 3. Follow the PCS up to glibc but always pass syscall arguments in W
> >>   registers, like AArch32 compat support (the least preferred option,
> >>   the only advantage is a single wrapper for all syscalls but it would
> >>   be doing unnecessary zeroing even for syscalls where it isn't needed)
> > 
> > This would mean we cannot pass 64-bit arguments in registers, right?
> 
> Note that there?s no 32bit registers (the ?w?-form always refers to the lower
> 32bits of a 64bit register, with implicit zero-extension)? and load/store
> instructions always use the full base-register (?x?-form) for address calculation.
> I.e. a load/store would inadvertently pickup ?random garbage? in the upper 
> 32bits, if no explicit zero-extension is applied.
> 
> In other words: all zero-extensions for 32bit arguments should be explicit
> on the kernel side.

I think that is what Catalin meant with the single wrapper in the description:
the kernel always zeroes out the upper 32 bits in the initial trap, and then
we only need to do sign-extensions for the few cases that need it, and pass 64-bit
arguments in two lower halves. In contrast, approach 1 adds a separate wrapper
for each syscall that takes care of both sign-extending where necessary and
zero-extending all othe 32-bit arguments but not the 64-bit arguments.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-21 18:31               ` Catalin Marinas
@ 2015-12-21 22:19                 ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-21 22:19 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Catalin Marinas, Andrew Pinski, Kapoor, Prasun, Andreas Schwab,
	Joseph S. Myers, Nathan Lynch, LKML, Alexander Graf,
	Alexey Klimov, broonie, Zhangjian (Bamvor),
	Andrew Pinski, David Daney, Jan Dakinevich, Philipp Tomsich,
	Yury Norov, Marcus Shawcroft, christoph.muellner

On Monday 21 December 2015, Catalin Marinas wrote:
> On Fri, Dec 18, 2015 at 01:47:55PM +0100, Arnd Bergmann wrote:
> > On Friday 18 December 2015 11:42:19 Catalin Marinas wrote:
> > > 2. Follow the PCS up to glibc and get glibc to zero the top part (not
> > >    always safe with hand-written assembly, though we already do this for
> > >    AArch32 where the PCS only specifies 4 arguments in registers, the
> > >    rest go on the stack)
> > 
> > I assume this needs special handling for syscalls with 64-bit arguments
> > in both glibc and kernel.
> 
> I think glibc only should suffice, if it is its responsibility to zero
> the top 32-bit part.

The kernel still needs to know about whether to call e.g. sys_llseek or
sys_lseek. The default syscall table contains llseek for 32-bit architectures,
but the current patch set uses lseek because that makes more sense when
you have 64-bit registers.

> > > 3. Follow the PCS up to glibc but always pass syscall arguments in W
> > >    registers, like AArch32 compat support (the least preferred option,
> > >    the only advantage is a single wrapper for all syscalls but it would
> > >    be doing unnecessary zeroing even for syscalls where it isn't needed)
> > 
> > This would mean we cannot pass 64-bit arguments in registers, right?
> 
> Not in a single register but two (like we do on AArch32).

Yes, that's what I mean. Essentially we'd use the unmodified 32-bit API
here.

> > > My preference, as stated above, is (1). You can write the wrappers in C
> > > directly and let the compiler upgrade the types when calling the native
> > > syscall. But any other option would be fine (take some inspiration from
> > > other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
> > > for all functions that we need to wrap, it would have been easier (so we
> > > need to add them but probably in the arch/arm64 code).
> > 
> > It would be nice to have that code architecture-independent, so we can
> > share it with s390 and only need to update one place when new syscalls
> > get added.
> 
> We could indeed move things like:
> 
> COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> 
> to the core code and share them between s390 and arm64/ILP32. So let's
> stick to option 1.

Ok.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-21 22:19                 ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-21 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 21 December 2015, Catalin Marinas wrote:
> On Fri, Dec 18, 2015 at 01:47:55PM +0100, Arnd Bergmann wrote:
> > On Friday 18 December 2015 11:42:19 Catalin Marinas wrote:
> > > 2. Follow the PCS up to glibc and get glibc to zero the top part (not
> > >    always safe with hand-written assembly, though we already do this for
> > >    AArch32 where the PCS only specifies 4 arguments in registers, the
> > >    rest go on the stack)
> > 
> > I assume this needs special handling for syscalls with 64-bit arguments
> > in both glibc and kernel.
> 
> I think glibc only should suffice, if it is its responsibility to zero
> the top 32-bit part.

The kernel still needs to know about whether to call e.g. sys_llseek or
sys_lseek. The default syscall table contains llseek for 32-bit architectures,
but the current patch set uses lseek because that makes more sense when
you have 64-bit registers.

> > > 3. Follow the PCS up to glibc but always pass syscall arguments in W
> > >    registers, like AArch32 compat support (the least preferred option,
> > >    the only advantage is a single wrapper for all syscalls but it would
> > >    be doing unnecessary zeroing even for syscalls where it isn't needed)
> > 
> > This would mean we cannot pass 64-bit arguments in registers, right?
> 
> Not in a single register but two (like we do on AArch32).

Yes, that's what I mean. Essentially we'd use the unmodified 32-bit API
here.

> > > My preference, as stated above, is (1). You can write the wrappers in C
> > > directly and let the compiler upgrade the types when calling the native
> > > syscall. But any other option would be fine (take some inspiration from
> > > other architectures). Unfortunately we don't have COMPAT_SYSCALL_DEFINE
> > > for all functions that we need to wrap, it would have been easier (so we
> > > need to add them but probably in the arch/arm64 code).
> > 
> > It would be nice to have that code architecture-independent, so we can
> > share it with s390 and only need to update one place when new syscalls
> > get added.
> 
> We could indeed move things like:
> 
> COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> 
> to the core code and share them between s390 and arm64/ILP32. So let's
> stick to option 1.

Ok.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-21 22:31     ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-21 22:31 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, catalin.marinas, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, Andrew Pinski, jan.dakinevich, Andrew Pinski,
	ddaney.cavm, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Tuesday 15 December 2015, Yury Norov wrote:
> +
> +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> +#define compat_sys_openat              sys_openat
> +

One more thing I just remembered: I think we want this behavior for all new
32-bit architectures, it was a bug to call compat_sys_openat for the generic
syscall table, as we don't support 32-bit off_t.

Could you split this out into a separate patch that does these changes:

- change the default asm-generic/unistd.h to use sys_openat/sys_open_by_handle_at
- change tile to override those two to keep the current (suboptimal) behavior
- change the force_o_largefile() definition so it defaults to true for all future
  architectures. The easiest way is probably to add a Kconfig symbol for this
  that gets selected by all 32-bit architectures, so we can use

#define force_o_largefile() ((BITS_PER_LONG != 32) || !IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-21 22:31     ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-21 22:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 15 December 2015, Yury Norov wrote:
> +
> +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> +#define compat_sys_openat              sys_openat
> +

One more thing I just remembered: I think we want this behavior for all new
32-bit architectures, it was a bug to call compat_sys_openat for the generic
syscall table, as we don't support 32-bit off_t.

Could you split this out into a separate patch that does these changes:

- change the default asm-generic/unistd.h to use sys_openat/sys_open_by_handle_at
- change tile to override those two to keep the current (suboptimal) behavior
- change the force_o_largefile() definition so it defaults to true for all future
  architectures. The easiest way is probably to add a Kconfig symbol for this
  that gets selected by all 32-bit architectures, so we can use

#define force_o_largefile() ((BITS_PER_LONG != 32) || !IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))

	Arnd

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-22 12:25     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 12:25 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:39AM +0300, Yury Norov wrote:
> statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
> ilp32 to workaround some issues. Here we create common file to share aarch32
> workarounds to with ilp32 code.
[...]
> --- /dev/null
> +++ b/arch/arm64/kernel/entry32-common.S
> @@ -0,0 +1,37 @@
> +#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>
> +
> +ENTRY(compat_sys_statfs64_wrapper)
> +	mov	w3, #84
> +	cmp	w1, #88
> +	csel	w1, w3, w1, eq
> +	b	compat_sys_statfs64
> +ENDPROC(compat_sys_statfs64_wrapper)
> +
> +ENTRY(compat_sys_fstatfs64_wrapper)
> +	mov	w3, #84
> +	cmp	w1, #88
> +	csel	w1, w3, w1, eq
> +	b	compat_sys_fstatfs64
> +ENDPROC(compat_sys_fstatfs64_wrapper)

I'm not convinced we need these wrappers for ILP32. They've been
introduced on arch/arm many years ago by commit Fixes: 713c481519f1
([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
space passing a size of 88 (the EABI size of struct compat_statfs64
without the packing and alignment attribute). Since that commit, the
sizeof(struct compat_statfs64) is 84 already. This should be the case
with the new ILP32 exported headers (no backwards compatibility), so
user space should never pass 88 as size. Therefore we could call
compat_sys_(f)statfs64 directly without wrappers.

-- 
Catalin

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-22 12:25     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 12:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:39AM +0300, Yury Norov wrote:
> statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
> ilp32 to workaround some issues. Here we create common file to share aarch32
> workarounds to with ilp32 code.
[...]
> --- /dev/null
> +++ b/arch/arm64/kernel/entry32-common.S
> @@ -0,0 +1,37 @@
> +#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>
> +
> +ENTRY(compat_sys_statfs64_wrapper)
> +	mov	w3, #84
> +	cmp	w1, #88
> +	csel	w1, w3, w1, eq
> +	b	compat_sys_statfs64
> +ENDPROC(compat_sys_statfs64_wrapper)
> +
> +ENTRY(compat_sys_fstatfs64_wrapper)
> +	mov	w3, #84
> +	cmp	w1, #88
> +	csel	w1, w3, w1, eq
> +	b	compat_sys_fstatfs64
> +ENDPROC(compat_sys_fstatfs64_wrapper)

I'm not convinced we need these wrappers for ILP32. They've been
introduced on arch/arm many years ago by commit Fixes: 713c481519f1
([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
space passing a size of 88 (the EABI size of struct compat_statfs64
without the packing and alignment attribute). Since that commit, the
sizeof(struct compat_statfs64) is 84 already. This should be the case
with the new ILP32 exported headers (no backwards compatibility), so
user space should never pass 88 as size. Therefore we could call
compat_sys_(f)statfs64 directly without wrappers.

-- 
Catalin

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

* Re: [PATCH v6 16/20] arm64: signal32: move ilp32 and aarch32 common code to separated file
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-22 14:29     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 14:29 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:42AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/kernel/signal32_common.c b/arch/arm64/kernel/signal32_common.c
> new file mode 100644
> index 0000000..446c7c0
> --- /dev/null
> +++ b/arch/arm64/kernel/signal32_common.c
> @@ -0,0 +1,116 @@
> +/*
> + * Based on arch/arm/kernel/signal.c
> + *
> + * Copyright (C) 1995-2009 Russell King
> + * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2015 Cavium Metworks.

I mentioned this before - moving unmodified code around shouldn't grant
Cavium new rights (but IANAL).

-- 
Catalin

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

* [PATCH v6 16/20] arm64: signal32: move ilp32 and aarch32 common code to separated file
@ 2015-12-22 14:29     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:42AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/kernel/signal32_common.c b/arch/arm64/kernel/signal32_common.c
> new file mode 100644
> index 0000000..446c7c0
> --- /dev/null
> +++ b/arch/arm64/kernel/signal32_common.c
> @@ -0,0 +1,116 @@
> +/*
> + * Based on arch/arm/kernel/signal.c
> + *
> + * Copyright (C) 1995-2009 Russell King
> + * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2015 Cavium Metworks.

I mentioned this before - moving unmodified code around shouldn't grant
Cavium new rights (but IANAL).

-- 
Catalin

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

* Re: [PATCH v6 17/20] arm64: ilp32: introduce ilp32-specific handlers for sigframe
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-22 17:08     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 17:08 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:43AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/kernel/entry_ilp32.S b/arch/arm64/kernel/entry_ilp32.S
> new file mode 100644
> index 0000000..424060f
> --- /dev/null
> +++ b/arch/arm64/kernel/entry_ilp32.S
> @@ -0,0 +1,32 @@
> +/*
> + * ILP32 system call wrappers
> + *
> + * Copyright (C) 2015 Cavium Networks.
> + * Author: 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/linkage.h>
> +#include <linux/const.h>
> +
> +#include <asm/assembler.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/errno.h>
> +#include <asm/page.h>
> +
> +ENTRY(ilp32_sys_rt_sigreturn_wrapper)
> +	mov	x0, sp
> +	b	ilp32_sys_rt_sigreturn
> +ENDPROC(ilp32_sys_rt_sigreturn_wrapper)

Do you need all these header includes?

> diff --git a/arch/arm64/kernel/signal_ilp32.c b/arch/arm64/kernel/signal_ilp32.c
> new file mode 100644
> index 0000000..d38434b
> --- /dev/null
> +++ b/arch/arm64/kernel/signal_ilp32.c
> @@ -0,0 +1,126 @@
> +/*
> + * Based on arch/arm/kernel/signal.c
> + *
> + * Copyright (C) 2015 Cavium Networks.

And missing extra copyright lines.

> + * 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_rt_sigframe {
> +	struct compat_siginfo info;
> +	struct sigframe sig;
> +};
> +
> +asmlinkage int 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 64-bit boundary,
> +	 * then 'sp' should be word aligned here.  If it's
> +	 * not, then the user is trying to mess with us.
> +	 */

The stack alignment is still 128-bit even with ILP32 (architecture
requirement).

> +	if (regs->sp & 15)
> +		goto badframe;

The check here is correct though.

-- 
Catalin

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

* [PATCH v6 17/20] arm64: ilp32: introduce ilp32-specific handlers for sigframe
@ 2015-12-22 17:08     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:43AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/kernel/entry_ilp32.S b/arch/arm64/kernel/entry_ilp32.S
> new file mode 100644
> index 0000000..424060f
> --- /dev/null
> +++ b/arch/arm64/kernel/entry_ilp32.S
> @@ -0,0 +1,32 @@
> +/*
> + * ILP32 system call wrappers
> + *
> + * Copyright (C) 2015 Cavium Networks.
> + * Author: 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/linkage.h>
> +#include <linux/const.h>
> +
> +#include <asm/assembler.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/errno.h>
> +#include <asm/page.h>
> +
> +ENTRY(ilp32_sys_rt_sigreturn_wrapper)
> +	mov	x0, sp
> +	b	ilp32_sys_rt_sigreturn
> +ENDPROC(ilp32_sys_rt_sigreturn_wrapper)

Do you need all these header includes?

> diff --git a/arch/arm64/kernel/signal_ilp32.c b/arch/arm64/kernel/signal_ilp32.c
> new file mode 100644
> index 0000000..d38434b
> --- /dev/null
> +++ b/arch/arm64/kernel/signal_ilp32.c
> @@ -0,0 +1,126 @@
> +/*
> + * Based on arch/arm/kernel/signal.c
> + *
> + * Copyright (C) 2015 Cavium Networks.

And missing extra copyright lines.

> + * 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_rt_sigframe {
> +	struct compat_siginfo info;
> +	struct sigframe sig;
> +};
> +
> +asmlinkage int 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 64-bit boundary,
> +	 * then 'sp' should be word aligned here.  If it's
> +	 * not, then the user is trying to mess with us.
> +	 */

The stack alignment is still 128-bit even with ILP32 (architecture
requirement).

> +	if (regs->sp & 15)
> +		goto badframe;

The check here is correct though.

-- 
Catalin

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

* Re: [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-22 17:11     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 17:11 UTC (permalink / raw)
  To: Yury Norov
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Wed, Dec 16, 2015 at 12:42:41AM +0300, Yury Norov wrote:
> 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 |  39 ++++++++
>  arch/arm64/kernel/Makefile             |   2 +-
>  arch/arm64/kernel/signal.c             | 154 +----------------------------
>  arch/arm64/kernel/signal_common.c      | 174 +++++++++++++++++++++++++++++++++

signal.c is always compiled, so I don't see the point of a
signal_common.c, just export the functions from signal.c
(signal32_common.c is a different story since we may not always compile
AArch32 support in).

-- 
Catalin

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

* [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file
@ 2015-12-22 17:11     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-22 17:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:41AM +0300, Yury Norov wrote:
> 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 |  39 ++++++++
>  arch/arm64/kernel/Makefile             |   2 +-
>  arch/arm64/kernel/signal.c             | 154 +----------------------------
>  arch/arm64/kernel/signal_common.c      | 174 +++++++++++++++++++++++++++++++++

signal.c is always compiled, so I don't see the point of a
signal_common.c, just export the functions from signal.c
(signal32_common.c is a different story since we may not always compile
AArch32 support in).

-- 
Catalin

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-22 12:25     ` Catalin Marinas
@ 2015-12-22 21:44       ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-22 21:44 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Yury Norov, linux-arm-kernel, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, broonie, Nathan_Lynch, agraf,
	klimov.linux, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Tuesday 22 December 2015, Catalin Marinas wrote:
> > +
> > +ENTRY(compat_sys_statfs64_wrapper)
> > +     mov     w3, #84
> > +     cmp     w1, #88
> > +     csel    w1, w3, w1, eq
> > +     b       compat_sys_statfs64
> > +ENDPROC(compat_sys_statfs64_wrapper)
> > +
> > +ENTRY(compat_sys_fstatfs64_wrapper)
> > +     mov     w3, #84
> > +     cmp     w1, #88
> > +     csel    w1, w3, w1, eq
> > +     b       compat_sys_fstatfs64
> > +ENDPROC(compat_sys_fstatfs64_wrapper)
> 
> I'm not convinced we need these wrappers for ILP32. They've been
> introduced on arch/arm many years ago by commit Fixes: 713c481519f1
> ([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
> space passing a size of 88 (the EABI size of struct compat_statfs64
> without the packing and alignment attribute). Since that commit, the
> sizeof(struct compat_statfs64) is 84 already. This should be the case
> with the new ILP32 exported headers (no backwards compatibility), so
> user space should never pass 88 as size. Therefore we could call
> compat_sys_(f)statfs64 directly without wrappers.

That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
though, and propagate the OABI alignment to arm64/ilp32 as well, rather
than using the 88-byte version that every other 32-bit architecture
except for x86-32 and arm32 has.

Another option would be to set "#define __statfs_word __u64" and use
the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
requires special-casing statfs in libc.

	Arnd

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-22 21:44       ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-22 21:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 22 December 2015, Catalin Marinas wrote:
> > +
> > +ENTRY(compat_sys_statfs64_wrapper)
> > +     mov     w3, #84
> > +     cmp     w1, #88
> > +     csel    w1, w3, w1, eq
> > +     b       compat_sys_statfs64
> > +ENDPROC(compat_sys_statfs64_wrapper)
> > +
> > +ENTRY(compat_sys_fstatfs64_wrapper)
> > +     mov     w3, #84
> > +     cmp     w1, #88
> > +     csel    w1, w3, w1, eq
> > +     b       compat_sys_fstatfs64
> > +ENDPROC(compat_sys_fstatfs64_wrapper)
> 
> I'm not convinced we need these wrappers for ILP32. They've been
> introduced on arch/arm many years ago by commit Fixes: 713c481519f1
> ([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
> space passing a size of 88 (the EABI size of struct compat_statfs64
> without the packing and alignment attribute). Since that commit, the
> sizeof(struct compat_statfs64) is 84 already. This should be the case
> with the new ILP32 exported headers (no backwards compatibility), so
> user space should never pass 88 as size. Therefore we could call
> compat_sys_(f)statfs64 directly without wrappers.

That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
though, and propagate the OABI alignment to arm64/ilp32 as well, rather
than using the 88-byte version that every other 32-bit architecture
except for x86-32 and arm32 has.

Another option would be to set "#define __statfs_word __u64" and use
the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
requires special-casing statfs in libc.

	Arnd

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-22 12:25     ` Catalin Marinas
@ 2015-12-23  4:21       ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-23  4:21 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, linux-arm-kernel, linux-kernel, pinskia, Prasun.Kapoor,
	schwab, broonie, Nathan_Lynch, agraf, klimov.linux,
	jan.dakinevich, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	joseph, christoph.muellner

On Tue, Dec 22, 2015 at 12:25:15PM +0000, Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 12:42:39AM +0300, Yury Norov wrote:
> > statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
> > ilp32 to workaround some issues. Here we create common file to share aarch32
> > workarounds to with ilp32 code.
> [...]
> > --- /dev/null
> > +++ b/arch/arm64/kernel/entry32-common.S
> > @@ -0,0 +1,37 @@
> > +#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>
> > +
> > +ENTRY(compat_sys_statfs64_wrapper)
> > +	mov	w3, #84
> > +	cmp	w1, #88
> > +	csel	w1, w3, w1, eq
> > +	b	compat_sys_statfs64
> > +ENDPROC(compat_sys_statfs64_wrapper)
> > +
> > +ENTRY(compat_sys_fstatfs64_wrapper)
> > +	mov	w3, #84
> > +	cmp	w1, #88
> > +	csel	w1, w3, w1, eq
> > +	b	compat_sys_fstatfs64
> > +ENDPROC(compat_sys_fstatfs64_wrapper)
> 
> I'm not convinced we need these wrappers for ILP32. They've been
> introduced on arch/arm many years ago by commit Fixes: 713c481519f1
> ([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
> space passing a size of 88 (the EABI size of struct compat_statfs64
> without the packing and alignment attribute). Since that commit, the
> sizeof(struct compat_statfs64) is 84 already. This should be the case
> with the new ILP32 exported headers (no backwards compatibility), so
> user space should never pass 88 as size. Therefore we could call
> compat_sys_(f)statfs64 directly without wrappers.
> 

With current glibc, sizeof(struct compat_statfs64) is 88, so I added
wrappers just to make this couple of syscalls work. AFAIR, glibc
doesn't use exported headers here, so we'd change it. Maybe Andrew
will share more details.

> -- 
> Catalin

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-23  4:21       ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-23  4:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 22, 2015 at 12:25:15PM +0000, Catalin Marinas wrote:
> On Wed, Dec 16, 2015 at 12:42:39AM +0300, Yury Norov wrote:
> > statfs64, fstat64 and mmap_pgoff has wrappers that needed both by aarch32 and
> > ilp32 to workaround some issues. Here we create common file to share aarch32
> > workarounds to with ilp32 code.
> [...]
> > --- /dev/null
> > +++ b/arch/arm64/kernel/entry32-common.S
> > @@ -0,0 +1,37 @@
> > +#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>
> > +
> > +ENTRY(compat_sys_statfs64_wrapper)
> > +	mov	w3, #84
> > +	cmp	w1, #88
> > +	csel	w1, w3, w1, eq
> > +	b	compat_sys_statfs64
> > +ENDPROC(compat_sys_statfs64_wrapper)
> > +
> > +ENTRY(compat_sys_fstatfs64_wrapper)
> > +	mov	w3, #84
> > +	cmp	w1, #88
> > +	csel	w1, w3, w1, eq
> > +	b	compat_sys_fstatfs64
> > +ENDPROC(compat_sys_fstatfs64_wrapper)
> 
> I'm not convinced we need these wrappers for ILP32. They've been
> introduced on arch/arm many years ago by commit Fixes: 713c481519f1
> ([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
> space passing a size of 88 (the EABI size of struct compat_statfs64
> without the packing and alignment attribute). Since that commit, the
> sizeof(struct compat_statfs64) is 84 already. This should be the case
> with the new ILP32 exported headers (no backwards compatibility), so
> user space should never pass 88 as size. Therefore we could call
> compat_sys_(f)statfs64 directly without wrappers.
> 

With current glibc, sizeof(struct compat_statfs64) is 88, so I added
wrappers just to make this couple of syscalls work. AFAIR, glibc
doesn't use exported headers here, so we'd change it. Maybe Andrew
will share more details.

> -- 
> Catalin

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-22 21:44       ` Arnd Bergmann
@ 2015-12-23 13:37         ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-23 13:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: pinskia, Prasun.Kapoor, schwab, broonie, Nathan_Lynch,
	linux-kernel, agraf, klimov.linux, Yury Norov, jan.dakinevich,
	joseph, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	linux-arm-kernel, christoph.muellner

On Tue, Dec 22, 2015 at 10:44:14PM +0100, Arnd Bergmann wrote:
> On Tuesday 22 December 2015, Catalin Marinas wrote:
> > > +
> > > +ENTRY(compat_sys_statfs64_wrapper)
> > > +     mov     w3, #84
> > > +     cmp     w1, #88
> > > +     csel    w1, w3, w1, eq
> > > +     b       compat_sys_statfs64
> > > +ENDPROC(compat_sys_statfs64_wrapper)
> > > +
> > > +ENTRY(compat_sys_fstatfs64_wrapper)
> > > +     mov     w3, #84
> > > +     cmp     w1, #88
> > > +     csel    w1, w3, w1, eq
> > > +     b       compat_sys_fstatfs64
> > > +ENDPROC(compat_sys_fstatfs64_wrapper)
> > 
> > I'm not convinced we need these wrappers for ILP32. They've been
> > introduced on arch/arm many years ago by commit Fixes: 713c481519f1
> > ([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
> > space passing a size of 88 (the EABI size of struct compat_statfs64
> > without the packing and alignment attribute). Since that commit, the
> > sizeof(struct compat_statfs64) is 84 already. This should be the case
> > with the new ILP32 exported headers (no backwards compatibility), so
> > user space should never pass 88 as size. Therefore we could call
> > compat_sys_(f)statfs64 directly without wrappers.
> 
> That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
> though, and propagate the OABI alignment to arm64/ilp32 as well, rather
> than using the 88-byte version that every other 32-bit architecture
> except for x86-32 and arm32 has.

Yuri replied that for EABI glibc, sizeof(struct statfs64) is already 88.
If that's correct and the packing attribute is ignored by glibc, we
could drop ARCH_PACK_COMPAT_STATFS64 as well (OABI not supported by
arm64). But I would be slightly worried since glibc is not the only user
of the kernel ABI.

For ILP32, I think we can skip defining ARCH_PACK_STATFS64 (of course,
only if __ILP32__) and state that sizeof(struct statfs64) is 88
(unpacked). In which case we need the wrappers above to be able to reuse
the compat_sys_statfs64 code.

> Another option would be to set "#define __statfs_word __u64" and use
> the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
> requires special-casing statfs in libc.

I wouldn't go this route as we kind of agreed that ILP32 should look
like any other 32-bit ABI.

-- 
Catalin

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-23 13:37         ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2015-12-23 13:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 22, 2015 at 10:44:14PM +0100, Arnd Bergmann wrote:
> On Tuesday 22 December 2015, Catalin Marinas wrote:
> > > +
> > > +ENTRY(compat_sys_statfs64_wrapper)
> > > +     mov     w3, #84
> > > +     cmp     w1, #88
> > > +     csel    w1, w3, w1, eq
> > > +     b       compat_sys_statfs64
> > > +ENDPROC(compat_sys_statfs64_wrapper)
> > > +
> > > +ENTRY(compat_sys_fstatfs64_wrapper)
> > > +     mov     w3, #84
> > > +     cmp     w1, #88
> > > +     csel    w1, w3, w1, eq
> > > +     b       compat_sys_fstatfs64
> > > +ENDPROC(compat_sys_fstatfs64_wrapper)
> > 
> > I'm not convinced we need these wrappers for ILP32. They've been
> > introduced on arch/arm many years ago by commit Fixes: 713c481519f1
> > ([ARM] 3108/2: old ABI compat: statfs64 and fstatfs64) to deal with user
> > space passing a size of 88 (the EABI size of struct compat_statfs64
> > without the packing and alignment attribute). Since that commit, the
> > sizeof(struct compat_statfs64) is 84 already. This should be the case
> > with the new ILP32 exported headers (no backwards compatibility), so
> > user space should never pass 88 as size. Therefore we could call
> > compat_sys_(f)statfs64 directly without wrappers.
> 
> That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
> though, and propagate the OABI alignment to arm64/ilp32 as well, rather
> than using the 88-byte version that every other 32-bit architecture
> except for x86-32 and arm32 has.

Yuri replied that for EABI glibc, sizeof(struct statfs64) is already 88.
If that's correct and the packing attribute is ignored by glibc, we
could drop ARCH_PACK_COMPAT_STATFS64 as well (OABI not supported by
arm64). But I would be slightly worried since glibc is not the only user
of the kernel ABI.

For ILP32, I think we can skip defining ARCH_PACK_STATFS64 (of course,
only if __ILP32__) and state that sizeof(struct statfs64) is 88
(unpacked). In which case we need the wrappers above to be able to reuse
the compat_sys_statfs64 code.

> Another option would be to set "#define __statfs_word __u64" and use
> the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
> requires special-casing statfs in libc.

I wouldn't go this route as we kind of agreed that ILP32 should look
like any other 32-bit ABI.

-- 
Catalin

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

* Re: [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-23 14:15     ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-23 14:15 UTC (permalink / raw)
  To: arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	Andrew Pinski, Andrew Pinski

On Wed, Dec 16, 2015 at 12:42:30AM +0300, Yury Norov wrote:
> --- a/arch/arm64/include/asm/unistd.h
> +++ b/arch/arm64/include/asm/unistd.h
> @@ -13,9 +13,8 @@
>   * 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
>  #define __ARCH_WANT_SYS_PAUSE
>  #define __ARCH_WANT_SYS_GETPGRP
> @@ -26,7 +25,9 @@
>  #define __ARCH_WANT_COMPAT_SYS_SENDFILE
>  #define __ARCH_WANT_SYS_FORK
>  #define __ARCH_WANT_SYS_VFORK
> +#endif
>  
> +#ifdef CONFIG_COMPAT

It seems like __NR_compat_* and __ARM_NR_compat_*
are needed by aarch32 only. If so, it should not be
defined for ilp32. And the only common definition
here would be __ARCH_WANT_COMPAT_STAT64.

>  /*
>   * Compat syscall numbers used by the AArch64 kernel.
>   */
> @@ -44,6 +45,8 @@
>  #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
>  #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
>  
> +#define __ARCH_WANT_COMPAT_STAT64
> +
>  #define __NR_compat_syscalls		390
>  #endif

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

* [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
@ 2015-12-23 14:15     ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-23 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 16, 2015 at 12:42:30AM +0300, Yury Norov wrote:
> --- a/arch/arm64/include/asm/unistd.h
> +++ b/arch/arm64/include/asm/unistd.h
> @@ -13,9 +13,8 @@
>   * 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
>  #define __ARCH_WANT_SYS_PAUSE
>  #define __ARCH_WANT_SYS_GETPGRP
> @@ -26,7 +25,9 @@
>  #define __ARCH_WANT_COMPAT_SYS_SENDFILE
>  #define __ARCH_WANT_SYS_FORK
>  #define __ARCH_WANT_SYS_VFORK
> +#endif
>  
> +#ifdef CONFIG_COMPAT

It seems like __NR_compat_* and __ARM_NR_compat_*
are needed by aarch32 only. If so, it should not be
defined for ilp32. And the only common definition
here would be __ARCH_WANT_COMPAT_STAT64.

>  /*
>   * Compat syscall numbers used by the AArch64 kernel.
>   */
> @@ -44,6 +45,8 @@
>  #define __ARM_NR_compat_cacheflush	(__ARM_NR_COMPAT_BASE+2)
>  #define __ARM_NR_compat_set_tls		(__ARM_NR_COMPAT_BASE+5)
>  
> +#define __ARCH_WANT_COMPAT_STAT64
> +
>  #define __NR_compat_syscalls		390
>  #endif

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-21 22:31     ` Arnd Bergmann
@ 2015-12-23 18:31       ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-23 18:31 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, pinskia, Prasun.Kapoor, catalin.marinas,
	broonie, Nathan_Lynch, linux-kernel, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, Andrew Pinski, ddaney.cavm,
	schwab, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Mon, Dec 21, 2015 at 11:31:57PM +0100, Arnd Bergmann wrote:
> On Tuesday 15 December 2015, Yury Norov wrote:
> > +
> > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> > +#define compat_sys_openat              sys_openat
> > +
> 
> One more thing I just remembered: I think we want this behavior for all new
> 32-bit architectures, it was a bug to call compat_sys_openat for the generic
> syscall table, as we don't support 32-bit off_t.
> 
> Could you split this out into a separate patch that does these changes:
> 
> - change the default asm-generic/unistd.h to use sys_openat/sys_open_by_handle_at
> - change tile to override those two to keep the current (suboptimal) behavior
> - change the force_o_largefile() definition so it defaults to true for all future
>   architectures. The easiest way is probably to add a Kconfig symbol for this
>   that gets selected by all 32-bit architectures, so we can use
> 
> #define force_o_largefile() ((BITS_PER_LONG != 32) || !IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))
> 

Hi Arnd,

First two items are OK. The last one... Do you need it to remove
compat_sys_openat and compat_sys_open_by_handle_at?

The patch that introduces CONFIG_ARCH_32BIT_OFF_T will affect all
architectures, and so I need to get ack from each maintainer. 

I will also have to ask them to test that change, because I have no
access to all the hardware. (Even with QEMU, I cannot test them all.)
I think the only man who is able to success with it is Linus :)...

Some arches has more than one compat mode. For example ARM64: aarch32
requires this config enabled, but ilp32 needs it disabled. Now we can
enable both features, but this will make them mutual exclusive. We can
instead (un)define __ARCH_WANT_32BIT_OFF_T for each ABI of each platform,
but it's even more work. And we'd think twice how to do it because
it's not mechanical work. For example, on aarch64 it will look like:

        #define __ARCH_WANT_32BIT_OFF_T is_a32_compat_task()

I have no idea how it will look on x86 or ppc.

In your previous email (Nov 18) you write that tile is the only user
of asm-generic/unistd.h that needs compat behaviour. If so, why not
just to turn it around, as you initially suggested, and fix tile. And
do nothing with force_o_largefile()?

By the way, is there a comprehensive list of linux platforms/abis, or
at least ones that use asm-generic/unistd.h?

BR,
Yury.

> 	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] 156+ messages in thread

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-23 18:31       ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-23 18:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 21, 2015 at 11:31:57PM +0100, Arnd Bergmann wrote:
> On Tuesday 15 December 2015, Yury Norov wrote:
> > +
> > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> > +#define compat_sys_openat              sys_openat
> > +
> 
> One more thing I just remembered: I think we want this behavior for all new
> 32-bit architectures, it was a bug to call compat_sys_openat for the generic
> syscall table, as we don't support 32-bit off_t.
> 
> Could you split this out into a separate patch that does these changes:
> 
> - change the default asm-generic/unistd.h to use sys_openat/sys_open_by_handle_at
> - change tile to override those two to keep the current (suboptimal) behavior
> - change the force_o_largefile() definition so it defaults to true for all future
>   architectures. The easiest way is probably to add a Kconfig symbol for this
>   that gets selected by all 32-bit architectures, so we can use
> 
> #define force_o_largefile() ((BITS_PER_LONG != 32) || !IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))
> 

Hi Arnd,

First two items are OK. The last one... Do you need it to remove
compat_sys_openat and compat_sys_open_by_handle_at?

The patch that introduces CONFIG_ARCH_32BIT_OFF_T will affect all
architectures, and so I need to get ack from each maintainer. 

I will also have to ask them to test that change, because I have no
access to all the hardware. (Even with QEMU, I cannot test them all.)
I think the only man who is able to success with it is Linus :)...

Some arches has more than one compat mode. For example ARM64: aarch32
requires this config enabled, but ilp32 needs it disabled. Now we can
enable both features, but this will make them mutual exclusive. We can
instead (un)define __ARCH_WANT_32BIT_OFF_T for each ABI of each platform,
but it's even more work. And we'd think twice how to do it because
it's not mechanical work. For example, on aarch64 it will look like:

        #define __ARCH_WANT_32BIT_OFF_T is_a32_compat_task()

I have no idea how it will look on x86 or ppc.

In your previous email (Nov 18) you write that tile is the only user
of asm-generic/unistd.h that needs compat behaviour. If so, why not
just to turn it around, as you initially suggested, and fix tile. And
do nothing with force_o_largefile()?

By the way, is there a comprehensive list of linux platforms/abis, or
at least ones that use asm-generic/unistd.h?

BR,
Yury.

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

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-23 13:37         ` Catalin Marinas
@ 2015-12-23 20:41           ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-23 20:41 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: pinskia, Prasun.Kapoor, schwab, broonie, Nathan_Lynch,
	linux-kernel, agraf, klimov.linux, Yury Norov, jan.dakinevich,
	joseph, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	linux-arm-kernel, christoph.muellner

On Wednesday 23 December 2015, Catalin Marinas wrote:
> > That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
> > though, and propagate the OABI alignment to arm64/ilp32 as well, rather
> > than using the 88-byte version that every other 32-bit architecture
> > except for x86-32 and arm32 has.
> 
> Yuri replied that for EABI glibc, sizeof(struct statfs64) is already 88.
> If that's correct and the packing attribute is ignored by glibc, we
> could drop ARCH_PACK_COMPAT_STATFS64 as well (OABI not supported by
> arm64). But I would be slightly worried since glibc is not the only user
> of the kernel ABI.

It looks like glibc has its own definition of 'struct statfs64', which
is incompatible with the one in the kernel headers for ARM EABI.

However, there are other libc implementations besides glibc, and we
can't assume that they all do it the same way, so we clearly have to
keep using the wrapper for ARM EABI. For ARM64/ILP32, we are probably
better off defining it the same way in kernel and libc without that
wrapper.

> For ILP32, I think we can skip defining ARCH_PACK_STATFS64 (of course,
> only if __ILP32__) and state that sizeof(struct statfs64) is 88
> (unpacked). In which case we need the wrappers above to be able to reuse
> the compat_sys_statfs64 code.
> 
> > Another option would be to set "#define __statfs_word __u64" and use
> > the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
> > requires special-casing statfs in libc.
> 
> I wouldn't go this route as we kind of agreed that ILP32 should look
> like any other 32-bit ABI.

It's really tricky then: in order to support EABI binaries from a libc
that uses the kernel headers with the OABI compatible definition, we
must not copy the 88 byte structure to user space, because that would
overwrite user space stack data, and that in turn means we have to set
ARCH_PACK_COMPAT_STATFS64, but that in turn prevents us from using the
generic 32-bit syscall ABI for the arm64/ilp32 fstatfs64 call. 

It seems that today, put_compat_statfs64() doesn't actually use
the size argument, and it just copies the individual fields, which
is fine either way. This means we could turn around the logic
in the arm32 wrapper, remove ARCH_PACK_COMPAT_STATFS64, and make
the ilp32 code call directly into compat_sys_fstatfs64(), but it
would be a bit fragile, as we rely on put_compat_statfs64() not
actually writing the padding fields that the native do_statfs64()
writes. If someone changed them to both use copy_to_user, we'd
silently introduce data corruption on rarely used libc implementations.

	Arnd

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-23 20:41           ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-23 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 23 December 2015, Catalin Marinas wrote:
> > That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
> > though, and propagate the OABI alignment to arm64/ilp32 as well, rather
> > than using the 88-byte version that every other 32-bit architecture
> > except for x86-32 and arm32 has.
> 
> Yuri replied that for EABI glibc, sizeof(struct statfs64) is already 88.
> If that's correct and the packing attribute is ignored by glibc, we
> could drop ARCH_PACK_COMPAT_STATFS64 as well (OABI not supported by
> arm64). But I would be slightly worried since glibc is not the only user
> of the kernel ABI.

It looks like glibc has its own definition of 'struct statfs64', which
is incompatible with the one in the kernel headers for ARM EABI.

However, there are other libc implementations besides glibc, and we
can't assume that they all do it the same way, so we clearly have to
keep using the wrapper for ARM EABI. For ARM64/ILP32, we are probably
better off defining it the same way in kernel and libc without that
wrapper.

> For ILP32, I think we can skip defining ARCH_PACK_STATFS64 (of course,
> only if __ILP32__) and state that sizeof(struct statfs64) is 88
> (unpacked). In which case we need the wrappers above to be able to reuse
> the compat_sys_statfs64 code.
> 
> > Another option would be to set "#define __statfs_word __u64" and use
> > the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
> > requires special-casing statfs in libc.
> 
> I wouldn't go this route as we kind of agreed that ILP32 should look
> like any other 32-bit ABI.

It's really tricky then: in order to support EABI binaries from a libc
that uses the kernel headers with the OABI compatible definition, we
must not copy the 88 byte structure to user space, because that would
overwrite user space stack data, and that in turn means we have to set
ARCH_PACK_COMPAT_STATFS64, but that in turn prevents us from using the
generic 32-bit syscall ABI for the arm64/ilp32 fstatfs64 call. 

It seems that today, put_compat_statfs64() doesn't actually use
the size argument, and it just copies the individual fields, which
is fine either way. This means we could turn around the logic
in the arm32 wrapper, remove ARCH_PACK_COMPAT_STATFS64, and make
the ilp32 code call directly into compat_sys_fstatfs64(), but it
would be a bit fragile, as we rely on put_compat_statfs64() not
actually writing the padding fields that the native do_statfs64()
writes. If someone changed them to both use copy_to_user, we'd
silently introduce data corruption on rarely used libc implementations.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-23 18:31       ` Yury Norov
@ 2015-12-23 21:48         ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-23 21:48 UTC (permalink / raw)
  To: Yury Norov
  Cc: linux-arm-kernel, pinskia, Prasun.Kapoor, catalin.marinas,
	broonie, Nathan_Lynch, linux-kernel, agraf, klimov.linux,
	Andrew Pinski, jan.dakinevich, Andrew Pinski, ddaney.cavm,
	schwab, bamvor.zhangjian, philipp.tomsich, joseph,
	christoph.muellner

On Wednesday 23 December 2015, Yury Norov wrote:
> On Mon, Dec 21, 2015 at 11:31:57PM +0100, Arnd Bergmann wrote:
> > On Tuesday 15 December 2015, Yury Norov wrote:
> > > +
> > > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> > > +#define compat_sys_openat              sys_openat
> > > +
> > 
> > One more thing I just remembered: I think we want this behavior for all new
> > 32-bit architectures, it was a bug to call compat_sys_openat for the generic
> > syscall table, as we don't support 32-bit off_t.
> > 
> > Could you split this out into a separate patch that does these changes:
> > 
> > - change the default asm-generic/unistd.h to use sys_openat/sys_open_by_handle_at
> > - change tile to override those two to keep the current (suboptimal) behavior
> > - change the force_o_largefile() definition so it defaults to true for all future
> >   architectures. The easiest way is probably to add a Kconfig symbol for this
> >   that gets selected by all 32-bit architectures, so we can use
> > 
> > #define force_o_largefile() ((BITS_PER_LONG != 32) || !IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))
> > 
> 
> Hi Arnd,
> 
> First two items are OK. The last one... Do you need it to remove
> compat_sys_openat and compat_sys_open_by_handle_at?

It's needed so all future architectures get it right.

> The patch that introduces CONFIG_ARCH_32BIT_OFF_T will affect all
> architectures, and so I need to get ack from each maintainer. 

Just post it to the linux-arch and linux-kernel mailing lists.
You are not actually changing behavior, so my Ack should be sufficient
here, as long as we make sure we handle all architectures the same
way.

> I will also have to ask them to test that change, because I have no
> access to all the hardware. (Even with QEMU, I cannot test them all.)
> I think the only man who is able to success with it is Linus :)...
> 
> Some arches has more than one compat mode. For example ARM64: aarch32
> requires this config enabled, but ilp32 needs it disabled. Now we can
> enable both features, but this will make them mutual exclusive. We can
> instead (un)define __ARCH_WANT_32BIT_OFF_T for each ABI of each platform,
> but it's even more work. And we'd think twice how to do it because
> it's not mechanical work. For example, on aarch64 it will look like:
> 
>         #define __ARCH_WANT_32BIT_OFF_T is_a32_compat_task()
> 
> I have no idea how it will look on x86 or ppc.

arm64 is not affected at all, because it's a 64-bit-only architecture
and force_o_largefile() already returns true here.

> In your previous email (Nov 18) you write that tile is the only user
> of asm-generic/unistd.h that needs compat behaviour. If so, why not
> just to turn it around, as you initially suggested, and fix tile. And
> do nothing with force_o_largefile()?

The first two of the three changes I listed above are for the
compat ABI, and there it is enough to change tile.

The third change has nothing to do with compat mode, but is about
native 32-bit architectures. However, we should change both in sync,
so the next architecture that gets added with both native 32-bit
mode and compat 32-bit mode on a 64-bit kernel behaves the same
way for all 32-bit user space, independent of what the kernel does.

We can have two separate patches to clarify that these don't have to
be done atomically, but we need to do both for consistency.
 
> By the way, is there a comprehensive list of linux platforms/abis, or
> at least ones that use asm-generic/unistd.h?

Just the source code.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2015-12-23 21:48         ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-23 21:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 23 December 2015, Yury Norov wrote:
> On Mon, Dec 21, 2015 at 11:31:57PM +0100, Arnd Bergmann wrote:
> > On Tuesday 15 December 2015, Yury Norov wrote:
> > > +
> > > +#define compat_sys_open_by_handle_at   sys_open_by_handle_at
> > > +#define compat_sys_openat              sys_openat
> > > +
> > 
> > One more thing I just remembered: I think we want this behavior for all new
> > 32-bit architectures, it was a bug to call compat_sys_openat for the generic
> > syscall table, as we don't support 32-bit off_t.
> > 
> > Could you split this out into a separate patch that does these changes:
> > 
> > - change the default asm-generic/unistd.h to use sys_openat/sys_open_by_handle_at
> > - change tile to override those two to keep the current (suboptimal) behavior
> > - change the force_o_largefile() definition so it defaults to true for all future
> >   architectures. The easiest way is probably to add a Kconfig symbol for this
> >   that gets selected by all 32-bit architectures, so we can use
> > 
> > #define force_o_largefile() ((BITS_PER_LONG != 32) || !IS_ENABLED(CONFIG_ARCH_32BIT_OFF_T))
> > 
> 
> Hi Arnd,
> 
> First two items are OK. The last one... Do you need it to remove
> compat_sys_openat and compat_sys_open_by_handle_at?

It's needed so all future architectures get it right.

> The patch that introduces CONFIG_ARCH_32BIT_OFF_T will affect all
> architectures, and so I need to get ack from each maintainer. 

Just post it to the linux-arch and linux-kernel mailing lists.
You are not actually changing behavior, so my Ack should be sufficient
here, as long as we make sure we handle all architectures the same
way.

> I will also have to ask them to test that change, because I have no
> access to all the hardware. (Even with QEMU, I cannot test them all.)
> I think the only man who is able to success with it is Linus :)...
> 
> Some arches has more than one compat mode. For example ARM64: aarch32
> requires this config enabled, but ilp32 needs it disabled. Now we can
> enable both features, but this will make them mutual exclusive. We can
> instead (un)define __ARCH_WANT_32BIT_OFF_T for each ABI of each platform,
> but it's even more work. And we'd think twice how to do it because
> it's not mechanical work. For example, on aarch64 it will look like:
> 
>         #define __ARCH_WANT_32BIT_OFF_T is_a32_compat_task()
> 
> I have no idea how it will look on x86 or ppc.

arm64 is not affected at all, because it's a 64-bit-only architecture
and force_o_largefile() already returns true here.

> In your previous email (Nov 18) you write that tile is the only user
> of asm-generic/unistd.h that needs compat behaviour. If so, why not
> just to turn it around, as you initially suggested, and fix tile. And
> do nothing with force_o_largefile()?

The first two of the three changes I listed above are for the
compat ABI, and there it is enough to change tile.

The third change has nothing to do with compat mode, but is about
native 32-bit architectures. However, we should change both in sync,
so the next architecture that gets added with both native 32-bit
mode and compat 32-bit mode on a 64-bit kernel behaves the same
way for all 32-bit user space, independent of what the kernel does.

We can have two separate patches to clarify that these don't have to
be done atomically, but we need to do both for consistency.
 
> By the way, is there a comprehensive list of linux platforms/abis, or
> at least ones that use asm-generic/unistd.h?

Just the source code.

	Arnd

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

* > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
  2015-12-15 21:42   ` Yury Norov
@ 2015-12-28  8:43     ` Bamvor Jian Zhang
  -1 siblings, 0 replies; 156+ messages in thread
From: Bamvor Jian Zhang @ 2015-12-28  8:43 UTC (permalink / raw)
  To: ynorov, arnd, catalin.marinas, linux-arm-kernel, linux-kernel
  Cc: pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	bamvor.zhangjian, philipp.tomsich, joseph, christoph.muellner,
	apinski, Andrew.Pinski, bamvor.zhangjian

I feel we need something like this to avoid the failure of compiling
when build with ARM64_ILP32(which will select COMPAT) and
ARMV8_DEPRECATED (which depends on the opcodes.o).

>From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
Date: Mon, 28 Dec 2015 12:57:46 +0800
Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED

When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
to the dependency of COMPAT. It leads to the following error:
    LD      init/built-in.o
    arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
    arch/arm64/kernel/built-in.o: In function `swp_handler':
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
    Makefile:927: recipe for target 'vmlinux' failed
    make: *** [vmlinux] Error 1

This patch fix this by updating the dependency from COMPAT to
AARCH32_EL0.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
---
 arch/arm64/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index deec37a..e52fd03 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -509,7 +509,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.1.4


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

* > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
@ 2015-12-28  8:43     ` Bamvor Jian Zhang
  0 siblings, 0 replies; 156+ messages in thread
From: Bamvor Jian Zhang @ 2015-12-28  8:43 UTC (permalink / raw)
  To: linux-arm-kernel

I feel we need something like this to avoid the failure of compiling
when build with ARM64_ILP32(which will select COMPAT) and
ARMV8_DEPRECATED (which depends on the opcodes.o).

>From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
Date: Mon, 28 Dec 2015 12:57:46 +0800
Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED

When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
to the dependency of COMPAT. It leads to the following error:
    LD      init/built-in.o
    arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
    arch/arm64/kernel/built-in.o: In function `swp_handler':
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
    /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
    Makefile:927: recipe for target 'vmlinux' failed
    make: *** [vmlinux] Error 1

This patch fix this by updating the dependency from COMPAT to
AARCH32_EL0.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
---
 arch/arm64/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index deec37a..e52fd03 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -509,7 +509,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.1.4

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

* Re: [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2015-12-28  8:43     ` Bamvor Jian Zhang
@ 2015-12-28  9:01       ` Zhangjian (Bamvor)
  -1 siblings, 0 replies; 156+ messages in thread
From: Zhangjian (Bamvor) @ 2015-12-28  9:01 UTC (permalink / raw)
  To: Bamvor Jian Zhang, ynorov, arnd, catalin.marinas,
	linux-arm-kernel, linux-kernel
  Cc: pinskia, Prasun.Kapoor, schwab, Nathan_Lynch, agraf,
	klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	philipp.tomsich, joseph, christoph.muellner, apinski,
	Andrew.Pinski, Zhangjian (Bamvor),
	baixin1

Fix the title.

On 16:43 2015/12/28, Bamvor Jian Zhang wrote:
> I feel we need something like this to avoid the failure of compiling
> when build with ARM64_ILP32(which will select COMPAT) and
> ARMV8_DEPRECATED (which depends on the opcodes.o).
>
>  From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
> From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> Date: Mon, 28 Dec 2015 12:57:46 +0800
> Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED
>
> When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
> to the dependency of COMPAT. It leads to the following error:
>      LD      init/built-in.o
>      arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
>      arch/arm64/kernel/built-in.o: In function `swp_handler':
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
>      Makefile:927: recipe for target 'vmlinux' failed
>      make: *** [vmlinux] Error 1
>
> This patch fix this by updating the dependency from COMPAT to
> AARCH32_EL0.
>
> Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> ---
>   arch/arm64/Kconfig | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index deec37a..e52fd03 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -509,7 +509,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.
>


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

* [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
@ 2015-12-28  9:01       ` Zhangjian (Bamvor)
  0 siblings, 0 replies; 156+ messages in thread
From: Zhangjian (Bamvor) @ 2015-12-28  9:01 UTC (permalink / raw)
  To: linux-arm-kernel

Fix the title.

On 16:43 2015/12/28, Bamvor Jian Zhang wrote:
> I feel we need something like this to avoid the failure of compiling
> when build with ARM64_ILP32(which will select COMPAT) and
> ARMV8_DEPRECATED (which depends on the opcodes.o).
>
>  From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
> From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> Date: Mon, 28 Dec 2015 12:57:46 +0800
> Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED
>
> When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
> to the dependency of COMPAT. It leads to the following error:
>      LD      init/built-in.o
>      arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
>      arch/arm64/kernel/built-in.o: In function `swp_handler':
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
>      /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
>      Makefile:927: recipe for target 'vmlinux' failed
>      make: *** [vmlinux] Error 1
>
> This patch fix this by updating the dependency from COMPAT to
> AARCH32_EL0.
>
> Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> ---
>   arch/arm64/Kconfig | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index deec37a..e52fd03 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -509,7 +509,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.
>

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

* Re: [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2015-12-28  9:01       ` Zhangjian (Bamvor)
@ 2015-12-29 12:27         ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-29 12:27 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Bamvor Jian Zhang, arnd, catalin.marinas, linux-arm-kernel,
	linux-kernel, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch,
	agraf, klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	philipp.tomsich, joseph, christoph.muellner, apinski,
	Andrew.Pinski, baixin1

On Mon, Dec 28, 2015 at 05:01:15PM +0800, Zhangjian (Bamvor) wrote:
> Fix the title.
> 
> On 16:43 2015/12/28, Bamvor Jian Zhang wrote:
> >I feel we need something like this to avoid the failure of compiling
> >when build with ARM64_ILP32(which will select COMPAT) and
> >ARMV8_DEPRECATED (which depends on the opcodes.o).
> >
> > From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
> >From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >Date: Mon, 28 Dec 2015 12:57:46 +0800
> >Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED
> >
> >When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
> >to the dependency of COMPAT. It leads to the following error:
> >     LD      init/built-in.o
> >     arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     arch/arm64/kernel/built-in.o: In function `swp_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     Makefile:927: recipe for target 'vmlinux' failed
> >     make: *** [vmlinux] Error 1
> >
> >This patch fix this by updating the dependency from COMPAT to
> >AARCH32_EL0.
> >
> >Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >---
> >  arch/arm64/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >index deec37a..e52fd03 100644
> >--- a/arch/arm64/Kconfig
> >+++ b/arch/arm64/Kconfig
> >@@ -509,7 +509,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.
> >

Thanks for catch. I will incorporate it to next submission. I also
think, config ARM64_ERRATUM_845719 should depend on AARCH32_EL0 as
well.

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

* [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
@ 2015-12-29 12:27         ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-29 12:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 28, 2015 at 05:01:15PM +0800, Zhangjian (Bamvor) wrote:
> Fix the title.
> 
> On 16:43 2015/12/28, Bamvor Jian Zhang wrote:
> >I feel we need something like this to avoid the failure of compiling
> >when build with ARM64_ILP32(which will select COMPAT) and
> >ARMV8_DEPRECATED (which depends on the opcodes.o).
> >
> > From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
> >From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >Date: Mon, 28 Dec 2015 12:57:46 +0800
> >Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED
> >
> >When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
> >to the dependency of COMPAT. It leads to the following error:
> >     LD      init/built-in.o
> >     arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     arch/arm64/kernel/built-in.o: In function `swp_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     Makefile:927: recipe for target 'vmlinux' failed
> >     make: *** [vmlinux] Error 1
> >
> >This patch fix this by updating the dependency from COMPAT to
> >AARCH32_EL0.
> >
> >Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >---
> >  arch/arm64/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >index deec37a..e52fd03 100644
> >--- a/arch/arm64/Kconfig
> >+++ b/arch/arm64/Kconfig
> >@@ -509,7 +509,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.
> >

Thanks for catch. I will incorporate it to next submission. I also
think, config ARM64_ERRATUM_845719 should depend on AARCH32_EL0 as
well.

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

* Re: [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2015-12-28  9:01       ` Zhangjian (Bamvor)
@ 2015-12-29 13:12         ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-29 13:12 UTC (permalink / raw)
  To: Zhangjian (Bamvor)
  Cc: Bamvor Jian Zhang, arnd, catalin.marinas, linux-arm-kernel,
	linux-kernel, pinskia, Prasun.Kapoor, schwab, Nathan_Lynch,
	agraf, klimov.linux, broonie, jan.dakinevich, ddaney.cavm,
	philipp.tomsich, joseph, christoph.muellner, apinski,
	Andrew.Pinski, baixin1

On Mon, Dec 28, 2015 at 05:01:15PM +0800, Zhangjian (Bamvor) wrote:
> Fix the title.

Hi,

Could you re-send your patch, as previous version has wrong subject,
and this - commented body. Or, I can just meld your change to patch #4.

Yury.

> 
> On 16:43 2015/12/28, Bamvor Jian Zhang wrote:
> >I feel we need something like this to avoid the failure of compiling
> >when build with ARM64_ILP32(which will select COMPAT) and
> >ARMV8_DEPRECATED (which depends on the opcodes.o).
> >
> > From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
> >From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >Date: Mon, 28 Dec 2015 12:57:46 +0800
> >Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED
> >
> >When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
> >to the dependency of COMPAT. It leads to the following error:
> >     LD      init/built-in.o
> >     arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     arch/arm64/kernel/built-in.o: In function `swp_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     Makefile:927: recipe for target 'vmlinux' failed
> >     make: *** [vmlinux] Error 1
> >
> >This patch fix this by updating the dependency from COMPAT to
> >AARCH32_EL0.
> >
> >Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >---
> >  arch/arm64/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >index deec37a..e52fd03 100644
> >--- a/arch/arm64/Kconfig
> >+++ b/arch/arm64/Kconfig
> >@@ -509,7 +509,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.
> >

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

* [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
@ 2015-12-29 13:12         ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-29 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Dec 28, 2015 at 05:01:15PM +0800, Zhangjian (Bamvor) wrote:
> Fix the title.

Hi,

Could you re-send your patch, as previous version has wrong subject,
and this - commented body. Or, I can just meld your change to patch #4.

Yury.

> 
> On 16:43 2015/12/28, Bamvor Jian Zhang wrote:
> >I feel we need something like this to avoid the failure of compiling
> >when build with ARM64_ILP32(which will select COMPAT) and
> >ARMV8_DEPRECATED (which depends on the opcodes.o).
> >
> > From f8b8ffdb449491ecf8ba465238bbdb4625a74ac0 Mon Sep 17 00:00:00 2001
> >From: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >Date: Mon, 28 Dec 2015 12:57:46 +0800
> >Subject: [PATCH] arm64: compat: fix wrong dependency of ARMV8_DEPRECATED
> >
> >When compile with ARM64_ILP32, ARMV8_DEPRECATED will be selected due
> >to the dependency of COMPAT. It leads to the following error:
> >     LD      init/built-in.o
> >     arch/arm64/kernel/built-in.o: In function `cp15barrier_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:467: undefined reference to `arm_check_condition'
> >     arch/arm64/kernel/built-in.o: In function `swp_handler':
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     /home/bamvor/works/source/kernel/linux_ilp32/arch/arm64/kernel/armv8_deprecated.c:386: undefined reference to `arm_check_condition'
> >     Makefile:927: recipe for target 'vmlinux' failed
> >     make: *** [vmlinux] Error 1
> >
> >This patch fix this by updating the dependency from COMPAT to
> >AARCH32_EL0.
> >
> >Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
> >---
> >  arch/arm64/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> >diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >index deec37a..e52fd03 100644
> >--- a/arch/arm64/Kconfig
> >+++ b/arch/arm64/Kconfig
> >@@ -509,7 +509,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.
> >

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

* [PATCH] arm64: compat: fix wrong dependency
  2015-12-29 12:27         ` Yury Norov
@ 2015-12-29 14:59           ` Bamvor Jian Zhang
  -1 siblings, 0 replies; 156+ messages in thread
From: Bamvor Jian Zhang @ 2015-12-29 14:59 UTC (permalink / raw)
  To: ynorov
  Cc: arnd, catalin.marinas, linux-arm-kernel, linux-kernel, pinskia,
	Prasun.Kapoor, schwab, Nathan_Lynch, agraf, klimov.linux,
	broonie, jan.dakinevich, ddaney.cavm, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner, apinski,
	Andrew.Pinski, bamvor.zhangjian, baixin1

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>
---
 arch/arm64/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index deec37a..7ea783b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -313,7 +313,7 @@ config ARM64_ERRATUM_832075
 
 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
@@ -509,7 +509,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.1.4


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

* [PATCH] arm64: compat: fix wrong dependency
@ 2015-12-29 14:59           ` Bamvor Jian Zhang
  0 siblings, 0 replies; 156+ messages in thread
From: Bamvor Jian Zhang @ 2015-12-29 14:59 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
 arch/arm64/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index deec37a..7ea783b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -313,7 +313,7 @@ config ARM64_ERRATUM_832075
 
 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
@@ -509,7 +509,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.1.4

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-23 20:41           ` Arnd Bergmann
@ 2015-12-30 17:29             ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-30 17:29 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Catalin Marinas, pinskia, Prasun.Kapoor, schwab, broonie,
	Nathan_Lynch, linux-kernel, agraf, klimov.linux, jan.dakinevich,
	joseph, ddaney.cavm, bamvor.zhangjian, philipp.tomsich,
	linux-arm-kernel, christoph.muellner

On Wed, Dec 23, 2015 at 09:41:54PM +0100, Arnd Bergmann wrote:
> On Wednesday 23 December 2015, Catalin Marinas wrote:
> > > That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
> > > though, and propagate the OABI alignment to arm64/ilp32 as well, rather
> > > than using the 88-byte version that every other 32-bit architecture
> > > except for x86-32 and arm32 has.
> > 
> > Yuri replied that for EABI glibc, sizeof(struct statfs64) is already 88.
> > If that's correct and the packing attribute is ignored by glibc, we
> > could drop ARCH_PACK_COMPAT_STATFS64 as well (OABI not supported by
> > arm64). But I would be slightly worried since glibc is not the only user
> > of the kernel ABI.
> 
> It looks like glibc has its own definition of 'struct statfs64', which
> is incompatible with the one in the kernel headers for ARM EABI.
> 
> However, there are other libc implementations besides glibc, and we
> can't assume that they all do it the same way, so we clearly have to
> keep using the wrapper for ARM EABI. For ARM64/ILP32, we are probably
> better off defining it the same way in kernel and libc without that
> wrapper.
> 
> > For ILP32, I think we can skip defining ARCH_PACK_STATFS64 (of course,
> > only if __ILP32__) and state that sizeof(struct statfs64) is 88
> > (unpacked). In which case we need the wrappers above to be able to reuse
> > the compat_sys_statfs64 code.
> > 
> > > Another option would be to set "#define __statfs_word __u64" and use
> > > the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
> > > requires special-casing statfs in libc.
> > 
> > I wouldn't go this route as we kind of agreed that ILP32 should look
> > like any other 32-bit ABI.
> 
> It's really tricky then: in order to support EABI binaries from a libc
> that uses the kernel headers with the OABI compatible definition, we
> must not copy the 88 byte structure to user space, because that would
> overwrite user space stack data, and that in turn means we have to set
> ARCH_PACK_COMPAT_STATFS64, but that in turn prevents us from using the
> generic 32-bit syscall ABI for the arm64/ilp32 fstatfs64 call. 
> 
> It seems that today, put_compat_statfs64() doesn't actually use
> the size argument, and it just copies the individual fields, which
> is fine either way. This means we could turn around the logic
> in the arm32 wrapper, remove ARCH_PACK_COMPAT_STATFS64, and make
> the ilp32 code call directly into compat_sys_fstatfs64(), but it
> would be a bit fragile, as we rely on put_compat_statfs64() not
> actually writing the padding fields that the native do_statfs64()
> writes. If someone changed them to both use copy_to_user, we'd
> silently introduce data corruption on rarely used libc implementations.
> 
> 	Arnd

So. For ilp32, the only wrapper left here, is compat_sys_mmap2_wrapper.
But this is workaroud, as comment tells:
        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.

Not sure we should pull it to ILP32. If so, we can call sys_mmap_pgoff()
directly. And we don't need this patch at all therefore. Any throughts?

Yury.

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-30 17:29             ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2015-12-30 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 23, 2015 at 09:41:54PM +0100, Arnd Bergmann wrote:
> On Wednesday 23 December 2015, Catalin Marinas wrote:
> > > That means we have to set ARCH_PACK_STATFS64 in the arm64 header files
> > > though, and propagate the OABI alignment to arm64/ilp32 as well, rather
> > > than using the 88-byte version that every other 32-bit architecture
> > > except for x86-32 and arm32 has.
> > 
> > Yuri replied that for EABI glibc, sizeof(struct statfs64) is already 88.
> > If that's correct and the packing attribute is ignored by glibc, we
> > could drop ARCH_PACK_COMPAT_STATFS64 as well (OABI not supported by
> > arm64). But I would be slightly worried since glibc is not the only user
> > of the kernel ABI.
> 
> It looks like glibc has its own definition of 'struct statfs64', which
> is incompatible with the one in the kernel headers for ARM EABI.
> 
> However, there are other libc implementations besides glibc, and we
> can't assume that they all do it the same way, so we clearly have to
> keep using the wrapper for ARM EABI. For ARM64/ILP32, we are probably
> better off defining it the same way in kernel and libc without that
> wrapper.
> 
> > For ILP32, I think we can skip defining ARCH_PACK_STATFS64 (of course,
> > only if __ILP32__) and state that sizeof(struct statfs64) is 88
> > (unpacked). In which case we need the wrappers above to be able to reuse
> > the compat_sys_statfs64 code.
> > 
> > > Another option would be to set "#define __statfs_word __u64" and use
> > > the 64-bit statfs call, instead of compat_sys_statfs64, but that in turn
> > > requires special-casing statfs in libc.
> > 
> > I wouldn't go this route as we kind of agreed that ILP32 should look
> > like any other 32-bit ABI.
> 
> It's really tricky then: in order to support EABI binaries from a libc
> that uses the kernel headers with the OABI compatible definition, we
> must not copy the 88 byte structure to user space, because that would
> overwrite user space stack data, and that in turn means we have to set
> ARCH_PACK_COMPAT_STATFS64, but that in turn prevents us from using the
> generic 32-bit syscall ABI for the arm64/ilp32 fstatfs64 call. 
> 
> It seems that today, put_compat_statfs64() doesn't actually use
> the size argument, and it just copies the individual fields, which
> is fine either way. This means we could turn around the logic
> in the arm32 wrapper, remove ARCH_PACK_COMPAT_STATFS64, and make
> the ilp32 code call directly into compat_sys_fstatfs64(), but it
> would be a bit fragile, as we rely on put_compat_statfs64() not
> actually writing the padding fields that the native do_statfs64()
> writes. If someone changed them to both use copy_to_user, we'd
> silently introduce data corruption on rarely used libc implementations.
> 
> 	Arnd

So. For ilp32, the only wrapper left here, is compat_sys_mmap2_wrapper.
But this is workaroud, as comment tells:
        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.

Not sure we should pull it to ILP32. If so, we can call sys_mmap_pgoff()
directly. And we don't need this patch at all therefore. Any throughts?

Yury.

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

* Re: [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
  2015-12-30 17:29             ` Yury Norov
@ 2015-12-30 22:36               ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-30 22:36 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, pinskia, Prasun.Kapoor, Catalin Marinas,
	Nathan_Lynch, linux-kernel, agraf, klimov.linux, broonie,
	jan.dakinevich, ddaney.cavm, schwab, bamvor.zhangjian,
	philipp.tomsich, joseph, christoph.muellner

On Wednesday 30 December 2015 20:29:05 Yury Norov wrote:
> 
> So. For ilp32, the only wrapper left here, is compat_sys_mmap2_wrapper.
> But this is workaroud, as comment tells:
>         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.
> 
> Not sure we should pull it to ILP32. If so, we can call sys_mmap_pgoff()
> directly. And we don't need this patch at all therefore. Any throughts?
> 
> 

I think providing the 64-bit version of sys_mmap() would be the simplest
API, as that avoids any possible confusion about the shift amount (hardcoded
12 bits vs PAGE_BITS). It fits in with the other syscalls that pass an loff_t
value here.

	Arnd

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

* [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32
@ 2015-12-30 22:36               ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2015-12-30 22:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 30 December 2015 20:29:05 Yury Norov wrote:
> 
> So. For ilp32, the only wrapper left here, is compat_sys_mmap2_wrapper.
> But this is workaroud, as comment tells:
>         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.
> 
> Not sure we should pull it to ILP32. If so, we can call sys_mmap_pgoff()
> directly. And we don't need this patch at all therefore. Any throughts?
> 
> 

I think providing the 64-bit version of sys_mmap() would be the simplest
API, as that avoids any possible confusion about the shift amount (hardcoded
12 bits vs PAGE_BITS). It fits in with the other syscalls that pass an loff_t
value here.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2015-12-17 20:50           ` Arnd Bergmann
@ 2016-01-05 15:26             ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2016-01-05 15:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrew Pinski, Catalin Marinas, linux-arm-kernel, LKML, Kapoor,
	Prasun, Andreas Schwab, broonie, Nathan Lynch, Alexander Graf,
	Alexey Klimov, Jan Dakinevich, Andrew Pinski, David Daney,
	Zhangjian (Bamvor),
	Philipp Tomsich, Joseph S. Myers, christoph.muellner

On Thu, Dec 17, 2015 at 09:50:52PM +0100, Arnd Bergmann wrote:
> On Thursday 17 December 2015 12:14:20 Andrew Pinski wrote:
> > On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > > On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> > >> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
> > >
> > >> > +#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
> > >>
> > >> I wonder whether we need wrappers (actually, not only for these but
> > >> sys_read etc.). These functions take either a pointer or a size_t
> > >> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> > >> kernel. Can we guarantee that user space zeros the top 32-bit of the
> > >> arguments passed here?
> > >
> > > I'm pretty sure that is safe. I haven't read the calling conventions
> > > specification for arm64 ilp32, but usually all function arguments are
> > > passed as 64-bit registers with proper sign-extend or zero-extend.
> > 
> > Well (just like LP64 on AARCH64), when passing a 32bit value to a
> > function, the upper 32bits are undefined.  I ran into this when I was
> > debugging the GCC go library on ILP32 (though reproduced with pure C
> > code) and the assembly functions inside glibc where pointers are
> > passed with the upper 32bits as undefined.
> > So we have an issue if called with syscall function or using pure
> > assembly to create the syscall functions (which glibc does).
> 
> Ok, I see :-(
> 
> So the calling conventions avoid the problem of being able to set
> the upper bits from malicious user space when the kernel assumes they
> are zeroed out (we had security bugs in this area, before we introduced
> SYSCALL_DEFINEx()), but it means that we need wrappers around each
> syscall that takes an argument that is different length between user
> and kernel space (as Catalin guessed). arch/s390 has the same problem and
> works around it with code in arch/s390/kernel/compat_wrapper.c, while
> other architectures (at least powerpc, x86 and tile IIRC, don't know much
> about mips, parisc and sparc) don't have the problem because of their
> calling conventions.
> 
> This also means that we cannot work around it in glibc at all, because
> we have to be able to handle malicious user space, so it has to be
> done in the kernel using something similar to what s390 does.
> 
> 	Arnd

So it seems like we (should) have 2 compat modes - with and without access
to upper half of register. I'm thinking now on how put it in generic
unistd.h less painfull way.

Beside of that, I think I almost finished with all current comments. As
this issue is not related to ILP32 directly, I think, it's better to show
it now, as there is pretty massive rework. What do you think?

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2016-01-05 15:26             ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2016-01-05 15:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 17, 2015 at 09:50:52PM +0100, Arnd Bergmann wrote:
> On Thursday 17 December 2015 12:14:20 Andrew Pinski wrote:
> > On Thu, Dec 17, 2015 at 12:10 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > > On Thursday 17 December 2015 18:27:53 Catalin Marinas wrote:
> > >> On Wed, Dec 16, 2015 at 12:42:38AM +0300, Yury Norov wrote:
> > >
> > >> > +#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
> > >>
> > >> I wonder whether we need wrappers (actually, not only for these but
> > >> sys_read etc.). These functions take either a pointer or a size_t
> > >> argument which are 32-bit with ILP32 but treated as 64-bit by an LP64
> > >> kernel. Can we guarantee that user space zeros the top 32-bit of the
> > >> arguments passed here?
> > >
> > > I'm pretty sure that is safe. I haven't read the calling conventions
> > > specification for arm64 ilp32, but usually all function arguments are
> > > passed as 64-bit registers with proper sign-extend or zero-extend.
> > 
> > Well (just like LP64 on AARCH64), when passing a 32bit value to a
> > function, the upper 32bits are undefined.  I ran into this when I was
> > debugging the GCC go library on ILP32 (though reproduced with pure C
> > code) and the assembly functions inside glibc where pointers are
> > passed with the upper 32bits as undefined.
> > So we have an issue if called with syscall function or using pure
> > assembly to create the syscall functions (which glibc does).
> 
> Ok, I see :-(
> 
> So the calling conventions avoid the problem of being able to set
> the upper bits from malicious user space when the kernel assumes they
> are zeroed out (we had security bugs in this area, before we introduced
> SYSCALL_DEFINEx()), but it means that we need wrappers around each
> syscall that takes an argument that is different length between user
> and kernel space (as Catalin guessed). arch/s390 has the same problem and
> works around it with code in arch/s390/kernel/compat_wrapper.c, while
> other architectures (at least powerpc, x86 and tile IIRC, don't know much
> about mips, parisc and sparc) don't have the problem because of their
> calling conventions.
> 
> This also means that we cannot work around it in glibc at all, because
> we have to be able to handle malicious user space, so it has to be
> done in the kernel using something similar to what s390 does.
> 
> 	Arnd

So it seems like we (should) have 2 compat modes - with and without access
to upper half of register. I'm thinking now on how put it in generic
unistd.h less painfull way.

Beside of that, I think I almost finished with all current comments. As
this issue is not related to ILP32 directly, I think, it's better to show
it now, as there is pretty massive rework. What do you think?

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-01-05 15:26             ` Yury Norov
@ 2016-01-05 21:12               ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2016-01-05 21:12 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Yury Norov, Andrew Pinski, Kapoor, Prasun, Catalin Marinas,
	Joseph S. Myers, Nathan Lynch, LKML, Alexander Graf,
	Alexey Klimov, broonie, Jan Dakinevich, Andrew Pinski,
	David Daney, Andreas Schwab, Zhangjian (Bamvor),
	Philipp Tomsich, christoph.muellner

On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > So the calling conventions avoid the problem of being able to set
> > the upper bits from malicious user space when the kernel assumes they
> > are zeroed out (we had security bugs in this area, before we introduced
> > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > syscall that takes an argument that is different length between user
> > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > about mips, parisc and sparc) don't have the problem because of their
> > calling conventions.
> > 
> > This also means that we cannot work around it in glibc at all, because
> > we have to be able to handle malicious user space, so it has to be
> > done in the kernel using something similar to what s390 does.
> > 
> >       Arnd
> 
> So it seems like we (should) have 2 compat modes - with and without access
> to upper half of register. I'm thinking now on how put it in generic
> unistd.h less painfull way.

I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
__SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
arm64-ilp32 and s390, the other two don't.

We can use some clever string concatenation to add a ##_wrapper to the name
of the handler where needed and then just have a file that implements
the wrappers, copied from s390.

Unfortunately, we can't just zero out all the upper halves and be done with
it: even if we went back to passing 64-bit arguments as separate 32-bit
registers, we'd still need to deal with sign-extending negative 32-bit
numbers.

> Beside of that, I think I almost finished with all current comments. As
> this issue is not related to ILP32 directly, I think, it's better to show
> it now, as there is pretty massive rework. What do you think?

Good idea, yes.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2016-01-05 21:12               ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2016-01-05 21:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > So the calling conventions avoid the problem of being able to set
> > the upper bits from malicious user space when the kernel assumes they
> > are zeroed out (we had security bugs in this area, before we introduced
> > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > syscall that takes an argument that is different length between user
> > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > about mips, parisc and sparc) don't have the problem because of their
> > calling conventions.
> > 
> > This also means that we cannot work around it in glibc at all, because
> > we have to be able to handle malicious user space, so it has to be
> > done in the kernel using something similar to what s390 does.
> > 
> >       Arnd
> 
> So it seems like we (should) have 2 compat modes - with and without access
> to upper half of register. I'm thinking now on how put it in generic
> unistd.h less painfull way.

I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
__SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
arm64-ilp32 and s390, the other two don't.

We can use some clever string concatenation to add a ##_wrapper to the name
of the handler where needed and then just have a file that implements
the wrappers, copied from s390.

Unfortunately, we can't just zero out all the upper halves and be done with
it: even if we went back to passing 64-bit arguments as separate 32-bit
registers, we'd still need to deal with sign-extending negative 32-bit
numbers.

> Beside of that, I think I almost finished with all current comments. As
> this issue is not related to ILP32 directly, I think, it's better to show
> it now, as there is pretty massive rework. What do you think?

Good idea, yes.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-01-05 21:12               ` Arnd Bergmann
@ 2016-01-06 17:10                 ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2016-01-06 17:10 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Andrew Pinski, Kapoor, Prasun, broonie,
	Nathan Lynch, LKML, Alexander Graf, Alexey Klimov, Yury Norov,
	Jan Dakinevich, Andrew Pinski, David Daney, Andreas Schwab,
	Zhangjian (Bamvor),
	Philipp Tomsich, Joseph S. Myers, christoph.muellner

On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > So the calling conventions avoid the problem of being able to set
> > > the upper bits from malicious user space when the kernel assumes they
> > > are zeroed out (we had security bugs in this area, before we introduced
> > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > syscall that takes an argument that is different length between user
> > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > about mips, parisc and sparc) don't have the problem because of their
> > > calling conventions.
> > > 
> > > This also means that we cannot work around it in glibc at all, because
> > > we have to be able to handle malicious user space, so it has to be
> > > done in the kernel using something similar to what s390 does.
> > 
> > So it seems like we (should) have 2 compat modes - with and without access
> > to upper half of register. I'm thinking now on how put it in generic
> > unistd.h less painfull way.
> 
> I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> arm64-ilp32 and s390, the other two don't.
> 
> We can use some clever string concatenation to add a ##_wrapper to the name
> of the handler where needed and then just have a file that implements
> the wrappers, copied from s390.
> 
> Unfortunately, we can't just zero out all the upper halves and be done with
> it: even if we went back to passing 64-bit arguments as separate 32-bit
> registers, we'd still need to deal with sign-extending negative 32-bit
> numbers.

How many syscalls would we need sign-extension for? Most are probably
already handled by specific compat_sys_* functions, otherwise A32 compat
wouldn't work properly.

Anyway, I think we can get away with not modifying the generic __SYSCALL
definition and only use something like
arch/s390/kernel/compat_wrapper.c. In sys_ilp32.c, we would make
__SYSCALL expand the function name with some ilp32_ prefix.

For existing compat_* syscalls, we only need to handle the pointer types
(something like the s390's __TYPE_IS_PTR). I think other types are
already handled by defining the prototype with compat_ulong_t etc.

For native syscalls like sys_read, apart from pointers we also need to
handle size_t. The wrapper would need to be defined using compat types:

ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)

and let the compiler handle the conversion to size_t automatically when
calling sys_read from the wrapper.

> > Beside of that, I think I almost finished with all current comments. As
> > this issue is not related to ILP32 directly, I think, it's better to show
> > it now, as there is pretty massive rework. What do you think?
> 
> Good idea, yes.

Note that we still need to sort the 0/sign extension out before we
"declare" the ILP32 ABI stable.

-- 
Catalin

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2016-01-06 17:10                 ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2016-01-06 17:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > So the calling conventions avoid the problem of being able to set
> > > the upper bits from malicious user space when the kernel assumes they
> > > are zeroed out (we had security bugs in this area, before we introduced
> > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > syscall that takes an argument that is different length between user
> > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > about mips, parisc and sparc) don't have the problem because of their
> > > calling conventions.
> > > 
> > > This also means that we cannot work around it in glibc at all, because
> > > we have to be able to handle malicious user space, so it has to be
> > > done in the kernel using something similar to what s390 does.
> > 
> > So it seems like we (should) have 2 compat modes - with and without access
> > to upper half of register. I'm thinking now on how put it in generic
> > unistd.h less painfull way.
> 
> I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> arm64-ilp32 and s390, the other two don't.
> 
> We can use some clever string concatenation to add a ##_wrapper to the name
> of the handler where needed and then just have a file that implements
> the wrappers, copied from s390.
> 
> Unfortunately, we can't just zero out all the upper halves and be done with
> it: even if we went back to passing 64-bit arguments as separate 32-bit
> registers, we'd still need to deal with sign-extending negative 32-bit
> numbers.

How many syscalls would we need sign-extension for? Most are probably
already handled by specific compat_sys_* functions, otherwise A32 compat
wouldn't work properly.

Anyway, I think we can get away with not modifying the generic __SYSCALL
definition and only use something like
arch/s390/kernel/compat_wrapper.c. In sys_ilp32.c, we would make
__SYSCALL expand the function name with some ilp32_ prefix.

For existing compat_* syscalls, we only need to handle the pointer types
(something like the s390's __TYPE_IS_PTR). I think other types are
already handled by defining the prototype with compat_ulong_t etc.

For native syscalls like sys_read, apart from pointers we also need to
handle size_t. The wrapper would need to be defined using compat types:

ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)

and let the compiler handle the conversion to size_t automatically when
calling sys_read from the wrapper.

> > Beside of that, I think I almost finished with all current comments. As
> > this issue is not related to ILP32 directly, I think, it's better to show
> > it now, as there is pretty massive rework. What do you think?
> 
> Good idea, yes.

Note that we still need to sort the 0/sign extension out before we
"declare" the ILP32 ABI stable.

-- 
Catalin

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-01-06 17:10                 ` Catalin Marinas
@ 2016-01-07 14:13                   ` Arnd Bergmann
  -1 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2016-01-07 14:13 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: linux-arm-kernel, Andrew Pinski, Kapoor, Prasun, broonie,
	Nathan Lynch, LKML, Alexander Graf, Alexey Klimov, Yury Norov,
	Jan Dakinevich, Andrew Pinski, David Daney, Andreas Schwab,
	Zhangjian (Bamvor),
	Philipp Tomsich, Joseph S. Myers, christoph.muellner

On Wednesday 06 January 2016 17:10:47 Catalin Marinas wrote:
> On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> > On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > > So the calling conventions avoid the problem of being able to set
> > > > the upper bits from malicious user space when the kernel assumes they
> > > > are zeroed out (we had security bugs in this area, before we introduced
> > > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > > syscall that takes an argument that is different length between user
> > > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > > about mips, parisc and sparc) don't have the problem because of their
> > > > calling conventions.
> > > > 
> > > > This also means that we cannot work around it in glibc at all, because
> > > > we have to be able to handle malicious user space, so it has to be
> > > > done in the kernel using something similar to what s390 does.
> > > 
> > > So it seems like we (should) have 2 compat modes - with and without access
> > > to upper half of register. I'm thinking now on how put it in generic
> > > unistd.h less painfull way.
> > 
> > I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> > __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> > arm64-ilp32 and s390, the other two don't.
> > 
> > We can use some clever string concatenation to add a ##_wrapper to the name
> > of the handler where needed and then just have a file that implements
> > the wrappers, copied from s390.
> > 
> > Unfortunately, we can't just zero out all the upper halves and be done with
> > it: even if we went back to passing 64-bit arguments as separate 32-bit
> > registers, we'd still need to deal with sign-extending negative 32-bit
> > numbers.
> 
> How many syscalls would we need sign-extension for? Most are probably
> already handled by specific compat_sys_* functions, otherwise A32 compat
> wouldn't work properly.

Good point. I suppose any system call that expects a negative argument
may run into this on all architectures and require a COMPAT_SYSCALL handler,
but only s390 cares about doing the extension for the entire set of syscalls.

This may be to work around a peculiarity of s390, which has now two
but three possible 32-to-64 extension modes: signed int, unsigned int
and pointer. The third one sets the top 33 bits to zero, clearing the
top bit of the 31-bit pointer value in the process. Nothing else needs
this, so if we just clear the upper bits on all system calls and go
back to passing 64-bit arguments as pairs, we are fine and have a much
simpler solution.

> Anyway, I think we can get away with not modifying the generic __SYSCALL
> definition and only use something like
> arch/s390/kernel/compat_wrapper.c. In sys_ilp32.c, we would make
> __SYSCALL expand the function name with some ilp32_ prefix.

I couldn't think of a way, but I'm gladly proven wrong here.

> For existing compat_* syscalls, we only need to handle the pointer types
> (something like the s390's __TYPE_IS_PTR). I think other types are
> already handled by defining the prototype with compat_ulong_t etc.

Right.
 
> For native syscalls like sys_read, apart from pointers we also need to
> handle size_t. The wrapper would need to be defined using compat types:
> 
> ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> 
> and let the compiler handle the conversion to size_t automatically when
> calling sys_read from the wrapper.

Correct. I don't think we need an ILP32_SYSCALL_DEFINEx set of macros
though, the existing COMPAT_SYSCALL_DEFINEx ones should get this right
already.

	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2016-01-07 14:13                   ` Arnd Bergmann
  0 siblings, 0 replies; 156+ messages in thread
From: Arnd Bergmann @ 2016-01-07 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 06 January 2016 17:10:47 Catalin Marinas wrote:
> On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> > On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > > So the calling conventions avoid the problem of being able to set
> > > > the upper bits from malicious user space when the kernel assumes they
> > > > are zeroed out (we had security bugs in this area, before we introduced
> > > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > > syscall that takes an argument that is different length between user
> > > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > > about mips, parisc and sparc) don't have the problem because of their
> > > > calling conventions.
> > > > 
> > > > This also means that we cannot work around it in glibc at all, because
> > > > we have to be able to handle malicious user space, so it has to be
> > > > done in the kernel using something similar to what s390 does.
> > > 
> > > So it seems like we (should) have 2 compat modes - with and without access
> > > to upper half of register. I'm thinking now on how put it in generic
> > > unistd.h less painfull way.
> > 
> > I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> > __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> > arm64-ilp32 and s390, the other two don't.
> > 
> > We can use some clever string concatenation to add a ##_wrapper to the name
> > of the handler where needed and then just have a file that implements
> > the wrappers, copied from s390.
> > 
> > Unfortunately, we can't just zero out all the upper halves and be done with
> > it: even if we went back to passing 64-bit arguments as separate 32-bit
> > registers, we'd still need to deal with sign-extending negative 32-bit
> > numbers.
> 
> How many syscalls would we need sign-extension for? Most are probably
> already handled by specific compat_sys_* functions, otherwise A32 compat
> wouldn't work properly.

Good point. I suppose any system call that expects a negative argument
may run into this on all architectures and require a COMPAT_SYSCALL handler,
but only s390 cares about doing the extension for the entire set of syscalls.

This may be to work around a peculiarity of s390, which has now two
but three possible 32-to-64 extension modes: signed int, unsigned int
and pointer. The third one sets the top 33 bits to zero, clearing the
top bit of the 31-bit pointer value in the process. Nothing else needs
this, so if we just clear the upper bits on all system calls and go
back to passing 64-bit arguments as pairs, we are fine and have a much
simpler solution.

> Anyway, I think we can get away with not modifying the generic __SYSCALL
> definition and only use something like
> arch/s390/kernel/compat_wrapper.c. In sys_ilp32.c, we would make
> __SYSCALL expand the function name with some ilp32_ prefix.

I couldn't think of a way, but I'm gladly proven wrong here.

> For existing compat_* syscalls, we only need to handle the pointer types
> (something like the s390's __TYPE_IS_PTR). I think other types are
> already handled by defining the prototype with compat_ulong_t etc.

Right.
 
> For native syscalls like sys_read, apart from pointers we also need to
> handle size_t. The wrapper would need to be defined using compat types:
> 
> ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> 
> and let the compiler handle the conversion to size_t automatically when
> calling sys_read from the wrapper.

Correct. I don't think we need an ILP32_SYSCALL_DEFINEx set of macros
though, the existing COMPAT_SYSCALL_DEFINEx ones should get this right
already.

	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-01-07 14:13                   ` Arnd Bergmann
@ 2016-01-07 15:42                     ` Yury Norov
  -1 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2016-01-07 15:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Catalin Marinas, linux-arm-kernel, Andrew Pinski, Kapoor, Prasun,
	broonie, Nathan Lynch, LKML, Alexander Graf, Alexey Klimov,
	Jan Dakinevich, Andrew Pinski, David Daney, Andreas Schwab,
	Zhangjian (Bamvor),
	Philipp Tomsich, Joseph S. Myers, christoph.muellner

On Thu, Jan 07, 2016 at 03:13:37PM +0100, Arnd Bergmann wrote:
> On Wednesday 06 January 2016 17:10:47 Catalin Marinas wrote:
> > On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> > > On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > > > So the calling conventions avoid the problem of being able to set
> > > > > the upper bits from malicious user space when the kernel assumes they
> > > > > are zeroed out (we had security bugs in this area, before we introduced
> > > > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > > > syscall that takes an argument that is different length between user
> > > > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > > > about mips, parisc and sparc) don't have the problem because of their
> > > > > calling conventions.
> > > > > 
> > > > > This also means that we cannot work around it in glibc at all, because
> > > > > we have to be able to handle malicious user space, so it has to be
> > > > > done in the kernel using something similar to what s390 does.
> > > > 
> > > > So it seems like we (should) have 2 compat modes - with and without access
> > > > to upper half of register. I'm thinking now on how put it in generic
> > > > unistd.h less painfull way.
> > > 
> > > I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> > > __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> > > arm64-ilp32 and s390, the other two don't.
> > > 
> > > We can use some clever string concatenation to add a ##_wrapper to the name
> > > of the handler where needed and then just have a file that implements
> > > the wrappers, copied from s390.
> > > 
> > > Unfortunately, we can't just zero out all the upper halves and be done with
> > > it: even if we went back to passing 64-bit arguments as separate 32-bit
> > > registers, we'd still need to deal with sign-extending negative 32-bit
> > > numbers.
> > 
> > How many syscalls would we need sign-extension for? Most are probably
> > already handled by specific compat_sys_* functions, otherwise A32 compat
> > wouldn't work properly.
> 
> Good point. I suppose any system call that expects a negative argument
> may run into this on all architectures and require a COMPAT_SYSCALL handler,
> but only s390 cares about doing the extension for the entire set of syscalls.
> 
> This may be to work around a peculiarity of s390, which has now two
> but three possible 32-to-64 extension modes: signed int, unsigned int
> and pointer. The third one sets the top 33 bits to zero, clearing the
> top bit of the 31-bit pointer value in the process. Nothing else needs
> this, so if we just clear the upper bits on all system calls and go
> back to passing 64-bit arguments as pairs, we are fine and have a much
> simpler solution.

Wrappers will not add extra complexity because we already have it in
s390 port. In other hand, splitting and then assembling 64-bit values
affects performance so small, that we may not care about it much.

So, both approaches are acceptable for me. But I'd choose wrappers,
because it looks more generic, and more fun. :)

This way we can make something like ILP16 easily (can't imagine what
for, though).

> 
> > Anyway, I think we can get away with not modifying the generic __SYSCALL
> > definition and only use something like
> > arch/s390/kernel/compat_wrapper.c. In sys_ilp32.c, we would make
> > __SYSCALL expand the function name with some ilp32_ prefix.
> 
> I couldn't think of a way, but I'm gladly proven wrong here.
> 
> > For existing compat_* syscalls, we only need to handle the pointer types
> > (something like the s390's __TYPE_IS_PTR). I think other types are
> > already handled by defining the prototype with compat_ulong_t etc.
> 
> Right.
>  
> > For native syscalls like sys_read, apart from pointers we also need to
> > handle size_t. The wrapper would need to be defined using compat types:
> > 
> > ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> > 
> > and let the compiler handle the conversion to size_t automatically when
> > calling sys_read from the wrapper.
> 
> Correct. I don't think we need an ILP32_SYSCALL_DEFINEx set of macros
> though, the existing COMPAT_SYSCALL_DEFINEx ones should get this right
> already.
> 
> 	Arnd

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2016-01-07 15:42                     ` Yury Norov
  0 siblings, 0 replies; 156+ messages in thread
From: Yury Norov @ 2016-01-07 15:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 07, 2016 at 03:13:37PM +0100, Arnd Bergmann wrote:
> On Wednesday 06 January 2016 17:10:47 Catalin Marinas wrote:
> > On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> > > On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > > > So the calling conventions avoid the problem of being able to set
> > > > > the upper bits from malicious user space when the kernel assumes they
> > > > > are zeroed out (we had security bugs in this area, before we introduced
> > > > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > > > syscall that takes an argument that is different length between user
> > > > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > > > about mips, parisc and sparc) don't have the problem because of their
> > > > > calling conventions.
> > > > > 
> > > > > This also means that we cannot work around it in glibc at all, because
> > > > > we have to be able to handle malicious user space, so it has to be
> > > > > done in the kernel using something similar to what s390 does.
> > > > 
> > > > So it seems like we (should) have 2 compat modes - with and without access
> > > > to upper half of register. I'm thinking now on how put it in generic
> > > > unistd.h less painfull way.
> > > 
> > > I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> > > __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> > > arm64-ilp32 and s390, the other two don't.
> > > 
> > > We can use some clever string concatenation to add a ##_wrapper to the name
> > > of the handler where needed and then just have a file that implements
> > > the wrappers, copied from s390.
> > > 
> > > Unfortunately, we can't just zero out all the upper halves and be done with
> > > it: even if we went back to passing 64-bit arguments as separate 32-bit
> > > registers, we'd still need to deal with sign-extending negative 32-bit
> > > numbers.
> > 
> > How many syscalls would we need sign-extension for? Most are probably
> > already handled by specific compat_sys_* functions, otherwise A32 compat
> > wouldn't work properly.
> 
> Good point. I suppose any system call that expects a negative argument
> may run into this on all architectures and require a COMPAT_SYSCALL handler,
> but only s390 cares about doing the extension for the entire set of syscalls.
> 
> This may be to work around a peculiarity of s390, which has now two
> but three possible 32-to-64 extension modes: signed int, unsigned int
> and pointer. The third one sets the top 33 bits to zero, clearing the
> top bit of the 31-bit pointer value in the process. Nothing else needs
> this, so if we just clear the upper bits on all system calls and go
> back to passing 64-bit arguments as pairs, we are fine and have a much
> simpler solution.

Wrappers will not add extra complexity because we already have it in
s390 port. In other hand, splitting and then assembling 64-bit values
affects performance so small, that we may not care about it much.

So, both approaches are acceptable for me. But I'd choose wrappers,
because it looks more generic, and more fun. :)

This way we can make something like ILP16 easily (can't imagine what
for, though).

> 
> > Anyway, I think we can get away with not modifying the generic __SYSCALL
> > definition and only use something like
> > arch/s390/kernel/compat_wrapper.c. In sys_ilp32.c, we would make
> > __SYSCALL expand the function name with some ilp32_ prefix.
> 
> I couldn't think of a way, but I'm gladly proven wrong here.
> 
> > For existing compat_* syscalls, we only need to handle the pointer types
> > (something like the s390's __TYPE_IS_PTR). I think other types are
> > already handled by defining the prototype with compat_ulong_t etc.
> 
> Right.
>  
> > For native syscalls like sys_read, apart from pointers we also need to
> > handle size_t. The wrapper would need to be defined using compat types:
> > 
> > ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> > 
> > and let the compiler handle the conversion to size_t automatically when
> > calling sys_read from the wrapper.
> 
> Correct. I don't think we need an ILP32_SYSCALL_DEFINEx set of macros
> though, the existing COMPAT_SYSCALL_DEFINEx ones should get this right
> already.
> 
> 	Arnd

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

* Re: [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
  2016-01-07 14:13                   ` Arnd Bergmann
@ 2016-01-07 17:23                     ` Catalin Marinas
  -1 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2016-01-07 17:23 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Zhangjian (Bamvor),
	Andrew Pinski, Kapoor, Prasun, Andreas Schwab, Joseph S. Myers,
	Nathan Lynch, LKML, Alexander Graf, Alexey Klimov, broonie,
	Yury Norov, Andrew Pinski, David Daney, Jan Dakinevich,
	Philipp Tomsich, linux-arm-kernel, christoph.muellner

On Thu, Jan 07, 2016 at 03:13:37PM +0100, Arnd Bergmann wrote:
> On Wednesday 06 January 2016 17:10:47 Catalin Marinas wrote:
> > On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> > > On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > > > So the calling conventions avoid the problem of being able to set
> > > > > the upper bits from malicious user space when the kernel assumes they
> > > > > are zeroed out (we had security bugs in this area, before we introduced
> > > > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > > > syscall that takes an argument that is different length between user
> > > > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > > > about mips, parisc and sparc) don't have the problem because of their
> > > > > calling conventions.
> > > > > 
> > > > > This also means that we cannot work around it in glibc at all, because
> > > > > we have to be able to handle malicious user space, so it has to be
> > > > > done in the kernel using something similar to what s390 does.
> > > > 
> > > > So it seems like we (should) have 2 compat modes - with and without access
> > > > to upper half of register. I'm thinking now on how put it in generic
> > > > unistd.h less painfull way.
> > > 
> > > I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> > > __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> > > arm64-ilp32 and s390, the other two don't.
> > > 
> > > We can use some clever string concatenation to add a ##_wrapper to the name
> > > of the handler where needed and then just have a file that implements
> > > the wrappers, copied from s390.
> > > 
> > > Unfortunately, we can't just zero out all the upper halves and be done with
> > > it: even if we went back to passing 64-bit arguments as separate 32-bit
> > > registers, we'd still need to deal with sign-extending negative 32-bit
> > > numbers.
> > 
> > How many syscalls would we need sign-extension for? Most are probably
> > already handled by specific compat_sys_* functions, otherwise A32 compat
> > wouldn't work properly.
> 
> Good point. I suppose any system call that expects a negative argument
> may run into this on all architectures and require a COMPAT_SYSCALL handler,
> but only s390 cares about doing the extension for the entire set of syscalls.
> 
> This may be to work around a peculiarity of s390, which has now two
> but three possible 32-to-64 extension modes: signed int, unsigned int
> and pointer. The third one sets the top 33 bits to zero, clearing the
> top bit of the 31-bit pointer value in the process. Nothing else needs
> this, so if we just clear the upper bits on all system calls and go
> back to passing 64-bit arguments as pairs, we are fine and have a much
> simpler solution.

It would be indeed simpler from a kernel perspective. I'm not sure about
the performance impact (a wrapper which does "mov wn, wn" for the first
6 registers, on top of existing wrappers). OTOH, with explicit wrappers
we have the overhead of an additional function call, so we may be better
off with the former.

> > For native syscalls like sys_read, apart from pointers we also need to
> > handle size_t. The wrapper would need to be defined using compat types:
> > 
> > ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> > 
> > and let the compiler handle the conversion to size_t automatically when
> > calling sys_read from the wrapper.
> 
> Correct. I don't think we need an ILP32_SYSCALL_DEFINEx set of macros
> though, the existing COMPAT_SYSCALL_DEFINEx ones should get this right
> already.

The existing COMPAT_SYSCALL_DEFINEx macros generate the wrapper and
definition for the compat_sys_* functions. What I meant by an
ILP32_SYSCALL_DEFINEx is a macro which only generates a wrapper that
calls into the native syscall (after sanitizing the arguments).

-- 
Catalin

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

* [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it
@ 2016-01-07 17:23                     ` Catalin Marinas
  0 siblings, 0 replies; 156+ messages in thread
From: Catalin Marinas @ 2016-01-07 17:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 07, 2016 at 03:13:37PM +0100, Arnd Bergmann wrote:
> On Wednesday 06 January 2016 17:10:47 Catalin Marinas wrote:
> > On Tue, Jan 05, 2016 at 10:12:20PM +0100, Arnd Bergmann wrote:
> > > On Tuesday 05 January 2016 18:26:57 Yury Norov wrote:
> > > > > So the calling conventions avoid the problem of being able to set
> > > > > the upper bits from malicious user space when the kernel assumes they
> > > > > are zeroed out (we had security bugs in this area, before we introduced
> > > > > SYSCALL_DEFINEx()), but it means that we need wrappers around each
> > > > > syscall that takes an argument that is different length between user
> > > > > and kernel space (as Catalin guessed). arch/s390 has the same problem and
> > > > > works around it with code in arch/s390/kernel/compat_wrapper.c, while
> > > > > other architectures (at least powerpc, x86 and tile IIRC, don't know much
> > > > > about mips, parisc and sparc) don't have the problem because of their
> > > > > calling conventions.
> > > > > 
> > > > > This also means that we cannot work around it in glibc at all, because
> > > > > we have to be able to handle malicious user space, so it has to be
> > > > > done in the kernel using something similar to what s390 does.
> > > > 
> > > > So it seems like we (should) have 2 compat modes - with and without access
> > > > to upper half of register. I'm thinking now on how put it in generic
> > > > unistd.h less painfull way.
> > > 
> > > I think we can do that by slightly modifying the existing __SYSCALL/__SC_3264/
> > > __SC_COMP/__SC_COMP_3264 macros: The first two need extra wrappers for
> > > arm64-ilp32 and s390, the other two don't.
> > > 
> > > We can use some clever string concatenation to add a ##_wrapper to the name
> > > of the handler where needed and then just have a file that implements
> > > the wrappers, copied from s390.
> > > 
> > > Unfortunately, we can't just zero out all the upper halves and be done with
> > > it: even if we went back to passing 64-bit arguments as separate 32-bit
> > > registers, we'd still need to deal with sign-extending negative 32-bit
> > > numbers.
> > 
> > How many syscalls would we need sign-extension for? Most are probably
> > already handled by specific compat_sys_* functions, otherwise A32 compat
> > wouldn't work properly.
> 
> Good point. I suppose any system call that expects a negative argument
> may run into this on all architectures and require a COMPAT_SYSCALL handler,
> but only s390 cares about doing the extension for the entire set of syscalls.
> 
> This may be to work around a peculiarity of s390, which has now two
> but three possible 32-to-64 extension modes: signed int, unsigned int
> and pointer. The third one sets the top 33 bits to zero, clearing the
> top bit of the 31-bit pointer value in the process. Nothing else needs
> this, so if we just clear the upper bits on all system calls and go
> back to passing 64-bit arguments as pairs, we are fine and have a much
> simpler solution.

It would be indeed simpler from a kernel perspective. I'm not sure about
the performance impact (a wrapper which does "mov wn, wn" for the first
6 registers, on top of existing wrappers). OTOH, with explicit wrappers
we have the overhead of an additional function call, so we may be better
off with the former.

> > For native syscalls like sys_read, apart from pointers we also need to
> > handle size_t. The wrapper would need to be defined using compat types:
> > 
> > ILP32_SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, compat_size_t, count)
> > 
> > and let the compiler handle the conversion to size_t automatically when
> > calling sys_read from the wrapper.
> 
> Correct. I don't think we need an ILP32_SYSCALL_DEFINEx set of macros
> though, the existing COMPAT_SYSCALL_DEFINEx ones should get this right
> already.

The existing COMPAT_SYSCALL_DEFINEx macros generate the wrapper and
definition for the compat_sys_* functions. What I meant by an
ILP32_SYSCALL_DEFINEx is a macro which only generates a wrapper that
calls into the native syscall (after sanitizing the arguments).

-- 
Catalin

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

end of thread, other threads:[~2016-01-07 17:23 UTC | newest]

Thread overview: 156+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-15 21:42 [RFC3 PATCH v6 00/20] ILP32 for ARM64 Yury Norov
2015-12-15 21:42 ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 01/20] arm64: ilp32: add documentation on the ILP32 ABI " Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 02/20] arm64: ensure the kernel is compiled for LP64 Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 03/20] arm64: rename COMPAT to AARCH32_EL0 in Kconfig Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-17 11:23   ` Catalin Marinas
2015-12-17 11:23     ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-23 14:15   ` Yury Norov
2015-12-23 14:15     ` Yury Norov
2015-12-28  8:43   ` > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile Bamvor Jian Zhang
2015-12-28  8:43     ` Bamvor Jian Zhang
2015-12-28  9:01     ` [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Zhangjian (Bamvor)
2015-12-28  9:01       ` Zhangjian (Bamvor)
2015-12-29 12:27       ` Yury Norov
2015-12-29 12:27         ` Yury Norov
2015-12-29 14:59         ` [PATCH] arm64: compat: fix wrong dependency Bamvor Jian Zhang
2015-12-29 14:59           ` Bamvor Jian Zhang
2015-12-29 13:12       ` [PATCH v6 04/20] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Yury Norov
2015-12-29 13:12         ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 05/20] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64 Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 06/20] thread: move thread bits accessors to separated file Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 07/20] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat) Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-17 11:38   ` Catalin Marinas
2015-12-17 11:38     ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64 Yury Norov
2015-12-15 21:42   ` [PATCH v6 08/20] arm64: ilp32: add is_ilp32_compat_{task, thread} " Yury Norov
2015-12-17 11:41   ` Catalin Marinas
2015-12-17 11:41     ` Catalin Marinas
2015-12-18 14:11     ` Yury Norov
2015-12-18 14:11       ` Yury Norov
2015-12-18 14:44       ` Yury Norov
2015-12-18 14:44         ` Yury Norov
2015-12-21 17:42         ` Catalin Marinas
2015-12-21 17:42           ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 09/20] arm64:ilp32: share HWCAP between LP64 and ILP32 Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-16 15:54   ` Arnd Bergmann
2015-12-16 15:54     ` Arnd Bergmann
2015-12-16 16:58     ` Catalin Marinas
2015-12-16 16:58       ` Catalin Marinas
2015-12-16 17:19       ` Catalin Marinas
2015-12-16 17:19         ` Catalin Marinas
2015-12-16 19:17         ` Arnd Bergmann
2015-12-16 19:17           ` Arnd Bergmann
2015-12-17 10:54           ` Catalin Marinas
2015-12-17 10:54             ` Catalin Marinas
2015-12-17 13:56             ` Arnd Bergmann
2015-12-17 13:56               ` Arnd Bergmann
2015-12-15 21:42 ` [PATCH v6 10/20] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-16 15:50   ` Arnd Bergmann
2015-12-16 15:50     ` Arnd Bergmann
2015-12-18 13:57     ` Yury Norov
2015-12-18 13:57       ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 11/20] arm64:ilp32: support core dump generation for ILP32 Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-17 14:05   ` Catalin Marinas
2015-12-17 14:05     ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 12/20] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-16 16:07   ` Arnd Bergmann
2015-12-16 16:07     ` Arnd Bergmann
2015-12-17 18:27   ` Catalin Marinas
2015-12-17 18:27     ` Catalin Marinas
2015-12-17 20:10     ` Arnd Bergmann
2015-12-17 20:10       ` Arnd Bergmann
2015-12-17 20:14       ` Andrew Pinski
2015-12-17 20:14         ` Andrew Pinski
2015-12-17 20:50         ` Arnd Bergmann
2015-12-17 20:50           ` Arnd Bergmann
2016-01-05 15:26           ` Yury Norov
2016-01-05 15:26             ` Yury Norov
2016-01-05 21:12             ` Arnd Bergmann
2016-01-05 21:12               ` Arnd Bergmann
2016-01-06 17:10               ` Catalin Marinas
2016-01-06 17:10                 ` Catalin Marinas
2016-01-07 14:13                 ` Arnd Bergmann
2016-01-07 14:13                   ` Arnd Bergmann
2016-01-07 15:42                   ` Yury Norov
2016-01-07 15:42                     ` Yury Norov
2016-01-07 17:23                   ` Catalin Marinas
2016-01-07 17:23                     ` Catalin Marinas
2015-12-18 11:42         ` Catalin Marinas
2015-12-18 11:42           ` Catalin Marinas
2015-12-18 12:47           ` Arnd Bergmann
2015-12-18 12:47             ` Arnd Bergmann
2015-12-21 18:31             ` Catalin Marinas
2015-12-21 18:31               ` Catalin Marinas
2015-12-21 22:19               ` Arnd Bergmann
2015-12-21 22:19                 ` Arnd Bergmann
2015-12-21 18:39             ` Dr. Philipp Tomsich
2015-12-21 18:39               ` Dr. Philipp Tomsich
2015-12-21 22:13               ` Arnd Bergmann
2015-12-21 22:13                 ` Arnd Bergmann
2015-12-21 22:31   ` Arnd Bergmann
2015-12-21 22:31     ` Arnd Bergmann
2015-12-23 18:31     ` Yury Norov
2015-12-23 18:31       ` Yury Norov
2015-12-23 21:48       ` Arnd Bergmann
2015-12-23 21:48         ` Arnd Bergmann
2015-12-15 21:42 ` [PATCH v6 13/20] arm64: ilp32: share aarch32 syscall wrappers to ilp32 Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-17 14:38   ` Andreas Schwab
2015-12-17 14:38     ` Andreas Schwab
2015-12-18 13:49     ` Yury Norov
2015-12-18 13:49       ` Yury Norov
2015-12-22 12:25   ` Catalin Marinas
2015-12-22 12:25     ` Catalin Marinas
2015-12-22 21:44     ` Arnd Bergmann
2015-12-22 21:44       ` Arnd Bergmann
2015-12-23 13:37       ` Catalin Marinas
2015-12-23 13:37         ` Catalin Marinas
2015-12-23 20:41         ` Arnd Bergmann
2015-12-23 20:41           ` Arnd Bergmann
2015-12-30 17:29           ` Yury Norov
2015-12-30 17:29             ` Yury Norov
2015-12-30 22:36             ` Arnd Bergmann
2015-12-30 22:36               ` Arnd Bergmann
2015-12-23  4:21     ` Yury Norov
2015-12-23  4:21       ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 14/20] arm64: signal: wrap struct ucontext, fp and lr with struct sigframe Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 15/20] arm64: signal: move ilp32 and lp64 common code to separated file Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-16 16:08   ` Arnd Bergmann
2015-12-16 16:08     ` Arnd Bergmann
2015-12-18 13:48     ` Yury Norov
2015-12-18 13:48       ` Yury Norov
2015-12-18 14:09       ` Arnd Bergmann
2015-12-18 14:09         ` Arnd Bergmann
2015-12-22 17:11   ` Catalin Marinas
2015-12-22 17:11     ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 16/20] arm64: signal32: move ilp32 and aarch32 " Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-22 14:29   ` Catalin Marinas
2015-12-22 14:29     ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 17/20] arm64: ilp32: introduce ilp32-specific handlers for sigframe Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-22 17:08   ` Catalin Marinas
2015-12-22 17:08     ` Catalin Marinas
2015-12-15 21:42 ` [PATCH v6 18/20] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 19/20] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32 Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-15 21:42 ` [PATCH v6 20/20] arm64:ilp32: add ARM64_ILP32 to Kconfig Yury Norov
2015-12-15 21:42   ` Yury Norov
2015-12-16 16:24 ` [RFC3 PATCH v6 00/20] ILP32 for ARM64 Arnd Bergmann
2015-12-16 16:24   ` Arnd Bergmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.