All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 00/24] ILP32 Support in ARM64
@ 2014-05-24  7:01 ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

New version of the patches with documentation, signal changes are simplified, using less compat syscalls and splitting up the patches so it is easier to review.  I have tested LTP on both LP64 and ILP32.  There is a few LTP failures but they are due to LTP being incorrect (sigaction structure in glibc is not the one which is used by the kernel)  I have not yet tested LTP for AARCH32 but I have done simple testing of AARCH32 so an executable still runs.  Each patch has been tested seperately though ILP32 won't fully work until the last patch has been added.

Thanks,
Andrew Pinski

Andrew Pinski (24):
  ARM64: Force LP64 to compile the kernel.
  ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
  ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
    instead.
  ARM64:ILP32: Set kernel_long to long long so we can reuse most of the
    same syscalls as LP64.
  ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
  Allow for some signal structures to be the same between a 32bit ABI
    and the 64bit ABI.
  ARM64:ILP32: Use the same size and layout of the signal structures
    for ILP32 as for LP64.
  Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to
    avoid confusion of not splitting the registers.
  ARM64:ILP32: Use the same syscall names as LP64.
  ARM64: Introduce is_a32_task and is_a32_thread. Use them in the
    correct locations.
  ARM64: Add ARM64_ILP32 to Kconfig.
  ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and
    TIF_32BIT_AARCH64.
  Drivers:input: Use is_compat_task for ARM64 also.
  ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks.
  ARM64:ILP32: Use the non compat HWCAP for ILP32.
  ARM64:ILP32 use the standard start_thread for ILP32 so the processor
    state is not AARCH32.
  ARM64:ILP32: Support core dump for ILP32.
  ARM64: Add loading of ILP32 binaries.
  ARM64: Add vdso for ILP32 and use it for the signal return.
  ptrace: Allow compat to use the native siginfo.
  ARM64:ILP32: The native siginfo is used instead of the compat
    siginfo.
  ARM64:ILP32: Use a seperate syscall table as a few syscalls need to
    be using the compat syscalls.
  ARM64:ILP32: Fix signal return for ILP32 when the user modified the
    signal stack.
  Add documentation about ARM64 ILP32 ABI.

 Documentation/arm64/ilp32.txt                 |   57 ++++++++
 arch/arm64/Kconfig                            |   15 ++-
 arch/arm64/Makefile                           |    4 +
 arch/arm64/include/asm/Kbuild                 |    1 -
 arch/arm64/include/asm/arch_timer.h           |    2 +-
 arch/arm64/include/asm/compat.h               |   65 +++++++++-
 arch/arm64/include/asm/elf.h                  |  101 +++++++++++++--
 arch/arm64/include/asm/fpsimd.h               |    2 +-
 arch/arm64/include/asm/hwcap.h                |   12 ++-
 arch/arm64/include/asm/memory.h               |    2 +-
 arch/arm64/include/asm/processor.h            |   11 ++-
 arch/arm64/include/asm/ptrace.h               |    2 +-
 arch/arm64/include/asm/signal32.h             |    2 +
 arch/arm64/include/asm/stat.h                 |    2 +
 arch/arm64/include/asm/syscalls.h             |    4 +
 arch/arm64/include/asm/thread_info.h          |    3 +-
 arch/arm64/include/asm/unistd.h               |    6 +-
 arch/arm64/include/asm/vdso.h                 |    4 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |    7 +-
 arch/arm64/include/uapi/asm/posix_types.h     |   12 ++
 arch/arm64/include/uapi/asm/siginfo.h         |   21 +++
 arch/arm64/include/uapi/asm/signal.h          |   32 +++++
 arch/arm64/include/uapi/asm/unistd.h          |    7 +
 arch/arm64/kernel/Makefile                    |    8 +-
 arch/arm64/kernel/asm-offsets.c               |    2 +-
 arch/arm64/kernel/entry.S                     |   19 ++-
 arch/arm64/kernel/head.S                      |    2 +-
 arch/arm64/kernel/hw_breakpoint.c             |    6 +-
 arch/arm64/kernel/process.c                   |    6 +-
 arch/arm64/kernel/ptrace.c                    |   51 +++++---
 arch/arm64/kernel/signal.c                    |   33 +++++-
 arch/arm64/kernel/sys_ilp32.c                 |  175 +++++++++++++++++++++++++
 arch/arm64/kernel/traps.c                     |    4 +-
 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 |  100 ++++++++++++++
 arch/arm64/kernel/vdso.c                      |   59 +++++++--
 drivers/input/input-compat.h                  |    2 +-
 include/linux/compat.h                        |    4 +
 include/uapi/asm-generic/siginfo.h            |   17 ++-
 include/uapi/asm-generic/signal.h             |   27 ++++-
 include/uapi/asm-generic/unistd.h             |    5 +-
 kernel/ptrace.c                               |   24 +++-
 44 files changed, 935 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/arm64/ilp32.txt
 create mode 100644 arch/arm64/include/uapi/asm/posix_types.h
 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

-- 
1.7.2.5


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

* [PATCHv2 00/24] ILP32 Support in ARM64
@ 2014-05-24  7:01 ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

New version of the patches with documentation, signal changes are simplified, using less compat syscalls and splitting up the patches so it is easier to review.  I have tested LTP on both LP64 and ILP32.  There is a few LTP failures but they are due to LTP being incorrect (sigaction structure in glibc is not the one which is used by the kernel)  I have not yet tested LTP for AARCH32 but I have done simple testing of AARCH32 so an executable still runs.  Each patch has been tested seperately though ILP32 won't fully work until the last patch has been added.

Thanks,
Andrew Pinski

Andrew Pinski (24):
  ARM64: Force LP64 to compile the kernel.
  ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
  ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
    instead.
  ARM64:ILP32: Set kernel_long to long long so we can reuse most of the
    same syscalls as LP64.
  ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
  Allow for some signal structures to be the same between a 32bit ABI
    and the 64bit ABI.
  ARM64:ILP32: Use the same size and layout of the signal structures
    for ILP32 as for LP64.
  Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to
    avoid confusion of not splitting the registers.
  ARM64:ILP32: Use the same syscall names as LP64.
  ARM64: Introduce is_a32_task and is_a32_thread. Use them in the
    correct locations.
  ARM64: Add ARM64_ILP32 to Kconfig.
  ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and
    TIF_32BIT_AARCH64.
  Drivers:input: Use is_compat_task for ARM64 also.
  ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks.
  ARM64:ILP32: Use the non compat HWCAP for ILP32.
  ARM64:ILP32 use the standard start_thread for ILP32 so the processor
    state is not AARCH32.
  ARM64:ILP32: Support core dump for ILP32.
  ARM64: Add loading of ILP32 binaries.
  ARM64: Add vdso for ILP32 and use it for the signal return.
  ptrace: Allow compat to use the native siginfo.
  ARM64:ILP32: The native siginfo is used instead of the compat
    siginfo.
  ARM64:ILP32: Use a seperate syscall table as a few syscalls need to
    be using the compat syscalls.
  ARM64:ILP32: Fix signal return for ILP32 when the user modified the
    signal stack.
  Add documentation about ARM64 ILP32 ABI.

 Documentation/arm64/ilp32.txt                 |   57 ++++++++
 arch/arm64/Kconfig                            |   15 ++-
 arch/arm64/Makefile                           |    4 +
 arch/arm64/include/asm/Kbuild                 |    1 -
 arch/arm64/include/asm/arch_timer.h           |    2 +-
 arch/arm64/include/asm/compat.h               |   65 +++++++++-
 arch/arm64/include/asm/elf.h                  |  101 +++++++++++++--
 arch/arm64/include/asm/fpsimd.h               |    2 +-
 arch/arm64/include/asm/hwcap.h                |   12 ++-
 arch/arm64/include/asm/memory.h               |    2 +-
 arch/arm64/include/asm/processor.h            |   11 ++-
 arch/arm64/include/asm/ptrace.h               |    2 +-
 arch/arm64/include/asm/signal32.h             |    2 +
 arch/arm64/include/asm/stat.h                 |    2 +
 arch/arm64/include/asm/syscalls.h             |    4 +
 arch/arm64/include/asm/thread_info.h          |    3 +-
 arch/arm64/include/asm/unistd.h               |    6 +-
 arch/arm64/include/asm/vdso.h                 |    4 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |    7 +-
 arch/arm64/include/uapi/asm/posix_types.h     |   12 ++
 arch/arm64/include/uapi/asm/siginfo.h         |   21 +++
 arch/arm64/include/uapi/asm/signal.h          |   32 +++++
 arch/arm64/include/uapi/asm/unistd.h          |    7 +
 arch/arm64/kernel/Makefile                    |    8 +-
 arch/arm64/kernel/asm-offsets.c               |    2 +-
 arch/arm64/kernel/entry.S                     |   19 ++-
 arch/arm64/kernel/head.S                      |    2 +-
 arch/arm64/kernel/hw_breakpoint.c             |    6 +-
 arch/arm64/kernel/process.c                   |    6 +-
 arch/arm64/kernel/ptrace.c                    |   51 +++++---
 arch/arm64/kernel/signal.c                    |   33 +++++-
 arch/arm64/kernel/sys_ilp32.c                 |  175 +++++++++++++++++++++++++
 arch/arm64/kernel/traps.c                     |    4 +-
 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 |  100 ++++++++++++++
 arch/arm64/kernel/vdso.c                      |   59 +++++++--
 drivers/input/input-compat.h                  |    2 +-
 include/linux/compat.h                        |    4 +
 include/uapi/asm-generic/siginfo.h            |   17 ++-
 include/uapi/asm-generic/signal.h             |   27 ++++-
 include/uapi/asm-generic/unistd.h             |    5 +-
 kernel/ptrace.c                               |   24 +++-
 44 files changed, 935 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/arm64/ilp32.txt
 create mode 100644 arch/arm64/include/uapi/asm/posix_types.h
 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

-- 
1.7.2.5

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

* [PATCH 01/24] ARM64: Force LP64 to compile the kernel.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:01   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Sometimes the compiler is set to default to ILP32 ABI so we want to make sure the kernel can compile in that case.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/Makefile |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2fceb71..e9dbd20 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -20,14 +20,18 @@ LIBGCC 		:= $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 KBUILD_DEFCONFIG := defconfig
 
 KBUILD_CFLAGS	+= -mgeneral-regs-only
+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
 
 comma = ,
-- 
1.7.2.5


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

* [PATCH 01/24] ARM64: Force LP64 to compile the kernel.
@ 2014-05-24  7:01   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

Sometimes the compiler is set to default to ILP32 ABI so we want to make sure the kernel can compile in that case.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/Makefile |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2fceb71..e9dbd20 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -20,14 +20,18 @@ LIBGCC 		:= $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 KBUILD_DEFCONFIG := defconfig
 
 KBUILD_CFLAGS	+= -mgeneral-regs-only
+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
 
 comma = ,
-- 
1.7.2.5

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

* [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:01   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

We want to split CONFIG_COMPAT so we can use the COMPAT interface in some cases including
for compat binfmt.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/Kconfig |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e759af5..032c712 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -287,9 +287,13 @@ 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
-	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	select OLD_SIGSUSPEND3
 	select COMPAT_OLD_SIGACTION
@@ -303,7 +307,7 @@ config COMPAT
 
 config SYSVIPC_COMPAT
 	def_bool y
-	depends on COMPAT && SYSVIPC
+	depends on AARCH32_EL0 && SYSVIPC
 
 endmenu
 
-- 
1.7.2.5


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

* [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
@ 2014-05-24  7:01   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

We want to split CONFIG_COMPAT so we can use the COMPAT interface in some cases including
for compat binfmt.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/Kconfig |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e759af5..032c712 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -287,9 +287,13 @@ 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
-	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	select OLD_SIGSUSPEND3
 	select COMPAT_OLD_SIGACTION
@@ -303,7 +307,7 @@ config COMPAT
 
 config SYSVIPC_COMPAT
 	def_bool y
-	depends on COMPAT && SYSVIPC
+	depends on AARCH32_EL0 && SYSVIPC
 
 endmenu
 
-- 
1.7.2.5

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

* [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:01   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

This patch changes CONFIG_COMPAT checks inside the arm64 which are AARCH32 specific.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/arch_timer.h |    2 +-
 arch/arm64/include/asm/elf.h        |   23 ++++++++++++++++++++---
 arch/arm64/include/asm/fpsimd.h     |    2 +-
 arch/arm64/include/asm/ptrace.h     |    2 +-
 arch/arm64/include/asm/signal32.h   |    2 ++
 arch/arm64/include/asm/stat.h       |    2 ++
 arch/arm64/include/asm/unistd.h     |    2 +-
 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          |   31 ++++++++++++++++++++++++-------
 arch/arm64/kernel/signal.c          |   13 +++++++++++++
 arch/arm64/kernel/traps.c           |    2 +-
 arch/arm64/kernel/vdso.c            |    6 +++---
 15 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 9400596..d9687d1 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -130,7 +130,7 @@ static inline void arch_timer_evtstrm_enable(int divider)
 			| ARCH_TIMER_VIRT_EVT_EN;
 	arch_timer_set_cntkctl(cntkctl);
 	elf_hwcap |= HWCAP_EVTSTRM;
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
 #endif
 }
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 01d3aab..36c3603 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -171,24 +171,41 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 
 #define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(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
 #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
 
+#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_SET_PERSONALITY(ex)
+#define COMPAT_ARCH_DLINFO
+
+#endif
+
+#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
+
 #endif /* CONFIG_COMPAT */
 
 #endif
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index c43b4ac..0229680 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -39,7 +39,7 @@ struct fpsimd_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/ptrace.h b/arch/arm64/include/asm/ptrace.h
index c7ba261..564b7df 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -109,7 +109,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 7c275e3..8873db0 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -20,6 +20,7 @@
 #ifdef CONFIG_COMPAT
 #include <linux/compat.h>
 
+#ifdef CONFIG_AARCH32_EL0
 #define AARCH32_KERN_SIGRET_CODE_OFFSET	0x500
 
 extern const compat_ulong_t aarch32_sigret_code[6];
@@ -48,6 +49,7 @@ static inline int compat_setup_rt_frame(int usig, struct k_sigaction *ka,
 static inline void compat_setup_restart_syscall(struct pt_regs *regs)
 {
 }
+#endif /* CONFIG_AARCH32_EL0 */
 #endif /* CONFIG_COMPAT */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SIGNAL32_H */
diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
index 15e3559..af04276 100644
--- a/arch/arm64/include/asm/stat.h
+++ b/arch/arm64/include/asm/stat.h
@@ -22,6 +22,7 @@
 
 #include <asm/compat.h>
 
+#ifdef CONFIG_AARCH32_EL0
 /*
  * struct stat64 is needed for compat tasks only. Its definition is different
  * from the generic struct stat64.
@@ -59,3 +60,4 @@ struct stat64 {
 
 #endif
 #endif
+#endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index a4654c6..11502bd 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
 #define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 7d811d9..00c0da4 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -11,7 +11,7 @@ arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 			   sys.o stacktrace.o time.o traps.o io.o vdso.o	\
 			   hyp-stub.o psci.o cpu_ops.o insn.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
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o topology.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 646f888..378d692 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -53,7 +53,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 39ac630..1e1ebfc 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -167,7 +167,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
@@ -207,7 +207,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)
@@ -370,7 +370,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 0fd5650..5bd1a94 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -200,7 +200,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 6a8928b..67a0f4d 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -69,7 +69,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())
@@ -607,7 +607,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 {
@@ -770,7 +770,7 @@ static int compat_vfp_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,
@@ -964,8 +964,8 @@ 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,
-			compat_ulong_t caddr, compat_ulong_t cdata)
+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;
 	unsigned long data = cdata;
@@ -1041,11 +1041,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#else /* !CONFIG_AARCH32_EL0 */
+long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
+			    compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	return -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
 	if (is_compat_thread(task_thread_info(task)))
 		return &user_aarch32_view;
 #endif
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 890a591..12b232a 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -417,3 +417,16 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 		tracehook_notify_resume(regs);
 	}
 }
+
+/* Some functions are needed for compat ptrace but we don't define
+   them if we don't have AARCH32 support compiled in */
+#if defined CONFIG_COMPAT && !defined CONFIG_AARCH32_EL0
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
+{
+	return -EFAULT;
+}
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+{
+	return -EFAULT;
+}
+#endif
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 7ffaddd..25dae1a 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -285,7 +285,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 50384fe..31e995b 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.
  */
@@ -102,7 +102,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 
 static int __init vdso_init(void)
 {
@@ -176,7 +176,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 	 * it conflicting with the vectors base.
 	 */
 	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 		if (vma->vm_start == AARCH32_VECTORS_BASE)
 			return "[vectors]";
 #endif
-- 
1.7.2.5


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

* [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead.
@ 2014-05-24  7:01   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch changes CONFIG_COMPAT checks inside the arm64 which are AARCH32 specific.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/arch_timer.h |    2 +-
 arch/arm64/include/asm/elf.h        |   23 ++++++++++++++++++++---
 arch/arm64/include/asm/fpsimd.h     |    2 +-
 arch/arm64/include/asm/ptrace.h     |    2 +-
 arch/arm64/include/asm/signal32.h   |    2 ++
 arch/arm64/include/asm/stat.h       |    2 ++
 arch/arm64/include/asm/unistd.h     |    2 +-
 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          |   31 ++++++++++++++++++++++++-------
 arch/arm64/kernel/signal.c          |   13 +++++++++++++
 arch/arm64/kernel/traps.c           |    2 +-
 arch/arm64/kernel/vdso.c            |    6 +++---
 15 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 9400596..d9687d1 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -130,7 +130,7 @@ static inline void arch_timer_evtstrm_enable(int divider)
 			| ARCH_TIMER_VIRT_EVT_EN;
 	arch_timer_set_cntkctl(cntkctl);
 	elf_hwcap |= HWCAP_EVTSTRM;
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
 #endif
 }
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 01d3aab..36c3603 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -171,24 +171,41 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 
 #define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(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
 #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
 
+#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_SET_PERSONALITY(ex)
+#define COMPAT_ARCH_DLINFO
+
+#endif
+
+#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
+
 #endif /* CONFIG_COMPAT */
 
 #endif
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index c43b4ac..0229680 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -39,7 +39,7 @@ struct fpsimd_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/ptrace.h b/arch/arm64/include/asm/ptrace.h
index c7ba261..564b7df 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -109,7 +109,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 7c275e3..8873db0 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -20,6 +20,7 @@
 #ifdef CONFIG_COMPAT
 #include <linux/compat.h>
 
+#ifdef CONFIG_AARCH32_EL0
 #define AARCH32_KERN_SIGRET_CODE_OFFSET	0x500
 
 extern const compat_ulong_t aarch32_sigret_code[6];
@@ -48,6 +49,7 @@ static inline int compat_setup_rt_frame(int usig, struct k_sigaction *ka,
 static inline void compat_setup_restart_syscall(struct pt_regs *regs)
 {
 }
+#endif /* CONFIG_AARCH32_EL0 */
 #endif /* CONFIG_COMPAT */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SIGNAL32_H */
diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
index 15e3559..af04276 100644
--- a/arch/arm64/include/asm/stat.h
+++ b/arch/arm64/include/asm/stat.h
@@ -22,6 +22,7 @@
 
 #include <asm/compat.h>
 
+#ifdef CONFIG_AARCH32_EL0
 /*
  * struct stat64 is needed for compat tasks only. Its definition is different
  * from the generic struct stat64.
@@ -59,3 +60,4 @@ struct stat64 {
 
 #endif
 #endif
+#endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index a4654c6..11502bd 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define __ARCH_WANT_COMPAT_SYS_GETDENTS64
 #define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 7d811d9..00c0da4 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -11,7 +11,7 @@ arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 			   sys.o stacktrace.o time.o traps.o io.o vdso.o	\
 			   hyp-stub.o psci.o cpu_ops.o insn.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
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o topology.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 646f888..378d692 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -53,7 +53,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 39ac630..1e1ebfc 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -167,7 +167,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
@@ -207,7 +207,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)
@@ -370,7 +370,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 0fd5650..5bd1a94 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -200,7 +200,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 6a8928b..67a0f4d 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -69,7 +69,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())
@@ -607,7 +607,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 {
@@ -770,7 +770,7 @@ static int compat_vfp_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,
@@ -964,8 +964,8 @@ 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,
-			compat_ulong_t caddr, compat_ulong_t cdata)
+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;
 	unsigned long data = cdata;
@@ -1041,11 +1041,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#else /* !CONFIG_AARCH32_EL0 */
+long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
+			    compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	return -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
 	if (is_compat_thread(task_thread_info(task)))
 		return &user_aarch32_view;
 #endif
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 890a591..12b232a 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -417,3 +417,16 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 		tracehook_notify_resume(regs);
 	}
 }
+
+/* Some functions are needed for compat ptrace but we don't define
+   them if we don't have AARCH32 support compiled in */
+#if defined CONFIG_COMPAT && !defined CONFIG_AARCH32_EL0
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
+{
+	return -EFAULT;
+}
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+{
+	return -EFAULT;
+}
+#endif
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 7ffaddd..25dae1a 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -285,7 +285,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 50384fe..31e995b 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.
  */
@@ -102,7 +102,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 
 	return ret;
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 
 static int __init vdso_init(void)
 {
@@ -176,7 +176,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 	 * it conflicting with the vectors base.
 	 */
 	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 		if (vma->vm_start == AARCH32_VECTORS_BASE)
 			return "[vectors]";
 #endif
-- 
1.7.2.5

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

* [PATCH 04/24] ARM64:ILP32: Set kernel_long to long long so we can reuse most of the same syscalls as LP64.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:01   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Since we want time_t and some other userland types to be the same between ILP32 and LP64, we define __kernel_long_t to be long long. 

Thanks,
Andrew Pinski


Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/Kbuild             |    1 -
 arch/arm64/include/uapi/asm/posix_types.h |   12 ++++++++++++
 2 files changed, 12 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm64/include/uapi/asm/posix_types.h

diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 83f71b3..f06a9c2 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -30,7 +30,6 @@ generic-y += msgbuf.h
 generic-y += mutex.h
 generic-y += pci.h
 generic-y += poll.h
-generic-y += posix_types.h
 generic-y += preempt.h
 generic-y += resource.h
 generic-y += rwsem.h
diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
new file mode 100644
index 0000000..53b15e6
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/posix_types.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_POSIX_TYPES_H
+#define __ASM_POSIX_TYPES_H
+
+#ifndef __LP64__	/* ILP32 */
+typedef long long __kernel_long_t;
+typedef unsigned long long __kernel_ulong_t;
+#define __kernel_long_t __kernel_long_t
+#endif
+
+#include <asm-generic/posix_types.h>
+
+#endif /* __ASM_POSIX_TYPES_H */
-- 
1.7.2.5


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

* [PATCH 04/24] ARM64:ILP32: Set kernel_long to long long so we can reuse most of the same syscalls as LP64.
@ 2014-05-24  7:01   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:01 UTC (permalink / raw)
  To: linux-arm-kernel

Since we want time_t and some other userland types to be the same between ILP32 and LP64, we define __kernel_long_t to be long long. 

Thanks,
Andrew Pinski


Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/Kbuild             |    1 -
 arch/arm64/include/uapi/asm/posix_types.h |   12 ++++++++++++
 2 files changed, 12 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm64/include/uapi/asm/posix_types.h

diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 83f71b3..f06a9c2 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -30,7 +30,6 @@ generic-y += msgbuf.h
 generic-y += mutex.h
 generic-y += pci.h
 generic-y += poll.h
-generic-y += posix_types.h
 generic-y += preempt.h
 generic-y += resource.h
 generic-y += rwsem.h
diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
new file mode 100644
index 0000000..53b15e6
--- /dev/null
+++ b/arch/arm64/include/uapi/asm/posix_types.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_POSIX_TYPES_H
+#define __ASM_POSIX_TYPES_H
+
+#ifndef __LP64__	/* ILP32 */
+typedef long long __kernel_long_t;
+typedef unsigned long long __kernel_ulong_t;
+#define __kernel_long_t __kernel_long_t
+#endif
+
+#include <asm-generic/posix_types.h>
+
+#endif /* __ASM_POSIX_TYPES_H */
-- 
1.7.2.5

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

* [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

We need to say to the userland API that bits per long is 32bits for ILP32.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/uapi/asm/bitsperlong.h |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
index fce9c29..5e06c59 100644
--- a/arch/arm64/include/uapi/asm/bitsperlong.h
+++ b/arch/arm64/include/uapi/asm/bitsperlong.h
@@ -16,7 +16,12 @@
 #ifndef __ASM_BITSPERLONG_H
 #define __ASM_BITSPERLONG_H
 
-#define __BITS_PER_LONG 64
+/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
+#ifdef __LP64__
+# define __BITS_PER_LONG 64
+#else
+# define __BITS_PER_LONG 32
+#endif
 
 #include <asm-generic/bitsperlong.h>
 
-- 
1.7.2.5


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

* [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

We need to say to the userland API that bits per long is 32bits for ILP32.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/uapi/asm/bitsperlong.h |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
index fce9c29..5e06c59 100644
--- a/arch/arm64/include/uapi/asm/bitsperlong.h
+++ b/arch/arm64/include/uapi/asm/bitsperlong.h
@@ -16,7 +16,12 @@
 #ifndef __ASM_BITSPERLONG_H
 #define __ASM_BITSPERLONG_H
 
-#define __BITS_PER_LONG 64
+/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
+#ifdef __LP64__
+# define __BITS_PER_LONG 64
+#else
+# define __BITS_PER_LONG 32
+#endif
 
 #include <asm-generic/bitsperlong.h>
 
-- 
1.7.2.5

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

* [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI.
  2014-05-24  7:01 ` Andrew Pinski
  (?)
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel,
	linux-arch
  Cc: Andrew Pinski

In ARM64, we want to allow the signal related structures to be same between the 32bit (ILP32) and the 64bit ABIs (LP64).  We still want to use the generic include files so we need some new defines that are used in UAPI; they default to the same as it is before.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/siginfo.h |   17 +++++++++++++----
 include/uapi/asm-generic/signal.h  |   27 +++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index ba5be7f..553aca9 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -4,9 +4,17 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 
+#ifndef __SIGINFO_VOIDPOINTER
+#define __SIGINFO_VOIDPOINTER(field) void __user *field
+#endif
+
+#ifndef __SIGINFO_BAND
+#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field
+#endif
+
 typedef union sigval {
 	int sival_int;
-	void __user *sival_ptr;
+	__SIGINFO_VOIDPOINTER(sival_ptr);
 } sigval_t;
 
 /*
@@ -86,7 +94,7 @@ typedef struct siginfo {
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			void __user *_addr; /* faulting insn/memory ref. */
+			__SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
 #ifdef __ARCH_SI_TRAPNO
 			int _trapno;	/* TRAP # which caused the signal */
 #endif
@@ -95,13 +103,13 @@ typedef struct siginfo {
 
 		/* SIGPOLL */
 		struct {
-			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			__SIGINFO_BAND(_band);	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 
 		/* SIGSYS */
 		struct {
-			void __user *_call_addr; /* calling user insn */
+			__SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
 			int _syscall;	/* triggering system call number */
 			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
 		} _sigsys;
@@ -283,6 +291,7 @@ typedef struct sigevent {
 		int _pad[SIGEV_PAD_SIZE];
 		 int _tid;
 
+		/* Note these two are handled only in userspace */
 		struct {
 			void (*_function)(sigval_t);
 			void *_attribute;	/* really pthread_attr_t */
diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
index 9df61f1..c4ce238 100644
--- a/include/uapi/asm-generic/signal.h
+++ b/include/uapi/asm-generic/signal.h
@@ -4,7 +4,9 @@
 #include <linux/types.h>
 
 #define _NSIG		64
+#ifndef _NSIG_BPW
 #define _NSIG_BPW	__BITS_PER_LONG
+#endif
 #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
 
 #define SIGHUP		 1
@@ -83,9 +85,13 @@
 #define MINSIGSTKSZ	2048
 #define SIGSTKSZ	8192
 
+#ifndef __SIGSET_INNER_TYPE
+#define __SIGSET_INNER_TYPE unsigned long
+#endif
+
 #ifndef __ASSEMBLY__
 typedef struct {
-	unsigned long sig[_NSIG_WORDS];
+	__SIGSET_INNER_TYPE sig[_NSIG_WORDS];
 } sigset_t;
 
 /* not actually used, but required for linux/syscalls.h */
@@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t;
 #endif
 
 #ifndef __KERNEL__
+
+#ifndef __SIGACTION_HANDLER
+#define __SIGACTION_HANDLER(field)	__sighandler_t field
+#endif
+
+#ifndef __SIGACTION_FLAGS
+#define __SIGACTION_FLAGS(field)	unsigned long field
+#endif
+
+#ifndef __SIGACTION_RESTORER
+#define __SIGACTION_RESTORER(field)	__sigrestore_t field
+#endif
+
 struct sigaction {
-	__sighandler_t sa_handler;
-	unsigned long sa_flags;
+	__SIGACTION_HANDLER(sa_handler);
+	__SIGACTION_FLAGS(sa_flags);
 #ifdef SA_RESTORER
-	__sigrestore_t sa_restorer;
+	__SIGACTION_RESTORER(sa_restorer);
 #endif
 	sigset_t sa_mask;		/* mask last for extensibility */
 };
-- 
1.7.2.5


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

* [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI.
  2014-05-24  7:01 ` Andrew Pinski
                   ` (6 preceding siblings ...)
  (?)
@ 2014-05-24  7:02 ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Andrew Pinski

In ARM64, we want to allow the signal related structures to be same between the 32bit (ILP32) and the 64bit ABIs (LP64).  We still want to use the generic include files so we need some new defines that are used in UAPI; they default to the same as it is before.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/siginfo.h |   17 +++++++++++++----
 include/uapi/asm-generic/signal.h  |   27 +++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index ba5be7f..553aca9 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -4,9 +4,17 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 
+#ifndef __SIGINFO_VOIDPOINTER
+#define __SIGINFO_VOIDPOINTER(field) void __user *field
+#endif
+
+#ifndef __SIGINFO_BAND
+#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field
+#endif
+
 typedef union sigval {
 	int sival_int;
-	void __user *sival_ptr;
+	__SIGINFO_VOIDPOINTER(sival_ptr);
 } sigval_t;
 
 /*
@@ -86,7 +94,7 @@ typedef struct siginfo {
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			void __user *_addr; /* faulting insn/memory ref. */
+			__SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
 #ifdef __ARCH_SI_TRAPNO
 			int _trapno;	/* TRAP # which caused the signal */
 #endif
@@ -95,13 +103,13 @@ typedef struct siginfo {
 
 		/* SIGPOLL */
 		struct {
-			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			__SIGINFO_BAND(_band);	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 
 		/* SIGSYS */
 		struct {
-			void __user *_call_addr; /* calling user insn */
+			__SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
 			int _syscall;	/* triggering system call number */
 			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
 		} _sigsys;
@@ -283,6 +291,7 @@ typedef struct sigevent {
 		int _pad[SIGEV_PAD_SIZE];
 		 int _tid;
 
+		/* Note these two are handled only in userspace */
 		struct {
 			void (*_function)(sigval_t);
 			void *_attribute;	/* really pthread_attr_t */
diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
index 9df61f1..c4ce238 100644
--- a/include/uapi/asm-generic/signal.h
+++ b/include/uapi/asm-generic/signal.h
@@ -4,7 +4,9 @@
 #include <linux/types.h>
 
 #define _NSIG		64
+#ifndef _NSIG_BPW
 #define _NSIG_BPW	__BITS_PER_LONG
+#endif
 #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
 
 #define SIGHUP		 1
@@ -83,9 +85,13 @@
 #define MINSIGSTKSZ	2048
 #define SIGSTKSZ	8192
 
+#ifndef __SIGSET_INNER_TYPE
+#define __SIGSET_INNER_TYPE unsigned long
+#endif
+
 #ifndef __ASSEMBLY__
 typedef struct {
-	unsigned long sig[_NSIG_WORDS];
+	__SIGSET_INNER_TYPE sig[_NSIG_WORDS];
 } sigset_t;
 
 /* not actually used, but required for linux/syscalls.h */
@@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t;
 #endif
 
 #ifndef __KERNEL__
+
+#ifndef __SIGACTION_HANDLER
+#define __SIGACTION_HANDLER(field)	__sighandler_t field
+#endif
+
+#ifndef __SIGACTION_FLAGS
+#define __SIGACTION_FLAGS(field)	unsigned long field
+#endif
+
+#ifndef __SIGACTION_RESTORER
+#define __SIGACTION_RESTORER(field)	__sigrestore_t field
+#endif
+
 struct sigaction {
-	__sighandler_t sa_handler;
-	unsigned long sa_flags;
+	__SIGACTION_HANDLER(sa_handler);
+	__SIGACTION_FLAGS(sa_flags);
 #ifdef SA_RESTORER
-	__sigrestore_t sa_restorer;
+	__SIGACTION_RESTORER(sa_restorer);
 #endif
 	sigset_t sa_mask;		/* mask last for extensibility */
 };
-- 
1.7.2.5

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

* [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Andrew Pinski

In ARM64, we want to allow the signal related structures to be same between the 32bit (ILP32) and the 64bit ABIs (LP64).  We still want to use the generic include files so we need some new defines that are used in UAPI; they default to the same as it is before.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/siginfo.h |   17 +++++++++++++----
 include/uapi/asm-generic/signal.h  |   27 +++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index ba5be7f..553aca9 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -4,9 +4,17 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 
+#ifndef __SIGINFO_VOIDPOINTER
+#define __SIGINFO_VOIDPOINTER(field) void __user *field
+#endif
+
+#ifndef __SIGINFO_BAND
+#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field
+#endif
+
 typedef union sigval {
 	int sival_int;
-	void __user *sival_ptr;
+	__SIGINFO_VOIDPOINTER(sival_ptr);
 } sigval_t;
 
 /*
@@ -86,7 +94,7 @@ typedef struct siginfo {
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			void __user *_addr; /* faulting insn/memory ref. */
+			__SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
 #ifdef __ARCH_SI_TRAPNO
 			int _trapno;	/* TRAP # which caused the signal */
 #endif
@@ -95,13 +103,13 @@ typedef struct siginfo {
 
 		/* SIGPOLL */
 		struct {
-			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			__SIGINFO_BAND(_band);	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 
 		/* SIGSYS */
 		struct {
-			void __user *_call_addr; /* calling user insn */
+			__SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
 			int _syscall;	/* triggering system call number */
 			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
 		} _sigsys;
@@ -283,6 +291,7 @@ typedef struct sigevent {
 		int _pad[SIGEV_PAD_SIZE];
 		 int _tid;
 
+		/* Note these two are handled only in userspace */
 		struct {
 			void (*_function)(sigval_t);
 			void *_attribute;	/* really pthread_attr_t */
diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
index 9df61f1..c4ce238 100644
--- a/include/uapi/asm-generic/signal.h
+++ b/include/uapi/asm-generic/signal.h
@@ -4,7 +4,9 @@
 #include <linux/types.h>
 
 #define _NSIG		64
+#ifndef _NSIG_BPW
 #define _NSIG_BPW	__BITS_PER_LONG
+#endif
 #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
 
 #define SIGHUP		 1
@@ -83,9 +85,13 @@
 #define MINSIGSTKSZ	2048
 #define SIGSTKSZ	8192
 
+#ifndef __SIGSET_INNER_TYPE
+#define __SIGSET_INNER_TYPE unsigned long
+#endif
+
 #ifndef __ASSEMBLY__
 typedef struct {
-	unsigned long sig[_NSIG_WORDS];
+	__SIGSET_INNER_TYPE sig[_NSIG_WORDS];
 } sigset_t;
 
 /* not actually used, but required for linux/syscalls.h */
@@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t;
 #endif
 
 #ifndef __KERNEL__
+
+#ifndef __SIGACTION_HANDLER
+#define __SIGACTION_HANDLER(field)	__sighandler_t field
+#endif
+
+#ifndef __SIGACTION_FLAGS
+#define __SIGACTION_FLAGS(field)	unsigned long field
+#endif
+
+#ifndef __SIGACTION_RESTORER
+#define __SIGACTION_RESTORER(field)	__sigrestore_t field
+#endif
+
 struct sigaction {
-	__sighandler_t sa_handler;
-	unsigned long sa_flags;
+	__SIGACTION_HANDLER(sa_handler);
+	__SIGACTION_FLAGS(sa_flags);
 #ifdef SA_RESTORER
-	__sigrestore_t sa_restorer;
+	__SIGACTION_RESTORER(sa_restorer);
 #endif
 	sigset_t sa_mask;		/* mask last for extensibility */
 };
-- 
1.7.2.5

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

* [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

In ARM64, we want to allow the signal related structures to be same between the 32bit (ILP32) and the 64bit ABIs (LP64).  We still want to use the generic include files so we need some new defines that are used in UAPI; they default to the same as it is before.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/siginfo.h |   17 +++++++++++++----
 include/uapi/asm-generic/signal.h  |   27 +++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index ba5be7f..553aca9 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -4,9 +4,17 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 
+#ifndef __SIGINFO_VOIDPOINTER
+#define __SIGINFO_VOIDPOINTER(field) void __user *field
+#endif
+
+#ifndef __SIGINFO_BAND
+#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field
+#endif
+
 typedef union sigval {
 	int sival_int;
-	void __user *sival_ptr;
+	__SIGINFO_VOIDPOINTER(sival_ptr);
 } sigval_t;
 
 /*
@@ -86,7 +94,7 @@ typedef struct siginfo {
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			void __user *_addr; /* faulting insn/memory ref. */
+			__SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
 #ifdef __ARCH_SI_TRAPNO
 			int _trapno;	/* TRAP # which caused the signal */
 #endif
@@ -95,13 +103,13 @@ typedef struct siginfo {
 
 		/* SIGPOLL */
 		struct {
-			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			__SIGINFO_BAND(_band);	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 
 		/* SIGSYS */
 		struct {
-			void __user *_call_addr; /* calling user insn */
+			__SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
 			int _syscall;	/* triggering system call number */
 			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
 		} _sigsys;
@@ -283,6 +291,7 @@ typedef struct sigevent {
 		int _pad[SIGEV_PAD_SIZE];
 		 int _tid;
 
+		/* Note these two are handled only in userspace */
 		struct {
 			void (*_function)(sigval_t);
 			void *_attribute;	/* really pthread_attr_t */
diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
index 9df61f1..c4ce238 100644
--- a/include/uapi/asm-generic/signal.h
+++ b/include/uapi/asm-generic/signal.h
@@ -4,7 +4,9 @@
 #include <linux/types.h>
 
 #define _NSIG		64
+#ifndef _NSIG_BPW
 #define _NSIG_BPW	__BITS_PER_LONG
+#endif
 #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
 
 #define SIGHUP		 1
@@ -83,9 +85,13 @@
 #define MINSIGSTKSZ	2048
 #define SIGSTKSZ	8192
 
+#ifndef __SIGSET_INNER_TYPE
+#define __SIGSET_INNER_TYPE unsigned long
+#endif
+
 #ifndef __ASSEMBLY__
 typedef struct {
-	unsigned long sig[_NSIG_WORDS];
+	__SIGSET_INNER_TYPE sig[_NSIG_WORDS];
 } sigset_t;
 
 /* not actually used, but required for linux/syscalls.h */
@@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t;
 #endif
 
 #ifndef __KERNEL__
+
+#ifndef __SIGACTION_HANDLER
+#define __SIGACTION_HANDLER(field)	__sighandler_t field
+#endif
+
+#ifndef __SIGACTION_FLAGS
+#define __SIGACTION_FLAGS(field)	unsigned long field
+#endif
+
+#ifndef __SIGACTION_RESTORER
+#define __SIGACTION_RESTORER(field)	__sigrestore_t field
+#endif
+
 struct sigaction {
-	__sighandler_t sa_handler;
-	unsigned long sa_flags;
+	__SIGACTION_HANDLER(sa_handler);
+	__SIGACTION_FLAGS(sa_flags);
 #ifdef SA_RESTORER
-	__sigrestore_t sa_restorer;
+	__SIGACTION_RESTORER(sa_restorer);
 #endif
 	sigset_t sa_mask;		/* mask last for extensibility */
 };
-- 
1.7.2.5

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

* [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Defines the macros which allow the signal structures to be the same between ILP32 and LP64.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>

---
 arch/arm64/include/uapi/asm/siginfo.h |   21 +++++++++++++++++++++
 arch/arm64/include/uapi/asm/signal.h  |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
index 5a74a08..1a6aa32 100644
--- a/arch/arm64/include/uapi/asm/siginfo.h
+++ b/arch/arm64/include/uapi/asm/siginfo.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2014 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
@@ -18,6 +19,26 @@
 
 #define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
 
+#ifdef __ILP32__
+# ifdef __AARCH64EB__
+#  define __SIGINFO_INNER(type, field)		\
+		int __pad#field;		\
+		type field
+# else
+#  define __SIGINFO_INNER(type, field)		\
+		type field;			\
+		int __pad#field
+# endif
+
+# undef __SIGINFO_VOIDPOINTER
+# define __SIGINFO_VOIDPOINTER(field)		\
+		__SIGINFO_INNER(void __user*, field)
+# undef __SIGINFO_BAND
+
+# define __SIGINFO_BAND(field)			\
+	__SIGINFO_INNER(long, field)
+#endif
+
 #include <asm-generic/siginfo.h>
 
 #endif
diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h
index 8d1e723..d90d53b 100644
--- a/arch/arm64/include/uapi/asm/signal.h
+++ b/arch/arm64/include/uapi/asm/signal.h
@@ -19,6 +19,38 @@
 /* Required for AArch32 compatibility. */
 #define SA_RESTORER	0x04000000
 
+/* For ILP32, sigset should be the same size fields as LP64 so use
+   unsigned long long. */
+#ifdef __ILP32__
+#define __SIGSET_INNER_TYPE __extension__ unsigned long long
+#define _NSIG_BPW 64
+
+# ifdef __AARCH64EB__
+#  define __SIGNAL_INNER(type, field)		\
+	__extension__ struct {			\
+		int __pad_##field;		\
+		type field;			\
+	} __attribute__((aligned(8)))
+# else
+#  define __SIGNAL_INNER(type, field)		\
+	__extension__ struct {			\
+		type field;			\
+		int __pad_##field;		\
+	} __attribute__((aligned(8)))
+# endif
+
+# define __SIGACTION_HANDLER(field)		\
+	__SIGNAL_INNER(__sighandler_t, field)
+
+
+#define __SIGACTION_FLAGS(field)		\
+	__extension__ unsigned long long field
+
+#define __SIGACTION_RESTORER(field)		\
+	__SIGNAL_INNER(__sigrestore_t, field)
+
+#endif
+
 #include <asm-generic/signal.h>
 
 #endif
-- 
1.7.2.5


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

* [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Defines the macros which allow the signal structures to be the same between ILP32 and LP64.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>

---
 arch/arm64/include/uapi/asm/siginfo.h |   21 +++++++++++++++++++++
 arch/arm64/include/uapi/asm/signal.h  |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
index 5a74a08..1a6aa32 100644
--- a/arch/arm64/include/uapi/asm/siginfo.h
+++ b/arch/arm64/include/uapi/asm/siginfo.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2014 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
@@ -18,6 +19,26 @@
 
 #define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
 
+#ifdef __ILP32__
+# ifdef __AARCH64EB__
+#  define __SIGINFO_INNER(type, field)		\
+		int __pad#field;		\
+		type field
+# else
+#  define __SIGINFO_INNER(type, field)		\
+		type field;			\
+		int __pad#field
+# endif
+
+# undef __SIGINFO_VOIDPOINTER
+# define __SIGINFO_VOIDPOINTER(field)		\
+		__SIGINFO_INNER(void __user*, field)
+# undef __SIGINFO_BAND
+
+# define __SIGINFO_BAND(field)			\
+	__SIGINFO_INNER(long, field)
+#endif
+
 #include <asm-generic/siginfo.h>
 
 #endif
diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h
index 8d1e723..d90d53b 100644
--- a/arch/arm64/include/uapi/asm/signal.h
+++ b/arch/arm64/include/uapi/asm/signal.h
@@ -19,6 +19,38 @@
 /* Required for AArch32 compatibility. */
 #define SA_RESTORER	0x04000000
 
+/* For ILP32, sigset should be the same size fields as LP64 so use
+   unsigned long long. */
+#ifdef __ILP32__
+#define __SIGSET_INNER_TYPE __extension__ unsigned long long
+#define _NSIG_BPW 64
+
+# ifdef __AARCH64EB__
+#  define __SIGNAL_INNER(type, field)		\
+	__extension__ struct {			\
+		int __pad_##field;		\
+		type field;			\
+	} __attribute__((aligned(8)))
+# else
+#  define __SIGNAL_INNER(type, field)		\
+	__extension__ struct {			\
+		type field;			\
+		int __pad_##field;		\
+	} __attribute__((aligned(8)))
+# endif
+
+# define __SIGACTION_HANDLER(field)		\
+	__SIGNAL_INNER(__sighandler_t, field)
+
+
+#define __SIGACTION_FLAGS(field)		\
+	__extension__ unsigned long long field
+
+#define __SIGACTION_RESTORER(field)		\
+	__SIGNAL_INNER(__sigrestore_t, field)
+
+#endif
+
 #include <asm-generic/signal.h>
 
 #endif
-- 
1.7.2.5

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

* [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
  2014-05-24  7:01 ` Andrew Pinski
  (?)
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel,
	linux-arch
  Cc: Andrew Pinski

In the ARM64 ILP32 case, we want to say the syscalls that normally would pass 64bit as two arguments are now passing as one so want to use the 64bit naming scheme.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/unistd.h |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3336406..0648659 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
  * they take different names.
  * Here we map the numbers so that both versions
  * use the same syscall table layout.
+ * For 32bit abis where 64bit can be passed via one
+ * register, use the same naming as the 64bit ones
+ * as they will only have a 64 bit off_t.
  */
-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
+#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
 #define __NR_fcntl __NR3264_fcntl
 #define __NR_statfs __NR3264_statfs
 #define __NR_fstatfs __NR3264_fstatfs
-- 
1.7.2.5


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

* [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
  2014-05-24  7:01 ` Andrew Pinski
                   ` (8 preceding siblings ...)
  (?)
@ 2014-05-24  7:02 ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Andrew Pinski

In the ARM64 ILP32 case, we want to say the syscalls that normally would pass 64bit as two arguments are now passing as one so want to use the 64bit naming scheme.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/unistd.h |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3336406..0648659 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
  * they take different names.
  * Here we map the numbers so that both versions
  * use the same syscall table layout.
+ * For 32bit abis where 64bit can be passed via one
+ * register, use the same naming as the 64bit ones
+ * as they will only have a 64 bit off_t.
  */
-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
+#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
 #define __NR_fcntl __NR3264_fcntl
 #define __NR_statfs __NR3264_statfs
 #define __NR_fstatfs __NR3264_fstatfs
-- 
1.7.2.5

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

* [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Andrew Pinski

In the ARM64 ILP32 case, we want to say the syscalls that normally would pass 64bit as two arguments are now passing as one so want to use the 64bit naming scheme.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/unistd.h |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3336406..0648659 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
  * they take different names.
  * Here we map the numbers so that both versions
  * use the same syscall table layout.
+ * For 32bit abis where 64bit can be passed via one
+ * register, use the same naming as the 64bit ones
+ * as they will only have a 64 bit off_t.
  */
-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
+#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
 #define __NR_fcntl __NR3264_fcntl
 #define __NR_statfs __NR3264_statfs
 #define __NR_fstatfs __NR3264_fstatfs
-- 
1.7.2.5

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

* [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

In the ARM64 ILP32 case, we want to say the syscalls that normally would pass 64bit as two arguments are now passing as one so want to use the 64bit naming scheme.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/uapi/asm-generic/unistd.h |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 3336406..0648659 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
  * they take different names.
  * Here we map the numbers so that both versions
  * use the same syscall table layout.
+ * For 32bit abis where 64bit can be passed via one
+ * register, use the same naming as the 64bit ones
+ * as they will only have a 64 bit off_t.
  */
-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
+#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
 #define __NR_fcntl __NR3264_fcntl
 #define __NR_statfs __NR3264_statfs
 #define __NR_fstatfs __NR3264_fstatfs
-- 
1.7.2.5

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

* [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Define __SYSCALL_NONCOMPAT so we use the 64bit naming scheme for ILP32.

Signed-off-by: Andrew Pinski <apinski@cavium.com>

---
 arch/arm64/include/uapi/asm/unistd.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
index 1caadc2..067eab0 100644
--- a/arch/arm64/include/uapi/asm/unistd.h
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2014 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
@@ -13,4 +14,10 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+
+/* For ILP32 AARCH64, we want to use the non compat names. */
+#if defined(__aarch64__) && defined(__ILP32__)
+#define __SYSCALL_NONCOMPAT
+#endif
+
 #include <asm-generic/unistd.h>
-- 
1.7.2.5


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

* [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Define __SYSCALL_NONCOMPAT so we use the 64bit naming scheme for ILP32.

Signed-off-by: Andrew Pinski <apinski@cavium.com>

---
 arch/arm64/include/uapi/asm/unistd.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
index 1caadc2..067eab0 100644
--- a/arch/arm64/include/uapi/asm/unistd.h
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2014 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
@@ -13,4 +14,10 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+
+/* For ILP32 AARCH64, we want to use the non compat names. */
+#if defined(__aarch64__) && defined(__ILP32__)
+#define __SYSCALL_NONCOMPAT
+#endif
+
 #include <asm-generic/unistd.h>
-- 
1.7.2.5

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

* [PATCH 10/24] ARM64: Introduce is_a32_task and is_a32_thread. Use them in the correct locations.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: 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.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h      |   31 +++++++++++++++++++++++++------
 arch/arm64/include/asm/elf.h         |    2 +-
 arch/arm64/include/asm/memory.h      |    2 +-
 arch/arm64/include/asm/processor.h   |    2 +-
 arch/arm64/include/asm/thread_info.h |    2 +-
 arch/arm64/kernel/hw_breakpoint.c    |    6 +++---
 arch/arm64/kernel/process.c          |    6 +++---
 arch/arm64/kernel/ptrace.c           |   10 +++++-----
 arch/arm64/kernel/signal.c           |    4 ++--
 arch/arm64/kernel/traps.c            |    2 +-
 10 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index e71f81f..fad7612 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -293,28 +293,47 @@ struct compat_shmid64_ds {
 	compat_ulong_t __unused5;
 };
 
-static inline int is_compat_task(void)
+#ifdef CONFIG_AARCH32_EL0
+static inline int is_a32_compat_task(void)
 {
 	return test_thread_flag(TIF_32BIT);
 }
-
-static inline int is_compat_thread(struct thread_info *thread)
+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
 
 #else /* !CONFIG_COMPAT */
 
-static inline int is_compat_task(void)
+static inline int is_a32_compat_task(void)
 {
 	return 0;
 }
-
-static inline int is_compat_thread(struct thread_info *thread)
+static inline int is_a32_compat_thread(struct thread_info *thread)
 {
 	return 0;
 }
 
 #endif /* CONFIG_COMPAT */
+
+static inline int is_compat_task(void)
+{
+	return is_a32_compat_task();
+}
+
+static inline int is_compat_thread(struct thread_info *thread)
+{
+	return is_a32_compat_thread(thread);
+}
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 36c3603..8180511 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -150,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/memory.h b/arch/arm64/include/asm/memory.h
index 993bce5..2ab203e 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -54,7 +54,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)
 #else
 #define TASK_SIZE		TASK_SIZE_64
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 45b20cd..ee487f3 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -38,7 +38,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
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 720e70b..b2bf728 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -106,7 +106,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 bee7897..87aa8c1 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -433,7 +433,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;
@@ -490,7 +490,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
@@ -677,7 +677,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/process.c b/arch/arm64/kernel/process.c
index 6391485..fa0117f 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -223,7 +223,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 	if (likely(!(p->flags & PF_KTHREAD))) {
 		*childregs = *current_pt_regs();
 		childregs->regs[0] = 0;
-		if (is_compat_thread(task_thread_info(p))) {
+		if (is_a32_compat_thread(task_thread_info(p))) {
 			if (stack_start)
 				childregs->compat_sp = stack_start;
 		} else {
@@ -264,12 +264,12 @@ static void tls_thread_switch(struct task_struct *next)
 {
 	unsigned long tpidr, tpidrro;
 
-	if (!is_compat_task()) {
+	if (!is_a32_compat_task()) {
 		asm("mrs %0, tpidr_el0" : "=r" (tpidr));
 		current->thread.tp_value = tpidr;
 	}
 
-	if (is_compat_thread(task_thread_info(next))) {
+	if (is_a32_compat_thread(task_thread_info(next))) {
 		tpidr = 0;
 		tpidrro = next->thread.tp_value;
 	} else {
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 67a0f4d..7fb1377 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -72,7 +72,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) {
@@ -1053,7 +1053,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);
 }
@@ -1063,7 +1063,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
 #ifdef CONFIG_AARCH32_EL0
-	if (is_compat_thread(task_thread_info(task)))
+	if (is_a32_compat_thread(task_thread_info(task)))
 		return &user_aarch32_view;
 #endif
 	return &user_aarch64_view;
@@ -1082,7 +1082,7 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		return regs->syscallno;
 
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		/* AArch32 uses ip (r12) for scratch */
 		saved_reg = regs->regs[12];
 		regs->regs[12] = dir;
@@ -1100,7 +1100,7 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
 	else if (tracehook_report_syscall_entry(regs))
 		regs->syscallno = ~0UL;
 
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		regs->regs[12] = saved_reg;
 	else
 		regs->regs[7] = saved_reg;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 12b232a..8168613 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -268,7 +268,7 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
 
 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(unsigned long sig, struct k_sigaction *ka,
 	/*
 	 * Set up the stack frame
 	 */
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		if (ka->sa.sa_flags & SA_SIGINFO)
 			ret = compat_setup_rt_frame(usig, ka, info, oldset,
 						    regs);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 25dae1a..5b1e40a 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -287,7 +287,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;
-- 
1.7.2.5


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

* [PATCH 10/24] ARM64: Introduce is_a32_task and is_a32_thread. Use them in the correct locations.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h      |   31 +++++++++++++++++++++++++------
 arch/arm64/include/asm/elf.h         |    2 +-
 arch/arm64/include/asm/memory.h      |    2 +-
 arch/arm64/include/asm/processor.h   |    2 +-
 arch/arm64/include/asm/thread_info.h |    2 +-
 arch/arm64/kernel/hw_breakpoint.c    |    6 +++---
 arch/arm64/kernel/process.c          |    6 +++---
 arch/arm64/kernel/ptrace.c           |   10 +++++-----
 arch/arm64/kernel/signal.c           |    4 ++--
 arch/arm64/kernel/traps.c            |    2 +-
 10 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index e71f81f..fad7612 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -293,28 +293,47 @@ struct compat_shmid64_ds {
 	compat_ulong_t __unused5;
 };
 
-static inline int is_compat_task(void)
+#ifdef CONFIG_AARCH32_EL0
+static inline int is_a32_compat_task(void)
 {
 	return test_thread_flag(TIF_32BIT);
 }
-
-static inline int is_compat_thread(struct thread_info *thread)
+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
 
 #else /* !CONFIG_COMPAT */
 
-static inline int is_compat_task(void)
+static inline int is_a32_compat_task(void)
 {
 	return 0;
 }
-
-static inline int is_compat_thread(struct thread_info *thread)
+static inline int is_a32_compat_thread(struct thread_info *thread)
 {
 	return 0;
 }
 
 #endif /* CONFIG_COMPAT */
+
+static inline int is_compat_task(void)
+{
+	return is_a32_compat_task();
+}
+
+static inline int is_compat_thread(struct thread_info *thread)
+{
+	return is_a32_compat_thread(thread);
+}
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 36c3603..8180511 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -150,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/memory.h b/arch/arm64/include/asm/memory.h
index 993bce5..2ab203e 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -54,7 +54,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)
 #else
 #define TASK_SIZE		TASK_SIZE_64
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 45b20cd..ee487f3 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -38,7 +38,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
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 720e70b..b2bf728 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -106,7 +106,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 bee7897..87aa8c1 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -433,7 +433,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;
@@ -490,7 +490,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
@@ -677,7 +677,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/process.c b/arch/arm64/kernel/process.c
index 6391485..fa0117f 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -223,7 +223,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 	if (likely(!(p->flags & PF_KTHREAD))) {
 		*childregs = *current_pt_regs();
 		childregs->regs[0] = 0;
-		if (is_compat_thread(task_thread_info(p))) {
+		if (is_a32_compat_thread(task_thread_info(p))) {
 			if (stack_start)
 				childregs->compat_sp = stack_start;
 		} else {
@@ -264,12 +264,12 @@ static void tls_thread_switch(struct task_struct *next)
 {
 	unsigned long tpidr, tpidrro;
 
-	if (!is_compat_task()) {
+	if (!is_a32_compat_task()) {
 		asm("mrs %0, tpidr_el0" : "=r" (tpidr));
 		current->thread.tp_value = tpidr;
 	}
 
-	if (is_compat_thread(task_thread_info(next))) {
+	if (is_a32_compat_thread(task_thread_info(next))) {
 		tpidr = 0;
 		tpidrro = next->thread.tp_value;
 	} else {
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 67a0f4d..7fb1377 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -72,7 +72,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) {
@@ -1053,7 +1053,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);
 }
@@ -1063,7 +1063,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
 #ifdef CONFIG_AARCH32_EL0
-	if (is_compat_thread(task_thread_info(task)))
+	if (is_a32_compat_thread(task_thread_info(task)))
 		return &user_aarch32_view;
 #endif
 	return &user_aarch64_view;
@@ -1082,7 +1082,7 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		return regs->syscallno;
 
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		/* AArch32 uses ip (r12) for scratch */
 		saved_reg = regs->regs[12];
 		regs->regs[12] = dir;
@@ -1100,7 +1100,7 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
 	else if (tracehook_report_syscall_entry(regs))
 		regs->syscallno = ~0UL;
 
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		regs->regs[12] = saved_reg;
 	else
 		regs->regs[7] = saved_reg;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 12b232a..8168613 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -268,7 +268,7 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
 
 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(unsigned long sig, struct k_sigaction *ka,
 	/*
 	 * Set up the stack frame
 	 */
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		if (ka->sa.sa_flags & SA_SIGINFO)
 			ret = compat_setup_rt_frame(usig, ka, info, oldset,
 						    regs);
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 25dae1a..5b1e40a 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -287,7 +287,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;
-- 
1.7.2.5

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

* [PATCH 11/24] ARM64: Add ARM64_ILP32 to Kconfig.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

This patch adds the config option for ILP32.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/Kconfig |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 032c712..92577da 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -288,7 +288,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
@@ -305,6 +305,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 AARCH32_EL0 && SYSVIPC
-- 
1.7.2.5


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

* [PATCH 11/24] ARM64: Add ARM64_ILP32 to Kconfig.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the config option for ILP32.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/Kconfig |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 032c712..92577da 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -288,7 +288,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
@@ -305,6 +305,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 AARCH32_EL0 && SYSVIPC
-- 
1.7.2.5

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

* [PATCH 12/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and TIF_32BIT_AARCH64.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

This patch adds the thread bit for ILP32 and has is_compat_task return true in that case.  We don't set it yet though.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h      |   32 ++++++++++++++++++++++++++++++--
 arch/arm64/include/asm/thread_info.h |    1 +
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fad7612..85f945c 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -313,6 +313,26 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 }
 #endif
 
+#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
+
 #else /* !CONFIG_COMPAT */
 
 static inline int is_a32_compat_task(void)
@@ -323,17 +343,25 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 {
 	return 0;
 }
+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_COMPAT */
 
 static inline int is_compat_task(void)
 {
-	return is_a32_compat_task();
+	return is_a32_compat_task() || is_ilp32_compat_task();
 }
 
 static inline int is_compat_thread(struct thread_info *thread)
 {
-	return is_a32_compat_thread(thread);
+	return is_a32_compat_thread(thread) || is_ilp32_compat_thread(thread);
 }
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index b2bf728..98baf65 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -108,6 +108,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)
-- 
1.7.2.5


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

* [PATCH 12/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and TIF_32BIT_AARCH64.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the thread bit for ILP32 and has is_compat_task return true in that case.  We don't set it yet though.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h      |   32 ++++++++++++++++++++++++++++++--
 arch/arm64/include/asm/thread_info.h |    1 +
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fad7612..85f945c 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -313,6 +313,26 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 }
 #endif
 
+#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
+
 #else /* !CONFIG_COMPAT */
 
 static inline int is_a32_compat_task(void)
@@ -323,17 +343,25 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
 {
 	return 0;
 }
+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_COMPAT */
 
 static inline int is_compat_task(void)
 {
-	return is_a32_compat_task();
+	return is_a32_compat_task() || is_ilp32_compat_task();
 }
 
 static inline int is_compat_thread(struct thread_info *thread)
 {
-	return is_a32_compat_thread(thread);
+	return is_a32_compat_thread(thread) || is_ilp32_compat_thread(thread);
 }
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index b2bf728..98baf65 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -108,6 +108,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)
-- 
1.7.2.5

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

* [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also.
  2014-05-24  7:01 ` Andrew Pinski
  (?)
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel,
	linux-input
  Cc: Andrew Pinski

Since TIF_32BIT in ARM64 (with ILP32 added) is not always says if this is a compat task, we need to have the input driver understand that and use is_compat_task instead.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 drivers/input/input-compat.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 148f66f..6656957 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -19,7 +19,7 @@
 
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
-#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
+#if defined(CONFIG_X86_64) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
 #  define INPUT_COMPAT_TEST is_compat_task()
 #elif defined(CONFIG_S390)
 #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
-- 
1.7.2.5


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

* [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also.
  2014-05-24  7:01 ` Andrew Pinski
                   ` (15 preceding siblings ...)
  (?)
@ 2014-05-24  7:02 ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Andrew Pinski

Since TIF_32BIT in ARM64 (with ILP32 added) is not always says if this is a compat task, we need to have the input driver understand that and use is_compat_task instead.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 drivers/input/input-compat.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 148f66f..6656957 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -19,7 +19,7 @@
 
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
-#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
+#if defined(CONFIG_X86_64) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
 #  define INPUT_COMPAT_TEST is_compat_task()
 #elif defined(CONFIG_S390)
 #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
-- 
1.7.2.5

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

* [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel; +Cc: Andrew Pinski

Since TIF_32BIT in ARM64 (with ILP32 added) is not always says if this is a compat task, we need to have the input driver understand that and use is_compat_task instead.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 drivers/input/input-compat.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 148f66f..6656957 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -19,7 +19,7 @@
 
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
-#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
+#if defined(CONFIG_X86_64) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
 #  define INPUT_COMPAT_TEST is_compat_task()
 #elif defined(CONFIG_S390)
 #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
-- 
1.7.2.5

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

* [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Since TIF_32BIT in ARM64 (with ILP32 added) is not always says if this is a compat task, we need to have the input driver understand that and use is_compat_task instead.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 drivers/input/input-compat.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 148f66f..6656957 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -19,7 +19,7 @@
 
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
-#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
+#if defined(CONFIG_X86_64) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
 #  define INPUT_COMPAT_TEST is_compat_task()
 #elif defined(CONFIG_S390)
 #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
-- 
1.7.2.5

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

* [PATCH 14/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Since __kernel_long_t (time_t) is long long, we need to tell the rest of kernel that we use 64bit time_t for compat when the task is not an AARCH32 task.  The reason why we check AARCH32 rather than ILP32 here is because if we don't have AARCH32 compiled in (which is going to be the common case due to AARCH32 requiring 4k pages).

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 85f945c..c77fc0f 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -76,6 +76,9 @@ struct compat_timeval {
 	s32		tv_usec;
 };
 
+/* ILP32 uses 64bit time_t and not the above compat structures */
+#define COMPAT_USE_64BIT_TIME !is_a32_compat_task()
+
 struct compat_stat {
 #ifdef __AARCH64EB__
 	short		st_dev;
-- 
1.7.2.5


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

* [PATCH 14/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Since __kernel_long_t (time_t) is long long, we need to tell the rest of kernel that we use 64bit time_t for compat when the task is not an AARCH32 task.  The reason why we check AARCH32 rather than ILP32 here is because if we don't have AARCH32 compiled in (which is going to be the common case due to AARCH32 requiring 4k pages).

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 85f945c..c77fc0f 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -76,6 +76,9 @@ struct compat_timeval {
 	s32		tv_usec;
 };
 
+/* ILP32 uses 64bit time_t and not the above compat structures */
+#define COMPAT_USE_64BIT_TIME !is_a32_compat_task()
+
 struct compat_stat {
 #ifdef __AARCH64EB__
 	short		st_dev;
-- 
1.7.2.5

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

* [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/hwcap.h |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 024c461..cb87f91 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -46,9 +46,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;
-- 
1.7.2.5


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

* [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/hwcap.h |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 024c461..cb87f91 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -46,9 +46,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;
-- 
1.7.2.5

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

* [PATCH 16/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

If we have both ILP32 and AARCH32 compiled in, we need use the non compat start thread for ILP32.  We have to use TIF_32BIT_AARCH64 explicit due to header depency issues.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index ee487f3..c61deaf 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -103,6 +103,15 @@ 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 thread are started the same way as LP64 threads.
+	   Note we cannot use is_ilp32_compat_task here as that
+	   would introduce a header depency issue.  */
+	if (test_thread_flag(TIF_32BIT_AARCH64)) {
+		start_thread(regs, pc, sp);
+		return;
+	}
+#endif
 	start_thread_common(regs, pc);
 	regs->pstate = COMPAT_PSR_MODE_USR;
 	if (pc & 1)
-- 
1.7.2.5


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

* [PATCH 16/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

If we have both ILP32 and AARCH32 compiled in, we need use the non compat start thread for ILP32.  We have to use TIF_32BIT_AARCH64 explicit due to header depency issues.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index ee487f3..c61deaf 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -103,6 +103,15 @@ 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 thread are started the same way as LP64 threads.
+	   Note we cannot use is_ilp32_compat_task here as that
+	   would introduce a header depency issue.  */
+	if (test_thread_flag(TIF_32BIT_AARCH64)) {
+		start_thread(regs, pc, sp);
+		return;
+	}
+#endif
 	start_thread_common(regs, pc);
 	regs->pstate = COMPAT_PSR_MODE_USR;
 	if (pc & 1)
-- 
1.7.2.5

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

* [PATCH 17/24] ARM64:ILP32: Support core dump for ILP32.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

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

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/elf.h |   22 ++++++++++++++++++++--
 arch/arm64/kernel/ptrace.c   |   12 ++++++------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 8180511..4106386 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -176,8 +176,8 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 
 /* 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
@@ -204,6 +204,24 @@ typedef elf_gregset_t			compat_elf_gregset_t;
 
 #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;
+#define PR_REG_SIZE(S)			(is_a32_compat_task() ? 72 : 272)
+#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
+
 #define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
 
 #endif /* CONFIG_COMPAT */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 7fb1377..7890f95 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -771,8 +771,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
 	},
@@ -805,7 +805,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);
@@ -825,7 +825,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;
 
 	ret = copy_regset_from_user(tsk, &user_aarch32_view,
@@ -985,7 +985,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;
 
@@ -993,7 +993,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;
 
-- 
1.7.2.5


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

* [PATCH 17/24] ARM64:ILP32: Support core dump for ILP32.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

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

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/elf.h |   22 ++++++++++++++++++++--
 arch/arm64/kernel/ptrace.c   |   12 ++++++------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 8180511..4106386 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -176,8 +176,8 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 
 /* 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
@@ -204,6 +204,24 @@ typedef elf_gregset_t			compat_elf_gregset_t;
 
 #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;
+#define PR_REG_SIZE(S)			(is_a32_compat_task() ? 72 : 272)
+#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
+
 #define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
 
 #endif /* CONFIG_COMPAT */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 7fb1377..7890f95 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -771,8 +771,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
 	},
@@ -805,7 +805,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);
@@ -825,7 +825,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;
 
 	ret = copy_regset_from_user(tsk, &user_aarch32_view,
@@ -985,7 +985,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;
 
@@ -993,7 +993,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;
 
-- 
1.7.2.5

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

* [PATCH 18/24] ARM64: Add loading of ILP32 binaries.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

This patch adds loading of the ILP32 binary, we set/clear the TIF_32BIT_AARCH64 for each personality.  We also use the non-compat DLINFO and setup_additional_pages as ILP32 uses a vdso just like LP64.

After this patch the kernel can load and execute simple programs including a "Hello World" with shard libraries.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/elf.h |   66 +++++++++++++++++++++++++++++++++++------
 1 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 4106386..3f979b5 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -135,7 +135,11 @@ extern unsigned long randomize_et_dyn(unsigned long base);
  */
 #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 {									\
@@ -185,25 +189,28 @@ typedef compat_a32_elf_greg_t		compat_a32_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
+#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)
 
 
 extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 				      int uses_interp);
-#define compat_arch_setup_additional_pages \
-					aarch32_setup_vectors_page
 
 #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_SET_PERSONALITY(ex)
-#define COMPAT_ARCH_DLINFO
-
+#define COMPAT_A32_SET_PERSONALITY(ex)	do {} while (0)
+#define COMPAT_A32_ARCH_DLINFO		do {} while (0)
+#define aarch32_setup_vectors_page(x, y) -EINVAL
 #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
@@ -222,7 +229,46 @@ typedef compat_a32_elf_greg_t compat_elf_greg_t;
 typedef compat_a32_elf_gregset_t compat_elf_gregset_t;
 #endif
 
-#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
+#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) || 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 */
 
-- 
1.7.2.5


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

* [PATCH 18/24] ARM64: Add loading of ILP32 binaries.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds loading of the ILP32 binary, we set/clear the TIF_32BIT_AARCH64 for each personality.  We also use the non-compat DLINFO and setup_additional_pages as ILP32 uses a vdso just like LP64.

After this patch the kernel can load and execute simple programs including a "Hello World" with shard libraries.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/elf.h |   66 +++++++++++++++++++++++++++++++++++------
 1 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 4106386..3f979b5 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -135,7 +135,11 @@ extern unsigned long randomize_et_dyn(unsigned long base);
  */
 #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 {									\
@@ -185,25 +189,28 @@ typedef compat_a32_elf_greg_t		compat_a32_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
+#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)
 
 
 extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 				      int uses_interp);
-#define compat_arch_setup_additional_pages \
-					aarch32_setup_vectors_page
 
 #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_SET_PERSONALITY(ex)
-#define COMPAT_ARCH_DLINFO
-
+#define COMPAT_A32_SET_PERSONALITY(ex)	do {} while (0)
+#define COMPAT_A32_ARCH_DLINFO		do {} while (0)
+#define aarch32_setup_vectors_page(x, y) -EINVAL
 #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
@@ -222,7 +229,46 @@ typedef compat_a32_elf_greg_t compat_elf_greg_t;
 typedef compat_a32_elf_gregset_t compat_elf_gregset_t;
 #endif
 
-#define compat_elf_check_arch(x)	compat_a32_elf_check_arch(x)
+#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) || 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 */
 
-- 
1.7.2.5

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

* [PATCH 19/24] ARM64: Add vdso for ILP32 and use it for the signal return.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

This patch adds the VDSO for ILP32. We need to use a different VDSO than LP64 since ILP32 uses ELF32 while LP64 uses ELF64.

After this patch, signal handling works mostly.  In that signals go through their action and then returned correctly.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/vdso.h                 |    4 +
 arch/arm64/kernel/Makefile                    |    5 +
 arch/arm64/kernel/signal.c                    |    4 +
 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 |  100 +++++++++++++++++++++++++
 arch/arm64/kernel/vdso.c                      |   53 +++++++++++--
 8 files changed, 266 insertions(+), 7 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 00c0da4..986962d 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,6 +24,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.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
@@ -31,3 +32,7 @@ extra-y					:= $(head-y) vmlinux.lds
 # vDSO - this must be built first to generate the symbol offsets
 $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
 $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
+
+# vDSO - this must be built first to generate the symbol offsets
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
+$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 8168613..fd49b58 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -233,6 +233,10 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 
 	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);
 
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..345d816
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -0,0 +1,100 @@
+/*
+ * 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>
+
+/*OUTPUT_FORMAT("elf32-littleaarch64", "elf32-bigaarch64", "elf32-littleaarch64")
+OUTPUT_ARCH(aarch64)
+*/
+SECTIONS
+{
+	. = 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 = .);
+
+	. = ALIGN(PAGE_SIZE);
+	PROVIDE(_vdso_data = .);
+
+	/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.39 {
+	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 31e995b..fee8964 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.
  */
@@ -104,45 +110,78 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 }
 #endif /* CONFIG_AARCH32_EL0 */
 
-static int __init vdso_init(void)
+static inline int __init vdso_init_common(char *vdso_start, char *vdso_end,
+					  unsigned long *vdso_pagesp,
+					  struct page ***vdso_pagelistp)
 {
 	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, %ld data) at base %p\n",
-		vdso_pages + 1, vdso_pages, 1L, &vdso_start);
+		vdso_pages + 1, vdso_pages, 1L, vdso_start);
 
 	/* 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;
 
 	/* Grab the vDSO code pages. */
 	for (i = 0; i < vdso_pages; i++)
-		vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		vdso_pagelist[i] = virt_to_page(vdso_start + i * PAGE_SIZE);
 
 	/* Grab the vDSO data page. */
 	vdso_pagelist[i] = virt_to_page(vdso_data);
 
 	return 0;
 }
+
+static int __init vdso_init(void)
+{
+	return vdso_init_common(&vdso_start, &vdso_end,
+				&vdso_pages, &vdso_pagelist);
+}
 arch_initcall(vdso_init);
 
+#ifdef CONFIG_ARM64_ILP32
+static int __init vdso_ilp32_init(void)
+{
+	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
+				&vdso_ilp32_pages, &vdso_ilp32_pagelist);
+}
+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_mapping_len;
 	int ret;
+	struct page **pagelist;
+	unsigned long pages;
 
 	/* Be sure to map the data page */
-	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
+#ifdef CONFIG_ARM64_ILP32
+	if (is_ilp32_compat_task()) {
+		pages = vdso_ilp32_pages;
+		pagelist = vdso_ilp32_pagelist;
+	} else
+#endif
+	{
+		pages = vdso_pages;
+		pagelist = vdso_pagelist;
+	}
+	vdso_mapping_len = (pages + 1) << PAGE_SHIFT;
 
 	down_write(&mm->mmap_sem);
 	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
@@ -155,7 +194,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
 				      VM_READ|VM_EXEC|
 				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				      vdso_pagelist);
+				      pagelist);
 	if (ret) {
 		mm->context.vdso = NULL;
 		goto up_fail;
-- 
1.7.2.5


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

* [PATCH 19/24] ARM64: Add vdso for ILP32 and use it for the signal return.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds the VDSO for ILP32. We need to use a different VDSO than LP64 since ILP32 uses ELF32 while LP64 uses ELF64.

After this patch, signal handling works mostly.  In that signals go through their action and then returned correctly.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/vdso.h                 |    4 +
 arch/arm64/kernel/Makefile                    |    5 +
 arch/arm64/kernel/signal.c                    |    4 +
 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 |  100 +++++++++++++++++++++++++
 arch/arm64/kernel/vdso.c                      |   53 +++++++++++--
 8 files changed, 266 insertions(+), 7 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 00c0da4..986962d 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,6 +24,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.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
@@ -31,3 +32,7 @@ extra-y					:= $(head-y) vmlinux.lds
 # vDSO - this must be built first to generate the symbol offsets
 $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
 $(obj)/vdso/vdso-offsets.h: $(obj)/vdso
+
+# vDSO - this must be built first to generate the symbol offsets
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
+$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 8168613..fd49b58 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -233,6 +233,10 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 
 	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);
 
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..345d816
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -0,0 +1,100 @@
+/*
+ * 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>
+
+/*OUTPUT_FORMAT("elf32-littleaarch64", "elf32-bigaarch64", "elf32-littleaarch64")
+OUTPUT_ARCH(aarch64)
+*/
+SECTIONS
+{
+	. = 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 = .);
+
+	. = ALIGN(PAGE_SIZE);
+	PROVIDE(_vdso_data = .);
+
+	/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.39 {
+	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 31e995b..fee8964 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.
  */
@@ -104,45 +110,78 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 }
 #endif /* CONFIG_AARCH32_EL0 */
 
-static int __init vdso_init(void)
+static inline int __init vdso_init_common(char *vdso_start, char *vdso_end,
+					  unsigned long *vdso_pagesp,
+					  struct page ***vdso_pagelistp)
 {
 	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, %ld data) at base %p\n",
-		vdso_pages + 1, vdso_pages, 1L, &vdso_start);
+		vdso_pages + 1, vdso_pages, 1L, vdso_start);
 
 	/* 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;
 
 	/* Grab the vDSO code pages. */
 	for (i = 0; i < vdso_pages; i++)
-		vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		vdso_pagelist[i] = virt_to_page(vdso_start + i * PAGE_SIZE);
 
 	/* Grab the vDSO data page. */
 	vdso_pagelist[i] = virt_to_page(vdso_data);
 
 	return 0;
 }
+
+static int __init vdso_init(void)
+{
+	return vdso_init_common(&vdso_start, &vdso_end,
+				&vdso_pages, &vdso_pagelist);
+}
 arch_initcall(vdso_init);
 
+#ifdef CONFIG_ARM64_ILP32
+static int __init vdso_ilp32_init(void)
+{
+	return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
+				&vdso_ilp32_pages, &vdso_ilp32_pagelist);
+}
+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_mapping_len;
 	int ret;
+	struct page **pagelist;
+	unsigned long pages;
 
 	/* Be sure to map the data page */
-	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
+#ifdef CONFIG_ARM64_ILP32
+	if (is_ilp32_compat_task()) {
+		pages = vdso_ilp32_pages;
+		pagelist = vdso_ilp32_pagelist;
+	} else
+#endif
+	{
+		pages = vdso_pages;
+		pagelist = vdso_pagelist;
+	}
+	vdso_mapping_len = (pages + 1) << PAGE_SHIFT;
 
 	down_write(&mm->mmap_sem);
 	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
@@ -155,7 +194,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
 				      VM_READ|VM_EXEC|
 				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				      vdso_pagelist);
+				      pagelist);
 	if (ret) {
 		mm->context.vdso = NULL;
 		goto up_fail;
-- 
1.7.2.5

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

* [PATCH 20/24] ptrace: Allow compat to use the native siginfo.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel,
	Roland McGrath, Oleg Nesterov
  Cc: Andrew Pinski

With ARM64 ILP32 ABI, we want to use the non-compat siginfo as we want to simplify signal handling for this new ABI.  This patch just adds a new define COMPAT_USE_NATIVE_SIGINFO and if it is true then read/write in the compat case as it was the non-compat case.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/linux/compat.h |    4 ++++
 kernel/ptrace.c        |   24 +++++++++++++++++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index e649426..2d8c535 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -24,6 +24,10 @@
 #define COMPAT_USE_64BIT_TIME 0
 #endif
 
+#ifndef COMPAT_USE_NATIVE_SIGINFO
+#define COMPAT_USE_NATIVE_SIGINFO 0
+#endif
+
 #ifndef __SC_DELOUSE
 #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v))
 #endif
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index adf9862..5f8bb5c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -663,7 +663,7 @@ static int ptrace_peek_siginfo(struct task_struct *child,
 			break;
 
 #ifdef CONFIG_COMPAT
-		if (unlikely(is_compat_task())) {
+		if (unlikely(is_compat_task() && !COMPAT_USE_NATIVE_SIGINFO)) {
 			compat_siginfo_t __user *uinfo = compat_ptr(data);
 
 			if (copy_siginfo_to_user32(uinfo, &info) ||
@@ -1132,16 +1132,26 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
 
 	case PTRACE_GETSIGINFO:
 		ret = ptrace_getsiginfo(child, &siginfo);
-		if (!ret)
-			ret = copy_siginfo_to_user32(
-				(struct compat_siginfo __user *) datap,
-				&siginfo);
+		if (!ret) {
+			if (COMPAT_USE_NATIVE_SIGINFO)
+				ret = copy_siginfo_to_user(
+					(struct siginfo __user *) datap,
+					&siginfo);
+			else
+				ret = copy_siginfo_to_user32(
+					(struct compat_siginfo __user *) datap,
+					&siginfo);
+		}
 		break;
 
 	case PTRACE_SETSIGINFO:
 		memset(&siginfo, 0, sizeof siginfo);
-		if (copy_siginfo_from_user32(
-			    &siginfo, (struct compat_siginfo __user *) datap))
+		if (COMPAT_USE_NATIVE_SIGINFO)
+			ret = copy_from_user(&siginfo, datap, sizeof(siginfo));
+		else
+			ret = copy_siginfo_from_user32(
+				 &siginfo, (struct compat_siginfo __user *) datap);
+		if (ret)
 			ret = -EFAULT;
 		else
 			ret = ptrace_setsiginfo(child, &siginfo);
-- 
1.7.2.5


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

* [PATCH 20/24] ptrace: Allow compat to use the native siginfo.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

With ARM64 ILP32 ABI, we want to use the non-compat siginfo as we want to simplify signal handling for this new ABI.  This patch just adds a new define COMPAT_USE_NATIVE_SIGINFO and if it is true then read/write in the compat case as it was the non-compat case.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/linux/compat.h |    4 ++++
 kernel/ptrace.c        |   24 +++++++++++++++++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index e649426..2d8c535 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -24,6 +24,10 @@
 #define COMPAT_USE_64BIT_TIME 0
 #endif
 
+#ifndef COMPAT_USE_NATIVE_SIGINFO
+#define COMPAT_USE_NATIVE_SIGINFO 0
+#endif
+
 #ifndef __SC_DELOUSE
 #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v))
 #endif
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index adf9862..5f8bb5c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -663,7 +663,7 @@ static int ptrace_peek_siginfo(struct task_struct *child,
 			break;
 
 #ifdef CONFIG_COMPAT
-		if (unlikely(is_compat_task())) {
+		if (unlikely(is_compat_task() && !COMPAT_USE_NATIVE_SIGINFO)) {
 			compat_siginfo_t __user *uinfo = compat_ptr(data);
 
 			if (copy_siginfo_to_user32(uinfo, &info) ||
@@ -1132,16 +1132,26 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
 
 	case PTRACE_GETSIGINFO:
 		ret = ptrace_getsiginfo(child, &siginfo);
-		if (!ret)
-			ret = copy_siginfo_to_user32(
-				(struct compat_siginfo __user *) datap,
-				&siginfo);
+		if (!ret) {
+			if (COMPAT_USE_NATIVE_SIGINFO)
+				ret = copy_siginfo_to_user(
+					(struct siginfo __user *) datap,
+					&siginfo);
+			else
+				ret = copy_siginfo_to_user32(
+					(struct compat_siginfo __user *) datap,
+					&siginfo);
+		}
 		break;
 
 	case PTRACE_SETSIGINFO:
 		memset(&siginfo, 0, sizeof siginfo);
-		if (copy_siginfo_from_user32(
-			    &siginfo, (struct compat_siginfo __user *) datap))
+		if (COMPAT_USE_NATIVE_SIGINFO)
+			ret = copy_from_user(&siginfo, datap, sizeof(siginfo));
+		else
+			ret = copy_siginfo_from_user32(
+				 &siginfo, (struct compat_siginfo __user *) datap);
+		if (ret)
 			ret = -EFAULT;
 		else
 			ret = ptrace_setsiginfo(child, &siginfo);
-- 
1.7.2.5

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

* [PATCH 21/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Set COMPAT_USE_NATIVE_SIGINFO to be true for non AARCH32 tasks.  The same reasoning why we check AARCH32 as we did for COMPAT_USE_64BIT_TIME_T.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index c77fc0f..aef8cd3 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -211,6 +211,9 @@ typedef struct compat_siginfo {
 	} _sifields;
 } compat_siginfo_t;
 
+/* ILP32 uses the native siginfo and not the compat struct */
+#define COMPAT_USE_NATIVE_SIGINFO	!is_a32_compat_task()
+
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
 
-- 
1.7.2.5


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

* [PATCH 21/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Set COMPAT_USE_NATIVE_SIGINFO to be true for non AARCH32 tasks.  The same reasoning why we check AARCH32 as we did for COMPAT_USE_64BIT_TIME_T.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index c77fc0f..aef8cd3 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -211,6 +211,9 @@ typedef struct compat_siginfo {
 	} _sifields;
 } compat_siginfo_t;
 
+/* ILP32 uses the native siginfo and not the compat struct */
+#define COMPAT_USE_NATIVE_SIGINFO	!is_a32_compat_task()
+
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #define COMPAT_LOFF_T_MAX	0x7fffffffffffffffL
 
-- 
1.7.2.5

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

Some syscalls are still need to use the compat versions.  So we need to have a seperate syscall table for ILP32.  This patch adds them including documentation on why we need to use each one.
This list is based on the list from https://lkml.org/lkml/2013/9/11/478.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/syscalls.h |    4 +
 arch/arm64/include/asm/unistd.h   |    4 +
 arch/arm64/kernel/Makefile        |    1 +
 arch/arm64/kernel/entry.S         |   13 +++-
 arch/arm64/kernel/sys_ilp32.c     |  175 +++++++++++++++++++++++++++++++++++++
 5 files changed, 196 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm64/kernel/sys_ilp32.c

diff --git a/arch/arm64/include/asm/syscalls.h b/arch/arm64/include/asm/syscalls.h
index 48fe7c6..b58dad7 100644
--- a/arch/arm64/include/asm/syscalls.h
+++ b/arch/arm64/include/asm/syscalls.h
@@ -25,6 +25,10 @@
  */
 asmlinkage long sys_rt_sigreturn_wrapper(void);
 
+#ifdef CONFIG_ARM64_ILP32
+long ilp32_sys_sigaltstack(const stack_t __user *, stack_t __user *);
+#endif
+
 #include <asm-generic/syscalls.h>
 
 #endif	/* __ASM_SYSCALLS_H */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 11502bd..831c7b6 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,6 +13,10 @@
  * 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_COMPAT_STAT64
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 986962d..b5884a1 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -13,6 +13,7 @@ arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o topology.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 1e1ebfc..8241ffe 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -620,9 +620,14 @@ 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
+	get_thread_info tsk
+	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
 	disable_step x16
@@ -643,6 +648,12 @@ ni_sys:
 	b	do_ni_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..1da1d11
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,175 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2013 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/export.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+
+/*
+ * Wrappers to pass the pt_regs argument.
+ */
+#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
+
+
+/* Using Compat syscalls where necessary */
+#define sys_ioctl		compat_sys_ioctl
+/* iovec */
+#define sys_readv		compat_sys_readv
+#define sys_writev		compat_sys_writev
+#define sys_preadv		compat_sys_preadv64
+#define sys_pwritev		compat_sys_pwritev64
+#define sys_vmsplice		compat_sys_vmsplice
+/* robust_list_head */
+#define sys_set_robust_list	compat_sys_set_robust_list
+#define sys_get_robust_list	compat_sys_get_robust_list
+
+/* kexec_segment */
+#define sys_kexec_load		compat_sys_kexec_load
+
+/* Ptrace has some structures which are different between ILP32 and LP64 */
+#define sys_ptrace		compat_sys_ptrace
+
+/* struct msghdr */
+#define sys_recvfrom		compat_sys_recvfrom
+#define sys_recvmmsg		compat_sys_recvmmsg
+#define sys_sendmmsg		compat_sys_sendmmsg
+#define sys_sendmsg		compat_sys_sendmsg
+#define sys_recvmsg		compat_sys_recvmsg
+
+#define sys_setsockopt		compat_sys_setsockopt
+#define sys_getsockopt		compat_sys_getsockopt
+
+/* Array of pointers */
+#define sys_execve		compat_sys_execve
+#define sys_move_pages		compat_sys_move_pages
+
+/* iovec */
+#define sys_process_vm_readv	compat_sys_process_vm_readv
+#define sys_process_vm_writev	compat_sys_process_vm_writev
+
+/* Pointer in struct */
+#define sys_mount               compat_sys_mount
+
+/* NUMA */
+/* unsigned long bitmaps */
+#define sys_get_mempolicy       compat_sys_get_mempolicy
+#define sys_set_mempolicy       compat_sys_set_mempolicy
+#define sys_mbind               compat_sys_mbind
+/* array of pointers */
+/* unsigned long bitmaps */
+#define sys_migrate_pages       compat_sys_migrate_pages
+
+/* Scheduler */
+/* unsigned long bitmaps */
+#define sys_sched_setaffinity   compat_sys_sched_setaffinity
+#define sys_sched_getaffinity   compat_sys_sched_getaffinity
+
+/* iov usage */
+#define sys_keyctl              compat_sys_keyctl
+
+/* aio */
+/* Pointer to Pointer  */
+#define sys_io_setup		compat_sys_io_setup
+/* Array of pointers */
+#define sys_io_submit           compat_sys_io_submit
+
+/* We need to make sure the pointer gets copied correctly. */
+asmlinkage long ilp32_sys_mq_notify(mqd_t mqdes,
+			const struct sigevent __user *u_notification)
+{
+	struct sigevent __user *p = NULL;
+	if (u_notification) {
+		struct sigevent n;
+		p = compat_alloc_user_space(sizeof(*p));
+		if (copy_from_user(&n, u_notification, sizeof(*p)))
+			return -EFAULT;
+		if (n.sigev_notify == SIGEV_THREAD)
+			n.sigev_value.sival_ptr = compat_ptr((uintptr_t)n.sigev_value.sival_ptr);
+		if (copy_to_user(p, &n, sizeof(*p)))
+			return -EFAULT;
+	}
+	return sys_mq_notify(mqdes, p);
+}
+
+/* sigevent contains sigval_t which is now 64bit always
+   but need special handling due to padding for SIGEV_THREAD.  */
+#define sys_mq_notify		ilp32_sys_mq_notify
+
+
+/* sigaltstack needs some special handling as the
+   padding for stack_t might not be non-zero. */
+long ilp32_sys_sigaltstack(const stack_t __user *uss_ptr,
+			   stack_t __user *uoss_ptr)
+{
+	stack_t uss, uoss;
+	int ret;
+	mm_segment_t seg;
+
+	if (uss_ptr) {
+		if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)))
+			return -EFAULT;
+		if (__get_user(uss.ss_sp, &uss_ptr->ss_sp) |
+			__get_user(uss.ss_flags, &uss_ptr->ss_flags) |
+			__get_user(uss.ss_size, &uss_ptr->ss_size))
+			return -EFAULT;
+		/* Zero extend the sp address and the size. */
+		uss.ss_sp = (void *)(uintptr_t)(unsigned int)(uintptr_t)uss.ss_sp;
+		uss.ss_size = (size_t)(unsigned int)uss.ss_size;
+	}
+	seg = get_fs();
+	set_fs(KERNEL_DS);
+	/* Note we need to use uoss as we have changed the segment to the
+	   kernel one so passing an user one around is wrong. */
+	ret = sys_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
+			      (stack_t __force __user *) &uoss);
+	set_fs(seg);
+	if (ret >= 0 && uoss_ptr)  {
+		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_t)) ||
+		    __put_user(uoss.ss_sp, &uoss_ptr->ss_sp) ||
+		    __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
+		    __put_user(uoss.ss_size, &uoss_ptr->ss_size))
+			ret = -EFAULT;
+	}
+	return ret;
+}
+
+/* sigaltstack needs some special handling as the padding
+   for stack_t might not be non-zero. */
+#define sys_sigaltstack		ilp32_sys_sigaltstack
+
+
+#include <asm/syscalls.h>
+
+#undef __SYSCALL
+#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>
+};
-- 
1.7.2.5


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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

Some syscalls are still need to use the compat versions.  So we need to have a seperate syscall table for ILP32.  This patch adds them including documentation on why we need to use each one.
This list is based on the list from https://lkml.org/lkml/2013/9/11/478.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/syscalls.h |    4 +
 arch/arm64/include/asm/unistd.h   |    4 +
 arch/arm64/kernel/Makefile        |    1 +
 arch/arm64/kernel/entry.S         |   13 +++-
 arch/arm64/kernel/sys_ilp32.c     |  175 +++++++++++++++++++++++++++++++++++++
 5 files changed, 196 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm64/kernel/sys_ilp32.c

diff --git a/arch/arm64/include/asm/syscalls.h b/arch/arm64/include/asm/syscalls.h
index 48fe7c6..b58dad7 100644
--- a/arch/arm64/include/asm/syscalls.h
+++ b/arch/arm64/include/asm/syscalls.h
@@ -25,6 +25,10 @@
  */
 asmlinkage long sys_rt_sigreturn_wrapper(void);
 
+#ifdef CONFIG_ARM64_ILP32
+long ilp32_sys_sigaltstack(const stack_t __user *, stack_t __user *);
+#endif
+
 #include <asm-generic/syscalls.h>
 
 #endif	/* __ASM_SYSCALLS_H */
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 11502bd..831c7b6 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,6 +13,10 @@
  * 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_COMPAT_STAT64
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 986962d..b5884a1 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -13,6 +13,7 @@ arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= sys_ilp32.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o topology.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 1e1ebfc..8241ffe 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -620,9 +620,14 @@ 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
+	get_thread_info tsk
+	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
 	disable_step x16
@@ -643,6 +648,12 @@ ni_sys:
 	b	do_ni_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..1da1d11
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,175 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2013 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/export.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+
+/*
+ * Wrappers to pass the pt_regs argument.
+ */
+#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
+
+
+/* Using Compat syscalls where necessary */
+#define sys_ioctl		compat_sys_ioctl
+/* iovec */
+#define sys_readv		compat_sys_readv
+#define sys_writev		compat_sys_writev
+#define sys_preadv		compat_sys_preadv64
+#define sys_pwritev		compat_sys_pwritev64
+#define sys_vmsplice		compat_sys_vmsplice
+/* robust_list_head */
+#define sys_set_robust_list	compat_sys_set_robust_list
+#define sys_get_robust_list	compat_sys_get_robust_list
+
+/* kexec_segment */
+#define sys_kexec_load		compat_sys_kexec_load
+
+/* Ptrace has some structures which are different between ILP32 and LP64 */
+#define sys_ptrace		compat_sys_ptrace
+
+/* struct msghdr */
+#define sys_recvfrom		compat_sys_recvfrom
+#define sys_recvmmsg		compat_sys_recvmmsg
+#define sys_sendmmsg		compat_sys_sendmmsg
+#define sys_sendmsg		compat_sys_sendmsg
+#define sys_recvmsg		compat_sys_recvmsg
+
+#define sys_setsockopt		compat_sys_setsockopt
+#define sys_getsockopt		compat_sys_getsockopt
+
+/* Array of pointers */
+#define sys_execve		compat_sys_execve
+#define sys_move_pages		compat_sys_move_pages
+
+/* iovec */
+#define sys_process_vm_readv	compat_sys_process_vm_readv
+#define sys_process_vm_writev	compat_sys_process_vm_writev
+
+/* Pointer in struct */
+#define sys_mount               compat_sys_mount
+
+/* NUMA */
+/* unsigned long bitmaps */
+#define sys_get_mempolicy       compat_sys_get_mempolicy
+#define sys_set_mempolicy       compat_sys_set_mempolicy
+#define sys_mbind               compat_sys_mbind
+/* array of pointers */
+/* unsigned long bitmaps */
+#define sys_migrate_pages       compat_sys_migrate_pages
+
+/* Scheduler */
+/* unsigned long bitmaps */
+#define sys_sched_setaffinity   compat_sys_sched_setaffinity
+#define sys_sched_getaffinity   compat_sys_sched_getaffinity
+
+/* iov usage */
+#define sys_keyctl              compat_sys_keyctl
+
+/* aio */
+/* Pointer to Pointer  */
+#define sys_io_setup		compat_sys_io_setup
+/* Array of pointers */
+#define sys_io_submit           compat_sys_io_submit
+
+/* We need to make sure the pointer gets copied correctly. */
+asmlinkage long ilp32_sys_mq_notify(mqd_t mqdes,
+			const struct sigevent __user *u_notification)
+{
+	struct sigevent __user *p = NULL;
+	if (u_notification) {
+		struct sigevent n;
+		p = compat_alloc_user_space(sizeof(*p));
+		if (copy_from_user(&n, u_notification, sizeof(*p)))
+			return -EFAULT;
+		if (n.sigev_notify == SIGEV_THREAD)
+			n.sigev_value.sival_ptr = compat_ptr((uintptr_t)n.sigev_value.sival_ptr);
+		if (copy_to_user(p, &n, sizeof(*p)))
+			return -EFAULT;
+	}
+	return sys_mq_notify(mqdes, p);
+}
+
+/* sigevent contains sigval_t which is now 64bit always
+   but need special handling due to padding for SIGEV_THREAD.  */
+#define sys_mq_notify		ilp32_sys_mq_notify
+
+
+/* sigaltstack needs some special handling as the
+   padding for stack_t might not be non-zero. */
+long ilp32_sys_sigaltstack(const stack_t __user *uss_ptr,
+			   stack_t __user *uoss_ptr)
+{
+	stack_t uss, uoss;
+	int ret;
+	mm_segment_t seg;
+
+	if (uss_ptr) {
+		if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)))
+			return -EFAULT;
+		if (__get_user(uss.ss_sp, &uss_ptr->ss_sp) |
+			__get_user(uss.ss_flags, &uss_ptr->ss_flags) |
+			__get_user(uss.ss_size, &uss_ptr->ss_size))
+			return -EFAULT;
+		/* Zero extend the sp address and the size. */
+		uss.ss_sp = (void *)(uintptr_t)(unsigned int)(uintptr_t)uss.ss_sp;
+		uss.ss_size = (size_t)(unsigned int)uss.ss_size;
+	}
+	seg = get_fs();
+	set_fs(KERNEL_DS);
+	/* Note we need to use uoss as we have changed the segment to the
+	   kernel one so passing an user one around is wrong. */
+	ret = sys_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
+			      (stack_t __force __user *) &uoss);
+	set_fs(seg);
+	if (ret >= 0 && uoss_ptr)  {
+		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_t)) ||
+		    __put_user(uoss.ss_sp, &uoss_ptr->ss_sp) ||
+		    __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
+		    __put_user(uoss.ss_size, &uoss_ptr->ss_size))
+			ret = -EFAULT;
+	}
+	return ret;
+}
+
+/* sigaltstack needs some special handling as the padding
+   for stack_t might not be non-zero. */
+#define sys_sigaltstack		ilp32_sys_sigaltstack
+
+
+#include <asm/syscalls.h>
+
+#undef __SYSCALL
+#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>
+};
-- 
1.7.2.5

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

* [PATCH 23/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel
  Cc: Andrew Pinski

If the user decided to change the stack_t that was on the stack when returning from the signal handler, the stack_t's padding for ILP32 might be not zero.  So we need to use the syscall version of restore_altstack (ilp32_sys_sigaltstack).

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/kernel/signal.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index fd49b58..d5682b6 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/vdso.h>
+#include <asm/syscalls.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -149,6 +150,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 	if (restore_sigframe(regs, frame))
 		goto badframe;
 
+#ifdef CONFIG_ARM64_ILP32
+	/* ILP32 has to be handled "special" due to maybe not zeroing out
+	   the upper 32bits of the pointer if the user changed the frame. */
+	if (is_ilp32_compat_task()) {
+		if (ilp32_sys_sigaltstack(&frame->uc.uc_stack,
+					  NULL) == -EFAULT)
+			goto badframe;
+		return regs->regs[0];
+	}
+#endif
+
 	if (restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
 
-- 
1.7.2.5


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

* [PATCH 23/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

If the user decided to change the stack_t that was on the stack when returning from the signal handler, the stack_t's padding for ILP32 might be not zero.  So we need to use the syscall version of restore_altstack (ilp32_sys_sigaltstack).

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/kernel/signal.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index fd49b58..d5682b6 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/vdso.h>
+#include <asm/syscalls.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -149,6 +150,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 	if (restore_sigframe(regs, frame))
 		goto badframe;
 
+#ifdef CONFIG_ARM64_ILP32
+	/* ILP32 has to be handled "special" due to maybe not zeroing out
+	   the upper 32bits of the pointer if the user changed the frame. */
+	if (is_ilp32_compat_task()) {
+		if (ilp32_sys_sigaltstack(&frame->uc.uc_stack,
+					  NULL) == -EFAULT)
+			goto badframe;
+		return regs->regs[0];
+	}
+#endif
+
 	if (restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
 
-- 
1.7.2.5

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

* [PATCH 24/24] Add documentation about ARM64 ILP32 ABI.
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-05-24  7:02   ` Andrew Pinski
  -1 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, linux-arm-kernel, linux-kernel,
	linux-doc
  Cc: Andrew Pinski

This adds the documentation about the ILP32 ABI and what is difference between it and the normal generic 32bit ABI.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>

---
 Documentation/arm64/ilp32.txt |   57 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)
 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..5be0613
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,57 @@
+			ILP32 AARCH64 SYSCALL ABI
+			=====================
+
+Author: Andrew Pinski  <apinski@cavium.com>
+Date: May 23, 2014
+
+This document describes the ILP32 syscall ABI and where it differs
+from the generic linux syscall interface.  
+ILP32 sets __kernel_long_t and __kernel_ulong_t both to 64bit
+(long long).  This effects the following types:
+* time_t: unsigned long long
+* clock_t: unsigned long long
+* fsword_t: long long
+* suseconds_t: long long
+* swblk_t: long long
+* fd_mask_t: long long
+
+Some structures are changed to reduce the difference in the code path
+for both ILP32 and LP64 ABIs for signal handling.
+
+The following structures have been changed so the layout of the structures are the same between ILP32 and LP64 ABIs.
+* timespec: Uses time_t and suseconds_t
+* timeval: Uses time_t and suseconds_t
+* stat: Uses timespec/time_t.
+* semid64_ds: Uses time_t.
+* msqid64_ds: Uses time_t.
+* shmid64_ds: Uses time_t.
+* rt_sigframe: Uses siginfo and ucontext.
+* siginfo_t: Uses clock_t and sigval_t
+* ucontext: Uses stack_t and sigset_t
+* stack_t: NOTE special handling inside the kernel is done to make sure
+  the pointers are zero extended
+* sigval_t: Contains pointers
+* sigevent: Uses sigval_t which causes it to be the same.  Special
+  handing is needed for reading; in the mq_notify syscall
+* sigaction: NOTE the userland structure inside glibc does
+  not match the kernel structure here (this causes issues with LTP).
+  Uses sigset_t. 
+* fd_set: This is done to avoid endian issues between ILP32 and LP64
+  Also the syscall which uses fd_set uses timespec
+
+
+Also the syscalls which normally would pass 64bit values as two
+arguments; now pass the 64bit value as one argument.  Also they have
+been renamed (removing the 64 from the name) to avoid confusion.
+The list of these syscalls:
+* fcntl
+* statfs
+* fstatfs
+* truncate
+* ftruncate
+* lseek
+* sendfile
+* newfstatat
+* fstat
+* mmap
+* fadvise64
-- 
1.7.2.5


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

* [PATCH 24/24] Add documentation about ARM64 ILP32 ABI.
@ 2014-05-24  7:02   ` Andrew Pinski
  0 siblings, 0 replies; 105+ messages in thread
From: Andrew Pinski @ 2014-05-24  7:02 UTC (permalink / raw)
  To: linux-arm-kernel

This adds the documentation about the ILP32 ABI and what is difference between it and the normal generic 32bit ABI.

Thanks,
Andrew Pinski

Signed-off-by: Andrew Pinski <apinski@cavium.com>

---
 Documentation/arm64/ilp32.txt |   57 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)
 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..5be0613
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,57 @@
+			ILP32 AARCH64 SYSCALL ABI
+			=====================
+
+Author: Andrew Pinski  <apinski@cavium.com>
+Date: May 23, 2014
+
+This document describes the ILP32 syscall ABI and where it differs
+from the generic linux syscall interface.  
+ILP32 sets __kernel_long_t and __kernel_ulong_t both to 64bit
+(long long).  This effects the following types:
+* time_t: unsigned long long
+* clock_t: unsigned long long
+* fsword_t: long long
+* suseconds_t: long long
+* swblk_t: long long
+* fd_mask_t: long long
+
+Some structures are changed to reduce the difference in the code path
+for both ILP32 and LP64 ABIs for signal handling.
+
+The following structures have been changed so the layout of the structures are the same between ILP32 and LP64 ABIs.
+* timespec: Uses time_t and suseconds_t
+* timeval: Uses time_t and suseconds_t
+* stat: Uses timespec/time_t.
+* semid64_ds: Uses time_t.
+* msqid64_ds: Uses time_t.
+* shmid64_ds: Uses time_t.
+* rt_sigframe: Uses siginfo and ucontext.
+* siginfo_t: Uses clock_t and sigval_t
+* ucontext: Uses stack_t and sigset_t
+* stack_t: NOTE special handling inside the kernel is done to make sure
+  the pointers are zero extended
+* sigval_t: Contains pointers
+* sigevent: Uses sigval_t which causes it to be the same.  Special
+  handing is needed for reading; in the mq_notify syscall
+* sigaction: NOTE the userland structure inside glibc does
+  not match the kernel structure here (this causes issues with LTP).
+  Uses sigset_t. 
+* fd_set: This is done to avoid endian issues between ILP32 and LP64
+  Also the syscall which uses fd_set uses timespec
+
+
+Also the syscalls which normally would pass 64bit values as two
+arguments; now pass the 64bit value as one argument.  Also they have
+been renamed (removing the 64 from the name) to avoid confusion.
+The list of these syscalls:
+* fcntl
+* statfs
+* fstatfs
+* truncate
+* ftruncate
+* lseek
+* sendfile
+* newfstatat
+* fstat
+* mmap
+* fadvise64
-- 
1.7.2.5

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

* Re: [PATCH 21/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-05-24 18:56     ` H. Peter Anvin
  -1 siblings, 0 replies; 105+ messages in thread
From: H. Peter Anvin @ 2014-05-24 18:56 UTC (permalink / raw)
  To: Andrew Pinski, linux-arm-kernel, linux-kernel

On 05/24/2014 12:02 AM, Andrew Pinski wrote:
>  
> +/* ILP32 uses the native siginfo and not the compat struct */
> +#define COMPAT_USE_NATIVE_SIGINFO	!is_a32_compat_task()
> +

<nitpick> Probably want parens around that expression? </nitpick>

	-hpa


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

* [PATCH 21/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo.
@ 2014-05-24 18:56     ` H. Peter Anvin
  0 siblings, 0 replies; 105+ messages in thread
From: H. Peter Anvin @ 2014-05-24 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/24/2014 12:02 AM, Andrew Pinski wrote:
>  
> +/* ILP32 uses the native siginfo and not the compat struct */
> +#define COMPAT_USE_NATIVE_SIGINFO	!is_a32_compat_task()
> +

<nitpick> Probably want parens around that expression? </nitpick>

	-hpa

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

* Re: [PATCHv2 00/24] ILP32 Support in ARM64
  2014-05-24  7:01 ` Andrew Pinski
@ 2014-06-16 17:08   ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-16 17:08 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

Andrew,

On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
> New version of the patches with documentation, signal changes are
> simplified, using less compat syscalls and splitting up the patches so
> it is easier to review.  I have tested LTP on both LP64 and ILP32.
> There is a few LTP failures but they are due to LTP being incorrect
> (sigaction structure in glibc is not the one which is used by the
> kernel)

Do you have more details about what's wrong here and where the fix
should go? LTP? glibc? Kernel?

I'll give you more specific comments on the code in the next couple of
days. But for cosmetics, please wrap the lines around 72 (or whatever)
characters both in emails, commit logs and Documentation/* files (and
you can drop the "Thanks" part in every commit log ;)).

> Andrew Pinski (24):
>   ARM64: Force LP64 to compile the kernel.
>   ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
>   ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
>     instead.
>   ARM64:ILP32: Set kernel_long to long long so we can reuse most of the
>     same syscalls as LP64.
>   ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
>   Allow for some signal structures to be the same between a 32bit ABI
>     and the 64bit ABI.
>   ARM64:ILP32: Use the same size and layout of the signal structures
>     for ILP32 as for LP64.
>   Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to
>     avoid confusion of not splitting the registers.
>   ARM64:ILP32: Use the same syscall names as LP64.
>   ARM64: Introduce is_a32_task and is_a32_thread. Use them in the
>     correct locations.
>   ARM64: Add ARM64_ILP32 to Kconfig.

Does this patch need to be in the middle of the series? It should come
after the ILP32 support is complete.

Thanks.

-- 
Catalin

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

* [PATCHv2 00/24] ILP32 Support in ARM64
@ 2014-06-16 17:08   ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-16 17:08 UTC (permalink / raw)
  To: linux-arm-kernel

Andrew,

On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
> New version of the patches with documentation, signal changes are
> simplified, using less compat syscalls and splitting up the patches so
> it is easier to review.  I have tested LTP on both LP64 and ILP32.
> There is a few LTP failures but they are due to LTP being incorrect
> (sigaction structure in glibc is not the one which is used by the
> kernel)

Do you have more details about what's wrong here and where the fix
should go? LTP? glibc? Kernel?

I'll give you more specific comments on the code in the next couple of
days. But for cosmetics, please wrap the lines around 72 (or whatever)
characters both in emails, commit logs and Documentation/* files (and
you can drop the "Thanks" part in every commit log ;)).

> Andrew Pinski (24):
>   ARM64: Force LP64 to compile the kernel.
>   ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
>   ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
>     instead.
>   ARM64:ILP32: Set kernel_long to long long so we can reuse most of the
>     same syscalls as LP64.
>   ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
>   Allow for some signal structures to be the same between a 32bit ABI
>     and the 64bit ABI.
>   ARM64:ILP32: Use the same size and layout of the signal structures
>     for ILP32 as for LP64.
>   Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to
>     avoid confusion of not splitting the registers.
>   ARM64:ILP32: Use the same syscall names as LP64.
>   ARM64: Introduce is_a32_task and is_a32_thread. Use them in the
>     correct locations.
>   ARM64: Add ARM64_ILP32 to Kconfig.

Does this patch need to be in the middle of the series? It should come
after the ILP32 support is complete.

Thanks.

-- 
Catalin

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

* Re: [PATCHv2 00/24] ILP32 Support in ARM64
  2014-06-16 17:08   ` Catalin Marinas
@ 2014-06-16 17:19     ` Pinski, Andrew
  -1 siblings, 0 replies; 105+ messages in thread
From: Pinski, Andrew @ 2014-06-16 17:19 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: Andrew Pinski, linux-arm-kernel, linux-kernel



> On Jun 16, 2014, at 10:08 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> 
> Andrew,
> 
>> On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
>> New version of the patches with documentation, signal changes are
>> simplified, using less compat syscalls and splitting up the patches so
>> it is easier to review.  I have tested LTP on both LP64 and ILP32.
>> There is a few LTP failures but they are due to LTP being incorrect
>> (sigaction structure in glibc is not the one which is used by the
>> kernel)
> 
> Do you have more details about what's wrong here and where the fix
> should go? LTP? glibc? Kernel?

LTP assumes some sigaction structure is the same between userland and kernel.
Glibc has the correct idea of what the kernel structure will be when passing to the kernel already. The fix should be done in LTP. There is already code in LTP for x86 for a similar issue which we should be able to advantage of. 

> 
> I'll give you more specific comments on the code in the next couple of
> days. But for cosmetics, please wrap the lines around 72 (or whatever)
> characters both in emails, commit logs and Documentation/* files (and
> you can drop the "Thanks" part in every commit log ;)).

Will do this with the rest of the review. 

> 
>> Andrew Pinski (24):
>>  ARM64: Force LP64 to compile the kernel.
>>  ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
>>  ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
>>    instead.
>>  ARM64:ILP32: Set kernel_long to long long so we can reuse most of the
>>    same syscalls as LP64.
>>  ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
>>  Allow for some signal structures to be the same between a 32bit ABI
>>    and the 64bit ABI.
>>  ARM64:ILP32: Use the same size and layout of the signal structures
>>    for ILP32 as for LP64.
>>  Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to
>>    avoid confusion of not splitting the registers.
>>  ARM64:ILP32: Use the same syscall names as LP64.
>>  ARM64: Introduce is_a32_task and is_a32_thread. Use them in the
>>    correct locations.
>>  ARM64: Add ARM64_ILP32 to Kconfig.
> 
> Does this patch need to be in the middle of the series? It should come
> after the ILP32 support is complete.


Ok, I will move it. I had added in the middle to test the newly added code. 

Thanks,
Andrew

> 
> Thanks.
> 
> -- 
> Catalin

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

* [PATCHv2 00/24] ILP32 Support in ARM64
@ 2014-06-16 17:19     ` Pinski, Andrew
  0 siblings, 0 replies; 105+ messages in thread
From: Pinski, Andrew @ 2014-06-16 17:19 UTC (permalink / raw)
  To: linux-arm-kernel



> On Jun 16, 2014, at 10:08 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> 
> Andrew,
> 
>> On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
>> New version of the patches with documentation, signal changes are
>> simplified, using less compat syscalls and splitting up the patches so
>> it is easier to review.  I have tested LTP on both LP64 and ILP32.
>> There is a few LTP failures but they are due to LTP being incorrect
>> (sigaction structure in glibc is not the one which is used by the
>> kernel)
> 
> Do you have more details about what's wrong here and where the fix
> should go? LTP? glibc? Kernel?

LTP assumes some sigaction structure is the same between userland and kernel.
Glibc has the correct idea of what the kernel structure will be when passing to the kernel already. The fix should be done in LTP. There is already code in LTP for x86 for a similar issue which we should be able to advantage of. 

> 
> I'll give you more specific comments on the code in the next couple of
> days. But for cosmetics, please wrap the lines around 72 (or whatever)
> characters both in emails, commit logs and Documentation/* files (and
> you can drop the "Thanks" part in every commit log ;)).

Will do this with the rest of the review. 

> 
>> Andrew Pinski (24):
>>  ARM64: Force LP64 to compile the kernel.
>>  ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig.
>>  ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
>>    instead.
>>  ARM64:ILP32: Set kernel_long to long long so we can reuse most of the
>>    same syscalls as LP64.
>>  ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
>>  Allow for some signal structures to be the same between a 32bit ABI
>>    and the 64bit ABI.
>>  ARM64:ILP32: Use the same size and layout of the signal structures
>>    for ILP32 as for LP64.
>>  Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to
>>    avoid confusion of not splitting the registers.
>>  ARM64:ILP32: Use the same syscall names as LP64.
>>  ARM64: Introduce is_a32_task and is_a32_thread. Use them in the
>>    correct locations.
>>  ARM64: Add ARM64_ILP32 to Kconfig.
> 
> Does this patch need to be in the middle of the series? It should come
> after the ILP32 support is complete.


Ok, I will move it. I had added in the middle to test the newly added code. 

Thanks,
Andrew

> 
> Thanks.
> 
> -- 
> Catalin

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

* Re: [PATCHv2 00/24] ILP32 Support in ARM64
  2014-06-16 17:19     ` Pinski, Andrew
@ 2014-06-17 10:43       ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 10:43 UTC (permalink / raw)
  To: Pinski, Andrew; +Cc: Andrew Pinski, linux-arm-kernel, linux-kernel

On Mon, Jun 16, 2014 at 05:19:32PM +0000, Pinski, Andrew wrote:
> > On Jun 16, 2014, at 10:08 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> >> On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
> >> New version of the patches with documentation, signal changes are
> >> simplified, using less compat syscalls and splitting up the patches so
> >> it is easier to review.  I have tested LTP on both LP64 and ILP32.
> >> There is a few LTP failures but they are due to LTP being incorrect
> >> (sigaction structure in glibc is not the one which is used by the
> >> kernel)
> > 
> > Do you have more details about what's wrong here and where the fix
> > should go? LTP? glibc? Kernel?
> 
> LTP assumes some sigaction structure is the same between userland and kernel.
> Glibc has the correct idea of what the kernel structure will be when
> passing to the kernel already. The fix should be done in LTP. There is
> already code in LTP for x86 for a similar issue which we should be
> able to advantage of. 

OK. I guess you are planning to submit the LTP patch at some point (once
kernel and glibc changes are agreed).

Any plans for big-endian ILP32?

> > I'll give you more specific comments on the code in the next couple of
> > days. But for cosmetics, please wrap the lines around 72 (or whatever)
> > characters both in emails, commit logs and Documentation/* files (and
> > you can drop the "Thanks" part in every commit log ;)).

I forgot to mention dropping the full stop at the end of every subject.

> Will do this with the rest of the review. 

More coding style issues: please have a look at
Documentation/CodingStyle. While I'm not usually bothered with minor
aspects, I would like at least some consistency for multi-line comment
style.

Also please get the patches through checkpatch.pl (it doesn't need to be
100% pass but it gives some clues).

There are a few #defines you added without corresponding brackets (hpa
commented on one already).

-- 
Catalin

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

* [PATCHv2 00/24] ILP32 Support in ARM64
@ 2014-06-17 10:43       ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 16, 2014 at 05:19:32PM +0000, Pinski, Andrew wrote:
> > On Jun 16, 2014, at 10:08 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> >> On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
> >> New version of the patches with documentation, signal changes are
> >> simplified, using less compat syscalls and splitting up the patches so
> >> it is easier to review.  I have tested LTP on both LP64 and ILP32.
> >> There is a few LTP failures but they are due to LTP being incorrect
> >> (sigaction structure in glibc is not the one which is used by the
> >> kernel)
> > 
> > Do you have more details about what's wrong here and where the fix
> > should go? LTP? glibc? Kernel?
> 
> LTP assumes some sigaction structure is the same between userland and kernel.
> Glibc has the correct idea of what the kernel structure will be when
> passing to the kernel already. The fix should be done in LTP. There is
> already code in LTP for x86 for a similar issue which we should be
> able to advantage of. 

OK. I guess you are planning to submit the LTP patch at some point (once
kernel and glibc changes are agreed).

Any plans for big-endian ILP32?

> > I'll give you more specific comments on the code in the next couple of
> > days. But for cosmetics, please wrap the lines around 72 (or whatever)
> > characters both in emails, commit logs and Documentation/* files (and
> > you can drop the "Thanks" part in every commit log ;)).

I forgot to mention dropping the full stop at the end of every subject.

> Will do this with the rest of the review. 

More coding style issues: please have a look at
Documentation/CodingStyle. While I'm not usually bothered with minor
aspects, I would like at least some consistency for multi-line comment
style.

Also please get the patches through checkpatch.pl (it doesn't need to be
100% pass but it gives some clues).

There are a few #defines you added without corresponding brackets (hpa
commented on one already).

-- 
Catalin

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

* Re: [PATCHv2 00/24] ILP32 Support in ARM64
  2014-06-17 10:43       ` Catalin Marinas
@ 2014-06-17 11:30         ` Pinski, Andrew
  -1 siblings, 0 replies; 105+ messages in thread
From: Pinski, Andrew @ 2014-06-17 11:30 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Pinski, Andrew, Andrew Pinski, linux-arm-kernel, linux-kernel



> On Jun 17, 2014, at 3:48 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> 
> On Mon, Jun 16, 2014 at 05:19:32PM +0000, Pinski, Andrew wrote:
>>>> On Jun 16, 2014, at 10:08 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
>>>> On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
>>>> New version of the patches with documentation, signal changes are
>>>> simplified, using less compat syscalls and splitting up the patches so
>>>> it is easier to review.  I have tested LTP on both LP64 and ILP32.
>>>> There is a few LTP failures but they are due to LTP being incorrect
>>>> (sigaction structure in glibc is not the one which is used by the
>>>> kernel)
>>> 
>>> Do you have more details about what's wrong here and where the fix
>>> should go? LTP? glibc? Kernel?
>> 
>> LTP assumes some sigaction structure is the same between userland and kernel.
>> Glibc has the correct idea of what the kernel structure will be when
>> passing to the kernel already. The fix should be done in LTP. There is
>> already code in LTP for x86 for a similar issue which we should be
>> able to advantage of. 
> 
> OK. I guess you are planning to submit the LTP patch at some point (once
> kernel and glibc changes are agreed).
> 
> Any plans for big-endian ILP32?

The support is there already and ltp results are no difference from little-endian. 

> 
>>> I'll give you more specific comments on the code in the next couple of
>>> days. But for cosmetics, please wrap the lines around 72 (or whatever)
>>> characters both in emails, commit logs and Documentation/* files (and
>>> you can drop the "Thanks" part in every commit log ;)).
> 
> I forgot to mention dropping the full stop at the end of every subject.
> 
>> Will do this with the rest of the review. 
> 
> More coding style issues: please have a look at
> Documentation/CodingStyle. While I'm not usually bothered with minor
> aspects, I would like at least some consistency for multi-line comment
> style.
> 
> Also please get the patches through checkpatch.pl (it doesn't need to be
> 100% pass but it gives some clues).

I did run them through checkpatch already. The only warnings left were over 80 column warnings. 


> 
> There are a few #defines you added without corresponding brackets (hpa
> commented on one already).

Checkpatch did not warn about these but I will fix them.

Thanks,
Andrew


> 
> -- 
> Catalin

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

* [PATCHv2 00/24] ILP32 Support in ARM64
@ 2014-06-17 11:30         ` Pinski, Andrew
  0 siblings, 0 replies; 105+ messages in thread
From: Pinski, Andrew @ 2014-06-17 11:30 UTC (permalink / raw)
  To: linux-arm-kernel



> On Jun 17, 2014, at 3:48 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> 
> On Mon, Jun 16, 2014 at 05:19:32PM +0000, Pinski, Andrew wrote:
>>>> On Jun 16, 2014, at 10:08 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
>>>> On Sat, May 24, 2014 at 12:01:55AM -0700, Andrew Pinski wrote:
>>>> New version of the patches with documentation, signal changes are
>>>> simplified, using less compat syscalls and splitting up the patches so
>>>> it is easier to review.  I have tested LTP on both LP64 and ILP32.
>>>> There is a few LTP failures but they are due to LTP being incorrect
>>>> (sigaction structure in glibc is not the one which is used by the
>>>> kernel)
>>> 
>>> Do you have more details about what's wrong here and where the fix
>>> should go? LTP? glibc? Kernel?
>> 
>> LTP assumes some sigaction structure is the same between userland and kernel.
>> Glibc has the correct idea of what the kernel structure will be when
>> passing to the kernel already. The fix should be done in LTP. There is
>> already code in LTP for x86 for a similar issue which we should be
>> able to advantage of. 
> 
> OK. I guess you are planning to submit the LTP patch at some point (once
> kernel and glibc changes are agreed).
> 
> Any plans for big-endian ILP32?

The support is there already and ltp results are no difference from little-endian. 

> 
>>> I'll give you more specific comments on the code in the next couple of
>>> days. But for cosmetics, please wrap the lines around 72 (or whatever)
>>> characters both in emails, commit logs and Documentation/* files (and
>>> you can drop the "Thanks" part in every commit log ;)).
> 
> I forgot to mention dropping the full stop at the end of every subject.
> 
>> Will do this with the rest of the review. 
> 
> More coding style issues: please have a look at
> Documentation/CodingStyle. While I'm not usually bothered with minor
> aspects, I would like at least some consistency for multi-line comment
> style.
> 
> Also please get the patches through checkpatch.pl (it doesn't need to be
> 100% pass but it gives some clues).

I did run them through checkpatch already. The only warnings left were over 80 column warnings. 


> 
> There are a few #defines you added without corresponding brackets (hpa
> commented on one already).

Checkpatch did not warn about these but I will fix them.

Thanks,
Andrew


> 
> -- 
> Catalin

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

* Re: [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead.
  2014-05-24  7:01   ` Andrew Pinski
@ 2014-06-17 15:15     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:15 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:01:58AM -0700, Andrew Pinski wrote:
> This patch changes CONFIG_COMPAT checks inside the arm64 which are AARCH32 specific.

Please state what it is changed to. I guess CONFIG_AARCH32_EL0. Longer
commit log is always better.

> --- a/arch/arm64/include/asm/signal32.h
> +++ b/arch/arm64/include/asm/signal32.h
> @@ -20,6 +20,7 @@
>  #ifdef CONFIG_COMPAT
>  #include <linux/compat.h>
>  
> +#ifdef CONFIG_AARCH32_EL0
>  #define AARCH32_KERN_SIGRET_CODE_OFFSET	0x500

Do we still need the top CONFIG_COMPAT for signal32.h? We don't use the
signal32 infrastructure for ILP32.

> diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
> index 15e3559..af04276 100644
> --- a/arch/arm64/include/asm/stat.h
> +++ b/arch/arm64/include/asm/stat.h
> @@ -22,6 +22,7 @@
>  
>  #include <asm/compat.h>
>  
> +#ifdef CONFIG_AARCH32_EL0

Same here, we have another #ifdef CONFIG_COMPAT above the #include.

> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c

[...]

> @@ -1041,11 +1041,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
>  
>  	return ret;
>  }
> -#endif /* CONFIG_COMPAT */
> +#else /* !CONFIG_AARCH32_EL0 */
> +long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
> +			    compat_ulong_t caddr, compat_ulong_t cdata)
> +{
> +	return -1;
> +}
> +#endif /* !CONFIG_AARCH32_EL0 */

Can you return an appropriate error code here?

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

So for ILP32, will we route ptrace calls via compat_arch_ptrace? Some
explanation for this code would help as it doesn't look like a simple
CONFIG_COMPAT conversion.

> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -417,3 +417,16 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
>  		tracehook_notify_resume(regs);
>  	}
>  }
> +
> +/* Some functions are needed for compat ptrace but we don't define
> +   them if we don't have AARCH32 support compiled in */

As per the kernel coding style, the multi-line comment should be:

/*
 * Some functions are needed for compat ptrace but we don't define
 * them if we don't have AARCH32 support compiled in.
 */

> +#if defined CONFIG_COMPAT && !defined CONFIG_AARCH32_EL0
> +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
> +{
> +	return -EFAULT;
> +}
> +int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
> +{
> +	return -EFAULT;
> +}
> +#endif

Maybe it gets clearer in subsequent patches on how this interacts with
ptrace. But at this stage in the series, COMPAT cannot be defined
without CONFIG_AARCH32_EL0, so the above could be removed.

-- 
Catalin

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

* [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead.
@ 2014-06-17 15:15     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:01:58AM -0700, Andrew Pinski wrote:
> This patch changes CONFIG_COMPAT checks inside the arm64 which are AARCH32 specific.

Please state what it is changed to. I guess CONFIG_AARCH32_EL0. Longer
commit log is always better.

> --- a/arch/arm64/include/asm/signal32.h
> +++ b/arch/arm64/include/asm/signal32.h
> @@ -20,6 +20,7 @@
>  #ifdef CONFIG_COMPAT
>  #include <linux/compat.h>
>  
> +#ifdef CONFIG_AARCH32_EL0
>  #define AARCH32_KERN_SIGRET_CODE_OFFSET	0x500

Do we still need the top CONFIG_COMPAT for signal32.h? We don't use the
signal32 infrastructure for ILP32.

> diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
> index 15e3559..af04276 100644
> --- a/arch/arm64/include/asm/stat.h
> +++ b/arch/arm64/include/asm/stat.h
> @@ -22,6 +22,7 @@
>  
>  #include <asm/compat.h>
>  
> +#ifdef CONFIG_AARCH32_EL0

Same here, we have another #ifdef CONFIG_COMPAT above the #include.

> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c

[...]

> @@ -1041,11 +1041,28 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
>  
>  	return ret;
>  }
> -#endif /* CONFIG_COMPAT */
> +#else /* !CONFIG_AARCH32_EL0 */
> +long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
> +			    compat_ulong_t caddr, compat_ulong_t cdata)
> +{
> +	return -1;
> +}
> +#endif /* !CONFIG_AARCH32_EL0 */

Can you return an appropriate error code here?

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

So for ILP32, will we route ptrace calls via compat_arch_ptrace? Some
explanation for this code would help as it doesn't look like a simple
CONFIG_COMPAT conversion.

> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -417,3 +417,16 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
>  		tracehook_notify_resume(regs);
>  	}
>  }
> +
> +/* Some functions are needed for compat ptrace but we don't define
> +   them if we don't have AARCH32 support compiled in */

As per the kernel coding style, the multi-line comment should be:

/*
 * Some functions are needed for compat ptrace but we don't define
 * them if we don't have AARCH32 support compiled in.
 */

> +#if defined CONFIG_COMPAT && !defined CONFIG_AARCH32_EL0
> +int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
> +{
> +	return -EFAULT;
> +}
> +int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
> +{
> +	return -EFAULT;
> +}
> +#endif

Maybe it gets clearer in subsequent patches on how this interacts with
ptrace. But at this stage in the series, COMPAT cannot be defined
without CONFIG_AARCH32_EL0, so the above could be removed.

-- 
Catalin

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

* Re: [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-17 15:22     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:22 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:00AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
> index fce9c29..5e06c59 100644
> --- a/arch/arm64/include/uapi/asm/bitsperlong.h
> +++ b/arch/arm64/include/uapi/asm/bitsperlong.h
> @@ -16,7 +16,12 @@
>  #ifndef __ASM_BITSPERLONG_H
>  #define __ASM_BITSPERLONG_H
>  
> -#define __BITS_PER_LONG 64
> +/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
> +#ifdef __LP64__
> +# define __BITS_PER_LONG 64
> +#else
> +# define __BITS_PER_LONG 32
> +#endif

I think it's enough to just define it for the __LP64__ case.

>  #include <asm-generic/bitsperlong.h>

The asm-generic definition if 32 by default.

-- 
Catalin

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

* [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
@ 2014-06-17 15:22     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:00AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
> index fce9c29..5e06c59 100644
> --- a/arch/arm64/include/uapi/asm/bitsperlong.h
> +++ b/arch/arm64/include/uapi/asm/bitsperlong.h
> @@ -16,7 +16,12 @@
>  #ifndef __ASM_BITSPERLONG_H
>  #define __ASM_BITSPERLONG_H
>  
> -#define __BITS_PER_LONG 64
> +/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
> +#ifdef __LP64__
> +# define __BITS_PER_LONG 64
> +#else
> +# define __BITS_PER_LONG 32
> +#endif

I think it's enough to just define it for the __LP64__ case.

>  #include <asm-generic/bitsperlong.h>

The asm-generic definition if 32 by default.

-- 
Catalin

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

* Re: [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
  2014-06-17 15:22     ` Catalin Marinas
@ 2014-06-17 15:29       ` Arnd Bergmann
  -1 siblings, 0 replies; 105+ messages in thread
From: Arnd Bergmann @ 2014-06-17 15:29 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Catalin Marinas, Andrew Pinski, linux-kernel

On Tuesday 17 June 2014 16:22:50 Catalin Marinas wrote:
> On Sat, May 24, 2014 at 12:02:00AM -0700, Andrew Pinski wrote:
> > diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
> > index fce9c29..5e06c59 100644
> > --- a/arch/arm64/include/uapi/asm/bitsperlong.h
> > +++ b/arch/arm64/include/uapi/asm/bitsperlong.h
> > @@ -16,7 +16,12 @@
> >  #ifndef __ASM_BITSPERLONG_H
> >  #define __ASM_BITSPERLONG_H
> >  
> > -#define __BITS_PER_LONG 64
> > +/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
> > +#ifdef __LP64__
> > +# define __BITS_PER_LONG 64
> > +#else
> > +# define __BITS_PER_LONG 32
> > +#endif
> 
> I think it's enough to just define it for the __LP64__ case.
> 
> >  #include <asm-generic/bitsperlong.h>
> 
> The asm-generic definition if 32 by default.

Andrew's version does seem more readable though, and is obviously correct.

	Arnd

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

* [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32.
@ 2014-06-17 15:29       ` Arnd Bergmann
  0 siblings, 0 replies; 105+ messages in thread
From: Arnd Bergmann @ 2014-06-17 15:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 17 June 2014 16:22:50 Catalin Marinas wrote:
> On Sat, May 24, 2014 at 12:02:00AM -0700, Andrew Pinski wrote:
> > diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
> > index fce9c29..5e06c59 100644
> > --- a/arch/arm64/include/uapi/asm/bitsperlong.h
> > +++ b/arch/arm64/include/uapi/asm/bitsperlong.h
> > @@ -16,7 +16,12 @@
> >  #ifndef __ASM_BITSPERLONG_H
> >  #define __ASM_BITSPERLONG_H
> >  
> > -#define __BITS_PER_LONG 64
> > +/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
> > +#ifdef __LP64__
> > +# define __BITS_PER_LONG 64
> > +#else
> > +# define __BITS_PER_LONG 32
> > +#endif
> 
> I think it's enough to just define it for the __LP64__ case.
> 
> >  #include <asm-generic/bitsperlong.h>
> 
> The asm-generic definition if 32 by default.

Andrew's version does seem more readable though, and is obviously correct.

	Arnd

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

* Re: [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-17 15:43     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:43 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, linux-arch

On Sat, May 24, 2014 at 12:02:01AM -0700, Andrew Pinski wrote:
> diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
> index ba5be7f..553aca9 100644
> --- a/include/uapi/asm-generic/siginfo.h
> +++ b/include/uapi/asm-generic/siginfo.h
> @@ -4,9 +4,17 @@
>  #include <linux/compiler.h>
>  #include <linux/types.h>
>  
> +#ifndef __SIGINFO_VOIDPOINTER
> +#define __SIGINFO_VOIDPOINTER(field) void __user *field
> +#endif

Nitpick: maybe a shorter name like __SIGINFO_VOIDPTR (or VOID_PTR).

> +
> +#ifndef __SIGINFO_BAND
> +#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field
> +#endif
> +
>  typedef union sigval {
>  	int sival_int;
> -	void __user *sival_ptr;
> +	__SIGINFO_VOIDPOINTER(sival_ptr);
>  } sigval_t;

I'll discuss this further in a subsequent patch. I assume here you'll
enforce the alignment via the __SIGINFO_VOIDPOINTER definition. The
alternative would be another macro for structure attributes.

>  /*
> @@ -86,7 +94,7 @@ typedef struct siginfo {
>  
>  		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
>  		struct {
> -			void __user *_addr; /* faulting insn/memory ref. */
> +			__SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
>  #ifdef __ARCH_SI_TRAPNO
>  			int _trapno;	/* TRAP # which caused the signal */
>  #endif
> @@ -95,13 +103,13 @@ typedef struct siginfo {
>  
>  		/* SIGPOLL */
>  		struct {
> -			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
> +			__SIGINFO_BAND(_band);	/* POLL_IN, POLL_OUT, POLL_MSG */
>  			int _fd;
>  		} _sigpoll;
>  
>  		/* SIGSYS */
>  		struct {
> -			void __user *_call_addr; /* calling user insn */
> +			__SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
>  			int _syscall;	/* triggering system call number */
>  			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
>  		} _sigsys;
> @@ -283,6 +291,7 @@ typedef struct sigevent {
>  		int _pad[SIGEV_PAD_SIZE];
>  		 int _tid;
>  
> +		/* Note these two are handled only in userspace */
>  		struct {
>  			void (*_function)(sigval_t);
>  			void *_attribute;	/* really pthread_attr_t */

SIGEV_PAD_SIZE would be the same with ILP32 because sizeof(sigval_t)
would not change. So I think that's fine.

> diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
> index 9df61f1..c4ce238 100644
> --- a/include/uapi/asm-generic/signal.h
> +++ b/include/uapi/asm-generic/signal.h
> @@ -4,7 +4,9 @@
>  #include <linux/types.h>
>  
>  #define _NSIG		64
> +#ifndef _NSIG_BPW
>  #define _NSIG_BPW	__BITS_PER_LONG
> +#endif
>  #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
>  
>  #define SIGHUP		 1
> @@ -83,9 +85,13 @@
>  #define MINSIGSTKSZ	2048
>  #define SIGSTKSZ	8192
>  
> +#ifndef __SIGSET_INNER_TYPE
> +#define __SIGSET_INNER_TYPE unsigned long
> +#endif
> +
>  #ifndef __ASSEMBLY__
>  typedef struct {
> -	unsigned long sig[_NSIG_WORDS];
> +	__SIGSET_INNER_TYPE sig[_NSIG_WORDS];
>  } sigset_t;

Would the default not work? The sigset_t structure ends up with the same
number of bits between LP64 and ILP32, whether you patch it or not.

>  
>  /* not actually used, but required for linux/syscalls.h */
> @@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t;
>  #endif
>  
>  #ifndef __KERNEL__
> +
> +#ifndef __SIGACTION_HANDLER
> +#define __SIGACTION_HANDLER(field)	__sighandler_t field
> +#endif
> +
> +#ifndef __SIGACTION_FLAGS
> +#define __SIGACTION_FLAGS(field)	unsigned long field
> +#endif
> +
> +#ifndef __SIGACTION_RESTORER
> +#define __SIGACTION_RESTORER(field)	__sigrestore_t field
> +#endif
> +
>  struct sigaction {
> -	__sighandler_t sa_handler;
> -	unsigned long sa_flags;
> +	__SIGACTION_HANDLER(sa_handler);
> +	__SIGACTION_FLAGS(sa_flags);
>  #ifdef SA_RESTORER
> -	__sigrestore_t sa_restorer;
> +	__SIGACTION_RESTORER(sa_restorer);
>  #endif
>  	sigset_t sa_mask;		/* mask last for extensibility */
>  };

Same comment here about the need for attributes (to clarify in
subsequent patch).

-- 
Catalin

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

* [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI.
@ 2014-06-17 15:43     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:01AM -0700, Andrew Pinski wrote:
> diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
> index ba5be7f..553aca9 100644
> --- a/include/uapi/asm-generic/siginfo.h
> +++ b/include/uapi/asm-generic/siginfo.h
> @@ -4,9 +4,17 @@
>  #include <linux/compiler.h>
>  #include <linux/types.h>
>  
> +#ifndef __SIGINFO_VOIDPOINTER
> +#define __SIGINFO_VOIDPOINTER(field) void __user *field
> +#endif

Nitpick: maybe a shorter name like __SIGINFO_VOIDPTR (or VOID_PTR).

> +
> +#ifndef __SIGINFO_BAND
> +#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field
> +#endif
> +
>  typedef union sigval {
>  	int sival_int;
> -	void __user *sival_ptr;
> +	__SIGINFO_VOIDPOINTER(sival_ptr);
>  } sigval_t;

I'll discuss this further in a subsequent patch. I assume here you'll
enforce the alignment via the __SIGINFO_VOIDPOINTER definition. The
alternative would be another macro for structure attributes.

>  /*
> @@ -86,7 +94,7 @@ typedef struct siginfo {
>  
>  		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
>  		struct {
> -			void __user *_addr; /* faulting insn/memory ref. */
> +			__SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
>  #ifdef __ARCH_SI_TRAPNO
>  			int _trapno;	/* TRAP # which caused the signal */
>  #endif
> @@ -95,13 +103,13 @@ typedef struct siginfo {
>  
>  		/* SIGPOLL */
>  		struct {
> -			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
> +			__SIGINFO_BAND(_band);	/* POLL_IN, POLL_OUT, POLL_MSG */
>  			int _fd;
>  		} _sigpoll;
>  
>  		/* SIGSYS */
>  		struct {
> -			void __user *_call_addr; /* calling user insn */
> +			__SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
>  			int _syscall;	/* triggering system call number */
>  			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
>  		} _sigsys;
> @@ -283,6 +291,7 @@ typedef struct sigevent {
>  		int _pad[SIGEV_PAD_SIZE];
>  		 int _tid;
>  
> +		/* Note these two are handled only in userspace */
>  		struct {
>  			void (*_function)(sigval_t);
>  			void *_attribute;	/* really pthread_attr_t */

SIGEV_PAD_SIZE would be the same with ILP32 because sizeof(sigval_t)
would not change. So I think that's fine.

> diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
> index 9df61f1..c4ce238 100644
> --- a/include/uapi/asm-generic/signal.h
> +++ b/include/uapi/asm-generic/signal.h
> @@ -4,7 +4,9 @@
>  #include <linux/types.h>
>  
>  #define _NSIG		64
> +#ifndef _NSIG_BPW
>  #define _NSIG_BPW	__BITS_PER_LONG
> +#endif
>  #define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
>  
>  #define SIGHUP		 1
> @@ -83,9 +85,13 @@
>  #define MINSIGSTKSZ	2048
>  #define SIGSTKSZ	8192
>  
> +#ifndef __SIGSET_INNER_TYPE
> +#define __SIGSET_INNER_TYPE unsigned long
> +#endif
> +
>  #ifndef __ASSEMBLY__
>  typedef struct {
> -	unsigned long sig[_NSIG_WORDS];
> +	__SIGSET_INNER_TYPE sig[_NSIG_WORDS];
>  } sigset_t;

Would the default not work? The sigset_t structure ends up with the same
number of bits between LP64 and ILP32, whether you patch it or not.

>  
>  /* not actually used, but required for linux/syscalls.h */
> @@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t;
>  #endif
>  
>  #ifndef __KERNEL__
> +
> +#ifndef __SIGACTION_HANDLER
> +#define __SIGACTION_HANDLER(field)	__sighandler_t field
> +#endif
> +
> +#ifndef __SIGACTION_FLAGS
> +#define __SIGACTION_FLAGS(field)	unsigned long field
> +#endif
> +
> +#ifndef __SIGACTION_RESTORER
> +#define __SIGACTION_RESTORER(field)	__sigrestore_t field
> +#endif
> +
>  struct sigaction {
> -	__sighandler_t sa_handler;
> -	unsigned long sa_flags;
> +	__SIGACTION_HANDLER(sa_handler);
> +	__SIGACTION_FLAGS(sa_flags);
>  #ifdef SA_RESTORER
> -	__sigrestore_t sa_restorer;
> +	__SIGACTION_RESTORER(sa_restorer);
>  #endif
>  	sigset_t sa_mask;		/* mask last for extensibility */
>  };

Same comment here about the need for attributes (to clarify in
subsequent patch).

-- 
Catalin

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

* Re: [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-17 15:58     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:58 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:02AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
> index 5a74a08..1a6aa32 100644
> --- a/arch/arm64/include/uapi/asm/siginfo.h
> +++ b/arch/arm64/include/uapi/asm/siginfo.h
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2014 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
> @@ -18,6 +19,26 @@
>  
>  #define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
>  
> +#ifdef __ILP32__

Does the compiler define __ILP32__ or it just undefined __LP64__.
Anyway, maybe we should have some consistency and only use one in all
places.

> +# ifdef __AARCH64EB__
> +#  define __SIGINFO_INNER(type, field)		\
> +		int __pad#field;		\
> +		type field
> +# else
> +#  define __SIGINFO_INNER(type, field)		\
> +		type field;			\
> +		int __pad#field
> +# endif
> +
> +# undef __SIGINFO_VOIDPOINTER
> +# define __SIGINFO_VOIDPOINTER(field)		\
> +		__SIGINFO_INNER(void __user*, field)
> +# undef __SIGINFO_BAND
> +
> +# define __SIGINFO_BAND(field)			\
> +	__SIGINFO_INNER(long, field)
> +#endif
> +
>  #include <asm-generic/siginfo.h>
>  
>  #endif

Do the above give us the correct alignment for the _sifields union in
siginfo? Or we get it as a side-effect of some other structure member
forcing 64-bit alignment?

> diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h
> index 8d1e723..d90d53b 100644
> --- a/arch/arm64/include/uapi/asm/signal.h
> +++ b/arch/arm64/include/uapi/asm/signal.h
> @@ -19,6 +19,38 @@
>  /* Required for AArch32 compatibility. */
>  #define SA_RESTORER	0x04000000
>  
> +/* For ILP32, sigset should be the same size fields as LP64 so use
> +   unsigned long long. */
> +#ifdef __ILP32__
> +#define __SIGSET_INNER_TYPE __extension__ unsigned long long
> +#define _NSIG_BPW 64
> +
> +# ifdef __AARCH64EB__
> +#  define __SIGNAL_INNER(type, field)		\
> +	__extension__ struct {			\
> +		int __pad_##field;		\
> +		type field;			\
> +	} __attribute__((aligned(8)))
> +# else
> +#  define __SIGNAL_INNER(type, field)		\
> +	__extension__ struct {			\
> +		type field;			\
> +		int __pad_##field;		\
> +	} __attribute__((aligned(8)))
> +# endif
> +
> +# define __SIGACTION_HANDLER(field)		\
> +	__SIGNAL_INNER(__sighandler_t, field)
> +
> +
> +#define __SIGACTION_FLAGS(field)		\
> +	__extension__ unsigned long long field
> +
> +#define __SIGACTION_RESTORER(field)		\
> +	__SIGNAL_INNER(__sigrestore_t, field)
> +
> +#endif
> +
>  #include <asm-generic/signal.h>
>  
>  #endif

I haven't seen any UAPI header using __extension__. Is this allowed? I
assume we should be allowed to use the exported kernel headers with
non-gcc compilers.

-- 
Catalin

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

* [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64.
@ 2014-06-17 15:58     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:02AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
> index 5a74a08..1a6aa32 100644
> --- a/arch/arm64/include/uapi/asm/siginfo.h
> +++ b/arch/arm64/include/uapi/asm/siginfo.h
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2014 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
> @@ -18,6 +19,26 @@
>  
>  #define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
>  
> +#ifdef __ILP32__

Does the compiler define __ILP32__ or it just undefined __LP64__.
Anyway, maybe we should have some consistency and only use one in all
places.

> +# ifdef __AARCH64EB__
> +#  define __SIGINFO_INNER(type, field)		\
> +		int __pad#field;		\
> +		type field
> +# else
> +#  define __SIGINFO_INNER(type, field)		\
> +		type field;			\
> +		int __pad#field
> +# endif
> +
> +# undef __SIGINFO_VOIDPOINTER
> +# define __SIGINFO_VOIDPOINTER(field)		\
> +		__SIGINFO_INNER(void __user*, field)
> +# undef __SIGINFO_BAND
> +
> +# define __SIGINFO_BAND(field)			\
> +	__SIGINFO_INNER(long, field)
> +#endif
> +
>  #include <asm-generic/siginfo.h>
>  
>  #endif

Do the above give us the correct alignment for the _sifields union in
siginfo? Or we get it as a side-effect of some other structure member
forcing 64-bit alignment?

> diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h
> index 8d1e723..d90d53b 100644
> --- a/arch/arm64/include/uapi/asm/signal.h
> +++ b/arch/arm64/include/uapi/asm/signal.h
> @@ -19,6 +19,38 @@
>  /* Required for AArch32 compatibility. */
>  #define SA_RESTORER	0x04000000
>  
> +/* For ILP32, sigset should be the same size fields as LP64 so use
> +   unsigned long long. */
> +#ifdef __ILP32__
> +#define __SIGSET_INNER_TYPE __extension__ unsigned long long
> +#define _NSIG_BPW 64
> +
> +# ifdef __AARCH64EB__
> +#  define __SIGNAL_INNER(type, field)		\
> +	__extension__ struct {			\
> +		int __pad_##field;		\
> +		type field;			\
> +	} __attribute__((aligned(8)))
> +# else
> +#  define __SIGNAL_INNER(type, field)		\
> +	__extension__ struct {			\
> +		type field;			\
> +		int __pad_##field;		\
> +	} __attribute__((aligned(8)))
> +# endif
> +
> +# define __SIGACTION_HANDLER(field)		\
> +	__SIGNAL_INNER(__sighandler_t, field)
> +
> +
> +#define __SIGACTION_FLAGS(field)		\
> +	__extension__ unsigned long long field
> +
> +#define __SIGACTION_RESTORER(field)		\
> +	__SIGNAL_INNER(__sigrestore_t, field)
> +
> +#endif
> +
>  #include <asm-generic/signal.h>
>  
>  #endif

I haven't seen any UAPI header using __extension__. Is this allowed? I
assume we should be allowed to use the exported kernel headers with
non-gcc compilers.

-- 
Catalin

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

* Re: [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
  2014-05-24  7:02   ` Andrew Pinski
  (?)
@ 2014-06-17 16:22     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 16:22 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, linux-arch

On Sat, May 24, 2014 at 12:02:03AM -0700, Andrew Pinski wrote:
> In the ARM64 ILP32 case, we want to say the syscalls that normally
> would pass 64bit as two arguments are now passing as one so want to
> use the 64bit naming scheme.
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  include/uapi/asm-generic/unistd.h |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
> index 3336406..0648659 100644
> --- a/include/uapi/asm-generic/unistd.h
> +++ b/include/uapi/asm-generic/unistd.h
> @@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
>   * they take different names.
>   * Here we map the numbers so that both versions
>   * use the same syscall table layout.
> + * For 32bit abis where 64bit can be passed via one
> + * register, use the same naming as the 64bit ones
> + * as they will only have a 64 bit off_t.
>   */
> -#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
> +#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
>  #define __NR_fcntl __NR3264_fcntl
>  #define __NR_statfs __NR3264_statfs
>  #define __NR_fstatfs __NR3264_fstatfs

I can see why you are defining this. For compat, we don't expose
__SYSCALL_COMPAT to user. But this to work with ILP32 UAPI headers we
would have to define __SYSCALL_NONCOMPAT in the arm64 uapi unistd.h if
!__LP64__. I think we should use some naming closer to what we expose
via UAPI already (on other architectures) like
__ARCH_WANT_64BIT_SYSCALLS (or maybe we could reuse
__ARCH_WANT_SYSCALL_OFF_T).

-- 
Catalin

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

* Re: [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
@ 2014-06-17 16:22     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 16:22 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arch, linux-kernel, linux-arm-kernel

On Sat, May 24, 2014 at 12:02:03AM -0700, Andrew Pinski wrote:
> In the ARM64 ILP32 case, we want to say the syscalls that normally
> would pass 64bit as two arguments are now passing as one so want to
> use the 64bit naming scheme.
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  include/uapi/asm-generic/unistd.h |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
> index 3336406..0648659 100644
> --- a/include/uapi/asm-generic/unistd.h
> +++ b/include/uapi/asm-generic/unistd.h
> @@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
>   * they take different names.
>   * Here we map the numbers so that both versions
>   * use the same syscall table layout.
> + * For 32bit abis where 64bit can be passed via one
> + * register, use the same naming as the 64bit ones
> + * as they will only have a 64 bit off_t.
>   */
> -#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
> +#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
>  #define __NR_fcntl __NR3264_fcntl
>  #define __NR_statfs __NR3264_statfs
>  #define __NR_fstatfs __NR3264_fstatfs

I can see why you are defining this. For compat, we don't expose
__SYSCALL_COMPAT to user. But this to work with ILP32 UAPI headers we
would have to define __SYSCALL_NONCOMPAT in the arm64 uapi unistd.h if
!__LP64__. I think we should use some naming closer to what we expose
via UAPI already (on other architectures) like
__ARCH_WANT_64BIT_SYSCALLS (or maybe we could reuse
__ARCH_WANT_SYSCALL_OFF_T).

-- 
Catalin

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

* [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers.
@ 2014-06-17 16:22     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-17 16:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:03AM -0700, Andrew Pinski wrote:
> In the ARM64 ILP32 case, we want to say the syscalls that normally
> would pass 64bit as two arguments are now passing as one so want to
> use the 64bit naming scheme.
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  include/uapi/asm-generic/unistd.h |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
> index 3336406..0648659 100644
> --- a/include/uapi/asm-generic/unistd.h
> +++ b/include/uapi/asm-generic/unistd.h
> @@ -875,8 +875,11 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
>   * they take different names.
>   * Here we map the numbers so that both versions
>   * use the same syscall table layout.
> + * For 32bit abis where 64bit can be passed via one
> + * register, use the same naming as the 64bit ones
> + * as they will only have a 64 bit off_t.
>   */
> -#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
> +#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || defined(__SYSCALL_NONCOMPAT)
>  #define __NR_fcntl __NR3264_fcntl
>  #define __NR_statfs __NR3264_statfs
>  #define __NR_fstatfs __NR3264_fstatfs

I can see why you are defining this. For compat, we don't expose
__SYSCALL_COMPAT to user. But this to work with ILP32 UAPI headers we
would have to define __SYSCALL_NONCOMPAT in the arm64 uapi unistd.h if
!__LP64__. I think we should use some naming closer to what we expose
via UAPI already (on other architectures) like
__ARCH_WANT_64BIT_SYSCALLS (or maybe we could reuse
__ARCH_WANT_SYSCALL_OFF_T).

-- 
Catalin

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

* Re: [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-18  8:51     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-18  8:51 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:04AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
> index 1caadc2..067eab0 100644
> --- a/arch/arm64/include/uapi/asm/unistd.h
> +++ b/arch/arm64/include/uapi/asm/unistd.h
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2014 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
> @@ -13,4 +14,10 @@
>   * You should have received a copy of the GNU General Public License
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
> +
> +/* For ILP32 AARCH64, we want to use the non compat names. */
> +#if defined(__aarch64__) && defined(__ILP32__)

Another inconsistency for !__LP64__ vs __ILP32__. BTW, do we still need
__aarch64__ check? Do we expect these headers to be used with AArch32?

> +#define __SYSCALL_NONCOMPAT

As I mentioned in a previous patch, I prefer something like
__ARCH_WANT...

-- 
Catalin

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

* [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64.
@ 2014-06-18  8:51     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-18  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:04AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
> index 1caadc2..067eab0 100644
> --- a/arch/arm64/include/uapi/asm/unistd.h
> +++ b/arch/arm64/include/uapi/asm/unistd.h
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright (C) 2012 ARM Ltd.
> + * Copyright (C) 2014 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
> @@ -13,4 +14,10 @@
>   * You should have received a copy of the GNU General Public License
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
> +
> +/* For ILP32 AARCH64, we want to use the non compat names. */
> +#if defined(__aarch64__) && defined(__ILP32__)

Another inconsistency for !__LP64__ vs __ILP32__. BTW, do we still need
__aarch64__ check? Do we expect these headers to be used with AArch32?

> +#define __SYSCALL_NONCOMPAT

As I mentioned in a previous patch, I prefer something like
__ARCH_WANT...

-- 
Catalin

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

* Re: [PATCH 10/24] ARM64: Introduce is_a32_task and is_a32_thread. Use them in the correct locations.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-18 17:47     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-18 17:47 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:05AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index e71f81f..fad7612 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -293,28 +293,47 @@ struct compat_shmid64_ds {
>  	compat_ulong_t __unused5;
>  };
>  
> -static inline int is_compat_task(void)
> +#ifdef CONFIG_AARCH32_EL0
> +static inline int is_a32_compat_task(void)
>  {
>  	return test_thread_flag(TIF_32BIT);
>  }
> -
> -static inline int is_compat_thread(struct thread_info *thread)
> +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
>  
>  #else /* !CONFIG_COMPAT */
>  
> -static inline int is_compat_task(void)
> +static inline int is_a32_compat_task(void)
>  {
>  	return 0;
>  }
> -
> -static inline int is_compat_thread(struct thread_info *thread)
> +static inline int is_a32_compat_thread(struct thread_info *thread)
>  {
>  	return 0;
>  }

Why do we have 2 dummy definitions for is_a32_compat_task()? Could we
not squash them into one with different #ifdefs?

>  
>  #endif /* CONFIG_COMPAT */
> +
> +static inline int is_compat_task(void)
> +{
> +	return is_a32_compat_task();
> +}
> +
> +static inline int is_compat_thread(struct thread_info *thread)
> +{
> +	return is_a32_compat_thread(thread);
> +}
>  #endif /* __KERNEL__ */
>  #endif /* __ASM_COMPAT_H */
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 36c3603..8180511 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -150,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))

I think I tried something similar in the past and while it works most of
the time, you can easily get into an #include mess since now elf.h needs
compat.h. Similarly for other header files where you've changed this.

> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
> index 720e70b..b2bf728 100644
> --- a/arch/arm64/include/asm/thread_info.h
> +++ b/arch/arm64/include/asm/thread_info.h
> @@ -106,7 +106,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 */

Can we not just keep TIF_32BIT for limiting the address space to 32-bit
and use another bit for AArch32 applications?

-- 
Catalin

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

* [PATCH 10/24] ARM64: Introduce is_a32_task and is_a32_thread. Use them in the correct locations.
@ 2014-06-18 17:47     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-18 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:05AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index e71f81f..fad7612 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -293,28 +293,47 @@ struct compat_shmid64_ds {
>  	compat_ulong_t __unused5;
>  };
>  
> -static inline int is_compat_task(void)
> +#ifdef CONFIG_AARCH32_EL0
> +static inline int is_a32_compat_task(void)
>  {
>  	return test_thread_flag(TIF_32BIT);
>  }
> -
> -static inline int is_compat_thread(struct thread_info *thread)
> +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
>  
>  #else /* !CONFIG_COMPAT */
>  
> -static inline int is_compat_task(void)
> +static inline int is_a32_compat_task(void)
>  {
>  	return 0;
>  }
> -
> -static inline int is_compat_thread(struct thread_info *thread)
> +static inline int is_a32_compat_thread(struct thread_info *thread)
>  {
>  	return 0;
>  }

Why do we have 2 dummy definitions for is_a32_compat_task()? Could we
not squash them into one with different #ifdefs?

>  
>  #endif /* CONFIG_COMPAT */
> +
> +static inline int is_compat_task(void)
> +{
> +	return is_a32_compat_task();
> +}
> +
> +static inline int is_compat_thread(struct thread_info *thread)
> +{
> +	return is_a32_compat_thread(thread);
> +}
>  #endif /* __KERNEL__ */
>  #endif /* __ASM_COMPAT_H */
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 36c3603..8180511 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -150,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))

I think I tried something similar in the past and while it works most of
the time, you can easily get into an #include mess since now elf.h needs
compat.h. Similarly for other header files where you've changed this.

> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
> index 720e70b..b2bf728 100644
> --- a/arch/arm64/include/asm/thread_info.h
> +++ b/arch/arm64/include/asm/thread_info.h
> @@ -106,7 +106,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 */

Can we not just keep TIF_32BIT for limiting the address space to 32-bit
and use another bit for AArch32 applications?

-- 
Catalin

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

* Re: [PATCH 12/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and TIF_32BIT_AARCH64.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-19 12:49     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:49 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:07AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index fad7612..85f945c 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -313,6 +313,26 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  }
>  #endif
>  
> +#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
> +
>  #else /* !CONFIG_COMPAT */
>  
>  static inline int is_a32_compat_task(void)
> @@ -323,17 +343,25 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  {
>  	return 0;
>  }
> +static inline int is_ilp32_compat_task(void)
> +{
> +	return 0;
> +}
> +static inline int is_ilp32_compat_thread(struct thread_info *thread)
> +{
> +	return 0;
> +}

As for a previous patch, it looks like we have too many dummy
definitions for is_ilp32_compat_*().

>  
>  #endif /* CONFIG_COMPAT */
>  
>  static inline int is_compat_task(void)
>  {
> -	return is_a32_compat_task();
> +	return is_a32_compat_task() || is_ilp32_compat_task();
>  }
>  
>  static inline int is_compat_thread(struct thread_info *thread)
>  {
> -	return is_a32_compat_thread(thread);
> +	return is_a32_compat_thread(thread) || is_ilp32_compat_thread(thread);
>  }
>  #endif /* __KERNEL__ */
>  #endif /* __ASM_COMPAT_H */
> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
> index b2bf728..98baf65 100644
> --- a/arch/arm64/include/asm/thread_info.h
> +++ b/arch/arm64/include/asm/thread_info.h
> @@ -108,6 +108,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) */

The is_compat_task() code could be simplified if we keep the TIF_32BIT
flag for both 32 and 64-bit applications (ILP32) and define TIF_AARCH32.

-- 
Catalin

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

* [PATCH 12/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and TIF_32BIT_AARCH64.
@ 2014-06-19 12:49     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:07AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index fad7612..85f945c 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -313,6 +313,26 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  }
>  #endif
>  
> +#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
> +
>  #else /* !CONFIG_COMPAT */
>  
>  static inline int is_a32_compat_task(void)
> @@ -323,17 +343,25 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
>  {
>  	return 0;
>  }
> +static inline int is_ilp32_compat_task(void)
> +{
> +	return 0;
> +}
> +static inline int is_ilp32_compat_thread(struct thread_info *thread)
> +{
> +	return 0;
> +}

As for a previous patch, it looks like we have too many dummy
definitions for is_ilp32_compat_*().

>  
>  #endif /* CONFIG_COMPAT */
>  
>  static inline int is_compat_task(void)
>  {
> -	return is_a32_compat_task();
> +	return is_a32_compat_task() || is_ilp32_compat_task();
>  }
>  
>  static inline int is_compat_thread(struct thread_info *thread)
>  {
> -	return is_a32_compat_thread(thread);
> +	return is_a32_compat_thread(thread) || is_ilp32_compat_thread(thread);
>  }
>  #endif /* __KERNEL__ */
>  #endif /* __ASM_COMPAT_H */
> diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
> index b2bf728..98baf65 100644
> --- a/arch/arm64/include/asm/thread_info.h
> +++ b/arch/arm64/include/asm/thread_info.h
> @@ -108,6 +108,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) */

The is_compat_task() code could be simplified if we keep the TIF_32BIT
flag for both 32 and 64-bit applications (ILP32) and define TIF_AARCH32.

-- 
Catalin

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

* Re: [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-19 12:50     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:50 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, linux-input

On Sat, May 24, 2014 at 12:02:08AM -0700, Andrew Pinski wrote:
> diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
> index 148f66f..6656957 100644
> --- a/drivers/input/input-compat.h
> +++ b/drivers/input/input-compat.h
> @@ -19,7 +19,7 @@
>  
>  /* Note to the author of this code: did it ever occur to
>     you why the ifdefs are needed? Think about it again. -AK */
> -#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
> +#if defined(CONFIG_X86_64) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
>  #  define INPUT_COMPAT_TEST is_compat_task()
>  #elif defined(CONFIG_S390)
>  #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)

And this patch could be removed if we keep TIF_32BIT common.

-- 
Catalin

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

* [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also.
@ 2014-06-19 12:50     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:08AM -0700, Andrew Pinski wrote:
> diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
> index 148f66f..6656957 100644
> --- a/drivers/input/input-compat.h
> +++ b/drivers/input/input-compat.h
> @@ -19,7 +19,7 @@
>  
>  /* Note to the author of this code: did it ever occur to
>     you why the ifdefs are needed? Think about it again. -AK */
> -#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
> +#if defined(CONFIG_X86_64) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
>  #  define INPUT_COMPAT_TEST is_compat_task()
>  #elif defined(CONFIG_S390)
>  #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)

And this patch could be removed if we keep TIF_32BIT common.

-- 
Catalin

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

* Re: [PATCH 14/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-19 12:52     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:52 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:09AM -0700, Andrew Pinski wrote:
> Since __kernel_long_t (time_t) is long long, we need to tell the rest
> of kernel that we use 64bit time_t for compat when the task is not an
> AARCH32 task.  The reason why we check AARCH32 rather than ILP32 here
> is because if we don't have AARCH32 compiled in (which is going to be
> the common case due to AARCH32 requiring 4k pages).
> 
> Thanks,
> Andrew Pinski
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  arch/arm64/include/asm/compat.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index 85f945c..c77fc0f 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -76,6 +76,9 @@ struct compat_timeval {
>  	s32		tv_usec;
>  };
>  
> +/* ILP32 uses 64bit time_t and not the above compat structures */
> +#define COMPAT_USE_64BIT_TIME !is_a32_compat_task()

Brackets.

BTW, you could write is_ilp32_compat_task().

-- 
Catalin

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

* [PATCH 14/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks.
@ 2014-06-19 12:52     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:09AM -0700, Andrew Pinski wrote:
> Since __kernel_long_t (time_t) is long long, we need to tell the rest
> of kernel that we use 64bit time_t for compat when the task is not an
> AARCH32 task.  The reason why we check AARCH32 rather than ILP32 here
> is because if we don't have AARCH32 compiled in (which is going to be
> the common case due to AARCH32 requiring 4k pages).
> 
> Thanks,
> Andrew Pinski
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  arch/arm64/include/asm/compat.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index 85f945c..c77fc0f 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -76,6 +76,9 @@ struct compat_timeval {
>  	s32		tv_usec;
>  };
>  
> +/* ILP32 uses 64bit time_t and not the above compat structures */
> +#define COMPAT_USE_64BIT_TIME !is_a32_compat_task()

Brackets.

BTW, you could write is_ilp32_compat_task().

-- 
Catalin

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

* Re: [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-06-19 12:54     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:54 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:10AM -0700, Andrew Pinski wrote:
> Signed-off-by: Andrew Pinski <apinski@cavium.com>

Please add some commit log, even if minimal.

> ---
>  arch/arm64/include/asm/hwcap.h |   12 ++++++++++--
>  1 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
> index 024c461..cb87f91 100644
> --- a/arch/arm64/include/asm/hwcap.h
> +++ b/arch/arm64/include/asm/hwcap.h
> @@ -46,9 +46,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;

Do any extra headers need to be included? It looks like we rely on the
code including hwcap.h to have the correct headers.

-- 
Catalin

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

* [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32.
@ 2014-06-19 12:54     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-06-19 12:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:10AM -0700, Andrew Pinski wrote:
> Signed-off-by: Andrew Pinski <apinski@cavium.com>

Please add some commit log, even if minimal.

> ---
>  arch/arm64/include/asm/hwcap.h |   12 ++++++++++--
>  1 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
> index 024c461..cb87f91 100644
> --- a/arch/arm64/include/asm/hwcap.h
> +++ b/arch/arm64/include/asm/hwcap.h
> @@ -46,9 +46,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;

Do any extra headers need to be included? It looks like we rely on the
code including hwcap.h to have the correct headers.

-- 
Catalin

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

* Re: [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-07-01 13:01     ` Dr. Philipp Tomsich
  -1 siblings, 0 replies; 105+ messages in thread
From: Dr. Philipp Tomsich @ 2014-07-01 13:01 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On 24 May 2014, at 09:02 , Andrew Pinski <apinski@cavium.com> 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

You missed the COMPAT_ELF_PLATFORM (in arm64/include/asm/elf.h), which is used to setup AT_PLATFORM in the auxilary vectors. I’d suggest to use a similar naming convention to what will be used in gdb (i.e. appending a “:ilp32” to the base architecture.

The proposed change would thus be:
---
 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 3f979b5..6d38edc 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -168,9 +168,9 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #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         (randomize_et_dyn(2 * TASK_SIZE_32 / 3))
-- 
1.9.0


Best,
Philipp.

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

* [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32.
@ 2014-07-01 13:01     ` Dr. Philipp Tomsich
  0 siblings, 0 replies; 105+ messages in thread
From: Dr. Philipp Tomsich @ 2014-07-01 13:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 24 May 2014, at 09:02 , Andrew Pinski <apinski@cavium.com> 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

You missed the COMPAT_ELF_PLATFORM (in arm64/include/asm/elf.h), which is used to setup AT_PLATFORM in the auxilary vectors. I?d suggest to use a similar naming convention to what will be used in gdb (i.e. appending a ?:ilp32? to the base architecture.

The proposed change would thus be:
---
 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 3f979b5..6d38edc 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -168,9 +168,9 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #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         (randomize_et_dyn(2 * TASK_SIZE_32 / 3))
-- 
1.9.0


Best,
Philipp.

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

* Re: [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-05-24  7:02   ` Andrew Pinski
@ 2014-07-01 15:05     ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-07-01 15:05 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel

On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 1e1ebfc..8241ffe 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -620,9 +620,14 @@ 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
> +	get_thread_info tsk
> +	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

This adds a slight penalty on the AArch64 SVC entry path. I can't tell
whether that's visible or not but I think the x86 guys decided to set an
extra bit to the syscall number to distinguish it from native calls.

> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> new file mode 100644
> index 0000000..1da1d11
> --- /dev/null
> +++ b/arch/arm64/kernel/sys_ilp32.c
[...]
> +/*
> + * Wrappers to pass the pt_regs argument.
> + */
> +#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
> +
> +
> +/* Using Compat syscalls where necessary */
> +#define sys_ioctl		compat_sys_ioctl
> +/* iovec */
> +#define sys_readv		compat_sys_readv
> +#define sys_writev		compat_sys_writev
> +#define sys_preadv		compat_sys_preadv64
> +#define sys_pwritev		compat_sys_pwritev64
> +#define sys_vmsplice		compat_sys_vmsplice

Do these actually work? compat_iovec has two members of 32-bit each
while the ILP32 iovec has a void * (32-bit) and a __kernel_size_t which
is 64-bit.

> +/* robust_list_head */
> +#define sys_set_robust_list	compat_sys_set_robust_list
> +#define sys_get_robust_list	compat_sys_get_robust_list

Same here, we have a size_t * argument. The compat function would write
back 32-bit but size_t is 64-bit for ILP32.

> +/* kexec_segment */
> +#define sys_kexec_load		compat_sys_kexec_load

More size_t members in the kexec_segment structure (but we don't yet
have kexec on arm64).

> +/* struct msghdr */
> +#define sys_recvfrom		compat_sys_recvfrom

Why compat here? struct sockaddr seems to be the same as the native one.

> +#define sys_recvmmsg		compat_sys_recvmmsg
> +#define sys_sendmmsg		compat_sys_sendmmsg
> +#define sys_sendmsg		compat_sys_sendmsg
> +#define sys_recvmsg		compat_sys_recvmsg

These get messier as well with a different size_t affecting struct
msghdr.

> +#define sys_setsockopt		compat_sys_setsockopt
> +#define sys_getsockopt		compat_sys_getsockopt

Looking at the sock_getsockopt() function, we have a union v copied
to/from user. However, such a union contains a struct timeval which for
ILP32 would be different than the compat one.

> +/* iovec */
> +#define sys_process_vm_readv	compat_sys_process_vm_readv
> +#define sys_process_vm_writev	compat_sys_process_vm_writev

See above for iovec.

> +/* Pointer in struct */
> +#define sys_mount               compat_sys_mount

Which structure is this?

> +/* Scheduler */
> +/* unsigned long bitmaps */
> +#define sys_sched_setaffinity   compat_sys_sched_setaffinity
> +#define sys_sched_getaffinity   compat_sys_sched_getaffinity

Does the long bitmask matter here? I can see the length is passed in
bytes.

> +/* iov usage */
> +#define sys_keyctl              compat_sys_keyctl

Same problem as iovec above.

> +/* aio */
> +/* Pointer to Pointer  */
> +#define sys_io_setup		compat_sys_io_setup

sys_io_setup takes a pointer to aio_context_t which is defined as
__kernel_ulong_t (same as LP64).

-- 
Catalin

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-07-01 15:05     ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-07-01 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 1e1ebfc..8241ffe 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -620,9 +620,14 @@ 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
> +	get_thread_info tsk
> +	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

This adds a slight penalty on the AArch64 SVC entry path. I can't tell
whether that's visible or not but I think the x86 guys decided to set an
extra bit to the syscall number to distinguish it from native calls.

> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> new file mode 100644
> index 0000000..1da1d11
> --- /dev/null
> +++ b/arch/arm64/kernel/sys_ilp32.c
[...]
> +/*
> + * Wrappers to pass the pt_regs argument.
> + */
> +#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
> +
> +
> +/* Using Compat syscalls where necessary */
> +#define sys_ioctl		compat_sys_ioctl
> +/* iovec */
> +#define sys_readv		compat_sys_readv
> +#define sys_writev		compat_sys_writev
> +#define sys_preadv		compat_sys_preadv64
> +#define sys_pwritev		compat_sys_pwritev64
> +#define sys_vmsplice		compat_sys_vmsplice

Do these actually work? compat_iovec has two members of 32-bit each
while the ILP32 iovec has a void * (32-bit) and a __kernel_size_t which
is 64-bit.

> +/* robust_list_head */
> +#define sys_set_robust_list	compat_sys_set_robust_list
> +#define sys_get_robust_list	compat_sys_get_robust_list

Same here, we have a size_t * argument. The compat function would write
back 32-bit but size_t is 64-bit for ILP32.

> +/* kexec_segment */
> +#define sys_kexec_load		compat_sys_kexec_load

More size_t members in the kexec_segment structure (but we don't yet
have kexec on arm64).

> +/* struct msghdr */
> +#define sys_recvfrom		compat_sys_recvfrom

Why compat here? struct sockaddr seems to be the same as the native one.

> +#define sys_recvmmsg		compat_sys_recvmmsg
> +#define sys_sendmmsg		compat_sys_sendmmsg
> +#define sys_sendmsg		compat_sys_sendmsg
> +#define sys_recvmsg		compat_sys_recvmsg

These get messier as well with a different size_t affecting struct
msghdr.

> +#define sys_setsockopt		compat_sys_setsockopt
> +#define sys_getsockopt		compat_sys_getsockopt

Looking at the sock_getsockopt() function, we have a union v copied
to/from user. However, such a union contains a struct timeval which for
ILP32 would be different than the compat one.

> +/* iovec */
> +#define sys_process_vm_readv	compat_sys_process_vm_readv
> +#define sys_process_vm_writev	compat_sys_process_vm_writev

See above for iovec.

> +/* Pointer in struct */
> +#define sys_mount               compat_sys_mount

Which structure is this?

> +/* Scheduler */
> +/* unsigned long bitmaps */
> +#define sys_sched_setaffinity   compat_sys_sched_setaffinity
> +#define sys_sched_getaffinity   compat_sys_sched_getaffinity

Does the long bitmask matter here? I can see the length is passed in
bytes.

> +/* iov usage */
> +#define sys_keyctl              compat_sys_keyctl

Same problem as iovec above.

> +/* aio */
> +/* Pointer to Pointer  */
> +#define sys_io_setup		compat_sys_io_setup

sys_io_setup takes a pointer to aio_context_t which is defined as
__kernel_ulong_t (same as LP64).

-- 
Catalin

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

* Re: [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-07-01 15:05     ` Catalin Marinas
@ 2014-07-01 15:30       ` Pinski, Andrew
  -1 siblings, 0 replies; 105+ messages in thread
From: Pinski, Andrew @ 2014-07-01 15:30 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: Andrew Pinski, linux-arm-kernel, linux-kernel



> On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> 
>> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>> index 1e1ebfc..8241ffe 100644
>> --- a/arch/arm64/kernel/entry.S
>> +++ b/arch/arm64/kernel/entry.S
>> @@ -620,9 +620,14 @@ 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
>> +    get_thread_info tsk
>> +    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
> 
> This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> whether that's visible or not but I think the x86 guys decided to set an
> extra bit to the syscall number to distinguish it from native calls.
> 
>> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
>> new file mode 100644
>> index 0000000..1da1d11
>> --- /dev/null
>> +++ b/arch/arm64/kernel/sys_ilp32.c
> [...]
>> +/*
>> + * Wrappers to pass the pt_regs argument.
>> + */
>> +#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
>> +
>> +
>> +/* Using Compat syscalls where necessary */
>> +#define sys_ioctl        compat_sys_ioctl
>> +/* iovec */
>> +#define sys_readv        compat_sys_readv
>> +#define sys_writev        compat_sys_writev
>> +#define sys_preadv        compat_sys_preadv64
>> +#define sys_pwritev        compat_sys_pwritev64
>> +#define sys_vmsplice        compat_sys_vmsplice
> 
> Do these actually work? compat_iovec has two members of 32-bit each
> while the ILP32 iovec has a void * (32-bit) and a __kernel_size_t which
> is 64-bit.

size_t should be unsigned long in ilp32 so a 32bit unsigned integer type.  That part of the abi was already defined in the arm abi documents.  Now are saying we should pass size_t different between user and kernel space?

> 
>> +/* robust_list_head */
>> +#define sys_set_robust_list    compat_sys_set_robust_list
>> +#define sys_get_robust_list    compat_sys_get_robust_list
> 
> Same here, we have a size_t * argument. The compat function would write
> back 32-bit but size_t is 64-bit for ILP32.

See above. Size_t is 32bits. 

> 
>> +/* kexec_segment */
>> +#define sys_kexec_load        compat_sys_kexec_load
> 
> More size_t members in the kexec_segment structure (but we don't yet
> have kexec on arm64).

See above. Size_t is 32bits. 

> 
>> +/* struct msghdr */
>> +#define sys_recvfrom        compat_sys_recvfrom
> 
> Why compat here? struct sockaddr seems to be the same as the native one.
> 
>> +#define sys_recvmmsg        compat_sys_recvmmsg
>> +#define sys_sendmmsg        compat_sys_sendmmsg
>> +#define sys_sendmsg        compat_sys_sendmsg
>> +#define sys_recvmsg        compat_sys_recvmsg
> 
> These get messier as well with a different size_t affecting struct
> msghdr.

See above about size_t. 


> 
>> +#define sys_setsockopt        compat_sys_setsockopt
>> +#define sys_getsockopt        compat_sys_getsockopt
> 
> Looking at the sock_getsockopt() function, we have a union v copied
> to/from user. However, such a union contains a struct timeval which for
> ILP32 would be different than the compat one.

I will look into this one but it might already be taken care of due to the compact uses 64bit time spec define. I will add a comment saying that if it is true. 


> 
>> +/* iovec */
>> +#define sys_process_vm_readv    compat_sys_process_vm_readv
>> +#define sys_process_vm_writev    compat_sys_process_vm_writev
> 
> See above for iovec.

See above for my size_t question. 

> 
>> +/* Pointer in struct */
>> +#define sys_mount               compat_sys_mount
> 
> Which structure is this?

NFS structure, I can expand out the comment if needed. 


> 
>> +/* Scheduler */
>> +/* unsigned long bitmaps */
>> +#define sys_sched_setaffinity   compat_sys_sched_setaffinity
>> +#define sys_sched_getaffinity   compat_sys_sched_getaffinity
> 
> Does the long bitmask matter here? I can see the length is passed in
> bytes.

Yes for big endian. If we were only supporting little endian, bit fields would not matter. 

> 
>> +/* iov usage */
>> +#define sys_keyctl              compat_sys_keyctl
> 
> Same problem as iovec above.
> 
>> +/* aio */
>> +/* Pointer to Pointer  */
>> +#define sys_io_setup        compat_sys_io_setup
> 
> sys_io_setup takes a pointer to aio_context_t which is defined as
> __kernel_ulong_t (same as LP64).

Let me look at why I did this one, I think the code which used aio was not in glibc which is why I used the compat version. 

Thanks,
Andrew

> 
> -- 
> Catalin

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-07-01 15:30       ` Pinski, Andrew
  0 siblings, 0 replies; 105+ messages in thread
From: Pinski, Andrew @ 2014-07-01 15:30 UTC (permalink / raw)
  To: linux-arm-kernel



> On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> 
>> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>> index 1e1ebfc..8241ffe 100644
>> --- a/arch/arm64/kernel/entry.S
>> +++ b/arch/arm64/kernel/entry.S
>> @@ -620,9 +620,14 @@ 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
>> +    get_thread_info tsk
>> +    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
> 
> This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> whether that's visible or not but I think the x86 guys decided to set an
> extra bit to the syscall number to distinguish it from native calls.
> 
>> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
>> new file mode 100644
>> index 0000000..1da1d11
>> --- /dev/null
>> +++ b/arch/arm64/kernel/sys_ilp32.c
> [...]
>> +/*
>> + * Wrappers to pass the pt_regs argument.
>> + */
>> +#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
>> +
>> +
>> +/* Using Compat syscalls where necessary */
>> +#define sys_ioctl        compat_sys_ioctl
>> +/* iovec */
>> +#define sys_readv        compat_sys_readv
>> +#define sys_writev        compat_sys_writev
>> +#define sys_preadv        compat_sys_preadv64
>> +#define sys_pwritev        compat_sys_pwritev64
>> +#define sys_vmsplice        compat_sys_vmsplice
> 
> Do these actually work? compat_iovec has two members of 32-bit each
> while the ILP32 iovec has a void * (32-bit) and a __kernel_size_t which
> is 64-bit.

size_t should be unsigned long in ilp32 so a 32bit unsigned integer type.  That part of the abi was already defined in the arm abi documents.  Now are saying we should pass size_t different between user and kernel space?

> 
>> +/* robust_list_head */
>> +#define sys_set_robust_list    compat_sys_set_robust_list
>> +#define sys_get_robust_list    compat_sys_get_robust_list
> 
> Same here, we have a size_t * argument. The compat function would write
> back 32-bit but size_t is 64-bit for ILP32.

See above. Size_t is 32bits. 

> 
>> +/* kexec_segment */
>> +#define sys_kexec_load        compat_sys_kexec_load
> 
> More size_t members in the kexec_segment structure (but we don't yet
> have kexec on arm64).

See above. Size_t is 32bits. 

> 
>> +/* struct msghdr */
>> +#define sys_recvfrom        compat_sys_recvfrom
> 
> Why compat here? struct sockaddr seems to be the same as the native one.
> 
>> +#define sys_recvmmsg        compat_sys_recvmmsg
>> +#define sys_sendmmsg        compat_sys_sendmmsg
>> +#define sys_sendmsg        compat_sys_sendmsg
>> +#define sys_recvmsg        compat_sys_recvmsg
> 
> These get messier as well with a different size_t affecting struct
> msghdr.

See above about size_t. 


> 
>> +#define sys_setsockopt        compat_sys_setsockopt
>> +#define sys_getsockopt        compat_sys_getsockopt
> 
> Looking at the sock_getsockopt() function, we have a union v copied
> to/from user. However, such a union contains a struct timeval which for
> ILP32 would be different than the compat one.

I will look into this one but it might already be taken care of due to the compact uses 64bit time spec define. I will add a comment saying that if it is true. 


> 
>> +/* iovec */
>> +#define sys_process_vm_readv    compat_sys_process_vm_readv
>> +#define sys_process_vm_writev    compat_sys_process_vm_writev
> 
> See above for iovec.

See above for my size_t question. 

> 
>> +/* Pointer in struct */
>> +#define sys_mount               compat_sys_mount
> 
> Which structure is this?

NFS structure, I can expand out the comment if needed. 


> 
>> +/* Scheduler */
>> +/* unsigned long bitmaps */
>> +#define sys_sched_setaffinity   compat_sys_sched_setaffinity
>> +#define sys_sched_getaffinity   compat_sys_sched_getaffinity
> 
> Does the long bitmask matter here? I can see the length is passed in
> bytes.

Yes for big endian. If we were only supporting little endian, bit fields would not matter. 

> 
>> +/* iov usage */
>> +#define sys_keyctl              compat_sys_keyctl
> 
> Same problem as iovec above.
> 
>> +/* aio */
>> +/* Pointer to Pointer  */
>> +#define sys_io_setup        compat_sys_io_setup
> 
> sys_io_setup takes a pointer to aio_context_t which is defined as
> __kernel_ulong_t (same as LP64).

Let me look at why I did this one, I think the code which used aio was not in glibc which is why I used the compat version. 

Thanks,
Andrew

> 
> -- 
> Catalin

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

* Re: [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-07-01 15:30       ` Pinski, Andrew
@ 2014-07-01 16:38         ` Arnd Bergmann
  -1 siblings, 0 replies; 105+ messages in thread
From: Arnd Bergmann @ 2014-07-01 16:38 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Pinski, Andrew, Catalin Marinas, Andrew Pinski, linux-kernel

On Tuesday 01 July 2014 15:30:51 Pinski, Andrew wrote:
> > On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> >> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> >> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> >> index 1e1ebfc..8241ffe 100644
> >> --- a/arch/arm64/kernel/entry.S
> >> +++ b/arch/arm64/kernel/entry.S
> >> @@ -620,9 +620,14 @@ 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
> >> +    get_thread_info tsk
> >> +    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
> > 
> > This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> > whether that's visible or not but I think the x86 guys decided to set an
> > extra bit to the syscall number to distinguish it from native calls.

IIRC the intention on x86 was that you should always be able to call
any of the three syscall ABIs (x86-32, x86-64, x32) from any process
by passing the right number, for flexibility.

	Arnd

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-07-01 16:38         ` Arnd Bergmann
  0 siblings, 0 replies; 105+ messages in thread
From: Arnd Bergmann @ 2014-07-01 16:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 01 July 2014 15:30:51 Pinski, Andrew wrote:
> > On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> >> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> >> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> >> index 1e1ebfc..8241ffe 100644
> >> --- a/arch/arm64/kernel/entry.S
> >> +++ b/arch/arm64/kernel/entry.S
> >> @@ -620,9 +620,14 @@ 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
> >> +    get_thread_info tsk
> >> +    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
> > 
> > This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> > whether that's visible or not but I think the x86 guys decided to set an
> > extra bit to the syscall number to distinguish it from native calls.

IIRC the intention on x86 was that you should always be able to call
any of the three syscall ABIs (x86-32, x86-64, x32) from any process
by passing the right number, for flexibility.

	Arnd

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

* Re: [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-07-01 15:30       ` Pinski, Andrew
@ 2014-07-01 16:49         ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-07-01 16:49 UTC (permalink / raw)
  To: Pinski, Andrew; +Cc: Andrew Pinski, linux-arm-kernel, linux-kernel

On Tue, Jul 01, 2014 at 04:30:51PM +0100, Pinski, Andrew wrote:
> On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> > On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> >> +/* Using Compat syscalls where necessary */
> >> +#define sys_ioctl        compat_sys_ioctl
> >> +/* iovec */
> >> +#define sys_readv        compat_sys_readv
> >> +#define sys_writev        compat_sys_writev
> >> +#define sys_preadv        compat_sys_preadv64
> >> +#define sys_pwritev        compat_sys_pwritev64
> >> +#define sys_vmsplice        compat_sys_vmsplice
> > 
> > Do these actually work? compat_iovec has two members of 32-bit each
> > while the ILP32 iovec has a void * (32-bit) and a __kernel_size_t which
> > is 64-bit.
> 
> size_t should be unsigned long in ilp32 so a 32bit unsigned integer
> type.  That part of the abi was already defined in the arm abi
> documents.  Now are saying we should pass size_t different between
> user and kernel space?

OK, I think you are right here. The ILP32 would not see __kernel_size_t
defined as __kernel_ulong_t because __BITS_PER_LONG != 64.

> >> +/* Pointer in struct */
> >> +#define sys_mount               compat_sys_mount
> > 
> > Which structure is this?
> 
> NFS structure, I can expand out the comment if needed. 

That would be good for future reference.

Thanks.

-- 
Catalin

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-07-01 16:49         ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-07-01 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 01, 2014 at 04:30:51PM +0100, Pinski, Andrew wrote:
> On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> > On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> >> +/* Using Compat syscalls where necessary */
> >> +#define sys_ioctl        compat_sys_ioctl
> >> +/* iovec */
> >> +#define sys_readv        compat_sys_readv
> >> +#define sys_writev        compat_sys_writev
> >> +#define sys_preadv        compat_sys_preadv64
> >> +#define sys_pwritev        compat_sys_pwritev64
> >> +#define sys_vmsplice        compat_sys_vmsplice
> > 
> > Do these actually work? compat_iovec has two members of 32-bit each
> > while the ILP32 iovec has a void * (32-bit) and a __kernel_size_t which
> > is 64-bit.
> 
> size_t should be unsigned long in ilp32 so a 32bit unsigned integer
> type.  That part of the abi was already defined in the arm abi
> documents.  Now are saying we should pass size_t different between
> user and kernel space?

OK, I think you are right here. The ILP32 would not see __kernel_size_t
defined as __kernel_ulong_t because __BITS_PER_LONG != 64.

> >> +/* Pointer in struct */
> >> +#define sys_mount               compat_sys_mount
> > 
> > Which structure is this?
> 
> NFS structure, I can expand out the comment if needed. 

That would be good for future reference.

Thanks.

-- 
Catalin

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

* Re: [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-07-01 16:38         ` Arnd Bergmann
@ 2014-07-01 16:50           ` Catalin Marinas
  -1 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-07-01 16:50 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Pinski, Andrew, Andrew Pinski, linux-kernel

On Tue, Jul 01, 2014 at 05:38:12PM +0100, Arnd Bergmann wrote:
> On Tuesday 01 July 2014 15:30:51 Pinski, Andrew wrote:
> > > On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> > >> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> > >> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > >> index 1e1ebfc..8241ffe 100644
> > >> --- a/arch/arm64/kernel/entry.S
> > >> +++ b/arch/arm64/kernel/entry.S
> > >> @@ -620,9 +620,14 @@ 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
> > >> +    get_thread_info tsk
> > >> +    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
> > > 
> > > This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> > > whether that's visible or not but I think the x86 guys decided to set an
> > > extra bit to the syscall number to distinguish it from native calls.
> 
> IIRC the intention on x86 was that you should always be able to call
> any of the three syscall ABIs (x86-32, x86-64, x32) from any process
> by passing the right number, for flexibility.

I don't see how this is useful though. Do you happen to have more
information?

-- 
Catalin

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-07-01 16:50           ` Catalin Marinas
  0 siblings, 0 replies; 105+ messages in thread
From: Catalin Marinas @ 2014-07-01 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 01, 2014 at 05:38:12PM +0100, Arnd Bergmann wrote:
> On Tuesday 01 July 2014 15:30:51 Pinski, Andrew wrote:
> > > On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> > >> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> > >> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > >> index 1e1ebfc..8241ffe 100644
> > >> --- a/arch/arm64/kernel/entry.S
> > >> +++ b/arch/arm64/kernel/entry.S
> > >> @@ -620,9 +620,14 @@ 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
> > >> +    get_thread_info tsk
> > >> +    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
> > > 
> > > This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> > > whether that's visible or not but I think the x86 guys decided to set an
> > > extra bit to the syscall number to distinguish it from native calls.
> 
> IIRC the intention on x86 was that you should always be able to call
> any of the three syscall ABIs (x86-32, x86-64, x32) from any process
> by passing the right number, for flexibility.

I don't see how this is useful though. Do you happen to have more
information?

-- 
Catalin

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

* Re: [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
  2014-07-01 16:50           ` Catalin Marinas
@ 2014-07-01 17:04             ` Arnd Bergmann
  -1 siblings, 0 replies; 105+ messages in thread
From: Arnd Bergmann @ 2014-07-01 17:04 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Catalin Marinas, Pinski, Andrew, Andrew Pinski, linux-kernel

On Tuesday 01 July 2014 17:50:41 Catalin Marinas wrote:
> On Tue, Jul 01, 2014 at 05:38:12PM +0100, Arnd Bergmann wrote:
> > On Tuesday 01 July 2014 15:30:51 Pinski, Andrew wrote:
> > > > On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> > > >> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> > > >> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > > >> index 1e1ebfc..8241ffe 100644
> > > >> --- a/arch/arm64/kernel/entry.S
> > > >> +++ b/arch/arm64/kernel/entry.S
> > > >> @@ -620,9 +620,14 @@ 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
> > > >> +    get_thread_info tsk
> > > >> +    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
> > > > 
> > > > This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> > > > whether that's visible or not but I think the x86 guys decided to set an
> > > > extra bit to the syscall number to distinguish it from native calls.
> > 
> > IIRC the intention on x86 was that you should always be able to call
> > any of the three syscall ABIs (x86-32, x86-64, x32) from any process
> > by passing the right number, for flexibility.
> 
> I don't see how this is useful though. Do you happen to have more
> information?

It's been a decade since this code was merged, so my memory isn't very
good here. I believe one of the main reasons was being able to run
emulation layers in user space that make use of the kernel helpers.

Another use case might be an application that wants to use the native
ioctl interface for a driver that does not have a (efficient) compat
ioctl handler.

	Arnd

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

* [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls.
@ 2014-07-01 17:04             ` Arnd Bergmann
  0 siblings, 0 replies; 105+ messages in thread
From: Arnd Bergmann @ 2014-07-01 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 01 July 2014 17:50:41 Catalin Marinas wrote:
> On Tue, Jul 01, 2014 at 05:38:12PM +0100, Arnd Bergmann wrote:
> > On Tuesday 01 July 2014 15:30:51 Pinski, Andrew wrote:
> > > > On Jul 1, 2014, at 8:07 AM, "Catalin Marinas" <catalin.marinas@arm.com> wrote:
> > > >> On Sat, May 24, 2014 at 12:02:17AM -0700, Andrew Pinski wrote:
> > > >> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > > >> index 1e1ebfc..8241ffe 100644
> > > >> --- a/arch/arm64/kernel/entry.S
> > > >> +++ b/arch/arm64/kernel/entry.S
> > > >> @@ -620,9 +620,14 @@ 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
> > > >> +    get_thread_info tsk
> > > >> +    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
> > > > 
> > > > This adds a slight penalty on the AArch64 SVC entry path. I can't tell
> > > > whether that's visible or not but I think the x86 guys decided to set an
> > > > extra bit to the syscall number to distinguish it from native calls.
> > 
> > IIRC the intention on x86 was that you should always be able to call
> > any of the three syscall ABIs (x86-32, x86-64, x32) from any process
> > by passing the right number, for flexibility.
> 
> I don't see how this is useful though. Do you happen to have more
> information?

It's been a decade since this code was merged, so my memory isn't very
good here. I believe one of the main reasons was being able to run
emulation layers in user space that make use of the kernel helpers.

Another use case might be an application that wants to use the native
ioctl interface for a driver that does not have a (efficient) compat
ioctl handler.

	Arnd

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

end of thread, other threads:[~2014-07-01 17:04 UTC | newest]

Thread overview: 105+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-24  7:01 [PATCHv2 00/24] ILP32 Support in ARM64 Andrew Pinski
2014-05-24  7:01 ` Andrew Pinski
2014-05-24  7:01 ` [PATCH 01/24] ARM64: Force LP64 to compile the kernel Andrew Pinski
2014-05-24  7:01   ` Andrew Pinski
2014-05-24  7:01 ` [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig Andrew Pinski
2014-05-24  7:01   ` Andrew Pinski
2014-05-24  7:01 ` [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Andrew Pinski
2014-05-24  7:01   ` Andrew Pinski
2014-06-17 15:15   ` Catalin Marinas
2014-06-17 15:15     ` Catalin Marinas
2014-05-24  7:01 ` [PATCH 04/24] ARM64:ILP32: Set kernel_long to long long so we can reuse most of the same syscalls as LP64 Andrew Pinski
2014-05-24  7:01   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-17 15:22   ` Catalin Marinas
2014-06-17 15:22     ` Catalin Marinas
2014-06-17 15:29     ` Arnd Bergmann
2014-06-17 15:29       ` Arnd Bergmann
2014-05-24  7:02 ` [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-17 15:43   ` Catalin Marinas
2014-06-17 15:43     ` Catalin Marinas
2014-05-24  7:02 ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-17 15:58   ` Catalin Marinas
2014-06-17 15:58     ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 08/24] Allow a 32bit ABI to use the naming of the 64bit ABI syscalls to avoid confusion of not splitting the registers Andrew Pinski
2014-05-24  7:02 ` Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-17 16:22   ` Catalin Marinas
2014-06-17 16:22     ` Catalin Marinas
2014-06-17 16:22     ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-18  8:51   ` Catalin Marinas
2014-06-18  8:51     ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 10/24] ARM64: Introduce is_a32_task and is_a32_thread. Use them in the correct locations Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-18 17:47   ` Catalin Marinas
2014-06-18 17:47     ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 11/24] ARM64: Add ARM64_ILP32 to Kconfig Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 12/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread and TIF_32BIT_AARCH64 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-19 12:49   ` Catalin Marinas
2014-06-19 12:49     ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 13/24] Drivers:input: Use is_compat_task for ARM64 also Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-19 12:50   ` Catalin Marinas
2014-06-19 12:50     ` Catalin Marinas
2014-05-24  7:02 ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 14/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-19 12:52   ` Catalin Marinas
2014-06-19 12:52     ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 15/24] ARM64:ILP32: Use the non compat HWCAP for ILP32 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-19 12:54   ` Catalin Marinas
2014-06-19 12:54     ` Catalin Marinas
2014-07-01 13:01   ` Dr. Philipp Tomsich
2014-07-01 13:01     ` Dr. Philipp Tomsich
2014-05-24  7:02 ` [PATCH 16/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 17/24] ARM64:ILP32: Support core dump for ILP32 Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 18/24] ARM64: Add loading of ILP32 binaries Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 19/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 20/24] ptrace: Allow compat to use the native siginfo Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 21/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24 18:56   ` H. Peter Anvin
2014-05-24 18:56     ` H. Peter Anvin
2014-05-24  7:02 ` [PATCH 22/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-07-01 15:05   ` Catalin Marinas
2014-07-01 15:05     ` Catalin Marinas
2014-07-01 15:30     ` Pinski, Andrew
2014-07-01 15:30       ` Pinski, Andrew
2014-07-01 16:38       ` Arnd Bergmann
2014-07-01 16:38         ` Arnd Bergmann
2014-07-01 16:50         ` Catalin Marinas
2014-07-01 16:50           ` Catalin Marinas
2014-07-01 17:04           ` Arnd Bergmann
2014-07-01 17:04             ` Arnd Bergmann
2014-07-01 16:49       ` Catalin Marinas
2014-07-01 16:49         ` Catalin Marinas
2014-05-24  7:02 ` [PATCH 23/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-05-24  7:02 ` [PATCH 24/24] Add documentation about ARM64 ILP32 ABI Andrew Pinski
2014-05-24  7:02   ` Andrew Pinski
2014-06-16 17:08 ` [PATCHv2 00/24] ILP32 Support in ARM64 Catalin Marinas
2014-06-16 17:08   ` Catalin Marinas
2014-06-16 17:19   ` Pinski, Andrew
2014-06-16 17:19     ` Pinski, Andrew
2014-06-17 10:43     ` Catalin Marinas
2014-06-17 10:43       ` Catalin Marinas
2014-06-17 11:30       ` Pinski, Andrew
2014-06-17 11:30         ` Pinski, Andrew

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.