linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 00/24] ILP32 support in ARM64
@ 2014-09-03 21:18 Andrew Pinski
  2014-09-03 21:18 ` [PATCH 01/24] ARM64: Force LP64 to compile the kernel Andrew Pinski
                   ` (24 more replies)
  0 siblings, 25 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

New version with all of the requested changes.  Updated to the latest sources.

Notable changes from the previous versions:
VDSO code has been factored out to be easier to understand and easier to maintain.
Move the config option to the last thing that gets added.
Added some extra COMPAT_* macros for core dumping for easier usage.


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/is_a32_thread and TIF_AARCH32 and use
    them in the correct locations
  ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread
  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
  compat_binfmt_elf: coredump: Allow some core dump macros be
    overridden for compat.
  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
  ARM64: Add ARM64_ILP32 to Kconfig
  Add documentation about ARM64 ILP32 ABI

 Documentation/arm64/ilp32.txt                 |   57 +++++++
 arch/arm64/Kconfig                            |   15 ++-
 arch/arm64/Makefile                           |    4 +
 arch/arm64/include/asm/arch_timer.h           |    2 +-
 arch/arm64/include/asm/compat.h               |   59 ++++++++
 arch/arm64/include/asm/elf.h                  |  100 ++++++++++++-
 arch/arm64/include/asm/fpsimd.h               |    2 +-
 arch/arm64/include/asm/hwcap.h                |    2 -
 arch/arm64/include/asm/processor.h            |   11 ++
 arch/arm64/include/asm/ptrace.h               |    2 +-
 arch/arm64/include/asm/signal32.h             |    4 +-
 arch/arm64/include/asm/stat.h                 |    4 +-
 arch/arm64/include/asm/syscalls.h             |    4 +
 arch/arm64/include/asm/thread_info.h          |    1 +
 arch/arm64/include/asm/unistd.h               |    6 +-
 arch/arm64/include/asm/vdso.h                 |    4 +
 arch/arm64/include/uapi/asm/bitsperlong.h     |    9 +-
 arch/arm64/include/uapi/asm/posix_types.h     |    8 +-
 arch/arm64/include/uapi/asm/siginfo.h         |   33 ++++
 arch/arm64/include/uapi/asm/signal.h          |   34 +++++
 arch/arm64/include/uapi/asm/unistd.h          |    6 +
 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             |    7 +-
 arch/arm64/kernel/process.c                   |    6 +-
 arch/arm64/kernel/ptrace.c                    |   52 +++++--
 arch/arm64/kernel/signal.c                    |   38 +++++-
 arch/arm64/kernel/sys_ilp32.c                 |  195 +++++++++++++++++++++++++
 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 |   98 +++++++++++++
 arch/arm64/kernel/vdso.c                      |   74 ++++++++--
 fs/compat_binfmt_elf.c                        |   17 ++
 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             |    6 +-
 kernel/ptrace.c                               |   25 +++-
 42 files changed, 989 insertions(+), 86 deletions(-)
 create mode 100644 Documentation/arm64/ilp32.txt
 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] 79+ messages in thread

* [PATCH 01/24] ARM64: Force LP64 to compile the kernel
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
@ 2014-09-03 21:18 ` Andrew Pinski
  2014-09-03 21:18 ` [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig Andrew Pinski
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

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 2df5e5d..b05340b 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] 79+ messages in thread

* [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
  2014-09-03 21:18 ` [PATCH 01/24] ARM64: Force LP64 to compile the kernel Andrew Pinski
@ 2014-09-03 21:18 ` Andrew Pinski
  2014-09-03 21:18 ` [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Andrew Pinski
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

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 fd4e81a..73c93dd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -375,9 +375,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
@@ -391,7 +395,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] 79+ messages in thread

* [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
  2014-09-03 21:18 ` [PATCH 01/24] ARM64: Force LP64 to compile the kernel Andrew Pinski
  2014-09-03 21:18 ` [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig Andrew Pinski
@ 2014-09-03 21:18 ` Andrew Pinski
  2014-09-03 21:18 ` [PATCH 04/24] ARM64:ILP32: Set kernel_long to long long so we can reuse most of the same syscalls as LP64 Andrew Pinski
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/arch_timer.h |    2 +-
 arch/arm64/include/asm/elf.h        |   20 +++++++++++++++++---
 arch/arm64/include/asm/fpsimd.h     |    2 +-
 arch/arm64/include/asm/ptrace.h     |    2 +-
 arch/arm64/include/asm/signal32.h   |    4 ++--
 arch/arm64/include/asm/stat.h       |    4 ++--
 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          |   34 ++++++++++++++++++++++++++++------
 arch/arm64/kernel/signal.c          |   15 +++++++++++++++
 arch/arm64/kernel/traps.c           |    2 +-
 arch/arm64/kernel/vdso.c            |    5 +++--
 15 files changed, 78 insertions(+), 26 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..b9217f0 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -171,14 +171,16 @@ 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
@@ -189,6 +191,18 @@ extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 #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 50f559f..63b19f1 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -52,7 +52,7 @@ struct fpsimd_partial_state {
 };
 
 
-#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+#if defined(__KERNEL__) && defined(CONFIG_AARCH32_EL0)
 /* Masks for extracting the FPSR and FPCR from the FPSCR */
 #define VFP_FPSCR_STAT_MASK	0xf800009f
 #define VFP_FPSCR_CTRL_MASK	0x07f79f00
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 41ed9e1..690a380 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -113,7 +113,7 @@ struct pt_regs {
 
 #define arch_has_single_step()	(1)
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #define compat_thumb_mode(regs) \
 	(((regs)->pstate & COMPAT_PSR_T_BIT))
 #else
diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
index eeaa975..522c345 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -17,7 +17,7 @@
 #define __ASM_SIGNAL32_H
 
 #ifdef __KERNEL__
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 #include <linux/compat.h>
 
 #define AARCH32_KERN_SIGRET_CODE_OFFSET	0x500
@@ -47,6 +47,6 @@ static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t
 static inline void compat_setup_restart_syscall(struct pt_regs *regs)
 {
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SIGNAL32_H */
diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
index 15e3559..e3b5865 100644
--- a/arch/arm64/include/asm/stat.h
+++ b/arch/arm64/include/asm/stat.h
@@ -18,7 +18,7 @@
 
 #include <uapi/asm/stat.h>
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 
 #include <asm/compat.h>
 
@@ -57,5 +57,5 @@ struct stat64 {
 	compat_u64	st_ino;
 };
 
-#endif
+#endif /* CONFIG_AARCH32_EL0 */
 #endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 6d2bf41..70e5559 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 df7ef87..6de85f5 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -17,7 +17,7 @@ arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 			   hyp-stub.o psci.o cpu_ops.o insn.o return_address.o	\
 			   cpuinfo.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_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 9a9fce0..d9c429c 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 f0b5e51..9314352 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -196,7 +196,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
@@ -236,7 +236,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)
@@ -399,7 +399,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 8730690..d3e2768 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -323,7 +323,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 fe63ac5..033e07c 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -36,6 +36,7 @@
 #include <linux/regset.h>
 #include <linux/tracehook.h>
 #include <linux/elf.h>
+#include <linux/errno.h>
 
 #include <asm/compat.h>
 #include <asm/debug-monitors.h>
@@ -75,7 +76,7 @@ static void ptrace_hbptriggered(struct perf_event *bp,
 		.si_addr	= (void __user *)(bkpt->trigger),
 	};
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 	int i;
 
 	if (!is_compat_task())
@@ -617,6 +618,7 @@ static const struct user_regset_view user_aarch64_view = {
 
 #ifdef CONFIG_COMPAT
 #include <linux/compat.h>
+#ifdef CONFIG_AARCH32_EL0
 
 enum compat_regset {
 	REGSET_COMPAT_GPR,
@@ -793,7 +795,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,
@@ -991,8 +993,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;
@@ -1068,11 +1070,31 @@ 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 -EINVAL;
+}
+#endif /* !CONFIG_AARCH32_EL0 */
+
+/*
+ * In ILP32, compat_arch_ptrace is used via the compat syscall, we don't need
+ * to do anything special for ILP32 though; only for AARCH32.
+ */
+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 6fa7921..8527d99 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -421,3 +421,18 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 		fpsimd_restore_current_state();
 
 }
+
+/*
+ * 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 02cd3f0..38a56d1 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -288,7 +288,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 32aeea0..a777ac3 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -35,6 +35,7 @@
 #include <asm/signal32.h>
 #include <asm/vdso.h>
 #include <asm/vdso_datapage.h>
+#include <asm/compat.h>
 
 extern char vdso_start, vdso_end;
 static unsigned long vdso_pages;
@@ -49,7 +50,7 @@ static union {
 } vdso_data_store __page_aligned_data;
 struct vdso_data *vdso_data = &vdso_data_store.data;
 
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
 /*
  * Create and map the vectors page for AArch32 tasks.
  */
@@ -107,7 +108,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 
 	return PTR_ERR_OR_ZERO(ret);
 }
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */
 
 static struct vm_special_mapping vdso_spec[2];
 
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 79+ 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-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (2 preceding siblings ...)
  2014-09-03 21:18 ` [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Andrew Pinski
@ 2014-09-03 21:18 ` Andrew Pinski
  2014-09-03 21:18 ` [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32 Andrew Pinski
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

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

diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h
index 7985ff6..0961945 100644
--- a/arch/arm64/include/uapi/asm/posix_types.h
+++ b/arch/arm64/include/uapi/asm/posix_types.h
@@ -5,6 +5,12 @@ typedef unsigned short __kernel_old_uid_t;
 typedef unsigned short __kernel_old_gid_t;
 #define __kernel_old_uid_t __kernel_old_uid_t
 
+#ifdef __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 */
+#endif /* __ASM_POSIX_TYPES_H */
-- 
1.7.2.5


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

* [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (3 preceding siblings ...)
  2014-09-03 21:18 ` [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-09-03 21:18 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI Andrew Pinski
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:18 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

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

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


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

* [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (4 preceding siblings ...)
  2014-09-03 21:18 ` [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32 Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64 Andrew Pinski
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

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..cb44f86 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_VOIDPTR
+#define __SIGINFO_VOIDPTR(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_VOIDPTR(sival_ptr);
 } sigval_t;
 
 /*
@@ -86,7 +94,7 @@ typedef struct siginfo {
 
 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
 		struct {
-			void __user *_addr; /* faulting insn/memory ref. */
+			__SIGINFO_VOIDPTR(_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_VOIDPTR(_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] 79+ messages in thread

* [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (5 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-18  3:41   ` zhangjian
  2014-09-03 21:19 ` [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
                   ` (17 subsequent siblings)
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/uapi/asm/siginfo.h |   33 ++++++++++++++++++++++++++++++++
 arch/arm64/include/uapi/asm/signal.h  |   34 +++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
index 5a74a08..c80c612 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,38 @@
 
 #define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
 
+#ifdef __ILP32__
+
+/*
+ * For ILP32, the siginfo structures should share the same layout and
+ * alignement requirements as LP64 ABI.
+ * To do this, use an extra pad field and add aligned attribute
+ * to the structure.
+ */
+
+# 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_VOIDPTR
+# define __SIGINFO_VOIDPTR(field)		\
+		__SIGINFO_INNER(void __user*, field)
+# undef __SIGINFO_BAND
+
+# define __SIGINFO_BAND(field)			\
+	__SIGINFO_INNER(long, field)
+
+/* Make the alignment of siginfo always 8 byte aligned. */
+#define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8)))
+
+#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..d33a5f7 100644
--- a/arch/arm64/include/uapi/asm/signal.h
+++ b/arch/arm64/include/uapi/asm/signal.h
@@ -16,9 +16,43 @@
 #ifndef __ASM_SIGNAL_H
 #define __ASM_SIGNAL_H
 
+#include <asm/posix-types.h>
+
 /* Required for AArch32 compatibility. */
 #define SA_RESTORER	0x04000000
 
+/*
+ * Since sigset is a bitmask, we need the same size fields for ILP32
+ * and LP64.  With big-endian, 32bit bitmask does not match up to
+ * 64bit bitmask (unlike with little-endian).
+ */
+#ifdef __ILP32__
+
+#define __SIGSET_INNER_TYPE __kernel_ulong_t
+#define _NSIG_BPW 64
+
+# ifdef __AARCH64EB__
+#  define __SIGNAL_INNER(type, field)		\
+		int __pad_##field;		\
+		type field;
+# else
+#  define __SIGNAL_INNER(type, field)		\
+		type field;			\
+		int __pad_##field;
+# endif
+
+# define __SIGACTION_HANDLER(field)		\
+	__SIGNAL_INNER(__sighandler_t, field)
+
+
+#define __SIGACTION_FLAGS(field)		\
+	__kernel_ulong_t 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] 79+ 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-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (6 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64 Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-04 10:11   ` Arnd Bergmann
  2014-09-03 21:19 ` [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64 Andrew Pinski
                   ` (16 subsequent siblings)
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

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

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 11d11bc..a7984a0 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -881,8 +881,12 @@ __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(__ARCH_WANT_64BIT_SYSCALLS)
 #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] 79+ messages in thread

* [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (7 preceding siblings ...)
  2014-09-03 21:19 ` [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-09-03 21:19 ` Andrew Pinski
  2014-10-01 12:48   ` Catalin Marinas
  2014-09-03 21:19 ` [PATCH 10/24] ARM64: Introduce is_a32_task/is_a32_thread and TIF_AARCH32 and use them in the correct locations Andrew Pinski
                   ` (15 subsequent siblings)
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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 |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h
index 1caadc2..13cbf8d 100644
--- a/arch/arm64/include/uapi/asm/unistd.h
+++ b/arch/arm64/include/uapi/asm/unistd.h
@@ -13,4 +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/>.
  */
+
+/* For ILP32, we want to use the non compat names. */
+#if defined(__ILP32__)
+#define __ARCH_WANT_64BIT_SYSCALLS
+#endif
+
 #include <asm-generic/unistd.h>
-- 
1.7.2.5


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

* [PATCH 10/24] ARM64: Introduce is_a32_task/is_a32_thread and TIF_AARCH32 and use them in the correct locations
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (8 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64 Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 11/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread Andrew Pinski
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 arch/arm64/include/asm/compat.h      |   21 +++++++++++++++++++++
 arch/arm64/include/asm/elf.h         |   12 ++++++++++--
 arch/arm64/include/asm/thread_info.h |    1 +
 arch/arm64/kernel/hw_breakpoint.c    |    7 ++++---
 arch/arm64/kernel/process.c          |    6 +++---
 arch/arm64/kernel/ptrace.c           |    8 ++++----
 arch/arm64/kernel/signal.c           |    5 +++--
 arch/arm64/kernel/traps.c            |    2 +-
 8 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 253e33b..8fcfb29 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -311,5 +311,26 @@ static inline int is_compat_thread(struct thread_info *thread)
 }
 
 #endif /* CONFIG_COMPAT */
+
+#ifdef CONFIG_AARCH32_EL0
+static inline int is_a32_compat_task(void)
+{
+	return test_thread_flag(TIF_AARCH32);
+}
+static inline int is_a32_compat_thread(struct thread_info *thread)
+{
+	return test_ti_thread_flag(thread, TIF_AARCH32);
+}
+#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
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index b9217f0..ca27c02 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_AARCH32);		\
+	clear_thread_flag(TIF_32BIT);		\
+} while (0)
 
 #define ARCH_DLINFO							\
 do {									\
@@ -184,7 +188,11 @@ typedef compat_elf_greg_t		compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
 					 ((x)->e_flags & EF_ARM_EABI_MASK))
 
 #define compat_start_thread		compat_start_thread
-#define COMPAT_SET_PERSONALITY(ex)	set_thread_flag(TIF_32BIT);
+#define COMPAT_SET_PERSONALITY(ex)		\
+do {						\
+	set_thread_flag(TIF_AARCH32);		\
+	set_thread_flag(TIF_32BIT);		\
+} while (0)
 #define COMPAT_ARCH_DLINFO
 extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
 				      int uses_interp);
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 45108d8..70aac31 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -114,6 +114,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SINGLESTEP		21
 #define TIF_32BIT		22	/* 32bit process */
 #define TIF_SWITCH_MM		23	/* deferred switch_mm */
+#define TIF_AARCH32		24	/* AARCH32 process */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index df1cf15..8e46a67 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -28,6 +28,7 @@
 #include <linux/ptrace.h>
 #include <linux/smp.h>
 
+#include <asm/compat.h>
 #include <asm/current.h>
 #include <asm/debug-monitors.h>
 #include <asm/hw_breakpoint.h>
@@ -433,7 +434,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 +491,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 +678,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 1309d64..8d775b4 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -260,7 +260,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 {
@@ -301,12 +301,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 033e07c..efabfc4 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -79,7 +79,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) {
@@ -1085,7 +1085,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);
 }
@@ -1095,7 +1095,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;
@@ -1122,7 +1122,7 @@ static void tracehook_report_syscall(struct pt_regs *regs,
 	 * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
 	 * used to denote syscall entry/exit:
 	 */
-	regno = (is_compat_task() ? 12 : 7);
+	regno = (is_a32_compat_task() ? 12 : 7);
 	saved_reg = regs->regs[regno];
 	regs->regs[regno] = dir;
 
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 8527d99..f47c064 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -26,6 +26,7 @@
 #include <linux/tracehook.h>
 #include <linux/ratelimit.h>
 
+#include <asm/compat.h>
 #include <asm/debug-monitors.h>
 #include <asm/elf.h>
 #include <asm/cacheflush.h>
@@ -276,7 +277,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
 
 static void setup_restart_syscall(struct pt_regs *regs)
 {
-	if (is_compat_task())
+	if (is_a32_compat_task())
 		compat_setup_restart_syscall(regs);
 	else
 		regs->regs[8] = __NR_restart_syscall;
@@ -302,7 +303,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 	/*
 	 * Set up the stack frame
 	 */
-	if (is_compat_task()) {
+	if (is_a32_compat_task()) {
 		if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 			ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
 		else
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 38a56d1..1d8bccc 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -290,7 +290,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] 79+ messages in thread

* [PATCH 11/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (9 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 10/24] ARM64: Introduce is_a32_task/is_a32_thread and TIF_AARCH32 and use them in the correct locations Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 12/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks Andrew Pinski
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

This patch adds the functions which returns if the current task is an
ILP32 task and one returns if the thread is an ILP32 thread.

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

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 8fcfb29..9082b27 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -332,5 +332,27 @@ 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) && !is_a32_compat_task();
+}
+static inline int is_ilp32_compat_thread(struct thread_info *thread)
+{
+	return test_ti_thread_flag(thread, TIF_32BIT) &&
+	       !is_a32_compat_thread(thread);
+}
+#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
+
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
-- 
1.7.2.5


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

* [PATCH 12/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (10 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 11/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 13/24] ARM64:ILP32: Use the non compat HWCAP for ILP32 Andrew Pinski
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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).

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 9082b27..eca6eec 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] 79+ messages in thread

* [PATCH 13/24] ARM64:ILP32: Use the non compat HWCAP for ILP32
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (11 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 12/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-10-01 13:12   ` Catalin Marinas
  2014-09-03 21:19 ` [PATCH 14/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32 Andrew Pinski
                   ` (11 subsequent siblings)
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eca6eec..2f84d2c 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -296,6 +296,16 @@ struct compat_shmid64_ds {
 	compat_ulong_t __unused5;
 };
 
+#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)
+
 static inline int is_compat_task(void)
 {
 	return test_thread_flag(TIF_32BIT);
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 024c461..31e7e02 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -46,8 +46,6 @@
 #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;
 #endif
 
-- 
1.7.2.5


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

* [PATCH 14/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (12 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 13/24] ARM64:ILP32: Use the non compat HWCAP for ILP32 Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 15/24] compat_binfmt_elf: coredump: Allow some core dump macros be overridden for compat Andrew Pinski
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

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

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 286b1be..7bd9f32 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -104,6 +104,17 @@ 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_AARCH32)) {
+		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] 79+ messages in thread

* [PATCH 15/24] compat_binfmt_elf: coredump: Allow some core dump macros be overridden for compat.
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (13 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 14/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32 Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 16/24] ARM64:ILP32: Support core dump for ILP32 Andrew Pinski
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

On some targets (x86 [32bit and x32] and arm64 [aarch32 and ilp32]), there are
two compat elf abis.  This adds a few more "#define * COMPAT_*" for compat
targets to define if needed.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 fs/compat_binfmt_elf.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c
index 4d24d17..8307927 100644
--- a/fs/compat_binfmt_elf.c
+++ b/fs/compat_binfmt_elf.c
@@ -130,6 +130,23 @@ static void cputime_to_compat_timeval(const cputime_t cputime,
 #define	arch_setup_additional_pages compat_arch_setup_additional_pages
 #endif
 
+
+#ifdef COMPAT_PR_REG_SIZE
+#define PR_REG_SIZE COMPAT_PR_REG_SIZE
+#endif
+
+#ifdef COMPAT_PRSTATUS_SIZE
+#define PRSTATUS_SIZE COMPAT_PRSTATUS_SIZE
+#endif
+
+#ifdef COMPAT_PR_REG_PTR
+#define PR_REG_PTR COMPAT_PR_REG_PTR
+#endif
+
+#ifdef COMPAT_SET_PR_FPVALID
+#define SET_PR_FPVALID COMPAT_SET_PR_FPVALID
+#endif
+
 /*
  * Rename a few of the symbols that binfmt_elf.c will define.
  * These are all local so the names don't really matter, but it
-- 
1.7.2.5


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

* [PATCH 16/24] ARM64:ILP32: Support core dump for ILP32
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (14 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 15/24] compat_binfmt_elf: coredump: Allow some core dump macros be overridden for compat Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-10-01 13:22   ` Catalin Marinas
  2014-09-03 21:19 ` [PATCH 17/24] ARM64: Add loading of ILP32 binaries Andrew Pinski
                   ` (8 subsequent siblings)
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

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

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index ca27c02..795dc9f 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -179,8 +179,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
@@ -209,6 +209,25 @@ 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.
+ */
+#ifdef CONFIG_ARM64_ILP32
+typedef elf_greg_t			compat_elf_greg_t;
+typedef elf_gregset_t			compat_elf_gregset_t;
+#define COMPAT_PR_REG_SIZE(S)		(is_a32_compat_task() ? 72 : 272)
+#define COMPAT_PRSTATUS_SIZE(S)		(is_a32_compat_task() ? 124 : 352)
+#define COMPAT_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 efabfc4..ffdd1a8 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -796,8 +796,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
 	},
@@ -830,7 +830,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);
@@ -851,7 +851,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
 	if (off & 3 || off >= COMPAT_USER_SZ)
 		return -EIO;
 
-	if (off >= sizeof(compat_elf_gregset_t))
+	if (off >= sizeof(compat_a32_elf_gregset_t))
 		return 0;
 
 	set_fs(KERNEL_DS);
@@ -1014,7 +1014,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;
 
@@ -1022,7 +1022,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] 79+ messages in thread

* [PATCH 17/24] ARM64: Add loading of ILP32 binaries
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (15 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 16/24] ARM64:ILP32: Support core dump for ILP32 Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 795dc9f..52083cd 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -16,6 +16,7 @@
 #ifndef __ASM_ELF_H
 #define __ASM_ELF_H
 
+#include <asm/errno.h>
 #include <asm/hwcap.h>
 
 /*
@@ -188,25 +189,26 @@ 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)		\
+#define COMPAT_A32_SET_PERSONALITY(ex)		\
 do {						\
 	set_thread_flag(TIF_AARCH32);		\
 	set_thread_flag(TIF_32BIT);		\
 } while (0)
-#define COMPAT_ARCH_DLINFO
+#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)
+static inline int aarch32_setup_vectors_page(struct linux_binprm *bprm,
+					     int uses_interp)
+{
+	return -EINVAL;
+}
 #endif
 
 /*
@@ -228,7 +230,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 {						\
+	clear_thread_flag(TIF_AARCH32);		\
+	set_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] 79+ messages in thread

* [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (16 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 17/24] ARM64: Add loading of ILP32 binaries Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-10 14:31   ` Christopher Covington
                     ` (2 more replies)
  2014-09-03 21:19 ` [PATCH 19/24] ptrace: Allow compat to use the native siginfo Andrew Pinski
                   ` (6 subsequent siblings)
  24 siblings, 3 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

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 |   98 +++++++++++++++++++++++++
 arch/arm64/kernel/vdso.c                      |   69 ++++++++++++++---
 8 files changed, 274 insertions(+), 13 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 6de85f5..dcb9033 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.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
@@ -38,3 +39,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 f47c064..5311147 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -242,6 +242,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..ac8029b
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -0,0 +1,98 @@
+/*
+ * 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
+{
+	PROVIDE(_vdso_data = . - PAGE_SIZE);
+	. = VDSO_LBASE + SIZEOF_HEADERS;
+
+	.hash		: { *(.hash) }			:text
+	.gnu.hash	: { *(.gnu.hash) }
+	.dynsym		: { *(.dynsym) }
+	.dynstr		: { *(.dynstr) }
+	.gnu.version	: { *(.gnu.version) }
+	.gnu.version_d	: { *(.gnu.version_d) }
+	.gnu.version_r	: { *(.gnu.version_r) }
+
+	.note		: { *(.note.*) }		:text	:note
+
+	. = ALIGN(16);
+
+	.text		: { *(.text*) }			:text	=0xd503201f
+	PROVIDE (__etext = .);
+	PROVIDE (_etext = .);
+	PROVIDE (etext = .);
+
+	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
+	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
+
+	.dynamic	: { *(.dynamic) }		:text	:dynamic
+
+	.rodata		: { *(.rodata*) }		:text
+
+	_end = .;
+	PROVIDE(end = .);
+
+	/DISCARD/	: {
+		*(.note.GNU-stack)
+		*(.data .data.* .gnu.linkonce.d.* .sdata*)
+		*(.bss .sbss .dynbss .dynsbss)
+	}
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
+	note		PT_NOTE		FLAGS(4);		/* PF_R */
+	eh_frame_hdr	PT_GNU_EH_FRAME;
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+	LINUX_2.6.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 a777ac3..21b3726 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -41,6 +41,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.
  */
@@ -110,24 +116,31 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
 }
 #endif /* CONFIG_AARCH32_EL0 */
 
-static struct vm_special_mapping vdso_spec[2];
+static struct vm_special_mapping vdso_spec[2][2];
 
-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,
+					  bool ilp32)
 {
 	int i;
+	unsigned long vdso_pages;
+	struct page **vdso_pagelist;
 
-	if (memcmp(&vdso_start, "\177ELF", 4)) {
+	if (memcmp(vdso_start, "\177ELF", 4)) {
 		pr_err("vDSO is not a valid ELF object!\n");
 		return -EINVAL;
 	}
 
-	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+	*vdso_pagesp = vdso_pages;
 	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
-		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
+		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
 
 	/* Allocate the vDSO pagelist, plus a page for the data. */
 	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
 				GFP_KERNEL);
+	*vdso_pagelistp = vdso_pagelist;
 	if (vdso_pagelist == NULL)
 		return -ENOMEM;
 
@@ -136,33 +149,63 @@ static int __init vdso_init(void)
 
 	/* Grab the vDSO code pages. */
 	for (i = 0; i < vdso_pages; i++)
-		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
 
 	/* Populate the special mapping structures */
-	vdso_spec[0] = (struct vm_special_mapping) {
+	vdso_spec[ilp32][0] = (struct vm_special_mapping) {
 		.name	= "[vvar]",
 		.pages	= vdso_pagelist,
 	};
 
-	vdso_spec[1] = (struct vm_special_mapping) {
+	vdso_spec[ilp32][1] = (struct vm_special_mapping) {
 		.name	= "[vdso]",
 		.pages	= &vdso_pagelist[1],
 	};
 
 	return 0;
 }
+
+static int __init vdso_init(void)
+{
+	return vdso_init_common(&vdso_start, &vdso_end,
+				&vdso_pages, &vdso_pagelist, 0);
+}
 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, 1);
+}
+arch_initcall(vdso_ilp32_init);
+#endif
+
 int arch_setup_additional_pages(struct linux_binprm *bprm,
 				int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
 	void *ret;
-
-	vdso_text_len = vdso_pages << PAGE_SHIFT;
+	struct page **pagelist;
+	unsigned long pages;
+	bool ilp32;
+
+#ifdef CONFIG_ARM64_ILP32
+	ilp32 = is_ilp32_compat_task();
+	if (is_ilp32_compat_task()) {
+		pages = vdso_ilp32_pages;
+		pagelist = vdso_ilp32_pagelist;
+	} else
+#endif
+	{
+		ilp32 = false;
+		pages = vdso_pages;
+		pagelist = vdso_pagelist;
+	}
+	vdso_text_len = pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
-	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
+	vdso_mapping_len = (pages + 1) << PAGE_SHIFT;
 
 	down_write(&mm->mmap_sem);
 	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
@@ -172,7 +215,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	}
 	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
 				       VM_READ|VM_MAYREAD,
-				       &vdso_spec[0]);
+				       &vdso_spec[ilp32][0]);
 	if (IS_ERR(ret))
 		goto up_fail;
 
@@ -181,7 +224,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
 				       VM_READ|VM_EXEC|
 				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
-				       &vdso_spec[1]);
+				       &vdso_spec[ilp32][1]);
 	if (IS_ERR(ret))
 		goto up_fail;
 
-- 
1.7.2.5


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

* [PATCH 19/24] ptrace: Allow compat to use the native siginfo
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (17 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-10-02 14:13   ` Catalin Marinas
  2014-09-03 21:19 ` [PATCH 20/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo Andrew Pinski
                   ` (5 subsequent siblings)
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

Signed-off-by: Andrew Pinski <apinski@cavium.com>
---
 include/linux/compat.h |    4 ++++
 kernel/ptrace.c        |   25 ++++++++++++++++++-------
 2 files changed, 22 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 54e7522..40ae023 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -657,7 +657,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) ||
@@ -1126,16 +1126,27 @@ 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] 79+ messages in thread

* [PATCH 20/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (18 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 19/24] ptrace: Allow compat to use the native siginfo Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls Andrew Pinski
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

Set COMPAT_USE_NATIVE_SIGINFO to be true for non AARCH32 tasks.

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 2f84d2c..87cb50d 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] 79+ messages in thread

* [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (19 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 20/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-10-02 15:23   ` Catalin Marinas
  2014-10-02 15:46   ` Catalin Marinas
  2014-09-03 21:19 ` [PATCH 22/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack Andrew Pinski
                   ` (3 subsequent siblings)
  24 siblings, 2 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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.

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     |  195 +++++++++++++++++++++++++++++++++++++
 5 files changed, 216 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 70e5559..c99815a 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 dcb9033..8a531fb 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -19,6 +19,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_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.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/entry.S b/arch/arm64/kernel/entry.S
index 9314352..dbedecf 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -643,9 +643,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, el0_ilp32_svc	// We are using ILP32
+#endif
+	adrp	stbl, sys_call_table		// load syscall table pointer
 el0_svc_naked:					// compat entry point
 	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
 	enable_dbg_and_irq
@@ -664,6 +669,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..8c68d28
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,195 @@
+/*
+ * 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
+
+/*
+ * Note places where mention unsigned long bitmaps, could
+ * use the non compat version for little-endian but big-endian
+ * has issues to do layout of the bits in the bitmaps.
+ */
+
+/* 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
+
+/*
+ * Note the timeval is taken care by COMPAT_USE_64BIT_TIME
+ * being true.
+ */
+#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
+
+/*
+ * The NFSv4 and ncpfs structures are depend on the long and
+ * pointer sizes.
+ */
+#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 */
+/* Array of pointers (iocb's) */
+#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] 79+ messages in thread

* [PATCH 22/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (20 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 23/24] ARM64: Add ARM64_ILP32 to Kconfig Andrew Pinski
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +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).

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

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 5311147..6316d54 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -35,6 +35,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,19 @@ 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] 79+ messages in thread

* [PATCH 23/24] ARM64: Add ARM64_ILP32 to Kconfig
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (21 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 22/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-03 21:19 ` [PATCH 24/24] Add documentation about ARM64 ILP32 ABI Andrew Pinski
  2014-10-02 15:52 ` [PATCHv3 00/24] ILP32 support in ARM64 Catalin Marinas
  24 siblings, 0 replies; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

This patch adds the config option for ILP32.

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 73c93dd..4ee4183 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -376,7 +376,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
@@ -393,6 +393,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] 79+ messages in thread

* [PATCH 24/24] Add documentation about ARM64 ILP32 ABI
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (22 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 23/24] ARM64: Add ARM64_ILP32 to Kconfig Andrew Pinski
@ 2014-09-03 21:19 ` Andrew Pinski
  2014-09-04 10:01   ` Arnd Bergmann
  2014-10-02 15:52 ` [PATCHv3 00/24] ILP32 support in ARM64 Catalin Marinas
  24 siblings, 1 reply; 79+ messages in thread
From: Andrew Pinski @ 2014-09-03 21:19 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, pinskia; +Cc: Andrew Pinski

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

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..0863aa4
--- /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] 79+ messages in thread

* Re: [PATCH 24/24] Add documentation about ARM64 ILP32 ABI
  2014-09-03 21:19 ` [PATCH 24/24] Add documentation about ARM64 ILP32 ABI Andrew Pinski
@ 2014-09-04 10:01   ` Arnd Bergmann
  0 siblings, 0 replies; 79+ messages in thread
From: Arnd Bergmann @ 2014-09-04 10:01 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Andrew Pinski, linux-kernel, pinskia

On Wednesday 03 September 2014 14:19:18 Andrew Pinski wrote:
> +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

What about data structures derived from these? I'm worried that
some of them (in particular time_t) leak into ioctl interfaces
when they are getting included in some other data structure that
is used as an ioctl argument.

Do you have a list of which data structures change based on the
scalar type changes?

	Arnd

^ permalink raw reply	[flat|nested] 79+ 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-09-03 21:19 ` [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-09-04 10:11   ` Arnd Bergmann
  2014-10-01 12:42     ` Catalin Marinas
  0 siblings, 1 reply; 79+ messages in thread
From: Arnd Bergmann @ 2014-09-04 10:11 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Andrew Pinski, linux-kernel, pinskia

On Wednesday 03 September 2014 14:19:02 Andrew Pinski wrote:
> + * 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(__ARCH_WANT_64BIT_SYSCALLS)
> 

I'm not sure if __ARCH_WANT_64BIT_SYSCALLS is the best name for
this, since it's really only about off_t. It took me a while
to understand what you are doing here.

	Arnd

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

* Re: [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return
  2014-09-03 21:19 ` [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
@ 2014-09-10 14:31   ` Christopher Covington
  2014-10-01 13:59   ` Catalin Marinas
  2014-10-02 13:38   ` Catalin Marinas
  2 siblings, 0 replies; 79+ messages in thread
From: Christopher Covington @ 2014-09-10 14:31 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

Hi Andrew,

On 09/03/2014 05:19 PM, Andrew Pinski wrote:
> 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.
> 
> 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 |   98 +++++++++++++++++++++++++
>  arch/arm64/kernel/vdso.c                      |   69 ++++++++++++++---
>  8 files changed, 274 insertions(+), 13 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 6de85f5..dcb9033 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>  arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.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
> @@ -38,3 +39,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 f47c064..5311147 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -242,6 +242,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);

In my opinion, moving the ifdef around the definition of
is_ilp32_compat_task() would make the code easier to read and maintain.

> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index a777ac3..21b3726 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -41,6 +41,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.
>   */
> @@ -110,24 +116,31 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
>  }
>  #endif /* CONFIG_AARCH32_EL0 */
>  
> -static struct vm_special_mapping vdso_spec[2];
> +static struct vm_special_mapping vdso_spec[2][2];
>  
> -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,
> +					  bool ilp32)
>  {
>  	int i;
> +	unsigned long vdso_pages;
> +	struct page **vdso_pagelist;
>  
> -	if (memcmp(&vdso_start, "\177ELF", 4)) {
> +	if (memcmp(vdso_start, "\177ELF", 4)) {
>  		pr_err("vDSO is not a valid ELF object!\n");
>  		return -EINVAL;
>  	}
>  
> -	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
> +	vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
> +	*vdso_pagesp = vdso_pages;
>  	pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
> -		vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
> +		vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
>  
>  	/* Allocate the vDSO pagelist, plus a page for the data. */
>  	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
>  				GFP_KERNEL);
> +	*vdso_pagelistp = vdso_pagelist;
>  	if (vdso_pagelist == NULL)
>  		return -ENOMEM;
>  
> @@ -136,33 +149,63 @@ static int __init vdso_init(void)
>  
>  	/* Grab the vDSO code pages. */
>  	for (i = 0; i < vdso_pages; i++)
> -		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
> +		vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
>  
>  	/* Populate the special mapping structures */
> -	vdso_spec[0] = (struct vm_special_mapping) {
> +	vdso_spec[ilp32][0] = (struct vm_special_mapping) {
>  		.name	= "[vvar]",
>  		.pages	= vdso_pagelist,
>  	};
>  
> -	vdso_spec[1] = (struct vm_special_mapping) {
> +	vdso_spec[ilp32][1] = (struct vm_special_mapping) {
>  		.name	= "[vdso]",
>  		.pages	= &vdso_pagelist[1],
>  	};
>  
>  	return 0;
>  }
> +
> +static int __init vdso_init(void)
> +{
> +	return vdso_init_common(&vdso_start, &vdso_end,
> +				&vdso_pages, &vdso_pagelist, 0);
> +}
>  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, 1);
> +}
> +arch_initcall(vdso_ilp32_init);
> +#endif
> +
>  int arch_setup_additional_pages(struct linux_binprm *bprm,
>  				int uses_interp)
>  {
>  	struct mm_struct *mm = current->mm;
>  	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
>  	void *ret;
> -
> -	vdso_text_len = vdso_pages << PAGE_SHIFT;
> +	struct page **pagelist;
> +	unsigned long pages;
> +	bool ilp32;
> +
> +#ifdef CONFIG_ARM64_ILP32
> +	ilp32 = is_ilp32_compat_task();
> +	if (is_ilp32_compat_task()) {
> +		pages = vdso_ilp32_pages;
> +		pagelist = vdso_ilp32_pagelist;
> +	} else
> +#endif

Same

> +	{
> +		ilp32 = false;
> +		pages = vdso_pages;
> +		pagelist = vdso_pagelist;
> +	}
> +	vdso_text_len = pages << PAGE_SHIFT;
>  	/* Be sure to map the data page */
> -	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
> +	vdso_mapping_len = (pages + 1) << PAGE_SHIFT;
>  
>  	down_write(&mm->mmap_sem);
>  	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
> @@ -172,7 +215,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>  	}
>  	ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
>  				       VM_READ|VM_MAYREAD,
> -				       &vdso_spec[0]);
> +				       &vdso_spec[ilp32][0]);
>  	if (IS_ERR(ret))
>  		goto up_fail;
>  
> @@ -181,7 +224,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>  	ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
>  				       VM_READ|VM_EXEC|
>  				       VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> -				       &vdso_spec[1]);
> +				       &vdso_spec[ilp32][1]);
>  	if (IS_ERR(ret))
>  		goto up_fail;
>  
> 

Regards,
Christopher

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by the Linux Foundation.

^ permalink raw reply	[flat|nested] 79+ 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-09-03 21:19 ` [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64 Andrew Pinski
@ 2014-09-18  3:41   ` zhangjian
  0 siblings, 0 replies; 79+ messages in thread
From: zhangjian @ 2014-09-18  3:41 UTC (permalink / raw)
  To: Andrew Pinski, zhangjian, Dingtianhong
  Cc: linux-arm-kernel, linux-kernel, pinskia, Xinwei Hu

On 2014/9/4 5:19, Andrew Pinski wrote:
> Defines the macros which allow the signal structures to be the same between ILP32 and LP64.
> 
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  arch/arm64/include/uapi/asm/siginfo.h |   33 ++++++++++++++++++++++++++++++++
>  arch/arm64/include/uapi/asm/signal.h  |   34 +++++++++++++++++++++++++++++++++
>  2 files changed, 67 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
> index 5a74a08..c80c612 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,38 @@
>  
>  #define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
>  
> +#ifdef __ILP32__
> +
> +/*
> + * For ILP32, the siginfo structures should share the same layout and
> + * alignement requirements as LP64 ABI.
> + * To do this, use an extra pad field and add aligned attribute
> + * to the structure.
> + */
> +
> +# 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_VOIDPTR
> +# define __SIGINFO_VOIDPTR(field)		\
> +		__SIGINFO_INNER(void __user*, field)
> +# undef __SIGINFO_BAND
> +
> +# define __SIGINFO_BAND(field)			\
> +	__SIGINFO_INNER(long, field)
> +
> +/* Make the alignment of siginfo always 8 byte aligned. */
> +#define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8)))
> +
> +#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..d33a5f7 100644
> --- a/arch/arm64/include/uapi/asm/signal.h
> +++ b/arch/arm64/include/uapi/asm/signal.h
> @@ -16,9 +16,43 @@
>  #ifndef __ASM_SIGNAL_H
>  #define __ASM_SIGNAL_H
>  
> +#include <asm/posix-types.h>
typos here, it should be
#include <asm/posix_types.h>
> +
>  /* Required for AArch32 compatibility. */
>  #define SA_RESTORER	0x04000000
>  
> +/*
> + * Since sigset is a bitmask, we need the same size fields for ILP32
> + * and LP64.  With big-endian, 32bit bitmask does not match up to
> + * 64bit bitmask (unlike with little-endian).
> + */
> +#ifdef __ILP32__
> +
> +#define __SIGSET_INNER_TYPE __kernel_ulong_t
> +#define _NSIG_BPW 64
> +
> +# ifdef __AARCH64EB__
> +#  define __SIGNAL_INNER(type, field)		\
> +		int __pad_##field;		\
> +		type field;
> +# else
> +#  define __SIGNAL_INNER(type, field)		\
> +		type field;			\
> +		int __pad_##field;
> +# endif
> +
> +# define __SIGACTION_HANDLER(field)		\
> +	__SIGNAL_INNER(__sighandler_t, field)
> +
> +
> +#define __SIGACTION_FLAGS(field)		\
> +	__kernel_ulong_t field
> +
> +#define __SIGACTION_RESTORER(field)		\
> +	__SIGNAL_INNER(__sigrestore_t, field)
> +
> +#endif
> +
>  #include <asm-generic/signal.h>
>  
>  #endif
> 



^ permalink raw reply	[flat|nested] 79+ 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-09-04 10:11   ` Arnd Bergmann
@ 2014-10-01 12:42     ` Catalin Marinas
  2014-10-01 14:00       ` Arnd Bergmann
  0 siblings, 1 reply; 79+ messages in thread
From: Catalin Marinas @ 2014-10-01 12:42 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-arm-kernel, pinskia, Andrew Pinski, linux-kernel

On Thu, Sep 04, 2014 at 11:11:04AM +0100, Arnd Bergmann wrote:
> On Wednesday 03 September 2014 14:19:02 Andrew Pinski wrote:
> > + * 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(__ARCH_WANT_64BIT_SYSCALLS)
> 
> I'm not sure if __ARCH_WANT_64BIT_SYSCALLS is the best name for
> this, since it's really only about off_t. It took me a while
> to understand what you are doing here.

I'm not sure I fully get it yet. So with this change, we avoid using
syscall numbers like __NR_ftruncate64 in favour of __NR_ftruncate. Why?
(maybe there's a valid reason, just not getting it).

Either way, ILP32 would still end up calling sys_ftruncate64() (rather
than the native sys_ftruncate()).

-- 
Catalin

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

* Re: [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64
  2014-09-03 21:19 ` [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64 Andrew Pinski
@ 2014-10-01 12:48   ` Catalin Marinas
  0 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-01 12:48 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:03PM +0100, Andrew Pinski wrote:
> Define __SYSCALL_NONCOMPAT so we use the 64bit naming scheme for ILP32.

The log doesn't match the actual patch.

> --- a/arch/arm64/include/uapi/asm/unistd.h
> +++ b/arch/arm64/include/uapi/asm/unistd.h
> @@ -13,4 +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/>.
>   */
> +
> +/* For ILP32, we want to use the non compat names. */
> +#if defined(__ILP32__)
> +#define __ARCH_WANT_64BIT_SYSCALLS
> +#endif
> +
>  #include <asm-generic/unistd.h>

-- 
Catalin

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

* Re: [PATCH 13/24] ARM64:ILP32: Use the non compat HWCAP for ILP32
  2014-09-03 21:19 ` [PATCH 13/24] ARM64:ILP32: Use the non compat HWCAP for ILP32 Andrew Pinski
@ 2014-10-01 13:12   ` Catalin Marinas
  0 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-01 13:12 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:07PM +0100, Andrew Pinski wrote:
> Signed-off-by: Andrew Pinski <apinski@cavium.com>
> ---
>  arch/arm64/include/asm/compat.h |   10 ++++++++++
>  arch/arm64/include/asm/hwcap.h  |    2 --
>  2 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index eca6eec..2f84d2c 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -296,6 +296,16 @@ struct compat_shmid64_ds {
>  	compat_ulong_t __unused5;
>  };
>  
> +#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)
> +
>  static inline int is_compat_task(void)
>  {
>  	return test_thread_flag(TIF_32BIT);
> diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
> index 024c461..31e7e02 100644
> --- a/arch/arm64/include/asm/hwcap.h
> +++ b/arch/arm64/include/asm/hwcap.h
> @@ -46,8 +46,6 @@
>  #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;
>  #endif

Any reason why you are moving the definitions from here? Can you not
include asm/compat.h in asm/hwcap.h? (or move the compat_elf_hwcap
declaration as well).

-- 
Catalin

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

* Re: [PATCH 16/24] ARM64:ILP32: Support core dump for ILP32
  2014-09-03 21:19 ` [PATCH 16/24] ARM64:ILP32: Support core dump for ILP32 Andrew Pinski
@ 2014-10-01 13:22   ` Catalin Marinas
  0 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-01 13:22 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:10PM +0100, Andrew Pinski wrote:
> +/*
> + * 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.
> + */
> +#ifdef CONFIG_ARM64_ILP32
> +typedef elf_greg_t			compat_elf_greg_t;
> +typedef elf_gregset_t			compat_elf_gregset_t;
> +#define COMPAT_PR_REG_SIZE(S)		(is_a32_compat_task() ? 72 : 272)
> +#define COMPAT_PRSTATUS_SIZE(S)		(is_a32_compat_task() ? 124 : 352)

Could you not use some sizeof() here instead of these magic numbers?

-- 
Catalin

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

* Re: [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return
  2014-09-03 21:19 ` [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
  2014-09-10 14:31   ` Christopher Covington
@ 2014-10-01 13:59   ` Catalin Marinas
  2014-10-02 13:38   ` Catalin Marinas
  2 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-01 13:59 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:12PM +0100, Andrew Pinski wrote:
> 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.

As you say "mostly", is there anything that does not work?

-- 
Catalin

^ permalink raw reply	[flat|nested] 79+ 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-10-01 12:42     ` Catalin Marinas
@ 2014-10-01 14:00       ` Arnd Bergmann
  2014-10-02 11:19         ` Catalin Marinas
  0 siblings, 1 reply; 79+ messages in thread
From: Arnd Bergmann @ 2014-10-01 14:00 UTC (permalink / raw)
  To: linux-arm-kernel; +Cc: Catalin Marinas, linux-kernel, Andrew Pinski, pinskia

On Wednesday 01 October 2014 13:42:27 Catalin Marinas wrote:
> On Thu, Sep 04, 2014 at 11:11:04AM +0100, Arnd Bergmann wrote:
> > On Wednesday 03 September 2014 14:19:02 Andrew Pinski wrote:
> > > + * 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(__ARCH_WANT_64BIT_SYSCALLS)
> > 
> > I'm not sure if __ARCH_WANT_64BIT_SYSCALLS is the best name for
> > this, since it's really only about off_t. It took me a while
> > to understand what you are doing here.
> 
> I'm not sure I fully get it yet. So with this change, we avoid using
> syscall numbers like __NR_ftruncate64 in favour of __NR_ftruncate. Why?
> (maybe there's a valid reason, just not getting it).

glibc depends on the name to decide which calling conventions it
uses. I assume this is the same on IPL32 ARM.

The general rule is that on a 32-bit architecture, __NR_ftruncate refers
to the system call that takes a 32-bit off_t argument, while __NR_ftruncate64
refers to the syscall that takes a 64-bit loff_t.

I would assume that the new ABI does not actually allow using 32-bit off_t
in applications (that would be silly) and defaults to using 64-bit offsets,
but it still needs to generate the right system calls.

> Either way, ILP32 would still end up calling sys_ftruncate64() (rather
> than the native sys_ftruncate()).

sys_ftruncate64 does not exist in 64-bit kernels, it can either call
compat_sys_ftruncate64_wrapper or sys_ftruncate. I'd assume it would
call the latter and pass a single 64-bit register, but that is another
matter.

	Arnd

^ permalink raw reply	[flat|nested] 79+ 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-10-01 14:00       ` Arnd Bergmann
@ 2014-10-02 11:19         ` Catalin Marinas
  0 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-02 11:19 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-arm-kernel, linux-kernel, Andrew Pinski, pinskia

On Wed, Oct 01, 2014 at 03:00:54PM +0100, Arnd Bergmann wrote:
> On Wednesday 01 October 2014 13:42:27 Catalin Marinas wrote:
> > On Thu, Sep 04, 2014 at 11:11:04AM +0100, Arnd Bergmann wrote:
> > > On Wednesday 03 September 2014 14:19:02 Andrew Pinski wrote:
> > > > + * 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(__ARCH_WANT_64BIT_SYSCALLS)
> > > 
> > > I'm not sure if __ARCH_WANT_64BIT_SYSCALLS is the best name for
> > > this, since it's really only about off_t. It took me a while
> > > to understand what you are doing here.
> > 
> > I'm not sure I fully get it yet. So with this change, we avoid using
> > syscall numbers like __NR_ftruncate64 in favour of __NR_ftruncate. Why?
> > (maybe there's a valid reason, just not getting it).
> 
> glibc depends on the name to decide which calling conventions it
> uses. I assume this is the same on IPL32 ARM.
> 
> The general rule is that on a 32-bit architecture, __NR_ftruncate refers
> to the system call that takes a 32-bit off_t argument, while __NR_ftruncate64
> refers to the syscall that takes a 64-bit loff_t.
> 
> I would assume that the new ABI does not actually allow using 32-bit off_t
> in applications (that would be silly) and defaults to using 64-bit offsets,
> but it still needs to generate the right system calls.

OK, so since ILP32 would have a 64-bit off_t, we want to use
__NR_ftruncate and sys_ftruncate with the off_t argument (rather than
loff_t).

> > Either way, ILP32 would still end up calling sys_ftruncate64() (rather
> > than the native sys_ftruncate()).
> 
> sys_ftruncate64 does not exist in 64-bit kernels, it can either call
> compat_sys_ftruncate64_wrapper or sys_ftruncate. I'd assume it would
> call the latter and pass a single 64-bit register, but that is another
> matter.

I think I get it now. Just for the record, we define __NR_ftruncate to
__NR3264_ftruncate. When we build the syscall table as per patch 21/24,
given that the kernel is built with __LP64__, we get the following
macros for the syscall function name:

#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
...
__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
	       compat_sys_ftruncate64)

Which would result in using sys_ftruncate rather than sys_ftruncate64.

I agree, maybe the name could be __ARCH_WANT_64BIT_OFF_T as that's the
only reason for these definitions.

-- 
Catalin

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

* Re: [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return
  2014-09-03 21:19 ` [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
  2014-09-10 14:31   ` Christopher Covington
  2014-10-01 13:59   ` Catalin Marinas
@ 2014-10-02 13:38   ` Catalin Marinas
  2 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-02 13:38 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:12PM +0100, Andrew Pinski wrote:
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index f47c064..5311147 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -242,6 +242,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

Could we avoid the #ifdef here given that is_ilp32_compat_task() returns
0 when !CONFIG_ARM64_ILP32? I haven't tried to compile it.

> 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

Do we expect so many ILP32 files as to use a separate vdso-ilp32
directory? I prefer a single vdso directory.

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

So we don't even need many new files, just different compiler flags.

> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index a777ac3..21b3726 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -41,6 +41,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

I think the compiler could optimise away some of these and avoid the
#ifdef (similarly in the code where we check for
is_ilp32_compat_task()).

-- 
Catalin

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

* Re: [PATCH 19/24] ptrace: Allow compat to use the native siginfo
  2014-09-03 21:19 ` [PATCH 19/24] ptrace: Allow compat to use the native siginfo Andrew Pinski
@ 2014-10-02 14:13   ` Catalin Marinas
  0 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-02 14:13 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:13PM +0100, Andrew Pinski wrote:
> diff --git a/kernel/ptrace.c b/kernel/ptrace.c
> index 54e7522..40ae023 100644
> --- a/kernel/ptrace.c
> +++ b/kernel/ptrace.c
> @@ -657,7 +657,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) ||
> @@ -1126,16 +1126,27 @@ 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);
> +		}

I haven't read the subsequent patch yet but couldn't you call
ptrace_request directly from the arm64 code for ILP32 tasks instead of
compat_ptrace_request()? Is the ILP32 ptrace support the same with the
LP64 one?

-- 
Catalin

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

* Re: [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls
  2014-09-03 21:19 ` [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls Andrew Pinski
@ 2014-10-02 15:23   ` Catalin Marinas
  2014-10-02 15:46   ` Catalin Marinas
  1 sibling, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-02 15:23 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:15PM +0100, Andrew Pinski wrote:
> +/*
> + * 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;

Do you need the first (uintptr_t) cast here?

> +               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.
> +        */

I wonder whether it would be safe to just zero the top 32 bits of ss_sp
on the user stack directly. Would we ever expect this to be read-only?

> +       ret = sys_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
> +                             (stack_t __force __user *) &uoss);

Nitpick: there shouldn't be any space after the type cast.

-- 
Catalin

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

* Re: [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls
  2014-09-03 21:19 ` [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls Andrew Pinski
  2014-10-02 15:23   ` Catalin Marinas
@ 2014-10-02 15:46   ` Catalin Marinas
  1 sibling, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2014-10-02 15:46 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:19:15PM +0100, Andrew Pinski wrote:
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 9314352..dbedecf 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -643,9 +643,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, el0_ilp32_svc  // We are using ILP32
> +#endif
> +       adrp    stbl, sys_call_table            // load syscall table pointer
>  el0_svc_naked:                                 // compat entry point
>         stp     x0, scno, [sp, #S_ORIG_X0]      // save the original x0 and syscall number
>         enable_dbg_and_irq

The kernel_entry macro already sets tsk to the current thread_info, so
no need to re-read it.

You could also move the TI_FLAGS reading unconditionally in el0_svc and
el0_svc_compat and we only have a tbnz here without the subsequent
TI_FLAGS read in el0_svc_naked.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
                   ` (23 preceding siblings ...)
  2014-09-03 21:19 ` [PATCH 24/24] Add documentation about ARM64 ILP32 ABI Andrew Pinski
@ 2014-10-02 15:52 ` Catalin Marinas
  2015-02-10 18:13   ` Rich Felker
  24 siblings, 1 reply; 79+ messages in thread
From: Catalin Marinas @ 2014-10-02 15:52 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: linux-arm-kernel, linux-kernel, pinskia

On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
> New version with all of the requested changes.  Updated to the latest sources.
> 
> Notable changes from the previous versions:
> VDSO code has been factored out to be easier to understand and easier to maintain.
> Move the config option to the last thing that gets added.
> Added some extra COMPAT_* macros for core dumping for easier usage.

Apart from a few comments I've made, I would also like to see non-empty
commit logs and long line wrapping (both in commit logs and
Documentation/). Otherwise, the patches look fine.

So what are the next steps? Are the glibc folk ok with the ILP32 Linux
ABI? On the kernel side, what I would like to see:

1. LTP results (in all combinations of AArch32, LP64, ILP32, big and
   little endian)
2. A way for us to reproduce the ILP32 tests - at which point could we
   get a toolchain? Ideally a filesystem as well, though maybe we could
   just use a busybox in the meantime.

Thanks.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2014-10-02 15:52 ` [PATCHv3 00/24] ILP32 support in ARM64 Catalin Marinas
@ 2015-02-10 18:13   ` Rich Felker
  2015-02-11 17:39     ` Catalin Marinas
  2015-02-11 18:33     ` H.J. Lu
  0 siblings, 2 replies; 79+ messages in thread
From: Rich Felker @ 2015-02-10 18:13 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Andrew Pinski, linux-arm-kernel, linux-kernel, pinskia, musl, libc-alpha

On Thu, 2 Oct 2014 at 16:52:18 +0100, Catalin Marinas wrote:
> On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
> > New version with all of the requested changes.  Updated to the
> > latest sources.
> > 
> > Notable changes from the previous versions:
> > VDSO code has been factored out to be easier to understand and
> > easier to maintain.
> > Move the config option to the last thing that gets added.
> > Added some extra COMPAT_* macros for core dumping for easier usage.
> 
> Apart from a few comments I've made, I would also like to see non-empty
> commit logs and long line wrapping (both in commit logs and
> Documentation/). Otherwise, the patches look fine.
> 
> So what are the next steps? Are the glibc folk ok with the ILP32 Linux
> ABI? On the kernel side, what I would like to see:

I don't know if this has been discussed on libc-alpha yet or not, but
I think we need to open a discussion of how it relates to open glibc
bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):

https://sourceware.org/bugzilla/show_bug.cgi?id=16437

While most of the other type changes proposed (I'm looking at
https://lkml.org/lkml/2014/9/3/719) are permissible and simply
ugly/undesirable, defining struct timespec with tv_nsec having any
type other than long conflicts with the requirements of C11 and POSIX,
and WG14 is unlikely to be interested in changing the C language
because the Linux kernel has the wrong type in timespec.

Note that on aarch64 ILP32, the consequences of not fixing this right
away will be much worse than on x32, since aarch64 (at least as I
understand it) supports big endian where it's not just a matter of
sign-extending the value from userspace and ignoring the padding, but
rather changing the offset of the tv_nsec member.

Working around the discrepencies in userspace IS possible, but ugly.
We do it in musl libc for x32 right now -- see:

http://git.musl-libc.org/cgit/musl/tree/arch/x32/syscall_arch.h?id=v1.1.6
http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/syscall_cp_fixup.c?id=v1.1.6

I imagine the workarounds in glibc might need to be considerably more
widespread and uglier.

Whatever happens on the kernel side, this needs to be coordinated with
userspace (glibc, etc.) properly so that the type error (glibc bug
16437) is not propagated into a new target that we actually want
people to use. I'd really like it if other undesirable type changes
could be cleaned up too, but perhaps that's too much to ask from the
kernel side.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-10 18:13   ` Rich Felker
@ 2015-02-11 17:39     ` Catalin Marinas
  2015-02-11 19:05       ` [musl] " Szabolcs Nagy
  2015-02-11 19:21       ` Rich Felker
  2015-02-11 18:33     ` H.J. Lu
  1 sibling, 2 replies; 79+ messages in thread
From: Catalin Marinas @ 2015-02-11 17:39 UTC (permalink / raw)
  To: Rich Felker
  Cc: Andrew Pinski, linux-arm-kernel, linux-kernel, pinskia, musl,
	libc-alpha, Marcus Shawcroft

(adding Marcus)

On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> On Thu, 2 Oct 2014 at 16:52:18 +0100, Catalin Marinas wrote:
> > On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
> > > New version with all of the requested changes.  Updated to the
> > > latest sources.
> > > 
> > > Notable changes from the previous versions:
> > > VDSO code has been factored out to be easier to understand and
> > > easier to maintain.
> > > Move the config option to the last thing that gets added.
> > > Added some extra COMPAT_* macros for core dumping for easier usage.
> > 
> > Apart from a few comments I've made, I would also like to see non-empty
> > commit logs and long line wrapping (both in commit logs and
> > Documentation/). Otherwise, the patches look fine.
> > 
> > So what are the next steps? Are the glibc folk ok with the ILP32 Linux
> > ABI? On the kernel side, what I would like to see:
> 
> I don't know if this has been discussed on libc-alpha yet or not, but
> I think we need to open a discussion of how it relates to open glibc
> bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=16437

I'm trying to understand the problem first. Quoting from the bug above
(which I guess is quoted form C11):

"The range and precision of times representable in clock_t and time_t
are implementation-defined. The timespec structure shall contain at
least the following members, in any order.

         time_t tv_sec; // whole seconds -- >= 0
         long   tv_nsec; // nanoseconds -- [0, 999999999]"

So changing time_t to 64-bit is fine on x32. The timespec struct
exported by the kernel always uses a long for tv_nsec. However, glibc uses
__syscall_slong_t which ends up as 64-bit for x32 (I guess it mirrors
the __kernel_long_t definition).

So w.r.t. C11, the exported kernel timespec looks fine. But I think the
x32 kernel support (and the current ILP32 patches) assume a native
struct timespec with tv_nsec as 64-bit.

If we are to be C11 conformant, glibc on x32 has a bug as it defines
timespec incorrectly. This hid a bug in the kernel handling the
corresponding x32 syscalls. What's the best fix for x32 I can't really
tell (we need people to agree on where the bugs are).

At least for AArch64 ILP32 we are still free to change the user/kernel
ABI, so we could add wrappers for the affected syscalls to fix this up.

> While most of the other type changes proposed (I'm looking at
> https://lkml.org/lkml/2014/9/3/719) are permissible and simply
> ugly/undesirable,

They may be ugly but definitely not undesirable ;).

> defining struct timespec with tv_nsec having any type other than long
> conflicts with the requirements of C11 and POSIX, and WG14 is unlikely
> to be interested in changing the C language because the Linux kernel
> has the wrong type in timespec.

I agree. The strange thing is that the Linux exported headers are fine.

> Note that on aarch64 ILP32, the consequences of not fixing this right
> away will be much worse than on x32, since aarch64 (at least as I
> understand it) supports big endian where it's not just a matter of
> sign-extending the value from userspace and ignoring the padding, but
> rather changing the offset of the tv_nsec member.

Indeed.

> Working around the discrepencies in userspace IS possible, but ugly.
> We do it in musl libc for x32 right now -- see:
> 
> http://git.musl-libc.org/cgit/musl/tree/arch/x32/syscall_arch.h?id=v1.1.6
> http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/syscall_cp_fixup.c?id=v1.1.6

For AArch64 ILP32 I would rather see the fix-ups in kernel wrappers.

Are you aware of other cases like this?

(the rest of the comment below for Marcus' attention)

> I imagine the workarounds in glibc might need to be considerably more
> widespread and uglier.
> 
> Whatever happens on the kernel side, this needs to be coordinated with
> userspace (glibc, etc.) properly so that the type error (glibc bug
> 16437) is not propagated into a new target that we actually want
> people to use. I'd really like it if other undesirable type changes
> could be cleaned up too, but perhaps that's too much to ask from the
> kernel side.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-10 18:13   ` Rich Felker
  2015-02-11 17:39     ` Catalin Marinas
@ 2015-02-11 18:33     ` H.J. Lu
  2015-02-11 19:02       ` Rich Felker
  1 sibling, 1 reply; 79+ messages in thread
From: H.J. Lu @ 2015-02-11 18:33 UTC (permalink / raw)
  To: Rich Felker
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Tue, Feb 10, 2015 at 10:13 AM, Rich Felker <dalias@libc.org> wrote:
> On Thu, 2 Oct 2014 at 16:52:18 +0100, Catalin Marinas wrote:
>> On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
>> > New version with all of the requested changes.  Updated to the
>> > latest sources.
>> >
>> > Notable changes from the previous versions:
>> > VDSO code has been factored out to be easier to understand and
>> > easier to maintain.
>> > Move the config option to the last thing that gets added.
>> > Added some extra COMPAT_* macros for core dumping for easier usage.
>>
>> Apart from a few comments I've made, I would also like to see non-empty
>> commit logs and long line wrapping (both in commit logs and
>> Documentation/). Otherwise, the patches look fine.
>>
>> So what are the next steps? Are the glibc folk ok with the ILP32 Linux
>> ABI? On the kernel side, what I would like to see:
>
> I don't know if this has been discussed on libc-alpha yet or not, but
> I think we need to open a discussion of how it relates to open glibc
> bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=16437

Please leave x32 out of this discussion.  I have resolved this bug
as WONTFIX.

> While most of the other type changes proposed (I'm looking at
> https://lkml.org/lkml/2014/9/3/719) are permissible and simply
> ugly/undesirable, defining struct timespec with tv_nsec having any
> type other than long conflicts with the requirements of C11 and POSIX,
> and WG14 is unlikely to be interested in changing the C language
> because the Linux kernel has the wrong type in timespec.
>
> Note that on aarch64 ILP32, the consequences of not fixing this right
> away will be much worse than on x32, since aarch64 (at least as I
> understand it) supports big endian where it's not just a matter of
> sign-extending the value from userspace and ignoring the padding, but
> rather changing the offset of the tv_nsec member.
>
> Working around the discrepencies in userspace IS possible, but ugly.
> We do it in musl libc for x32 right now -- see:
>
> http://git.musl-libc.org/cgit/musl/tree/arch/x32/syscall_arch.h?id=v1.1.6
> http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/syscall_cp_fixup.c?id=v1.1.6

You are free to do what you feel appropriate.  I have no plans
to change x32 on this in glibc at this moment.

> I imagine the workarounds in glibc might need to be considerably more
> widespread and uglier.
>
> Whatever happens on the kernel side, this needs to be coordinated with
> userspace (glibc, etc.) properly so that the type error (glibc bug
> 16437) is not propagated into a new target that we actually want
> people to use. I'd really like it if other undesirable type changes
> could be cleaned up too, but perhaps that's too much to ask from the
> kernel side.
>
> Rich



-- 
H.J.

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 18:33     ` H.J. Lu
@ 2015-02-11 19:02       ` Rich Felker
  2015-02-11 19:16         ` H.J. Lu
  2015-02-11 21:41         ` Joseph Myers
  0 siblings, 2 replies; 79+ messages in thread
From: Rich Felker @ 2015-02-11 19:02 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Wed, Feb 11, 2015 at 10:33:32AM -0800, H.J. Lu wrote:
> On Tue, Feb 10, 2015 at 10:13 AM, Rich Felker <dalias@libc.org> wrote:
> > On Thu, 2 Oct 2014 at 16:52:18 +0100, Catalin Marinas wrote:
> >> On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
> >> > New version with all of the requested changes.  Updated to the
> >> > latest sources.
> >> >
> >> > Notable changes from the previous versions:
> >> > VDSO code has been factored out to be easier to understand and
> >> > easier to maintain.
> >> > Move the config option to the last thing that gets added.
> >> > Added some extra COMPAT_* macros for core dumping for easier usage.
> >>
> >> Apart from a few comments I've made, I would also like to see non-empty
> >> commit logs and long line wrapping (both in commit logs and
> >> Documentation/). Otherwise, the patches look fine.
> >>
> >> So what are the next steps? Are the glibc folk ok with the ILP32 Linux
> >> ABI? On the kernel side, what I would like to see:
> >
> > I don't know if this has been discussed on libc-alpha yet or not, but
> > I think we need to open a discussion of how it relates to open glibc
> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> >
> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> 
> Please leave x32 out of this discussion.  I have resolved this bug
> as WONTFIX.

>From the glibc side, I thought things went by a consensus process
these days, not the old WONTFIX regime of he who shall not be named.
If this is not fixed for x32, then x32 cannot provide a conforming C
environment and thus it's rather a toy target. But I think we should
discuss this on libc-alpha. In the mean time please leave it REOPENED.

Rich

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 17:39     ` Catalin Marinas
@ 2015-02-11 19:05       ` Szabolcs Nagy
  2015-02-11 19:22         ` H.J. Lu
                           ` (2 more replies)
  2015-02-11 19:21       ` Rich Felker
  1 sibling, 3 replies; 79+ messages in thread
From: Szabolcs Nagy @ 2015-02-11 19:05 UTC (permalink / raw)
  To: musl
  Cc: Rich Felker, Andrew Pinski, linux-arm-kernel, linux-kernel,
	pinskia, libc-alpha, Marcus Shawcroft

* Catalin Marinas <catalin.marinas@arm.com> [2015-02-11 17:39:19 +0000]:
> (adding Marcus)
> 
> On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > I don't know if this has been discussed on libc-alpha yet or not, but
> > I think we need to open a discussion of how it relates to open glibc
> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > 
> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
...
> So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> x32 kernel support (and the current ILP32 patches) assume a native
> struct timespec with tv_nsec as 64-bit.
> 
> If we are to be C11 conformant, glibc on x32 has a bug as it defines
> timespec incorrectly. This hid a bug in the kernel handling the
> corresponding x32 syscalls. What's the best fix for x32 I can't really
> tell (we need people to agree on where the bugs are).
> 
> At least for AArch64 ILP32 we are still free to change the user/kernel
> ABI, so we could add wrappers for the affected syscalls to fix this up.
> 

yes, afaik on x32 the 64bit kernel expects 64bit layout,
arm64 can fix this

> > While most of the other type changes proposed (I'm looking at
> > https://lkml.org/lkml/2014/9/3/719) are permissible and simply
> > ugly/undesirable,
> 
> They may be ugly but definitely not undesirable ;).
> 

several types have the same c level definition across all archs..
except x32 because of

 typedef long long __kernel_long_t;

this should not cause posix/c conformance issues (as you noted
timespec is ok in the uapi header only the kernel side behaviour
is wrong)

however note that the kernel documentation is explicit about some of
the types and now x32 does not match those which you may consider
as a documentation issue, but it can easily break existing code so
at least some of the type changes are undesirable
(now it's not clear what libc should do with these)

http://man7.org/linux/man-pages/man2/sysinfo.2.html
http://man7.org/linux/man-pages/man2/adjtimex.2.html
http://man7.org/linux/man-pages/man2/getrusage.2.html

> > Note that on aarch64 ILP32, the consequences of not fixing this right
> > away will be much worse than on x32, since aarch64 (at least as I
> > understand it) supports big endian where it's not just a matter of
> > sign-extending the value from userspace and ignoring the padding, but
> > rather changing the offset of the tv_nsec member.
> 
> Indeed.
> 

the ugliest (little endian only) workaround in glibc now is i think

http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/bits/resource.h;hb=HEAD#l183

> > Working around the discrepencies in userspace IS possible, but ugly.
> > We do it in musl libc for x32 right now -- see:
> > 
> > http://git.musl-libc.org/cgit/musl/tree/arch/x32/syscall_arch.h?id=v1.1.6
> > http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/syscall_cp_fixup.c?id=v1.1.6
> 
> For AArch64 ILP32 I would rather see the fix-ups in kernel wrappers.
> 
> Are you aware of other cases like this?
> 

i know at least one android kernel issue: there is an ioctl for the
alarm device that takes timespec argument

(i think it's not in the mainline kernel and i guess android does
not care about x32 so it was not an issue so far, but this is something
that should not be fixed on the libc side)

wrt. ioctl/fcntl another issue if there is ever a call that takes signed
long or signed int argument which has to be signextended when doing a syscall

(i think this is also a problem if userspace code uses syscall(2) directly,
libc cannot possibly know where to signextend and the kernel side does not
do the fixup right now)

> (the rest of the comment below for Marcus' attention)
> 
> > I imagine the workarounds in glibc might need to be considerably more
> > widespread and uglier.
> > 
> > Whatever happens on the kernel side, this needs to be coordinated with
> > userspace (glibc, etc.) properly so that the type error (glibc bug
> > 16437) is not propagated into a new target that we actually want
> > people to use. I'd really like it if other undesirable type changes
> > could be cleaned up too, but perhaps that's too much to ask from the
> > kernel side.
> 
> -- 
> Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:02       ` Rich Felker
@ 2015-02-11 19:16         ` H.J. Lu
  2015-02-11 19:25           ` Rich Felker
  2015-02-11 21:41         ` Joseph Myers
  1 sibling, 1 reply; 79+ messages in thread
From: H.J. Lu @ 2015-02-11 19:16 UTC (permalink / raw)
  To: Rich Felker
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Wed, Feb 11, 2015 at 11:02 AM, Rich Felker <dalias@libc.org> wrote:
> On Wed, Feb 11, 2015 at 10:33:32AM -0800, H.J. Lu wrote:
>> On Tue, Feb 10, 2015 at 10:13 AM, Rich Felker <dalias@libc.org> wrote:
>> > On Thu, 2 Oct 2014 at 16:52:18 +0100, Catalin Marinas wrote:
>> >> On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
>> >> > New version with all of the requested changes.  Updated to the
>> >> > latest sources.
>> >> >
>> >> > Notable changes from the previous versions:
>> >> > VDSO code has been factored out to be easier to understand and
>> >> > easier to maintain.
>> >> > Move the config option to the last thing that gets added.
>> >> > Added some extra COMPAT_* macros for core dumping for easier usage.
>> >>
>> >> Apart from a few comments I've made, I would also like to see non-empty
>> >> commit logs and long line wrapping (both in commit logs and
>> >> Documentation/). Otherwise, the patches look fine.
>> >>
>> >> So what are the next steps? Are the glibc folk ok with the ILP32 Linux
>> >> ABI? On the kernel side, what I would like to see:
>> >
>> > I don't know if this has been discussed on libc-alpha yet or not, but
>> > I think we need to open a discussion of how it relates to open glibc
>> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
>> >
>> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
>>
>> Please leave x32 out of this discussion.  I have resolved this bug
>> as WONTFIX.
>
> From the glibc side, I thought things went by a consensus process
> these days, not the old WONTFIX regime of he who shall not be named.
> If this is not fixed for x32, then x32 cannot provide a conforming C
> environment and thus it's rather a toy target. But I think we should
> discuss this on libc-alpha. In the mean time please leave it REOPENED.

As I said in PR,  the issue has been raised in Mar, 2012 when the
x32 port was submitted.  It has been decided that x32 won't conform
to tv_nsec, blksize_t, and suseconds_t as long.  I don't believe we
will change them to conform to POSIX.

As for if x32 is a toy target or not, it will be decided by whether it
delivers what users are looking for, not by if tv_nsec, blksize_t, and
suseconds_t conform to POSIX.

-- 
H.J.

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 17:39     ` Catalin Marinas
  2015-02-11 19:05       ` [musl] " Szabolcs Nagy
@ 2015-02-11 19:21       ` Rich Felker
  2015-02-12 18:17         ` Catalin Marinas
  1 sibling, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-11 19:21 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Andrew Pinski, linux-arm-kernel, linux-kernel, pinskia, musl,
	libc-alpha, Marcus Shawcroft

On Wed, Feb 11, 2015 at 05:39:19PM +0000, Catalin Marinas wrote:
> (adding Marcus)
> 
> On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > On Thu, 2 Oct 2014 at 16:52:18 +0100, Catalin Marinas wrote:
> > > On Wed, Sep 03, 2014 at 10:18:54PM +0100, Andrew Pinski wrote:
> > > > New version with all of the requested changes.  Updated to the
> > > > latest sources.
> > > > 
> > > > Notable changes from the previous versions:
> > > > VDSO code has been factored out to be easier to understand and
> > > > easier to maintain.
> > > > Move the config option to the last thing that gets added.
> > > > Added some extra COMPAT_* macros for core dumping for easier usage.
> > > 
> > > Apart from a few comments I've made, I would also like to see non-empty
> > > commit logs and long line wrapping (both in commit logs and
> > > Documentation/). Otherwise, the patches look fine.
> > > 
> > > So what are the next steps? Are the glibc folk ok with the ILP32 Linux
> > > ABI? On the kernel side, what I would like to see:
> > 
> > I don't know if this has been discussed on libc-alpha yet or not, but
> > I think we need to open a discussion of how it relates to open glibc
> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > 
> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> 
> I'm trying to understand the problem first. Quoting from the bug above
> (which I guess is quoted form C11):
> 
> "The range and precision of times representable in clock_t and time_t
> are implementation-defined. The timespec structure shall contain at
> least the following members, in any order.
> 
>          time_t tv_sec; // whole seconds -- >= 0
>          long   tv_nsec; // nanoseconds -- [0, 999999999]"
> 
> So changing time_t to 64-bit is fine on x32. The timespec struct
> exported by the kernel always uses a long for tv_nsec. However, glibc uses
> __syscall_slong_t which ends up as 64-bit for x32 (I guess it mirrors
> the __kernel_long_t definition).
> 
> So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> x32 kernel support (and the current ILP32 patches) assume a native
> struct timespec with tv_nsec as 64-bit.

The exported kernel timespec is not fine if long is defined as a
32-bit type, which it is for x32 and the proposed aarch64-ILP32 ABIs.
The type being long means that code like

	long *p = &ts->tv_nsec;
	*p = 42;

is valid. With the proposed definition of timespec, this results in a
compiler warning or error on valid code, which is better than
dangerously wrong code generation, but we can easily hide the warning
via:

	void *p = &ts->tv_nsec;
	long *q = p;
	*q = 42;

Imagine this happening in places such as with callbacks that take void
pointers, for example pthread_create.

But even if the breakage could always be diagnosed by the compiler,
you're still breaking perfectly valid, conforming C programs.

> If we are to be C11 conformant, glibc on x32 has a bug as it defines
> timespec incorrectly. This hid a bug in the kernel handling the
> corresponding x32 syscalls. What's the best fix for x32 I can't really
> tell (we need people to agree on where the bugs are).

For the kernel, it should be casting the value to int/int32_t to
ignore the junk in the upper bits. But that only works on little
endian. On big endian it's a bigger mess.

However at this point fixing it on the kernel side is not very useful
for x32, at least not right away. Since people will still be running
old kernels with the wrong behavior, the fixup has to happen in
userspace to support those old kernels until the libc drops support
for kernels too old to handle it right.

> At least for AArch64 ILP32 we are still free to change the user/kernel
> ABI, so we could add wrappers for the affected syscalls to fix this up.

Yes. That's what I'd like to see before aarch64-ILP32 is officially
launched. It's a lot harder to retroactively fix this. Right now it's
fairly easy -- just a small wrapper/fixup layer in the kernel.

> > While most of the other type changes proposed (I'm looking at
> > https://lkml.org/lkml/2014/9/3/719) are permissible and simply
> > ugly/undesirable,
> 
> They may be ugly but definitely not undesirable ;).

I can point you to a few other cases that may be undesirable, but less
severe than timespec:

- https://sourceware.org/bugzilla/show_bug.cgi?id=16438
- http://man7.org/linux/man-pages/man2/sysinfo.2.html

In the case of sysinfo, the public API documentation documents the
fields as having type unsigned long, but on x32 (and presumably
aarch64-ILP32 as proposed) they have type unsigned long long.

I can probably find more examples if you're interested.

> > defining struct timespec with tv_nsec having any type other than long
> > conflicts with the requirements of C11 and POSIX, and WG14 is unlikely
> > to be interested in changing the C language because the Linux kernel
> > has the wrong type in timespec.
> 
> I agree. The strange thing is that the Linux exported headers are fine.

I'm confused why you think they're fine.

> > Note that on aarch64 ILP32, the consequences of not fixing this right
> > away will be much worse than on x32, since aarch64 (at least as I
> > understand it) supports big endian where it's not just a matter of
> > sign-extending the value from userspace and ignoring the padding, but
> > rather changing the offset of the tv_nsec member.
> 
> Indeed.
> 
> > Working around the discrepencies in userspace IS possible, but ugly.
> > We do it in musl libc for x32 right now -- see:
> > 
> > http://git.musl-libc.org/cgit/musl/tree/arch/x32/syscall_arch.h?id=v1.1.6
> > http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/syscall_cp_fixup.c?id=v1.1.6
> 
> For AArch64 ILP32 I would rather see the fix-ups in kernel wrappers.
> 
> Are you aware of other cases like this?

For musl x32, the only other thing we had to work around with code was:

http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/sysinfo.c?id=v1.1.6

However, code was mostly only needed where the data is being passed
from userspace to the kernel; for the other direction, most of the
discrepencies were handled simply by defining structures with extra
32-bit padding fields next to their 32-bit longs. I'm including below
a diff of our arch/x86_64/bits versus arch/x32/bits trees to
demonstrate the changes made.

Rich



--- arch/x86_64/bits/alltypes.h.in
+++ arch/x32/bits/alltypes.h.in
@@ -1,12 +1,12 @@
-#define _Addr long
-#define _Int64 long
-#define _Reg long
+#define _Addr int
+#define _Int64 long long
+#define _Reg long long
 
 TYPEDEF __builtin_va_list va_list;
 TYPEDEF __builtin_va_list __isoc_va_list;
 
 #ifndef __cplusplus
-TYPEDEF int wchar_t;
+TYPEDEF long wchar_t;
 #endif
 
 #if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 2
@@ -19,8 +19,8 @@
 
 TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
 
-TYPEDEF long time_t;
-TYPEDEF long suseconds_t;
+TYPEDEF long long time_t;
+TYPEDEF long long suseconds_t;
 
 TYPEDEF struct { union { int __i[14]; unsigned long __s[7]; } __u; } pthread_attr_t;
 TYPEDEF struct { union { int __i[10]; volatile void *volatile __p[5]; } __u; } pthread_mutex_t;
--- arch/x86_64/bits/ipc.h
+++ arch/x32/bits/ipc.h
@@ -7,8 +7,8 @@
 	gid_t cgid;
 	mode_t mode;
 	int __ipc_perm_seq;
-	long __pad1;
-	long __pad2;
+	long long __pad1;
+	long long __pad2;
 };
 
 #define IPC_64 0
--- arch/x86_64/bits/limits.h
+++ arch/x32/bits/limits.h
@@ -1,8 +1,8 @@
 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
  || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
 #define PAGE_SIZE 4096
-#define LONG_BIT 64
+#define LONG_BIT 32
 #endif
 
-#define LONG_MAX  0x7fffffffffffffffL
+#define LONG_MAX  0x7fffffffL
 #define LLONG_MAX  0x7fffffffffffffffLL
--- arch/x86_64/bits/msg.h
+++ arch/x32/bits/msg.h
@@ -5,9 +5,12 @@
 	time_t msg_rtime;
 	time_t msg_ctime;
 	unsigned long msg_cbytes;
+	long __unused1;
 	msgqnum_t msg_qnum;
+	long __unused2;
 	msglen_t msg_qbytes;
+	long __unused3;
 	pid_t msg_lspid;
 	pid_t msg_lrpid;
-	unsigned long __unused[2];
+	unsigned long long __unused[2];
 };
--- arch/x86_64/bits/reg.h
+++ arch/x32/bits/reg.h
@@ -1,5 +1,5 @@
 #undef __WORDSIZE
-#define __WORDSIZE 64
+#define __WORDSIZE 32
 #define R15    0
 #define R14    1
 #define R13    2
--- arch/x86_64/bits/setjmp.h
+++ arch/x32/bits/setjmp.h
@@ -1 +1 @@
-typedef unsigned long __jmp_buf[8];
+typedef unsigned long long __jmp_buf[8];
--- arch/x86_64/bits/shm.h
+++ arch/x32/bits/shm.h
@@ -10,17 +10,24 @@
 	pid_t shm_cpid;
 	pid_t shm_lpid;
 	unsigned long shm_nattch;
-	unsigned long __pad1;
-	unsigned long __pad2;
+	unsigned long __pad0;
+	unsigned long long __pad1;
+	unsigned long long __pad2;
 };
 
 struct shminfo {
-	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+	unsigned long shmmax, __pad0, shmmin, __pad1, shmmni, __pad2,
+	              shmseg, __pad3, shmall, __pad4;
+	unsigned long long __unused[4];
 };
 
 struct shm_info {
 	int __used_ids;
-	unsigned long shm_tot, shm_rss, shm_swp;
-	unsigned long __swap_attempts, __swap_successes;
-};
-
+	int __pad_ids;
+	unsigned long shm_tot, __pad0, shm_rss, __pad1, shm_swp, __pad2;
+	unsigned long __swap_attempts, __pad3, __swap_successes, __pad4;
+}
+#ifdef __GNUC__
+__attribute__((__aligned__(8)))
+#endif
+;
--- arch/x86_64/bits/signal.h
+++ arch/x32/bits/signal.h
@@ -42,12 +42,12 @@
 	unsigned padding[24];
 } *fpregset_t;
 struct sigcontext {
-	unsigned long r8, r9, r10, r11, r12, r13, r14, r15;
-	unsigned long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;
+	unsigned long long r8, r9, r10, r11, r12, r13, r14, r15;
+	unsigned long long rdi, rsi, rbp, rbx, rdx, rax, rcx, rsp, rip, eflags;
 	unsigned short cs, gs, fs, __pad0;
-	unsigned long err, trapno, oldmask, cr2;
+	unsigned long long err, trapno, oldmask, cr2;
 	struct _fpstate *fpstate;
-	unsigned long __reserved1[8];
+	unsigned long long __reserved1[8];
 };
 typedef struct {
 	gregset_t gregs;
@@ -56,7 +56,7 @@
 } mcontext_t;
 #else
 typedef struct {
-	unsigned long __space[32];
+	unsigned long long __space[32];
 } mcontext_t;
 #endif
 
@@ -72,7 +72,7 @@
 	stack_t uc_stack;
 	mcontext_t uc_mcontext;
 	sigset_t uc_sigmask;
-	unsigned long __fpregs_mem[64];
+	unsigned long long __fpregs_mem[64];
 } ucontext_t;
 
 #define SA_NOCLDSTOP  1
--- arch/x86_64/bits/stat.h
+++ arch/x32/bits/stat.h
@@ -18,5 +18,5 @@
 	struct timespec st_atim;
 	struct timespec st_mtim;
 	struct timespec st_ctim;
-	long __unused[3];
+	long long __unused[3];
 };
--- arch/x86_64/bits/statfs.h
+++ arch/x32/bits/statfs.h
@@ -1,7 +1,9 @@
 struct statfs {
-	unsigned long f_type, f_bsize;
+	unsigned long f_type, __pad0, f_bsize, __pad1;
 	fsblkcnt_t f_blocks, f_bfree, f_bavail;
 	fsfilcnt_t f_files, f_ffree;
 	fsid_t f_fsid;
-	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+	unsigned long f_namelen, __pad2, f_frsize, __pad3;
+	unsigned long f_flags, __pad4;
+	unsigned long long f_spare[4];
 };
--- arch/x86_64/bits/stdint.h
+++ arch/x32/bits/stdint.h
@@ -12,9 +12,9 @@
 #define UINT_FAST16_MAX UINT32_MAX
 #define UINT_FAST32_MAX UINT32_MAX
 
-#define INTPTR_MIN      INT64_MIN
-#define INTPTR_MAX      INT64_MAX
-#define UINTPTR_MAX     UINT64_MAX
-#define PTRDIFF_MIN     INT64_MIN
-#define PTRDIFF_MAX     INT64_MAX
-#define SIZE_MAX        UINT64_MAX
+#define INTPTR_MIN      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#define PTRDIFF_MIN     INT32_MIN
+#define PTRDIFF_MAX     INT32_MAX
+#define SIZE_MAX        UINT32_MAX

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:05       ` [musl] " Szabolcs Nagy
@ 2015-02-11 19:22         ` H.J. Lu
  2015-02-11 19:50         ` arnd
  2015-02-12  8:12         ` Szabolcs Nagy
  2 siblings, 0 replies; 79+ messages in thread
From: H.J. Lu @ 2015-02-11 19:22 UTC (permalink / raw)
  To: musl, Rich Felker, Andrew Pinski, linux-arm-kernel, linux-kernel,
	pinskia, libc-alpha, Marcus Shawcroft

On Wed, Feb 11, 2015 at 11:05 AM, Szabolcs Nagy <nsz@port70.net> wrote:
> i know at least one android kernel issue: there is an ioctl for the
> alarm device that takes timespec argument
>
> (i think it's not in the mainline kernel and i guess android does
> not care about x32 so it was not an issue so far, but this is something
> that should not be fixed on the libc side)
>

I have documented some remaining x32 kernel issues at:

https://sites.google.com/site/x32abi/

-- 
H.J.

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:16         ` H.J. Lu
@ 2015-02-11 19:25           ` Rich Felker
  2015-02-11 19:34             ` H.J. Lu
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-11 19:25 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Wed, Feb 11, 2015 at 11:16:58AM -0800, H.J. Lu wrote:
> >> > I don't know if this has been discussed on libc-alpha yet or not, but
> >> > I think we need to open a discussion of how it relates to open glibc
> >> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> >> >
> >> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> >>
> >> Please leave x32 out of this discussion.  I have resolved this bug
> >> as WONTFIX.
> >
> > From the glibc side, I thought things went by a consensus process
> > these days, not the old WONTFIX regime of he who shall not be named.
> > If this is not fixed for x32, then x32 cannot provide a conforming C
> > environment and thus it's rather a toy target. But I think we should
> > discuss this on libc-alpha. In the mean time please leave it REOPENED.
> 
> As I said in PR,  the issue has been raised in Mar, 2012 when the
> x32 port was submitted.  It has been decided that x32 won't conform
> to tv_nsec, blksize_t, and suseconds_t as long.  I don't believe we
> will change them to conform to POSIX.

I briefly reviewed that discussion and I think the decision made was
about an obscure POSIX requirement about supporting at least one
compilation environment where certain types have rank <= long. This is
trivially satisfied if you consider x32 and x86_64 separate
compilation environments, but it's not related to the core issue: that
the definition of timespec violates core (not obscure) requirements of
both POSIX and C11. At the time you were probably unaware of the C11
requirement. Note that it's a LOT harder to effect change in the C
standard, so even if the Austin Group would be amenable to changing
the requirement for timespec to allow something like nseconds_t,
getting WG14 to make this change to work around a Linux/glibc mistake
does not sound practical.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:25           ` Rich Felker
@ 2015-02-11 19:34             ` H.J. Lu
  2015-02-11 19:47               ` Rich Felker
  0 siblings, 1 reply; 79+ messages in thread
From: H.J. Lu @ 2015-02-11 19:34 UTC (permalink / raw)
  To: Rich Felker
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Wed, Feb 11, 2015 at 11:25 AM, Rich Felker <dalias@libc.org> wrote:
> On Wed, Feb 11, 2015 at 11:16:58AM -0800, H.J. Lu wrote:
>> >> > I don't know if this has been discussed on libc-alpha yet or not, but
>> >> > I think we need to open a discussion of how it relates to open glibc
>> >> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
>> >> >
>> >> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
>> >>
>> >> Please leave x32 out of this discussion.  I have resolved this bug
>> >> as WONTFIX.
>> >
>> > From the glibc side, I thought things went by a consensus process
>> > these days, not the old WONTFIX regime of he who shall not be named.
>> > If this is not fixed for x32, then x32 cannot provide a conforming C
>> > environment and thus it's rather a toy target. But I think we should
>> > discuss this on libc-alpha. In the mean time please leave it REOPENED.
>>
>> As I said in PR,  the issue has been raised in Mar, 2012 when the
>> x32 port was submitted.  It has been decided that x32 won't conform
>> to tv_nsec, blksize_t, and suseconds_t as long.  I don't believe we
>> will change them to conform to POSIX.
>
> I briefly reviewed that discussion and I think the decision made was
> about an obscure POSIX requirement about supporting at least one
> compilation environment where certain types have rank <= long. This is

The example you gave in PR is similar to

https://sourceware.org/ml/libc-alpha/2012-03/msg00456.html

> trivially satisfied if you consider x32 and x86_64 separate
> compilation environments, but it's not related to the core issue: that
> the definition of timespec violates core (not obscure) requirements of
> both POSIX and C11. At the time you were probably unaware of the C11
> requirement. Note that it's a LOT harder to effect change in the C
> standard, so even if the Austin Group would be amenable to changing
> the requirement for timespec to allow something like nseconds_t,
> getting WG14 to make this change to work around a Linux/glibc mistake
> does not sound practical.

That is very unfortunate.  I consider it is too late for x32 to change.


-- 
H.J.

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:34             ` H.J. Lu
@ 2015-02-11 19:47               ` Rich Felker
  2015-02-11 19:57                 ` H.J. Lu
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-11 19:47 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Wed, Feb 11, 2015 at 11:34:23AM -0800, H.J. Lu wrote:
> On Wed, Feb 11, 2015 at 11:25 AM, Rich Felker <dalias@libc.org> wrote:
> > On Wed, Feb 11, 2015 at 11:16:58AM -0800, H.J. Lu wrote:
> >> >> > I don't know if this has been discussed on libc-alpha yet or not, but
> >> >> > I think we need to open a discussion of how it relates to open glibc
> >> >> > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> >> >> >
> >> >> > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> >> >>
> >> >> Please leave x32 out of this discussion.  I have resolved this bug
> >> >> as WONTFIX.
> >> >
> >> > From the glibc side, I thought things went by a consensus process
> >> > these days, not the old WONTFIX regime of he who shall not be named.
> >> > If this is not fixed for x32, then x32 cannot provide a conforming C
> >> > environment and thus it's rather a toy target. But I think we should
> >> > discuss this on libc-alpha. In the mean time please leave it REOPENED.
> >>
> >> As I said in PR,  the issue has been raised in Mar, 2012 when the
> >> x32 port was submitted.  It has been decided that x32 won't conform
> >> to tv_nsec, blksize_t, and suseconds_t as long.  I don't believe we
> >> will change them to conform to POSIX.
> >
> > I briefly reviewed that discussion and I think the decision made was
> > about an obscure POSIX requirement about supporting at least one
> > compilation environment where certain types have rank <= long. This is
> 
> The example you gave in PR is similar to
> 
> https://sourceware.org/ml/libc-alpha/2012-03/msg00456.html

Yes, but after that the conversation seemed to get derailed into the
blksize_t etc. stuff about "compilation environments" that's largely
irrelevant. I think this prevented the core tv_nsec issue from getting
discussed further, unless I'm missing part of that thread.

> > trivially satisfied if you consider x32 and x86_64 separate
> > compilation environments, but it's not related to the core issue: that
> > the definition of timespec violates core (not obscure) requirements of
> > both POSIX and C11. At the time you were probably unaware of the C11
> > requirement. Note that it's a LOT harder to effect change in the C
> > standard, so even if the Austin Group would be amenable to changing
> > the requirement for timespec to allow something like nseconds_t,
> > getting WG14 to make this change to work around a Linux/glibc mistake
> > does not sound practical.
> 
> That is very unfortunate.  I consider it is too late for x32 to change.

Why? It's hardly an incompatible ABI change, as long as the
kernel/libc fills the upper bits (for old programs that read them
based on the old headers) when structs are read from the kernel to the
application, and ignores the upper bits (potentially set or left
uninitialized by the application) when strings are passed from
userspace to the kernel. Newly built apps using the struct definition
with 32-bit tv_nsec would need new libc to ensure that the high bits
aren't interpreted, but this could be handled by symbol versioning.

Rich

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:05       ` [musl] " Szabolcs Nagy
  2015-02-11 19:22         ` H.J. Lu
@ 2015-02-11 19:50         ` arnd
  2015-02-11 20:12           ` Rich Felker
  2015-02-12  8:12         ` Szabolcs Nagy
  2 siblings, 1 reply; 79+ messages in thread
From: arnd @ 2015-02-11 19:50 UTC (permalink / raw)
  To: Szabolcs Nagy, musl
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel, Rich Felker,
	Andrew Pinski, linux-arm-kernel

> Szabolcs Nagy <nsz@port70.net> hat am 11. Februar 2015 um 20:05 geschrieben:
> * Catalin Marinas <catalin.marinas@arm.com> [2015-02-11 17:39:19 +0000]:
> > (adding Marcus)
> >
> > On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > > I don't know if this has been discussed on libc-alpha yet or not, but
> > > I think we need to open a discussion of how it relates to open glibc
> > > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > >
> > > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> ...
> > So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> > x32 kernel support (and the current ILP32 patches) assume a native
> > struct timespec with tv_nsec as 64-bit.
> >
> > If we are to be C11 conformant, glibc on x32 has a bug as it defines
> > timespec incorrectly. This hid a bug in the kernel handling the
> > corresponding x32 syscalls. What's the best fix for x32 I can't really
> > tell (we need people to agree on where the bugs are).
> >
> > At least for AArch64 ILP32 we are still free to change the user/kernel
> > ABI, so we could add wrappers for the affected syscalls to fix this up.
> >
>
> yes, afaik on x32 the 64bit kernel expects 64bit layout,
> arm64 can fix this
 
We have to fix it on all 32-bit architectures when we move to 64-bit time_t.
 
I think ideally you'd want a user space definition like

typedef long long time_t;
struct timespec {
      time_t tv_sec;
      long long tv_nsec;
};

which is the only way to avoid passing uninitialized tv_nsec into the kernel
from arbitrary user space doing ioctl. This is of course against POSIX and
C99. Changing POSIX to allow it is probably easier than the C standard,
but we have a couple of years before we need to make this the default.

In the kernel headers, the current plan is to provide interfaces taking
structures 
 
typedef long long __kernel_time64_t;
struct __kernel_timespec64_t {
      __kernel_time64_t tv_sec;
      long long tv_nsec;
};
 
at least for ioctls, to avoid the ambiguity with libc headers specifying
something else.

A libc could use other definitions with added padding for what it exports
to user space though, or even make this depend on compile-time flags to
determine whether to make tv_nsec as long long, or to insert padding
in the right place based on endianess.

> > > While most of the other type changes proposed (I'm looking at
> > > https://lkml.org/lkml/2014/9/3/719) are permissible and simply
> > > ugly/undesirable,
> >
> > They may be ugly but definitely not undesirable ;).
> >
>
> several types have the same c level definition across all archs..
> except x32 because of
>
> typedef long long __kernel_long_t;
>
> this should not cause posix/c conformance issues (as you noted
> timespec is ok in the uapi header only the kernel side behaviour
> is wrong)
 
The kernel behavior is right for the syscalls except ioctl, the uapi
header is wrong (not according to C99, but according to common sense)
and needs to be changed in order to work with big-endian. For x32,
I wonder if we can just #define timespec as __kernel_timespec64
once we introduce that.

> > > Working around the discrepencies in userspace IS possible, but ugly.
> > > We do it in musl libc for x32 right now -- see:
> > >
> > > http://git.musl-libc.org/cgit/musl/tree/arch/x32/syscall_arch.h?id=v1.1.6
> > > http://git.musl-libc.org/cgit/musl/tree/arch/x32/src/syscall_cp_fixup.c?id=v1.1.6
> >
> > For AArch64 ILP32 I would rather see the fix-ups in kernel wrappers.
> >
> > Are you aware of other cases like this?
> >
>
> i know at least one android kernel issue: there is an ioctl for the
> alarm device that takes timespec argument
>
> (i think it's not in the mainline kernel and i guess android does
> not care about x32 so it was not an issue so far, but this is something
> that should not be fixed on the libc side)

ioctl is a known problem with x32 and the ARM ILP32 support. This is
not limited to timespec but to any driver that uses an ioctl with
a data structure that includes a __kernel_long_t or __kernel_ulong_t
argument. There are a couple of drivers using these, and we either
need to change the structures to use 'long' instead, or fix the driver
to be aware of the difference between old-style 32-bit compat and
x32-style compat ioctl handling.

The types affected by this are
include/uapi/asm-generic/posix_types.h:typedef __kernel_ulong_t __kernel_ino_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_ulong_t __kernel_size_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_long_t
         __kernel_suseconds_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_long_t
 __kernel_ssize_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_long_t
 __kernel_ptrdiff_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_long_t  __kernel_off_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_long_t  __kernel_time_t;
include/uapi/asm-generic/posix_types.h:typedef __kernel_long_t
 __kernel_clock_t;

and anything derived from this.

     Arnd

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:47               ` Rich Felker
@ 2015-02-11 19:57                 ` H.J. Lu
  2015-02-11 20:15                   ` Andy Lutomirski
  0 siblings, 1 reply; 79+ messages in thread
From: H.J. Lu @ 2015-02-11 19:57 UTC (permalink / raw)
  To: Rich Felker
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

>> > trivially satisfied if you consider x32 and x86_64 separate
>> > compilation environments, but it's not related to the core issue: that
>> > the definition of timespec violates core (not obscure) requirements of
>> > both POSIX and C11. At the time you were probably unaware of the C11
>> > requirement. Note that it's a LOT harder to effect change in the C
>> > standard, so even if the Austin Group would be amenable to changing
>> > the requirement for timespec to allow something like nseconds_t,
>> > getting WG14 to make this change to work around a Linux/glibc mistake
>> > does not sound practical.
>>
>> That is very unfortunate.  I consider it is too late for x32 to change.
>
> Why? It's hardly an incompatible ABI change, as long as the
> kernel/libc fills the upper bits (for old programs that read them
> based on the old headers) when structs are read from the kernel to the
> application, and ignores the upper bits (potentially set or left
> uninitialized by the application) when strings are passed from
> userspace to the kernel. Newly built apps using the struct definition
> with 32-bit tv_nsec would need new libc to ensure that the high bits
> aren't interpreted, but this could be handled by symbol versioning.
>

We have considered this option.  But since kernel wouldn't change
tv_nsec/tv_usec handling just for x32, it wasn't selected.



-- 
H.J.

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:50         ` arnd
@ 2015-02-11 20:12           ` Rich Felker
       [not found]             ` <1383502854.512344.1423688575473.JavaMail.open-xchange@oxbaltgw09.schlund.de>
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-11 20:12 UTC (permalink / raw)
  To: arnd
  Cc: Szabolcs Nagy, musl, libc-alpha, pinskia, Marcus Shawcroft,
	linux-kernel, Andrew Pinski, linux-arm-kernel

On Wed, Feb 11, 2015 at 08:50:06PM +0100, arnd@arndb.de wrote:
> > > At least for AArch64 ILP32 we are still free to change the user/kernel
> > > ABI, so we could add wrappers for the affected syscalls to fix this up.
> > >
> >
> > yes, afaik on x32 the 64bit kernel expects 64bit layout,
> > arm64 can fix this
>  
> We have to fix it on all 32-bit architectures when we move to 64-bit time_t.
>  
> I think ideally you'd want a user space definition like
> 
> typedef long long time_t;
> struct timespec {
>       time_t tv_sec;
>       long long tv_nsec;
> };
> 
> which is the only way to avoid passing uninitialized tv_nsec into the kernel
> from arbitrary user space doing ioctl. This is of course against POSIX and
> C99. Changing POSIX to allow it is probably easier than the C standard,
> but we have a couple of years before we need to make this the default.

I don't see why you want it to be long long. There is no harm in
passing uninitialized padding to the kernel; the kernel just needs to
do the right thing and ignore it (or avoid reading it to begin with).
Changing the C standard in an incompatible way that invalidates
existing code is not preferable over fixing an implementation bug in
one implementation. Even if C16 or so changed the requirement, people
will still be looking to C11 (and even C99) for years or decades to
come. Alignment of code to language standards moves slowly.

The other direction, passing uninitialized data from the kernel to
userspace, would be dangerous. But it doesn't happen as long as the
userspace padding is positioned (in an endian-dependent manner) where
the high bits of the kernel type would lie. It could happen if you
used a separate conversion wrapper that ony wrote 32 bits, but if you
wanted to take that approach you'd just need the wrapper to also write
the padding field manually.

> In the kernel headers, the current plan is to provide interfaces taking
> structures 
>  
> typedef long long __kernel_time64_t;
> struct __kernel_timespec64_t {
>       __kernel_time64_t tv_sec;
>       long long tv_nsec;
> };
>  
> at least for ioctls, to avoid the ambiguity with libc headers specifying
> something else.

This seems hideous from an application standpoint. Application
programmers don't want to know, and shouldn't need to know, these
silly implementation details that make no sense except as historical
baggage. They should just be able to use "struct timespec" everywhere
and have it work.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:57                 ` H.J. Lu
@ 2015-02-11 20:15                   ` Andy Lutomirski
  2015-02-12 15:50                     ` Catalin Marinas
  0 siblings, 1 reply; 79+ messages in thread
From: Andy Lutomirski @ 2015-02-11 20:15 UTC (permalink / raw)
  To: H.J. Lu, Rich Felker
  Cc: Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On 02/11/2015 11:57 AM, H.J. Lu wrote:
>>>> trivially satisfied if you consider x32 and x86_64 separate
>>>> compilation environments, but it's not related to the core issue: that
>>>> the definition of timespec violates core (not obscure) requirements of
>>>> both POSIX and C11. At the time you were probably unaware of the C11
>>>> requirement. Note that it's a LOT harder to effect change in the C
>>>> standard, so even if the Austin Group would be amenable to changing
>>>> the requirement for timespec to allow something like nseconds_t,
>>>> getting WG14 to make this change to work around a Linux/glibc mistake
>>>> does not sound practical.
>>>
>>> That is very unfortunate.  I consider it is too late for x32 to change.
>>
>> Why? It's hardly an incompatible ABI change, as long as the
>> kernel/libc fills the upper bits (for old programs that read them
>> based on the old headers) when structs are read from the kernel to the
>> application, and ignores the upper bits (potentially set or left
>> uninitialized by the application) when strings are passed from
>> userspace to the kernel. Newly built apps using the struct definition
>> with 32-bit tv_nsec would need new libc to ensure that the high bits
>> aren't interpreted, but this could be handled by symbol versioning.
>>
>
> We have considered this option.  But since kernel wouldn't change
> tv_nsec/tv_usec handling just for x32, it wasn't selected.
>

Did anyone *ask* the kernel people (e.g. hpa)?

--Andy

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
       [not found]             ` <1383502854.512344.1423688575473.JavaMail.open-xchange@oxbaltgw09.schlund.de>
@ 2015-02-11 21:09               ` arnd
  2015-02-11 21:37               ` Rich Felker
  1 sibling, 0 replies; 79+ messages in thread
From: arnd @ 2015-02-11 21:09 UTC (permalink / raw)
  To: Rich Felker
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel,
	Szabolcs Nagy, Andrew Pinski, linux-arm-kernel, musl

Sorry about the HTML mail, I'm currently travelling without access to my regular
mail client. 

> "arnd@arndb.de" <arnd@arndb.de> hat am 11. Februar 2015 um 22:02 geschrieben:
> 
>  Rich Felker <dalias@libc.org> hat am 11. Februar 2015 um 21:12 geschrieben:
>  > On Wed, Feb 11, 2015 at 08:50:06PM +0100, arnd@arndb.de wrote:
>  > > > > At least for AArch64 ILP32 we are still free to change the
>  > > > > user/kernel
>  > > > > ABI, so we could add wrappers for the affected syscalls to fix this
>  > > > > up.
>  > > > yes, afaik on x32 the 64bit kernel expects 64bit layout,
>  > > > arm64 can fix this
>  > >
>  > > We have to fix it on all 32-bit architectures when we move to 64-bit
>  > > time_t.
>  > >
>  > > I think ideally you'd want a user space definition like
>  > >
>  > > typedef long long time_t;
>  > > struct timespec {
>  > > time_t tv_sec;
>  > > long long tv_nsec;
>  > > };
>  > >
>  > > which is the only way to avoid passing uninitialized tv_nsec into the
>  > > kernel
>  > > from arbitrary user space doing ioctl. This is of course against POSIX
>  > > and
>  > > C99. Changing POSIX to allow it is probably easier than the C standard,
>  > > but we have a couple of years before we need to make this the default.
>  >
>  > I don't see why you want it to be long long. There is no harm in
>  > passing uninitialized padding to the kernel; the kernel just needs to
>  > do the right thing and ignore it (or avoid reading it to begin with).
>   
>  This would however mean having three different implementations
>  in the kernel rather than just two: Every driver that can pass a timespec
>  with this model needs to handle the native 64-bit case (64/64), the legacy
>  32-bit case (32/32) and the y2038-safe case (64/32). Most code can
>  already handle the first two, and none today handles the third. If you
>  want to make the handling explicitly incompatible with native 64-bit
>  mode, you get a lot of untested code in obscure places that are never
>  tested properly, while using the normal behavior in the kernel at least
>  gives us the same bugs that we already have on native 64-bit systems.
>   
>  In some cases, there may also be a measurable performance penalty
>  in interpreting a user space data structure manually over copying
>  it (including the timespec values) in one chunk.
>   
>  An alternative would be to change the native 64-bit case to ignore the upper
>  half of tv_nsec and always just copy the low bits. This should work
>  fine almost all of the time, but I fear that there might be corner cases
>  where existing 64-bit user space depends on passing large or negative
>  tv_nsec values into the kernel.
>   
>  > The other direction, passing uninitialized data from the kernel to
>  > userspace, would be dangerous. But it doesn't happen as long as the
>  > userspace padding is positioned (in an endian-dependent manner) where
>  > the high bits of the kernel type would lie. It could happen if you
>  > used a separate conversion wrapper that ony wrote 32 bits, but if you
>  > wanted to take that approach you'd just need the wrapper to also write
>  > the padding field manually.
>   
>  Going from kernel to user space should not be an issue as long as we
>  always just write two 64-bit words, and this will zero-fill the upper half.
> 
>  > > In the kernel headers, the current plan is to provide interfaces taking
>  > > structures
>  > >
>  > > typedef long long __kernel_time64_t;
>  > > struct __kernel_timespec64_t {
>  > > __kernel_time64_t tv_sec;
>  > > long long tv_nsec;
>  > > };
>  > >
>  > > at least for ioctls, to avoid the ambiguity with libc headers specifying
>  > > something else.
>  >
>  > This seems hideous from an application standpoint. Application
>  > programmers don't want to know, and shouldn't need to know, these
>  > silly implementation details that make no sense except as historical
>  > baggage. They should just be able to use "struct timespec" everywhere
>  > and have it work.
>  The kernel does not even know how timespec is defined by libc, and we have
>  to at least be able to handle the common cases of timespec being 32/32
>  and 64/64 (or 64/32 plus explicit padding). For system calls, we can rely
>  on libc calling the syscalls that match the definition (or convert the
>  structure as necessary), while for ioctl the command number is chosen
>  by the application and has to match the structure definition provided in
>  the same header.
>   
>  In a lot of cases, the ioctl command number is defined (correctly) using the
>  _IOR/_IOW macros that take the size of the structure into account, but then
>  you also have cases where you get indirect pointers and the size of data
> structure
>  passed by the ioctl command is independent of the size of timespec or time_t.
>   
>  This is not just limited to time_t, we have a lot of data types for which we
> define
>  __kernel_*_t types for this purpose, to deal with ioctls that need a specific
>  layout independent of what libc uses.
>   
>        Arnd
> 

 

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
       [not found]             ` <1383502854.512344.1423688575473.JavaMail.open-xchange@oxbaltgw09.schlund.de>
  2015-02-11 21:09               ` arnd
@ 2015-02-11 21:37               ` Rich Felker
  2015-02-16 17:20                 ` Arnd Bergmann
  1 sibling, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-11 21:37 UTC (permalink / raw)
  To: arnd
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel,
	Szabolcs Nagy, Andrew Pinski, linux-arm-kernel, musl

On Wed, Feb 11, 2015 at 10:02:55PM +0100, arnd@arndb.de wrote:
> Rich Felker <dalias@libc.org> hat am 11. Februar 2015 um 21:12 geschrieben:
> > On Wed, Feb 11, 2015 at 08:50:06PM +0100, arnd@arndb.de wrote:
> > > > > At least for AArch64 ILP32 we are still free to change the user/kernel
> > > > > ABI, so we could add wrappers for the affected syscalls to fix this up.
> > > > yes, afaik on x32 the 64bit kernel expects 64bit layout,
> > > > arm64 can fix this
> > >
> > > We have to fix it on all 32-bit architectures when we move to 64-bit time_t.
> > >
> > > I think ideally you'd want a user space definition like
> > >
> > > typedef long long time_t;
> > > struct timespec {
> > > time_t tv_sec;
> > > long long tv_nsec;
> > > };
> > >
> > > which is the only way to avoid passing uninitialized tv_nsec into the kernel
> > > from arbitrary user space doing ioctl. This is of course against POSIX and
> > > C99. Changing POSIX to allow it is probably easier than the C standard,
> > > but we have a couple of years before we need to make this the default.
> >
> > I don't see why you want it to be long long. There is no harm in
> > passing uninitialized padding to the kernel; the kernel just needs to
> > do the right thing and ignore it (or avoid reading it to begin with).
>  
> This would however mean having three different implementations
> in the kernel rather than just two: Every driver that can pass a timespec
> with this model needs to handle the native 64-bit case (64/64), the legacy
> 32-bit case (32/32) and the y2038-safe case (64/32). Most code can
> already handle the first two, and none today handles the third. If you
> want to make the handling explicitly incompatible with native 64-bit
> mode, you get a lot of untested code in obscure places that are never
> tested properly, while using the normal behavior in the kernel at least
> gives us the same bugs that we already have on native 64-bit systems.

Would it really be that hard to do:

	if (ILP32_on_64_process) tv_nsec = (int)tv_nsec;

or similar? That's all that's needed.

> In some cases, there may also be a measurable performance penalty
> in interpreting a user space data structure manually over copying
> it (including the timespec values) in one chunk.

I don't think the above would be measurable.

> An alternative would be to change the native 64-bit case to ignore the upper
> half of tv_nsec and always just copy the low bits. This should work
> fine almost all of the time, but I fear that there might be corner cases
> where existing 64-bit user space depends on passing large or negative
> tv_nsec values into the kernel.

Most functions using caller-provided timespecs are required to
diagnose invalid forms with EINVAL when tv_nsec>=1000000000 or <0, so
if the kernel examines only the low 32 bits on ABIs where long is
64-bit, userspace would need to be responsible for doing this
checking.

> > The other direction, passing uninitialized data from the kernel to
> > userspace, would be dangerous. But it doesn't happen as long as the
> > userspace padding is positioned (in an endian-dependent manner) where
> > the high bits of the kernel type would lie. It could happen if you
> > used a separate conversion wrapper that ony wrote 32 bits, but if you
> > wanted to take that approach you'd just need the wrapper to also write
> > the padding field manually.
>  
> Going from kernel to user space should not be an issue as long as we
> always just write two 64-bit words, and this will zero-fill the upper half.

Agreed.

> > > In the kernel headers, the current plan is to provide interfaces taking
> > > structures
> > >
> > > typedef long long __kernel_time64_t;
> > > struct __kernel_timespec64_t {
> > > __kernel_time64_t tv_sec;
> > > long long tv_nsec;
> > > };
> > >
> > > at least for ioctls, to avoid the ambiguity with libc headers specifying
> > > something else.
> >
> > This seems hideous from an application standpoint. Application
> > programmers don't want to know, and shouldn't need to know, these
> > silly implementation details that make no sense except as historical
> > baggage. They should just be able to use "struct timespec" everywhere
> > and have it work.
> 
> The kernel does not even know how timespec is defined by libc, and we have
> to at least be able to handle the common cases of timespec being 32/32
> and 64/64 (or 64/32 plus explicit padding). For system calls, we can rely
> on libc calling the syscalls that match the definition (or convert the
> structure as necessary), while for ioctl the command number is chosen
> by the application and has to match the structure definition provided in
> the same header.

Generally I would think the kernel knows the model the process is
using, but if not, all you need is separate ioctl numbers for
userspace to use depending on which definition it's using.

> In a lot of cases, the ioctl command number is defined (correctly) using the
> _IOR/_IOW macros that take the size of the structure into account, but then
> you also have cases where you get indirect pointers and the size of data
> structure
> passed by the ioctl command is independent of the size of timespec or time_t.
>  
> This is not just limited to time_t, we have a lot of data types for which we
> define
> __kernel_*_t types for this purpose, to deal with ioctls that need a specific
> layout independent of what libc uses.

That doesn't make it any less of a mess. :(

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:02       ` Rich Felker
  2015-02-11 19:16         ` H.J. Lu
@ 2015-02-11 21:41         ` Joseph Myers
  1 sibling, 0 replies; 79+ messages in thread
From: Joseph Myers @ 2015-02-11 21:41 UTC (permalink / raw)
  To: Rich Felker
  Cc: H.J. Lu, Catalin Marinas, Andrew Pinski, linux-arm-kernel, LKML,
	Andrew Pinski, musl, GNU C Library

On Wed, 11 Feb 2015, Rich Felker wrote:

> > > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> > 
> > Please leave x32 out of this discussion.  I have resolved this bug
> > as WONTFIX.
> 
> From the glibc side, I thought things went by a consensus process
> these days, not the old WONTFIX regime of he who shall not be named.
> If this is not fixed for x32, then x32 cannot provide a conforming C
> environment and thus it's rather a toy target. But I think we should
> discuss this on libc-alpha. In the mean time please leave it REOPENED.

Indeed.  x86 is handled primarily by community review, and even when we 
have maintainers for architectures or other subsystems, being maintainer 
serves as a shortcut to presume consensus in the absence of controversy 
(in the expectation that the community won't object), not to override 
community discussion if something is more controversial.  I've reopened 
the bug.

I believe I made clear in the discussion of 64-bit time interfaces for 
32-bit systems that the x32 ABI mistake was not one to be repeated - that 
since there is obviously no need for nanoseconds values that cannot fit in 
32 bits, nanoseconds (and microseconds) values should remain as long in 
accordance with POSIX.  It's absolutely fine for the userspace structures 
to have an explicit __glibc_reserved padding field in an endian-dependent 
place to keep the low part of the nanoseconds value in the same place as 
it would be for a 64-bit type, but if the kernel doesn't ignore that 
padding for the 64-bit time interfaces then all places that pass these 
structures from glibc to the kernel need to copy them and zero the padding 
in the copy.

Whether the high 32 bits can be treated as padding for interfaces where 
long is 64-bit depends on whether the interfaces in question are required 
to return an error such as EINVAL for out-of-range nanoseconds values.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:05       ` [musl] " Szabolcs Nagy
  2015-02-11 19:22         ` H.J. Lu
  2015-02-11 19:50         ` arnd
@ 2015-02-12  8:12         ` Szabolcs Nagy
  2015-02-12 17:07           ` Catalin Marinas
  2 siblings, 1 reply; 79+ messages in thread
From: Szabolcs Nagy @ 2015-02-12  8:12 UTC (permalink / raw)
  To: musl, Rich Felker, Andrew Pinski, linux-arm-kernel, linux-kernel,
	pinskia, libc-alpha, Marcus Shawcroft

* Szabolcs Nagy <nsz@port70.net> [2015-02-11 20:05:37 +0100]:
> 
> (i think this is also a problem if userspace code uses syscall(2) directly,
> libc cannot possibly know where to signextend and the kernel side does not
> do the fixup right now)
> 

nobody picked up this issue, is this resolved?

ie. if userspace calls syscall(SYS_foo,...) directly with 32bit
longs does it always work out correctly on the kernel side?

the sign extension is a problem for signed long arguments,
i only found these in the kernel:


fs/buffer.c:SYSCALL_DEFINE2(bdflush, int, func, long, data)

fs/open.c:SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)

fs/aio.c:SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
fs/aio.c-               struct iocb __user * __user *, iocbpp)

fs/aio.c:SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
fs/aio.c-               long, min_nr,
fs/aio.c-               long, nr,

kernel/ptrace.c:SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
kernel/ptrace.c-                unsigned long, data)

ipc/syscall.c:SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
ipc/syscall.c-          unsigned long, third, void __user *, ptr, long, fifth)

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 20:15                   ` Andy Lutomirski
@ 2015-02-12 15:50                     ` Catalin Marinas
  2015-02-12 16:13                       ` Rich Felker
  2015-02-12 16:30                       ` H.J. Lu
  0 siblings, 2 replies; 79+ messages in thread
From: Catalin Marinas @ 2015-02-12 15:50 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: H.J. Lu, Rich Felker, GNU C Library, Andrew Pinski, musl, LKML,
	Andrew Pinski, linux-arm-kernel

On Wed, Feb 11, 2015 at 12:15:56PM -0800, Andy Lutomirski wrote:
> On 02/11/2015 11:57 AM, H.J. Lu wrote:
> >>>>trivially satisfied if you consider x32 and x86_64 separate
> >>>>compilation environments, but it's not related to the core issue: that
> >>>>the definition of timespec violates core (not obscure) requirements of
> >>>>both POSIX and C11. At the time you were probably unaware of the C11
> >>>>requirement. Note that it's a LOT harder to effect change in the C
> >>>>standard, so even if the Austin Group would be amenable to changing
> >>>>the requirement for timespec to allow something like nseconds_t,
> >>>>getting WG14 to make this change to work around a Linux/glibc mistake
> >>>>does not sound practical.
> >>>
> >>>That is very unfortunate.  I consider it is too late for x32 to change.
> >>
> >>Why? It's hardly an incompatible ABI change, as long as the
> >>kernel/libc fills the upper bits (for old programs that read them
> >>based on the old headers) when structs are read from the kernel to the
> >>application, and ignores the upper bits (potentially set or left
> >>uninitialized by the application) when strings are passed from
> >>userspace to the kernel. Newly built apps using the struct definition
> >>with 32-bit tv_nsec would need new libc to ensure that the high bits
> >>aren't interpreted, but this could be handled by symbol versioning.
> >>
> >
> >We have considered this option.  But since kernel wouldn't change
> >tv_nsec/tv_usec handling just for x32, it wasn't selected.
> 
> Did anyone *ask* the kernel people (e.g. hpa)?

It seems so:

https://lkml.org/lkml/2011/8/31/244

Couple of more replies from hpa:

https://lkml.org/lkml/2011/8/31/261
https://lkml.org/lkml/2012/2/8/408

It looks like hpa was going to talk the POSIX committee but I don't know
what the conclusion was and didn't follow the thread (at the time I
wasn't interested in ARM ILP32).

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-12 15:50                     ` Catalin Marinas
@ 2015-02-12 16:13                       ` Rich Felker
  2015-02-12 16:30                       ` H.J. Lu
  1 sibling, 0 replies; 79+ messages in thread
From: Rich Felker @ 2015-02-12 16:13 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Andy Lutomirski, H.J. Lu, GNU C Library, Andrew Pinski, musl,
	LKML, Andrew Pinski, linux-arm-kernel

On Thu, Feb 12, 2015 at 03:50:24PM +0000, Catalin Marinas wrote:
> On Wed, Feb 11, 2015 at 12:15:56PM -0800, Andy Lutomirski wrote:
> > On 02/11/2015 11:57 AM, H.J. Lu wrote:
> > >>>>trivially satisfied if you consider x32 and x86_64 separate
> > >>>>compilation environments, but it's not related to the core issue: that
> > >>>>the definition of timespec violates core (not obscure) requirements of
> > >>>>both POSIX and C11. At the time you were probably unaware of the C11
> > >>>>requirement. Note that it's a LOT harder to effect change in the C
> > >>>>standard, so even if the Austin Group would be amenable to changing
> > >>>>the requirement for timespec to allow something like nseconds_t,
> > >>>>getting WG14 to make this change to work around a Linux/glibc mistake
> > >>>>does not sound practical.
> > >>>
> > >>>That is very unfortunate.  I consider it is too late for x32 to change.
> > >>
> > >>Why? It's hardly an incompatible ABI change, as long as the
> > >>kernel/libc fills the upper bits (for old programs that read them
> > >>based on the old headers) when structs are read from the kernel to the
> > >>application, and ignores the upper bits (potentially set or left
> > >>uninitialized by the application) when strings are passed from
> > >>userspace to the kernel. Newly built apps using the struct definition
> > >>with 32-bit tv_nsec would need new libc to ensure that the high bits
> > >>aren't interpreted, but this could be handled by symbol versioning.
> > >>
> > >
> > >We have considered this option.  But since kernel wouldn't change
> > >tv_nsec/tv_usec handling just for x32, it wasn't selected.
> > 
> > Did anyone *ask* the kernel people (e.g. hpa)?
> 
> It seems so:
> 
> https://lkml.org/lkml/2011/8/31/244
> 
> Couple of more replies from hpa:
> 
> https://lkml.org/lkml/2011/8/31/261
> https://lkml.org/lkml/2012/2/8/408
> 
> It looks like hpa was going to talk the POSIX committee but I don't know
> what the conclusion was and didn't follow the thread (at the time I
> wasn't interested in ARM ILP32).

At this point POSIX committee is not sufficient. ISO C specifies
timespec now, and as Jens Gustedt mentioned (I don't think his reply
made it to the whole CC list; see the musl list archive here:
http://www.openwall.com/lists/musl/2015/02/11/21 ), it seems unlikely
that one could pose a convincing argument for this requirement to be
changed in the C language.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-12 15:50                     ` Catalin Marinas
  2015-02-12 16:13                       ` Rich Felker
@ 2015-02-12 16:30                       ` H.J. Lu
  2015-02-12 17:00                         ` Rich Felker
  1 sibling, 1 reply; 79+ messages in thread
From: H.J. Lu @ 2015-02-12 16:30 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Andy Lutomirski, Rich Felker, GNU C Library, Andrew Pinski, musl,
	LKML, Andrew Pinski, linux-arm-kernel

On Thu, Feb 12, 2015 at 7:50 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Wed, Feb 11, 2015 at 12:15:56PM -0800, Andy Lutomirski wrote:
>> On 02/11/2015 11:57 AM, H.J. Lu wrote:
>> >>>>trivially satisfied if you consider x32 and x86_64 separate
>> >>>>compilation environments, but it's not related to the core issue: that
>> >>>>the definition of timespec violates core (not obscure) requirements of
>> >>>>both POSIX and C11. At the time you were probably unaware of the C11
>> >>>>requirement. Note that it's a LOT harder to effect change in the C
>> >>>>standard, so even if the Austin Group would be amenable to changing
>> >>>>the requirement for timespec to allow something like nseconds_t,
>> >>>>getting WG14 to make this change to work around a Linux/glibc mistake
>> >>>>does not sound practical.
>> >>>
>> >>>That is very unfortunate.  I consider it is too late for x32 to change.
>> >>
>> >>Why? It's hardly an incompatible ABI change, as long as the
>> >>kernel/libc fills the upper bits (for old programs that read them
>> >>based on the old headers) when structs are read from the kernel to the
>> >>application, and ignores the upper bits (potentially set or left
>> >>uninitialized by the application) when strings are passed from
>> >>userspace to the kernel. Newly built apps using the struct definition
>> >>with 32-bit tv_nsec would need new libc to ensure that the high bits
>> >>aren't interpreted, but this could be handled by symbol versioning.
>> >>
>> >
>> >We have considered this option.  But since kernel wouldn't change
>> >tv_nsec/tv_usec handling just for x32, it wasn't selected.
>>
>> Did anyone *ask* the kernel people (e.g. hpa)?
>
> It seems so:
>
> https://lkml.org/lkml/2011/8/31/244
>
> Couple of more replies from hpa:
>
> https://lkml.org/lkml/2011/8/31/261
> https://lkml.org/lkml/2012/2/8/408
>
> It looks like hpa was going to talk the POSIX committee but I don't know
> what the conclusion was and didn't follow the thread (at the time I
> wasn't interested in ARM ILP32).

Just for the record,  tv_nsec/tv_usec can be changed to long
as long as kernel always read them as 32 bits and write them
as 64 bits for both LP64 and ILP32 in 64-bit  imespec amd timeval.
In glibc, they can be changed to long without breaking existing binaries.
For x86-32, 64-bit __time_t must be 64-bit aligned.  Otherwise, there will
be no padding in 64-bit timespec nor timeval.

-- 
H.J.

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-12 16:30                       ` H.J. Lu
@ 2015-02-12 17:00                         ` Rich Felker
  0 siblings, 0 replies; 79+ messages in thread
From: Rich Felker @ 2015-02-12 17:00 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Catalin Marinas, Andy Lutomirski, GNU C Library, Andrew Pinski,
	musl, LKML, Andrew Pinski, linux-arm-kernel

On Thu, Feb 12, 2015 at 08:30:10AM -0800, H.J. Lu wrote:
> On Thu, Feb 12, 2015 at 7:50 AM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
> > On Wed, Feb 11, 2015 at 12:15:56PM -0800, Andy Lutomirski wrote:
> >> On 02/11/2015 11:57 AM, H.J. Lu wrote:
> >> >>>>trivially satisfied if you consider x32 and x86_64 separate
> >> >>>>compilation environments, but it's not related to the core issue: that
> >> >>>>the definition of timespec violates core (not obscure) requirements of
> >> >>>>both POSIX and C11. At the time you were probably unaware of the C11
> >> >>>>requirement. Note that it's a LOT harder to effect change in the C
> >> >>>>standard, so even if the Austin Group would be amenable to changing
> >> >>>>the requirement for timespec to allow something like nseconds_t,
> >> >>>>getting WG14 to make this change to work around a Linux/glibc mistake
> >> >>>>does not sound practical.
> >> >>>
> >> >>>That is very unfortunate.  I consider it is too late for x32 to change.
> >> >>
> >> >>Why? It's hardly an incompatible ABI change, as long as the
> >> >>kernel/libc fills the upper bits (for old programs that read them
> >> >>based on the old headers) when structs are read from the kernel to the
> >> >>application, and ignores the upper bits (potentially set or left
> >> >>uninitialized by the application) when strings are passed from
> >> >>userspace to the kernel. Newly built apps using the struct definition
> >> >>with 32-bit tv_nsec would need new libc to ensure that the high bits
> >> >>aren't interpreted, but this could be handled by symbol versioning.
> >> >>
> >> >
> >> >We have considered this option.  But since kernel wouldn't change
> >> >tv_nsec/tv_usec handling just for x32, it wasn't selected.
> >>
> >> Did anyone *ask* the kernel people (e.g. hpa)?
> >
> > It seems so:
> >
> > https://lkml.org/lkml/2011/8/31/244
> >
> > Couple of more replies from hpa:
> >
> > https://lkml.org/lkml/2011/8/31/261
> > https://lkml.org/lkml/2012/2/8/408
> >
> > It looks like hpa was going to talk the POSIX committee but I don't know
> > what the conclusion was and didn't follow the thread (at the time I
> > wasn't interested in ARM ILP32).
> 
> Just for the record,  tv_nsec/tv_usec can be changed to long
> as long as kernel always read them as 32 bits and write them
> as 64 bits for both LP64 and ILP32 in 64-bit  imespec amd timeval.

No; currently userspace relies on the kernel to produce EINVAL when
tv_nsec is not in the range [0,999999999]. If the kernel just reads it
as 32-bit unconditionally, tv_nsec=0x100000000 would fail to produce
EINVAL in LP64 models where tv_nsec is a 64-bit object in userspace.

> In glibc, they can be changed to long without breaking existing binaries.

This is true only if glibc or the kernel ignores the upper bits.
Otherwise, programs could end up passing junk that glibc and/or the
kernel interprets.

> For x86-32, 64-bit __time_t must be 64-bit aligned.  Otherwise, there will
> be no padding in 64-bit timespec nor timeval.

Just adding an explicit padding member when long is 32-bit would be
cleaner. This makes it possible to manually set/clear/inspect the bits
without memset. I don't see any reason to require actual alignment of
the struct on x86-32 unless you're going with a whole new ABI where
64-bit types are aligned. Of course if we're thinking about making
64-bit time_t on 32-bit archs, that's an incompatible ABI already and
would be a great time to make lots of other ABI fixes... But I wonder
if anyone is going to care about actual x86-32 hardware as Y2038
approaches.

Rich

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-12  8:12         ` Szabolcs Nagy
@ 2015-02-12 17:07           ` Catalin Marinas
  0 siblings, 0 replies; 79+ messages in thread
From: Catalin Marinas @ 2015-02-12 17:07 UTC (permalink / raw)
  To: Szabolcs Nagy
  Cc: musl, Rich Felker, Andrew Pinski, linux-arm-kernel, linux-kernel,
	pinskia, libc-alpha, Marcus Shawcroft

On Thu, Feb 12, 2015 at 09:12:34AM +0100, Szabolcs Nagy wrote:
> * Szabolcs Nagy <nsz@port70.net> [2015-02-11 20:05:37 +0100]:
> > (i think this is also a problem if userspace code uses syscall(2) directly,
> > libc cannot possibly know where to signextend and the kernel side does not
> > do the fixup right now)
> 
> nobody picked up this issue, is this resolved?
> 
> ie. if userspace calls syscall(SYS_foo,...) directly with 32bit
> longs does it always work out correctly on the kernel side?

I think the only way to solve this is to have syscall wrappers in the
kernel rather than glibc.

> the sign extension is a problem for signed long arguments,
> i only found these in the kernel:
> 
> fs/buffer.c:SYSCALL_DEFINE2(bdflush, int, func, long, data)

This is part of the deprecated syscalls, it is not used on new user
ABIs.

> fs/open.c:SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)

The kernel uses a long (64-bit) here and the user ABI defines this as an
off_t. With x32, this should be a long long (__kernel_long_t), so not a
problem.

> fs/aio.c:SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
> fs/aio.c-               struct iocb __user * __user *, iocbpp)
> 
> fs/aio.c:SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
> fs/aio.c-               long, min_nr,
> fs/aio.c-               long, nr,

These would need some int->long conversion for nr, min_nr (it may be
done in x32 glibc already but as you said it would not work via
syscall() directly).

> kernel/ptrace.c:SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
> kernel/ptrace.c-                unsigned long, data)

The pid in user space would be pid_t which is 32-bit. The kernel seems
to use it as pid_t afterwards, so looks safe. For addr and data, I guess
it needs wrappers to zero the top part.

> ipc/syscall.c:SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
> ipc/syscall.c-          unsigned long, third, void __user *, ptr, long, fifth)

ipc(2) shows the first, second, third as ints. I guess some kernel
wrapper is needed here as well.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 19:21       ` Rich Felker
@ 2015-02-12 18:17         ` Catalin Marinas
  2015-02-12 18:59           ` arnd
  0 siblings, 1 reply; 79+ messages in thread
From: Catalin Marinas @ 2015-02-12 18:17 UTC (permalink / raw)
  To: Rich Felker
  Cc: libc-alpha, pinskia, musl, linux-kernel, Andrew Pinski,
	Marcus Shawcroft, linux-arm-kernel

On Wed, Feb 11, 2015 at 02:21:18PM -0500, Rich Felker wrote:
> On Wed, Feb 11, 2015 at 05:39:19PM +0000, Catalin Marinas wrote:
> > On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > > I don't know if this has been discussed on libc-alpha yet or not, but
> > > I think we need to open a discussion of how it relates to open glibc
> > > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > > 
> > > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> > 
> > I'm trying to understand the problem first. Quoting from the bug above
> > (which I guess is quoted form C11):
> > 
> > "The range and precision of times representable in clock_t and time_t
> > are implementation-defined. The timespec structure shall contain at
> > least the following members, in any order.
> > 
> >          time_t tv_sec; // whole seconds -- >= 0
> >          long   tv_nsec; // nanoseconds -- [0, 999999999]"
> > 
> > So changing time_t to 64-bit is fine on x32. The timespec struct
> > exported by the kernel always uses a long for tv_nsec. However, glibc uses
> > __syscall_slong_t which ends up as 64-bit for x32 (I guess it mirrors
> > the __kernel_long_t definition).
> > 
> > So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> > x32 kernel support (and the current ILP32 patches) assume a native
> > struct timespec with tv_nsec as 64-bit.
> 
> The exported kernel timespec is not fine if long is defined as a
> 32-bit type, which it is for x32 and the proposed aarch64-ILP32 ABIs.

The exported kernel headers comply with POSIX as they use long for
tv_nsec. The exported headers can be used in user space and with an
ILP32 ABI, long is 32-bit. The problem is the syscall handler which uses
the same structure in kernel where long is 64-bit. But this doesn't
change the fact that the exported header was still correct from a user
perspective.

The solution (for new ports) could be similar to the other such
solutions in the compat layer. A kernel internal structure which is
binary-compatible with the ILP32 user one (as exported by the kernel):

struct ilp32_timespec_kernel_internal_only {
	__kernel_time_t	tv_sec;			/* seconds */
	int		tv_nsec;		/* nanoseconds */
};

and a syscall wrapper which converts between ilp32_timespec and timespec
(take compat_sys_clock_settime as an example).

If the user structure has some padding (and as I've read in this thread
it is allowed), it could be even easier for the kernel. The padding
could be 32-bit before or after tv_nsec, depending on endianness.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-12 18:17         ` Catalin Marinas
@ 2015-02-12 18:59           ` arnd
  2015-02-13 13:33             ` Catalin Marinas
  0 siblings, 1 reply; 79+ messages in thread
From: arnd @ 2015-02-12 18:59 UTC (permalink / raw)
  To: Catalin Marinas, Rich Felker
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel,
	Andrew Pinski, linux-arm-kernel, musl

> Catalin Marinas <catalin.marinas@arm.com> hat am 12. Februar 2015 um 19:17
> geschrieben:
> On Wed, Feb 11, 2015 at 02:21:18PM -0500, Rich Felker wrote:
> > On Wed, Feb 11, 2015 at 05:39:19PM +0000, Catalin Marinas wrote:
> > > On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > > > I don't know if this has been discussed on libc-alpha yet or not, but
> > > > I think we need to open a discussion of how it relates to open glibc
> > > > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > > >
> > > > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> > >
> > > I'm trying to understand the problem first. Quoting from the bug above
> > > (which I guess is quoted form C11):
> > >
> > > "The range and precision of times representable in clock_t and time_t
> > > are implementation-defined. The timespec structure shall contain at
> > > least the following members, in any order.
> > >
> > > time_t tv_sec; // whole seconds -- >= 0
> > > long tv_nsec; // nanoseconds -- [0, 999999999]"
> > >
> > > So changing time_t to 64-bit is fine on x32. The timespec struct
> > > exported by the kernel always uses a long for tv_nsec. However, glibc uses
> > > __syscall_slong_t which ends up as 64-bit for x32 (I guess it mirrors
> > > the __kernel_long_t definition).
> > >
> > > So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> > > x32 kernel support (and the current ILP32 patches) assume a native
> > > struct timespec with tv_nsec as 64-bit.
> >
> > The exported kernel timespec is not fine if long is defined as a
> > 32-bit type, which it is for x32 and the proposed aarch64-ILP32 ABIs.
>
> The exported kernel headers comply with POSIX as they use long for
> tv_nsec. The exported headers can be used in user space and with an
> ILP32 ABI, long is 32-bit. The problem is the syscall handler which uses
> the same structure in kernel where long is 64-bit. But this doesn't
> change the fact that the exported header was still correct from a user
> perspective.

This is not ILP32 specific really, we need to add the same set of syscalls
for all 32-bit systems, in addition to the existing ones that take
a 32-bit time_t.

> The solution (for new ports) could be similar to the other such
> solutions in the compat layer. A kernel internal structure which is
> binary-compatible with the ILP32 user one (as exported by the kernel):
>
> struct ilp32_timespec_kernel_internal_only {
> __kernel_time_t tv_sec; /* seconds */
> int tv_nsec; /* nanoseconds */
> };
>
> and a syscall wrapper which converts between ilp32_timespec and timespec
> (take compat_sys_clock_settime as an example).

We then have to to this on all architectures, and not call it ilp32_timespec,
but call it something else.

I would much prefer to only have two versions of each syscall that takes a
timespec rather than three versions, or having a version that behaves
differently based on the type of program calling it. On native 32-bit
systems, we should have the native syscall taking the 16-byte structure
(using long long __kernel_time64_t) along with the compatibility syscall
with a 8-byte structure for existing applications.

On 64-bit systems, the same syscall source can be used for the normal 16-byte
structure on native 64-bit tasks, ilp32 tasks (x32, aarch64-32), and future
compat32 (i386, aarch32, ...) tasks, while the syscall for the 8-byte structure
deals with legacy compat32 tasks that do not yet use __kernel_time64_t.

> If the user structure has some padding (and as I've read in this thread
> it is allowed), it could be even easier for the kernel. The padding
> could be 32-bit before or after tv_nsec, depending on endianness.

The problem as pointed out before is that if you do this, 32-bit tasks
need to have the padding word zeroed at some stage for data passed into
the kernel, while 64-bit tasks need to return an error if the upper half
of the tv_nsec word is nonzero, at least for interfaces that are documented
to do this.

This can be done either in the kernel or in the libc. In the kernel, it
comes down to a function like

int get_user_timespec64(struct timespec64 *ts, struct __kernel_timespec64 __user
*uts, bool task_32bit)
{
       struct __kernel_timespec64 input;

       if (copy_from_user(&input, uts, sizeof(input))
              return -EFAULT;

       ts->tv_sec = input.tv_sec;
       if (task_32bit)
               ts->tv_nsec = (int)input.tv_nsec;
       else
               ts->tv_nsec = input.tv_nsec;

       return 0;
}

with data types of

struct timespec64 {
       time64_t tv_sec;
       long tv_nsec;
};

struct __kernel_timespec64 {
       __kernel_time64_t tv_nsec;
#if (__BYTE_ORDER == __BIG_ENDIAN) && (__BITS_PER_LONG == 32)
       u32 __pad;     
#endif
       long tv_nsec;
#if (__BYTE_ORDER == __LITTLE_ENDIAN) && (__BITS_PER_LONG == 32)
       u32 __pad;
#endif
};

The data structure definition is a little bit fragile, as it depends on
user space not using the __BIT_ENDIAN symbol in a conflicting way. So
far we have managed to keep that outside of general purpose headers, but
it should at least blow up in an obvious way if it does, rather than
breaking silently.

I still think it's more practical to keep the zeroing in user space though.
In that case, we keep defining __kernel_timespec64 with a 'typedef long
long __kernel_snseconds_t', and it's up to the libc to either use
__kernel_timespec64 as its timespec, or to define a C11-compliant
timespec itself and zero out the bits before passing the data to the kernel.

     Arnd

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-12 18:59           ` arnd
@ 2015-02-13 13:33             ` Catalin Marinas
  2015-02-13 16:30               ` Rich Felker
  0 siblings, 1 reply; 79+ messages in thread
From: Catalin Marinas @ 2015-02-13 13:33 UTC (permalink / raw)
  To: arnd
  Cc: Rich Felker, libc-alpha, pinskia, musl, linux-kernel,
	Andrew Pinski, Marcus Shawcroft, linux-arm-kernel

On Thu, Feb 12, 2015 at 07:59:24PM +0100, Arnd Bergmann wrote:
> > Catalin Marinas <catalin.marinas@arm.com> hat am 12. Februar 2015 um 19:17
> > geschrieben:
> > On Wed, Feb 11, 2015 at 02:21:18PM -0500, Rich Felker wrote:
> > > On Wed, Feb 11, 2015 at 05:39:19PM +0000, Catalin Marinas wrote:
> > > > On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > > > > I don't know if this has been discussed on libc-alpha yet or not, but
> > > > > I think we need to open a discussion of how it relates to open glibc
> > > > > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > > > >
> > > > > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> > > >
> > > > I'm trying to understand the problem first. Quoting from the bug above
> > > > (which I guess is quoted form C11):
> > > >
> > > > "The range and precision of times representable in clock_t and time_t
> > > > are implementation-defined. The timespec structure shall contain at
> > > > least the following members, in any order.
> > > >
> > > > time_t tv_sec; // whole seconds -- >= 0
> > > > long tv_nsec; // nanoseconds -- [0, 999999999]"
> > > >
> > > > So changing time_t to 64-bit is fine on x32. The timespec struct
> > > > exported by the kernel always uses a long for tv_nsec. However, glibc uses
> > > > __syscall_slong_t which ends up as 64-bit for x32 (I guess it mirrors
> > > > the __kernel_long_t definition).
> > > >
> > > > So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> > > > x32 kernel support (and the current ILP32 patches) assume a native
> > > > struct timespec with tv_nsec as 64-bit.
> > >
> > > The exported kernel timespec is not fine if long is defined as a
> > > 32-bit type, which it is for x32 and the proposed aarch64-ILP32 ABIs.
> >
> > The exported kernel headers comply with POSIX as they use long for
> > tv_nsec. The exported headers can be used in user space and with an
> > ILP32 ABI, long is 32-bit. The problem is the syscall handler which uses
> > the same structure in kernel where long is 64-bit. But this doesn't
> > change the fact that the exported header was still correct from a user
> > perspective.
> 
> This is not ILP32 specific really, we need to add the same set of syscalls
> for all 32-bit systems, in addition to the existing ones that take
> a 32-bit time_t.

We can look at this as two scenarios:

1. existing 32-bit user space with a 32-bit time_t
2. new 32-bit user space, potentially with 64-bit time_t

For (1), we need an additional set of syscalls in parallel with the
old ones and most likely a different structure, let's say timespec64.

For (2), we could go for a 64-bit time_t in timespec directly, without
any timespec64 and additional set of syscalls (though internally the
kernel may handle them as timespec64).

For compat support on a 64-bit kernel, we may need to support both
32-bit time_t via compat_timespec and a 64-bit time_t via a new
compat_timespec64. In case of AArch64 ILP32, any timespec syscall should
be routed directly to the corresponding compat_timespec64 handlers as we
define a 64-bit time_t.

For new 32-bit native architectures (no compat layer), we may want to
enforce a 64-bit time_t from the beginning.

Anyway, since AArch64 ILP32 does not have a legacy ABI with 32-bit
time_t, we can start implementing it independently of the additional
syscalls for 32-bit timespec64. Eventually, the same code path will be
used for legacy 32-bit with the new 64-bit time_t syscalls.

> > The solution (for new ports) could be similar to the other such
> > solutions in the compat layer. A kernel internal structure which is
> > binary-compatible with the ILP32 user one (as exported by the kernel):
> >
> > struct ilp32_timespec_kernel_internal_only {
> > __kernel_time_t tv_sec; /* seconds */
> > int tv_nsec; /* nanoseconds */
> > };
> >
> > and a syscall wrapper which converts between ilp32_timespec and timespec
> > (take compat_sys_clock_settime as an example).
> 
> We then have to to this on all architectures, and not call it ilp32_timespec,
> but call it something else.
> 
> I would much prefer to only have two versions of each syscall that takes a
> timespec rather than three versions, or having a version that behaves
> differently based on the type of program calling it. On native 32-bit
> systems, we should have the native syscall taking the 16-byte structure
> (using long long __kernel_time64_t)

Can this also be 12 bytes in general if tv_nsec stays as 32-bit? The
size of such structure would be 16 bytes on ARM but I guess this depends
on long long the alignment requirements on specific architectures.

> along with the compatibility syscall with a 8-byte structure for
> existing applications.
> 
> On 64-bit systems, the same syscall source can be used for the normal 16-byte
> structure on native 64-bit tasks, ilp32 tasks (x32, aarch64-32), and future
> compat32 (i386, aarch32, ...) tasks, while the syscall for the 8-byte structure
> deals with legacy compat32 tasks that do not yet use __kernel_time64_t.

We could do with two syscalls but, as you said, we need some padding and
zeroing when the sizeof(time_t) != sizeof(long).

> > If the user structure has some padding (and as I've read in this thread
> > it is allowed), it could be even easier for the kernel. The padding
> > could be 32-bit before or after tv_nsec, depending on endianness.
> 
> The problem as pointed out before is that if you do this, 32-bit tasks
> need to have the padding word zeroed at some stage for data passed into
> the kernel, while 64-bit tasks need to return an error if the upper half
> of the tv_nsec word is nonzero, at least for interfaces that are documented
> to do this.
> 
> This can be done either in the kernel or in the libc.

I think this should be in the kernel as user is allowed to invoke
syscalls directly outside the libc wrappers.

> In the kernel, it comes down to a function like
> 
> int get_user_timespec64(struct timespec64 *ts, struct __kernel_timespec64 __user
> *uts, bool task_32bit)
> {
>        struct __kernel_timespec64 input;
> 
>        if (copy_from_user(&input, uts, sizeof(input))
>               return -EFAULT;
> 
>        ts->tv_sec = input.tv_sec;
>        if (task_32bit)
>                ts->tv_nsec = (int)input.tv_nsec;
>        else
>                ts->tv_nsec = input.tv_nsec;
> 
>        return 0;
> }

The only drawback is that native 64-bit and new 32-bit have the same
handling path, potentially slowing down the former (it may not be
noticeable).

> with data types of
> 
> struct timespec64 {
>        time64_t tv_sec;
>        long tv_nsec;
> };
> 
> struct __kernel_timespec64 {
>        __kernel_time64_t tv_nsec;
> #if (__BYTE_ORDER == __BIG_ENDIAN) && (__BITS_PER_LONG == 32)
>        u32 __pad;     
> #endif
>        long tv_nsec;
> #if (__BYTE_ORDER == __LITTLE_ENDIAN) && (__BITS_PER_LONG == 32)
>        u32 __pad;
> #endif
> };
> 
> The data structure definition is a little bit fragile, as it depends on
> user space not using the __BIT_ENDIAN symbol in a conflicting way. So
> far we have managed to keep that outside of general purpose headers, but
> it should at least blow up in an obvious way if it does, rather than
> breaking silently.
> 
> I still think it's more practical to keep the zeroing in user space though.
> In that case, we keep defining __kernel_timespec64 with a 'typedef long
> long __kernel_snseconds_t', and it's up to the libc to either use
> __kernel_timespec64 as its timespec, or to define a C11-compliant
> timespec itself and zero out the bits before passing the data to the kernel.

The problem with doing this in user space is syscall(2). If we don't
allow it, then it's fine to do the padding in libc.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-13 13:33             ` Catalin Marinas
@ 2015-02-13 16:30               ` Rich Felker
  2015-02-13 17:33                 ` Catalin Marinas
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-13 16:30 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: arnd, libc-alpha, pinskia, musl, linux-kernel, Andrew Pinski,
	Marcus Shawcroft, linux-arm-kernel

On Fri, Feb 13, 2015 at 01:33:56PM +0000, Catalin Marinas wrote:
> On Thu, Feb 12, 2015 at 07:59:24PM +0100, Arnd Bergmann wrote:
> > > Catalin Marinas <catalin.marinas@arm.com> hat am 12. Februar 2015 um 19:17
> > > geschrieben:
> > > On Wed, Feb 11, 2015 at 02:21:18PM -0500, Rich Felker wrote:
> > > > On Wed, Feb 11, 2015 at 05:39:19PM +0000, Catalin Marinas wrote:
> > > > > On Tue, Feb 10, 2015 at 06:13:02PM +0000, Rich Felker wrote:
> > > > > > I don't know if this has been discussed on libc-alpha yet or not, but
> > > > > > I think we need to open a discussion of how it relates to open glibc
> > > > > > bug #16437, which presently applies only to x32 (ILP32 ABI on x86_64):
> > > > > >
> > > > > > https://sourceware.org/bugzilla/show_bug.cgi?id=16437
> > > > >
> > > > > I'm trying to understand the problem first. Quoting from the bug above
> > > > > (which I guess is quoted form C11):
> > > > >
> > > > > "The range and precision of times representable in clock_t and time_t
> > > > > are implementation-defined. The timespec structure shall contain at
> > > > > least the following members, in any order.
> > > > >
> > > > > time_t tv_sec; // whole seconds -- >= 0
> > > > > long tv_nsec; // nanoseconds -- [0, 999999999]"
> > > > >
> > > > > So changing time_t to 64-bit is fine on x32. The timespec struct
> > > > > exported by the kernel always uses a long for tv_nsec. However, glibc uses
> > > > > __syscall_slong_t which ends up as 64-bit for x32 (I guess it mirrors
> > > > > the __kernel_long_t definition).
> > > > >
> > > > > So w.r.t. C11, the exported kernel timespec looks fine. But I think the
> > > > > x32 kernel support (and the current ILP32 patches) assume a native
> > > > > struct timespec with tv_nsec as 64-bit.
> > > >
> > > > The exported kernel timespec is not fine if long is defined as a
> > > > 32-bit type, which it is for x32 and the proposed aarch64-ILP32 ABIs.
> > >
> > > The exported kernel headers comply with POSIX as they use long for
> > > tv_nsec. The exported headers can be used in user space and with an
> > > ILP32 ABI, long is 32-bit. The problem is the syscall handler which uses
> > > the same structure in kernel where long is 64-bit. But this doesn't
> > > change the fact that the exported header was still correct from a user
> > > perspective.
> > 
> > This is not ILP32 specific really, we need to add the same set of syscalls
> > for all 32-bit systems, in addition to the existing ones that take
> > a 32-bit time_t.
> 
> We can look at this as two scenarios:
> 
> 1. existing 32-bit user space with a 32-bit time_t
> 2. new 32-bit user space, potentially with 64-bit time_t
> 
> For (1), we need an additional set of syscalls in parallel with the
> old ones and most likely a different structure, let's say timespec64.
> 
> For (2), we could go for a 64-bit time_t in timespec directly, without
> any timespec64 and additional set of syscalls (though internally the
> kernel may handle them as timespec64).
> 
> For compat support on a 64-bit kernel, we may need to support both
> 32-bit time_t via compat_timespec and a 64-bit time_t via a new
> compat_timespec64. In case of AArch64 ILP32, any timespec syscall should
> be routed directly to the corresponding compat_timespec64 handlers as we
> define a 64-bit time_t.
> 
> For new 32-bit native architectures (no compat layer), we may want to
> enforce a 64-bit time_t from the beginning.
> 
> Anyway, since AArch64 ILP32 does not have a legacy ABI with 32-bit
> time_t, we can start implementing it independently of the additional
> syscalls for 32-bit timespec64. Eventually, the same code path will be
> used for legacy 32-bit with the new 64-bit time_t syscalls.

This sounds right.

> > > The solution (for new ports) could be similar to the other such
> > > solutions in the compat layer. A kernel internal structure which is
> > > binary-compatible with the ILP32 user one (as exported by the kernel):
> > >
> > > struct ilp32_timespec_kernel_internal_only {
> > > __kernel_time_t tv_sec; /* seconds */
> > > int tv_nsec; /* nanoseconds */
> > > };
> > >
> > > and a syscall wrapper which converts between ilp32_timespec and timespec
> > > (take compat_sys_clock_settime as an example).
> > 
> > We then have to to this on all architectures, and not call it ilp32_timespec,
> > but call it something else.
> > 
> > I would much prefer to only have two versions of each syscall that takes a
> > timespec rather than three versions, or having a version that behaves
> > differently based on the type of program calling it. On native 32-bit
> > systems, we should have the native syscall taking the 16-byte structure
> > (using long long __kernel_time64_t)
> 
> Can this also be 12 bytes in general if tv_nsec stays as 32-bit? The
> size of such structure would be 16 bytes on ARM but I guess this depends
> on long long the alignment requirements on specific architectures.

The only archs with modern relevance I'm aware of where 64-bit types
are not aligned are i386 and, by a regretable but hard-to-fix mistake,
or1k. I don't have much opinion on whether the 64-bit-time_t timespec
should be 12 bytes or 16 bytes on such archs. From my perspective it's
a new ABI anyway so I'd like to be able to fix the 64-bit alignment
issue at the same time, in which case the question would go away, but
I'm sure others (glibc) will prefer a more transitional approach with
symbol versioning or feature test macros or something.

> > along with the compatibility syscall with a 8-byte structure for
> > existing applications.
> > 
> > On 64-bit systems, the same syscall source can be used for the normal 16-byte
> > structure on native 64-bit tasks, ilp32 tasks (x32, aarch64-32), and future
> > compat32 (i386, aarch32, ...) tasks, while the syscall for the 8-byte structure
> > deals with legacy compat32 tasks that do not yet use __kernel_time64_t.
> 
> We could do with two syscalls but, as you said, we need some padding and
> zeroing when the sizeof(time_t) != sizeof(long).
> 
> > > If the user structure has some padding (and as I've read in this thread
> > > it is allowed), it could be even easier for the kernel. The padding
> > > could be 32-bit before or after tv_nsec, depending on endianness.
> > 
> > The problem as pointed out before is that if you do this, 32-bit tasks
> > need to have the padding word zeroed at some stage for data passed into
> > the kernel, while 64-bit tasks need to return an error if the upper half
> > of the tv_nsec word is nonzero, at least for interfaces that are documented
> > to do this.
> > 
> > This can be done either in the kernel or in the libc.
> 
> I think this should be in the kernel as user is allowed to invoke
> syscalls directly outside the libc wrappers.

I agree, but see details below on why.

> > In the kernel, it comes down to a function like
> > 
> > int get_user_timespec64(struct timespec64 *ts, struct __kernel_timespec64 __user
> > *uts, bool task_32bit)
> > {
> >        struct __kernel_timespec64 input;
> > 
> >        if (copy_from_user(&input, uts, sizeof(input))
> >               return -EFAULT;
> > 
> >        ts->tv_sec = input.tv_sec;
> >        if (task_32bit)
> >                ts->tv_nsec = (int)input.tv_nsec;
> >        else
> >                ts->tv_nsec = input.tv_nsec;
> > 
> >        return 0;
> > }
> 
> The only drawback is that native 64-bit and new 32-bit have the same
> handling path, potentially slowing down the former (it may not be
> noticeable).

Offhand, I would not consider a single predictable branch on syscall
entry or return to be noticable relative to general syscall overhead.

> > The data structure definition is a little bit fragile, as it depends on
> > user space not using the __BIT_ENDIAN symbol in a conflicting way. So
> > far we have managed to keep that outside of general purpose headers, but
> > it should at least blow up in an obvious way if it does, rather than
> > breaking silently.
> > 
> > I still think it's more practical to keep the zeroing in user space though.
> > In that case, we keep defining __kernel_timespec64 with a 'typedef long
> > long __kernel_snseconds_t', and it's up to the libc to either use
> > __kernel_timespec64 as its timespec, or to define a C11-compliant
> > timespec itself and zero out the bits before passing the data to the kernel.
> 
> The problem with doing this in user space is syscall(2). If we don't
> allow it, then it's fine to do the padding in libc.

It's already the case that callers have to tiptoe around syscall(2)
usage on a per-arch basis for silly things like the convention for
passing 64-bit arguments on 32-bit archs, different arg orders to work
around 64-bit alignment and issues with too many args, and various
legacy issues. So I think manual use of syscall(2) is a less-critical
issue, though of course from a libc perspective I would very much like
for the kernel to handle it right.

What is important, on the other hand, is how timespec creeps into
other things. It's a member of lots of other important structs used
for communication with the kernel, some of which libc can't be aware
of -- things like ioctls, socket options, etc. where kernel device
drivers and network protocols, etc. may add new ones that libc isn't
aware of. IMO these are the most compelling reason to ask that the
kernel handle accepting timespecs in the proper userspace ABI form.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-13 16:30               ` Rich Felker
@ 2015-02-13 17:33                 ` Catalin Marinas
  2015-02-13 18:37                   ` Rich Felker
  0 siblings, 1 reply; 79+ messages in thread
From: Catalin Marinas @ 2015-02-13 17:33 UTC (permalink / raw)
  To: Rich Felker
  Cc: libc-alpha, arnd, pinskia, musl, linux-kernel, Andrew Pinski,
	Marcus Shawcroft, linux-arm-kernel

On Fri, Feb 13, 2015 at 11:30:13AM -0500, Rich Felker wrote:
> On Fri, Feb 13, 2015 at 01:33:56PM +0000, Catalin Marinas wrote:
> > On Thu, Feb 12, 2015 at 07:59:24PM +0100, Arnd Bergmann wrote:
> > > Catalin Marinas <catalin.marinas@arm.com> hat am 12. Februar 2015 um 19:17
> > > geschrieben:
> > > > The solution (for new ports) could be similar to the other such
> > > > solutions in the compat layer. A kernel internal structure which is
> > > > binary-compatible with the ILP32 user one (as exported by the kernel):
> > > >
> > > > struct ilp32_timespec_kernel_internal_only {
> > > > __kernel_time_t tv_sec; /* seconds */
> > > > int tv_nsec; /* nanoseconds */
> > > > };
> > > >
> > > > and a syscall wrapper which converts between ilp32_timespec and timespec
> > > > (take compat_sys_clock_settime as an example).
> > > 
> > > We then have to to this on all architectures, and not call it ilp32_timespec,
> > > but call it something else.
> > > 
> > > I would much prefer to only have two versions of each syscall that takes a
> > > timespec rather than three versions, or having a version that behaves
> > > differently based on the type of program calling it. On native 32-bit
> > > systems, we should have the native syscall taking the 16-byte structure
> > > (using long long __kernel_time64_t)
> > 
> > Can this also be 12 bytes in general if tv_nsec stays as 32-bit? The
> > size of such structure would be 16 bytes on ARM but I guess this depends
> > on long long the alignment requirements on specific architectures.
> 
> The only archs with modern relevance I'm aware of where 64-bit types
> are not aligned are i386 and, by a regretable but hard-to-fix mistake,
> or1k. I don't have much opinion on whether the 64-bit-time_t timespec
> should be 12 bytes or 16 bytes on such archs. From my perspective it's
> a new ABI anyway so I'd like to be able to fix the 64-bit alignment
> issue at the same time, in which case the question would go away, but
> I'm sure others (glibc) will prefer a more transitional approach with
> symbol versioning or feature test macros or something.

The good thing about 16-byte timespec64 with appropriate (endianness
aware) struct padding is that the kernel can write tv_nsec to user as a
64-bit value (long on a 64-bit kernel). It's only the reading from user
that the 32-bit needs to be sign-extended into the kernel structure.

> > > In the kernel, it comes down to a function like
> > > 
> > > int get_user_timespec64(struct timespec64 *ts, struct __kernel_timespec64 __user
> > > *uts, bool task_32bit)
> > > {
> > >        struct __kernel_timespec64 input;
> > > 
> > >        if (copy_from_user(&input, uts, sizeof(input))
> > >               return -EFAULT;
> > > 
> > >        ts->tv_sec = input.tv_sec;
> > >        if (task_32bit)
> > >                ts->tv_nsec = (int)input.tv_nsec;
> > >        else
> > >                ts->tv_nsec = input.tv_nsec;
> > > 
> > >        return 0;
> > > }
> > 
> > The only drawback is that native 64-bit and new 32-bit have the same
> > handling path, potentially slowing down the former (it may not be
> > noticeable).
> 
> Offhand, I would not consider a single predictable branch on syscall
> entry or return to be noticable relative to general syscall overhead.

It's not just a check+branch but accessing some TIF flag which requires
reading the current_thread_info()->flags and testing it. It is probably
lost in the noise, unless you do such calls in loop where you may notice
a slight variation (it depends on the branch predictor as well; on some
architecture we may be able to make use of unlikely(task_32bit)).

> > > The data structure definition is a little bit fragile, as it depends on
> > > user space not using the __BIT_ENDIAN symbol in a conflicting way. So
> > > far we have managed to keep that outside of general purpose headers, but
> > > it should at least blow up in an obvious way if it does, rather than
> > > breaking silently.
> > > 
> > > I still think it's more practical to keep the zeroing in user space though.
> > > In that case, we keep defining __kernel_timespec64 with a 'typedef long
> > > long __kernel_snseconds_t', and it's up to the libc to either use
> > > __kernel_timespec64 as its timespec, or to define a C11-compliant
> > > timespec itself and zero out the bits before passing the data to the kernel.
> > 
> > The problem with doing this in user space is syscall(2). If we don't
> > allow it, then it's fine to do the padding in libc.
> 
> It's already the case that callers have to tiptoe around syscall(2)
> usage on a per-arch basis for silly things like the convention for
> passing 64-bit arguments on 32-bit archs, different arg orders to work
> around 64-bit alignment and issues with too many args, and various
> legacy issues. So I think manual use of syscall(2) is a less-critical
> issue, though of course from a libc perspective I would very much like
> for the kernel to handle it right.

I think there is another problem with sign-extending tv_nsec in libc.
The prototype for functions like clock_settime(2) take a const struct
timespec *. There isn't anything to prevent such structure being in a
read-only section, even though it is unlikely. So libc would have to
duplicate the structure rather than just sign-extending tv_nsec in
place.

BTW, I'll be offline for a week (holiday) and I won't be able to follow
up on this thread.

-- 
Catalin

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-13 17:33                 ` Catalin Marinas
@ 2015-02-13 18:37                   ` Rich Felker
  2015-02-16 14:40                     ` Arnd Bergmann
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-13 18:37 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: libc-alpha, arnd, pinskia, musl, linux-kernel, Andrew Pinski,
	Marcus Shawcroft, linux-arm-kernel

On Fri, Feb 13, 2015 at 05:33:46PM +0000, Catalin Marinas wrote:
> > > > The data structure definition is a little bit fragile, as it depends on
> > > > user space not using the __BIT_ENDIAN symbol in a conflicting way. So
> > > > far we have managed to keep that outside of general purpose headers, but
> > > > it should at least blow up in an obvious way if it does, rather than
> > > > breaking silently.
> > > > 
> > > > I still think it's more practical to keep the zeroing in user space though.
> > > > In that case, we keep defining __kernel_timespec64 with a 'typedef long
> > > > long __kernel_snseconds_t', and it's up to the libc to either use
> > > > __kernel_timespec64 as its timespec, or to define a C11-compliant
> > > > timespec itself and zero out the bits before passing the data to the kernel.
> > > 
> > > The problem with doing this in user space is syscall(2). If we don't
> > > allow it, then it's fine to do the padding in libc.
> > 
> > It's already the case that callers have to tiptoe around syscall(2)
> > usage on a per-arch basis for silly things like the convention for
> > passing 64-bit arguments on 32-bit archs, different arg orders to work
> > around 64-bit alignment and issues with too many args, and various
> > legacy issues. So I think manual use of syscall(2) is a less-critical
> > issue, though of course from a libc perspective I would very much like
> > for the kernel to handle it right.
> 
> I think there is another problem with sign-extending tv_nsec in libc.
> The prototype for functions like clock_settime(2) take a const struct
> timespec *. There isn't anything to prevent such structure being in a
> read-only section, even though it is unlikely. So libc would have to
> duplicate the structure rather than just sign-extending tv_nsec in
> place.

Yes, we already have to do this for x32 in musl. I'd rather not have
to do the same for aarch64-ILP32.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-13 18:37                   ` Rich Felker
@ 2015-02-16 14:40                     ` Arnd Bergmann
  2015-02-16 15:38                       ` Rich Felker
  0 siblings, 1 reply; 79+ messages in thread
From: Arnd Bergmann @ 2015-02-16 14:40 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Rich Felker, Catalin Marinas, libc-alpha, pinskia, musl,
	linux-kernel, Andrew Pinski, Marcus Shawcroft

On Friday 13 February 2015 13:37:07 Rich Felker wrote:
> On Fri, Feb 13, 2015 at 05:33:46PM +0000, Catalin Marinas wrote:
> > > > > The data structure definition is a little bit fragile, as it depends on
> > > > > user space not using the __BIT_ENDIAN symbol in a conflicting way. So
> > > > > far we have managed to keep that outside of general purpose headers, but
> > > > > it should at least blow up in an obvious way if it does, rather than
> > > > > breaking silently.
> > > > > 
> > > > > I still think it's more practical to keep the zeroing in user space though.
> > > > > In that case, we keep defining __kernel_timespec64 with a 'typedef long
> > > > > long __kernel_snseconds_t', and it's up to the libc to either use
> > > > > __kernel_timespec64 as its timespec, or to define a C11-compliant
> > > > > timespec itself and zero out the bits before passing the data to the kernel.
> > > > 
> > > > The problem with doing this in user space is syscall(2). If we don't
> > > > allow it, then it's fine to do the padding in libc.
> > > 
> > > It's already the case that callers have to tiptoe around syscall(2)
> > > usage on a per-arch basis for silly things like the convention for
> > > passing 64-bit arguments on 32-bit archs, different arg orders to work
> > > around 64-bit alignment and issues with too many args, and various
> > > legacy issues.

Right. If one wants to use syscall(), they have to know exactly what the
kernel's calling conventions are, including knowing what the timespec
definition looks like, which could have a different size and padding
compared to the user space one.

> > I think there is another problem with sign-extending tv_nsec in libc.
> > The prototype for functions like clock_settime(2) take a const struct
> > timespec *. There isn't anything to prevent such structure being in a
> > read-only section, even though it is unlikely. So libc would have to
> > duplicate the structure rather than just sign-extending tv_nsec in
> > place.

Do we actually need sign-extend, or does zero-extend have the exact
same effect? For all I can tell, all invalid nanoseconds values
remain invalid, and the accepted values are unchanged regardless
of which type extension gets used.

> Yes, we already have to do this for x32 in musl. I'd rather not have
> to do the same for aarch64-ILP32.

This would of course be solved by using a 64-bit __kernel_snseconds_t
or snseconds_t, and I suspect other libc implementations would just do
that, when they are less strict about posix/c11 compliance compared
to musl.

If you don't mind the (slight) distraction, can you describe what your
plans are for handling 64-bit time_t on the existing 32-bit ABIs?
I'm involved in both the efforts to do that and the ilp32 code on
ARM, so it would be good for me to understand your plans for musl to
get the bigger picture. Specifically, which of these do you plan
to support (if you know already):

- using 64-bit time_t on future arm32/i386/... kernels
- using 64-bit time_t on existing arm32/i386/... kernels with native
  32-bit time_t
- using 32-bit time_t on future architectures that only support 64-bit
  time_t in the kernel
- running existing binaries with 32-bit time_t on a library with 64-bit
  time_t support, using symbol versioning
- compiling new code with 32-bit time_t against a library that supports
  both 32-bit and 64-bit time_t at runtime.
- building a libc for existing architectures but without support for
  running existing 32-bit time_t applications.

	Arnd

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-16 14:40                     ` Arnd Bergmann
@ 2015-02-16 15:38                       ` Rich Felker
  2015-02-16 16:54                         ` Arnd Bergmann
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-16 15:38 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Catalin Marinas, libc-alpha, pinskia, musl,
	linux-kernel, Andrew Pinski, Marcus Shawcroft

On Mon, Feb 16, 2015 at 03:40:54PM +0100, Arnd Bergmann wrote:
> On Friday 13 February 2015 13:37:07 Rich Felker wrote:
> > On Fri, Feb 13, 2015 at 05:33:46PM +0000, Catalin Marinas wrote:
> > > > > > The data structure definition is a little bit fragile, as it depends on
> > > > > > user space not using the __BIT_ENDIAN symbol in a conflicting way. So
> > > > > > far we have managed to keep that outside of general purpose headers, but
> > > > > > it should at least blow up in an obvious way if it does, rather than
> > > > > > breaking silently.
> > > > > > 
> > > > > > I still think it's more practical to keep the zeroing in user space though.
> > > > > > In that case, we keep defining __kernel_timespec64 with a 'typedef long
> > > > > > long __kernel_snseconds_t', and it's up to the libc to either use
> > > > > > __kernel_timespec64 as its timespec, or to define a C11-compliant
> > > > > > timespec itself and zero out the bits before passing the data to the kernel.
> > > > > 
> > > > > The problem with doing this in user space is syscall(2). If we don't
> > > > > allow it, then it's fine to do the padding in libc.
> > > > 
> > > > It's already the case that callers have to tiptoe around syscall(2)
> > > > usage on a per-arch basis for silly things like the convention for
> > > > passing 64-bit arguments on 32-bit archs, different arg orders to work
> > > > around 64-bit alignment and issues with too many args, and various
> > > > legacy issues.
> 
> Right. If one wants to use syscall(), they have to know exactly what the
> kernel's calling conventions are, including knowing what the timespec
> definition looks like, which could have a different size and padding
> compared to the user space one.
> 
> > > I think there is another problem with sign-extending tv_nsec in libc.
> > > The prototype for functions like clock_settime(2) take a const struct
> > > timespec *. There isn't anything to prevent such structure being in a
> > > read-only section, even though it is unlikely. So libc would have to
> > > duplicate the structure rather than just sign-extending tv_nsec in
> > > place.
> 
> Do we actually need sign-extend, or does zero-extend have the exact
> same effect? For all I can tell, all invalid nanoseconds values
> remain invalid, and the accepted values are unchanged regardless
> of which type extension gets used.

I think it matters for futimensat which has some special negative
codes you can store in tv_nsec, but perhaps there's an easy trick to
distinguish them even with zero extending.

> > Yes, we already have to do this for x32 in musl. I'd rather not have
> > to do the same for aarch64-ILP32.
> 
> This would of course be solved by using a 64-bit __kernel_snseconds_t
> or snseconds_t, and I suspect other libc implementations would just do
> that, when they are less strict about posix/c11 compliance compared
> to musl.

I think they would be more strict if this were for a target that
actually sees use and they were getting bug reports from C programmers
annoyed that their code was not working correctly or not even
compiling. AFAIK there are no distros based on x32 now and it's
something of an alternate model on x86_64 distros that some people are
playing around with.

> If you don't mind the (slight) distraction, can you describe what your
> plans are for handling 64-bit time_t on the existing 32-bit ABIs?
> I'm involved in both the efforts to do that and the ilp32 code on
> ARM, so it would be good for me to understand your plans for musl to
> get the bigger picture. Specifically, which of these do you plan
> to support (if you know already):

It largely depends on if there's demand. If we have users who want to
run 32-bit systems with an ABI that will survive Y2038, it will be
supported, but as a new ABI for these targets. This will likely allow
fixing other ABI issues at the same time -- for example, on i386 I
would probably switch to mandating SSE2 for floating point, and
possibly using regparm everywhere. There are a couple of different
ways it could be done though:

1. On a per-arch basis, defining a new ABI variant for the arch.

2. With a new abstraction at the syscall boundary to get rid of all
kernel-arch-specific structures in userspace and redefine all types to
have plenty of room for growth.

In regards to your specific questions about ways it could be done:

> - using 64-bit time_t on future arm32/i386/... kernels
> - using 64-bit time_t on existing arm32/i386/... kernels with native
>   32-bit time_t

If the former is supported, I would think we'd want to support the
latter too. An ABI that only works on very-new kernels is very
restrictive in who can use it. Kernel support hardly matters (until
Y2038 actually arrives); the point of 64-bit time_t is to have an ABI
that's _ready_ for it so existing binaries can keep working.

> - using 32-bit time_t on future architectures that only support 64-bit
>   time_t in the kernel

Definitely will not be supported. Introducing a new ABI with 32-bit
time_t is a huge mistake, and the only reason it's been done for some
of the new targets musl supports is because the kernel does it, and
working around a mismatch between kernel and user time_t is a huge
problem -- all sorts of things, including for example struct stat,
depend on the time_t definition, and if you're going to allow mismatch
with kernel you might as well go ahead and have a full translation
layer for kernel structs like this.

> - running existing binaries with 32-bit time_t on a library with 64-bit
>   time_t support, using symbol versioning

Symbol versions don't solve any problem, and they mask dangerous bugs,
so no. The problem is that a symbol version is only able to represent
a single interface boundary (between a caller and libc), not all the
other interface boundaries between third-party libraries. If code
compiled for 32-bit time_t calls into code that uses 64-bit time_t
with a time_t* argument and the callee writes back a result, it's
corrupted the caller's memory. Symbol versions have no way to diagnose
this.

They're also bound at ld-time, whereas the choice of needed version
depends on compile-time (which definitions were used in the header the
code was compiled against).

> - compiling new code with 32-bit time_t against a library that supports
>   both 32-bit and 64-bit time_t at runtime.

No; see above.

> - building a libc for existing architectures but without support for
>   running existing 32-bit time_t applications.

Yes; this would be the way a new ABI would always work. But since musl
inherently supports multi-arch (each arch variant has its own
PT_INTERP name and library path config) you can easily run both types
of binaries on the same system. They just need completely separate
library ecosystems. This is the only way I know to prevent the
dangerous issues that arise with other [non-]solutions like symbol
versioning or feature test macros (as in -D_FILE_OFFSET_BITS=64) for
the problem.

Rich

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

* Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-16 15:38                       ` Rich Felker
@ 2015-02-16 16:54                         ` Arnd Bergmann
  0 siblings, 0 replies; 79+ messages in thread
From: Arnd Bergmann @ 2015-02-16 16:54 UTC (permalink / raw)
  To: Rich Felker
  Cc: linux-arm-kernel, Catalin Marinas, libc-alpha, pinskia, musl,
	linux-kernel, Andrew Pinski, Marcus Shawcroft

On Monday 16 February 2015 10:38:18 Rich Felker wrote:
> On Mon, Feb 16, 2015 at 03:40:54PM +0100, Arnd Bergmann wrote:
> > On Friday 13 February 2015 13:37:07 Rich Felker wrote:
> > > On Fri, Feb 13, 2015 at 05:33:46PM +0000, Catalin Marinas wrote:
> > > > I think there is another problem with sign-extending tv_nsec in libc.
> > > > The prototype for functions like clock_settime(2) take a const struct
> > > > timespec *. There isn't anything to prevent such structure being in a
> > > > read-only section, even though it is unlikely. So libc would have to
> > > > duplicate the structure rather than just sign-extending tv_nsec in
> > > > place.
> > 
> > Do we actually need sign-extend, or does zero-extend have the exact
> > same effect? For all I can tell, all invalid nanoseconds values
> > remain invalid, and the accepted values are unchanged regardless
> > of which type extension gets used.
> 
> I think it matters for futimensat which has some special negative
> codes you can store in tv_nsec, but perhaps there's an easy trick to
> distinguish them even with zero extending.

Ah, good point.

> > > Yes, we already have to do this for x32 in musl. I'd rather not have
> > > to do the same for aarch64-ILP32.
> > 
> > This would of course be solved by using a 64-bit __kernel_snseconds_t
> > or snseconds_t, and I suspect other libc implementations would just do
> > that, when they are less strict about posix/c11 compliance compared
> > to musl.
> 
> I think they would be more strict if this were for a target that
> actually sees use and they were getting bug reports from C programmers
> annoyed that their code was not working correctly or not even
> compiling. AFAIK there are no distros based on x32 now and it's
> something of an alternate model on x86_64 distros that some people are
> playing around with.

I would expect to see much more build breakage and runtime problems
from going to 64-bit time_t than from anything accessing the tv_nsec
field.

I'd also like to hear opinions from other libc maintainers on this.

> > If you don't mind the (slight) distraction, can you describe what your
> > plans are for handling 64-bit time_t on the existing 32-bit ABIs?
> > I'm involved in both the efforts to do that and the ilp32 code on
> > ARM, so it would be good for me to understand your plans for musl to
> > get the bigger picture. Specifically, which of these do you plan
> > to support (if you know already):
> 
> It largely depends on if there's demand. If we have users who want to
> run 32-bit systems with an ABI that will survive Y2038, it will be
> supported, but as a new ABI for these targets. This will likely allow
> fixing other ABI issues at the same time -- for example, on i386 I
> would probably switch to mandating SSE2 for floating point, and
> possibly using regparm everywhere.

I see. Note that in case of i386, the main use case would be
embedded systems, so while using regparm works, mandating anything
that is not part of the quark soc (mmx, sse, cmov, ...) might
be counterproductive.

Regarding ARM, you can probably do it more modern though and
require armv7-hardfloat, if you don't do that already.

> There are a couple of different ways it could be done though:
>
> 1. On a per-arch basis, defining a new ABI variant for the arch.
> 
> 2. With a new abstraction at the syscall boundary to get rid of all
> kernel-arch-specific structures in userspace and redefine all types to
> have plenty of room for growth.

We currently plan to change the kernel for all 32-bit
architectures to support the new ABI everywhere, in order to
avoid special casing rarely used architectures, which would
in turn be a potential source for bugs.

We will only add system calls with 64-bit time_t that don't have
a replacement already. So e.g. according to the current plan, there
won't be a time(2) or gettimeofday(2) system call with 64-bit
time_t in the kernel, but we expect the C library to implement
these through clock_gettime(2).

> In regards to your specific questions about ways it could be done:
> 
> > - using 64-bit time_t on future arm32/i386/... kernels
> > - using 64-bit time_t on existing arm32/i386/... kernels with native
> >   32-bit time_t
> 
> If the former is supported, I would think we'd want to support the
> latter too. An ABI that only works on very-new kernels is very
> restrictive in who can use it. Kernel support hardly matters (until
> Y2038 actually arrives); the point of 64-bit time_t is to have an ABI
> that's _ready_ for it so existing binaries can keep working.

Ok.

> > - using 32-bit time_t on future architectures that only support 64-bit
> >   time_t in the kernel
> 
> Definitely will not be supported. Introducing a new ABI with 32-bit
> time_t is a huge mistake, and the only reason it's been done for some
> of the new targets musl supports is because the kernel does it, and
> working around a mismatch between kernel and user time_t is a huge
> problem -- all sorts of things, including for example struct stat,
> depend on the time_t definition, and if you're going to allow mismatch
> with kernel you might as well go ahead and have a full translation
> layer for kernel structs like this.

Makes sense, I hope we can do the same for all libc implementations

> > - running existing binaries with 32-bit time_t on a library with 64-bit
> >   time_t support, using symbol versioning
> 
> Symbol versions don't solve any problem, and they mask dangerous bugs,
> so no. The problem is that a symbol version is only able to represent
> a single interface boundary (between a caller and libc), not all the
> other interface boundaries between third-party libraries. If code
> compiled for 32-bit time_t calls into code that uses 64-bit time_t
> with a time_t* argument and the callee writes back a result, it's
> corrupted the caller's memory. Symbol versions have no way to diagnose
> this.
> 
> They're also bound at ld-time, whereas the choice of needed version
> depends on compile-time (which definitions were used in the header the
> code was compiled against).

Ok, good. This differs from the approach taken by glibc though,
as they plan to use symbol versioning for this, like it was used
for off_t interfaces.

Introducing a new ABI like this definitely helps us prototype
the entire environment when doing the kernel port for the new
syscalls, this should be a lot easier to do than glibc with all
combinations of backwards compatibility.

> > - building a libc for existing architectures but without support for
> >   running existing 32-bit time_t applications.
> 
> Yes; this would be the way a new ABI would always work. But since musl
> inherently supports multi-arch (each arch variant has its own
> PT_INTERP name and library path config) you can easily run both types
> of binaries on the same system. They just need completely separate
> library ecosystems. This is the only way I know to prevent the
> dangerous issues that arise with other [non-]solutions like symbol
> versioning or feature test macros (as in -D_FILE_OFFSET_BITS=64) for
> the problem.

Ok, good. This will also help in case of embedded systems that want
to ensure that we use 64-bit time_t system-wide. I plan to add a
configuration option to the kernel to disallow all code that is
not y2038-safe (including ext3, NFSv3 and drivers with broken ioctls),
and it helps to have the same thing in user space. Of course the kernel
will by default have to support both ABIs.

Thanks a lot for your feedback.

	Arnd

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-11 21:37               ` Rich Felker
@ 2015-02-16 17:20                 ` Arnd Bergmann
  2015-02-16 17:51                   ` Rich Felker
  0 siblings, 1 reply; 79+ messages in thread
From: Arnd Bergmann @ 2015-02-16 17:20 UTC (permalink / raw)
  To: Rich Felker
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel,
	Szabolcs Nagy, Andrew Pinski, linux-arm-kernel, musl

On Wednesday 11 February 2015 16:37:58 Rich Felker wrote:
> On Wed, Feb 11, 2015 at 10:02:55PM +0100, arnd@arndb.de wrote:
> > Rich Felker <dalias@libc.org> hat am 11. Februar 2015 um 21:12 geschrieben:
> > > On Wed, Feb 11, 2015 at 08:50:06PM +0100, arnd@arndb.de wrote:
> > > > > > At least for AArch64 ILP32 we are still free to change the user/kernel
> > > > > > ABI, so we could add wrappers for the affected syscalls to fix this up.
> > > > > yes, afaik on x32 the 64bit kernel expects 64bit layout,
> > > > > arm64 can fix this
> > > >
> > > > We have to fix it on all 32-bit architectures when we move to 64-bit time_t.
> > > >
> > > > I think ideally you'd want a user space definition like
> > > >
> > > > typedef long long time_t;
> > > > struct timespec {
> > > > time_t tv_sec;
> > > > long long tv_nsec;
> > > > };
> > > >
> > > > which is the only way to avoid passing uninitialized tv_nsec into the kernel
> > > > from arbitrary user space doing ioctl. This is of course against POSIX and
> > > > C99. Changing POSIX to allow it is probably easier than the C standard,
> > > > but we have a couple of years before we need to make this the default.
> > >
> > > I don't see why you want it to be long long. There is no harm in
> > > passing uninitialized padding to the kernel; the kernel just needs to
> > > do the right thing and ignore it (or avoid reading it to begin with).
> >  
> > This would however mean having three different implementations
> > in the kernel rather than just two: Every driver that can pass a timespec
> > with this model needs to handle the native 64-bit case (64/64), the legacy
> > 32-bit case (32/32) and the y2038-safe case (64/32). Most code can
> > already handle the first two, and none today handles the third. If you
> > want to make the handling explicitly incompatible with native 64-bit
> > mode, you get a lot of untested code in obscure places that are never
> > tested properly, while using the normal behavior in the kernel at least
> > gives us the same bugs that we already have on native 64-bit systems.
> 
> Would it really be that hard to do:
> 
> 	if (ILP32_on_64_process) tv_nsec = (int)tv_nsec;
> 
> or similar? That's all that's needed.
> 
> > In some cases, there may also be a measurable performance penalty
> > in interpreting a user space data structure manually over copying
> > it (including the timespec values) in one chunk.
> 
> I don't think the above would be measurable.

It depends: Copying the structure first and then doing the conversion
in kernel space on the specific members as you do in the example
should indeed have a trivial performance impact. However, it is also
the hardest for driver writers to get right, and it's better not to
trust them with corner cases like this.

To make it more readable, we would probably introduce a helper function
that copies the timespec from user space memory to kernel space and
then does all the checks and conversions as required. However, doing
separate copies can (depending on the architecture) have a noticeable
impact. An example for this would be architectures that require setting
up a page table entry for the user space page in order to access the
data and then destroy it again afterwards, with the correct TLB flushes.

We can do something like this for the old-style compat handlers that
use 32-bit time_t, but I'd prefer not to have it in the fast path for
the native 64-bit time_t on 64-bit architectures.

> > An alternative would be to change the native 64-bit case to ignore the upper
> > half of tv_nsec and always just copy the low bits. This should work
> > fine almost all of the time, but I fear that there might be corner cases
> > where existing 64-bit user space depends on passing large or negative
> > tv_nsec values into the kernel.
> 
> Most functions using caller-provided timespecs are required to
> diagnose invalid forms with EINVAL when tv_nsec>=1000000000 or <0, so
> if the kernel examines only the low 32 bits on ABIs where long is
> 64-bit, userspace would need to be responsible for doing this
> checking.

Right, that would not be good, in particular because we should not
change that for existing architectures.

> > > > In the kernel headers, the current plan is to provide interfaces taking
> > > > structures
> > > >
> > > > typedef long long __kernel_time64_t;
> > > > struct __kernel_timespec64_t {
> > > > __kernel_time64_t tv_sec;
> > > > long long tv_nsec;
> > > > };
> > > >
> > > > at least for ioctls, to avoid the ambiguity with libc headers specifying
> > > > something else.
> > >
> > > This seems hideous from an application standpoint. Application
> > > programmers don't want to know, and shouldn't need to know, these
> > > silly implementation details that make no sense except as historical
> > > baggage. They should just be able to use "struct timespec" everywhere
> > > and have it work.
> > 
> > The kernel does not even know how timespec is defined by libc, and we have
> > to at least be able to handle the common cases of timespec being 32/32
> > and 64/64 (or 64/32 plus explicit padding). For system calls, we can rely
> > on libc calling the syscalls that match the definition (or convert the
> > structure as necessary), while for ioctl the command number is chosen
> > by the application and has to match the structure definition provided in
> > the same header.
> 
> Generally I would think the kernel knows the model the process is
> using, but if not, all you need is separate ioctl numbers for
> userspace to use depending on which definition it's using.

I've checked now, and indeed the kernel knows for ilp32 x86 and arm, since
it uses a different ELF interpreter. I thought it might be running the
ilp32 binaries as ELF64, but it does not.

I would like to avoid separate ioctl command numbers, but we have to
do it for 64-bit time_t on the original 32-bit architectures in the
cases where the size is not already encoded in the command number.

	Arnd

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-16 17:20                 ` Arnd Bergmann
@ 2015-02-16 17:51                   ` Rich Felker
  2015-02-16 19:38                     ` Arnd Bergmann
  0 siblings, 1 reply; 79+ messages in thread
From: Rich Felker @ 2015-02-16 17:51 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel,
	Szabolcs Nagy, Andrew Pinski, linux-arm-kernel, musl

On Mon, Feb 16, 2015 at 06:20:18PM +0100, Arnd Bergmann wrote:
> > Would it really be that hard to do:
> > 
> > 	if (ILP32_on_64_process) tv_nsec = (int)tv_nsec;
> > 
> > or similar? That's all that's needed.
> > 
> > > In some cases, there may also be a measurable performance penalty
> > > in interpreting a user space data structure manually over copying
> > > it (including the timespec values) in one chunk.
> > 
> > I don't think the above would be measurable.
> 
> It depends: Copying the structure first and then doing the conversion
> in kernel space on the specific members as you do in the example
> should indeed have a trivial performance impact. However, it is also
> the hardest for driver writers to get right, and it's better not to
> trust them with corner cases like this.
> 
> To make it more readable, we would probably introduce a helper function
> that copies the timespec from user space memory to kernel space and
> then does all the checks and conversions as required. However, doing
> separate copies can (depending on the architecture) have a noticeable
> impact. An example for this would be architectures that require setting
> up a page table entry for the user space page in order to access the
> data and then destroy it again afterwards, with the correct TLB flushes.
> 
> We can do something like this for the old-style compat handlers that
> use 32-bit time_t, but I'd prefer not to have it in the fast path for
> the native 64-bit time_t on 64-bit architectures.

I know this isn't the place to discuss large architectural kernel
changes, but it would be really nice if the kernel had proper abstract
knowledge, at syscall entry time, what regions of memory from
userspace the syscall is going to need and a way of marshalling them
all together as prep for enterring the code that implements the
syscalls, and if conversion between different ABIs could take place
mostly automatically at this layer. Perhaps this kind of thing is an
idea that could be kept open for the future. I suspect the
combinatorics of different legacy interfaces are going to continue
getting worse, and it would be much nicer to have the support factored
out of the actual syscall implementations.

> > Generally I would think the kernel knows the model the process is
> > using, but if not, all you need is separate ioctl numbers for
> > userspace to use depending on which definition it's using.
> 
> I've checked now, and indeed the kernel knows for ilp32 x86 and arm, since
> it uses a different ELF interpreter. I thought it might be running the
> ilp32 binaries as ELF64, but it does not.

This would result in lots of problems like argv[], auxv[], envp[],
etc. being in the wrong format.

> I would like to avoid separate ioctl command numbers, but we have to
> do it for 64-bit time_t on the original 32-bit architectures in the
> cases where the size is not already encoded in the command number.

Indeed, I don't see any way around that.

Rich

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

* Re: [musl] Re: [PATCHv3 00/24] ILP32 support in ARM64
  2015-02-16 17:51                   ` Rich Felker
@ 2015-02-16 19:38                     ` Arnd Bergmann
  0 siblings, 0 replies; 79+ messages in thread
From: Arnd Bergmann @ 2015-02-16 19:38 UTC (permalink / raw)
  To: Rich Felker
  Cc: libc-alpha, pinskia, Marcus Shawcroft, linux-kernel,
	Szabolcs Nagy, Andrew Pinski, linux-arm-kernel, musl

On Monday 16 February 2015 12:51:35 Rich Felker wrote:
> On Mon, Feb 16, 2015 at 06:20:18PM +0100, Arnd Bergmann wrote:
> > > Would it really be that hard to do:
> > > 
> > > 	if (ILP32_on_64_process) tv_nsec = (int)tv_nsec;
> > > 
> > > or similar? That's all that's needed.
> > > 
> > > > In some cases, there may also be a measurable performance penalty
> > > > in interpreting a user space data structure manually over copying
> > > > it (including the timespec values) in one chunk.
> > > 
> > > I don't think the above would be measurable.
> > 
> > It depends: Copying the structure first and then doing the conversion
> > in kernel space on the specific members as you do in the example
> > should indeed have a trivial performance impact. However, it is also
> > the hardest for driver writers to get right, and it's better not to
> > trust them with corner cases like this.
> > 
> > To make it more readable, we would probably introduce a helper function
> > that copies the timespec from user space memory to kernel space and
> > then does all the checks and conversions as required. However, doing
> > separate copies can (depending on the architecture) have a noticeable
> > impact. An example for this would be architectures that require setting
> > up a page table entry for the user space page in order to access the
> > data and then destroy it again afterwards, with the correct TLB flushes.
> > 
> > We can do something like this for the old-style compat handlers that
> > use 32-bit time_t, but I'd prefer not to have it in the fast path for
> > the native 64-bit time_t on 64-bit architectures.
> 
> I know this isn't the place to discuss large architectural kernel
> changes, but it would be really nice if the kernel had proper abstract
> knowledge, at syscall entry time, what regions of memory from
> userspace the syscall is going to need and a way of marshalling them
> all together as prep for enterring the code that implements the
> syscalls, and if conversion between different ABIs could take place
> mostly automatically at this layer. Perhaps this kind of thing is an
> idea that could be kept open for the future. I suspect the
> combinatorics of different legacy interfaces are going to continue
> getting worse, and it would be much nicer to have the support factored
> out of the actual syscall implementations.

Some subsystems (e.g. v4l) do this in their ioctls, and it sounds
like a nice idea, but as I count 17457 instances of copy_{to,from}_user
or {get,put}_user in the kernel, I believe we are basically stuck
with the current way.

> > > Generally I would think the kernel knows the model the process is
> > > using, but if not, all you need is separate ioctl numbers for
> > > userspace to use depending on which definition it's using.
> > 
> > I've checked now, and indeed the kernel knows for ilp32 x86 and arm, since
> > it uses a different ELF interpreter. I thought it might be running the
> > ilp32 binaries as ELF64, but it does not.
> 
> This would result in lots of problems like argv[], auxv[], envp[],
> etc. being in the wrong format.

Right. It depends a bit on the scope though: My impression is that
a lot of people who ask for ilp32 mode on arm64 are just interested
in getting to work one or two applications. If that was the only
goal, they could work around the problem (mostly) in user space, but
as it turns out, the kernel patch is doing the entire job of
implementing the new ABI at syscall level to the point where you
can (mostly) just recompile all of user space.

	Arnd

^ permalink raw reply	[flat|nested] 79+ 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 ` [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64 Andrew Pinski
@ 2014-06-17 15:58   ` Catalin Marinas
  0 siblings, 0 replies; 79+ 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] 79+ 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 [PATCHv2 00/24] ILP32 Support " Andrew Pinski
@ 2014-05-24  7:02 ` Andrew Pinski
  2014-06-17 15:58   ` Catalin Marinas
  0 siblings, 1 reply; 79+ 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] 79+ messages in thread

end of thread, other threads:[~2015-02-16 19:39 UTC | newest]

Thread overview: 79+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-03 21:18 [PATCHv3 00/24] ILP32 support in ARM64 Andrew Pinski
2014-09-03 21:18 ` [PATCH 01/24] ARM64: Force LP64 to compile the kernel Andrew Pinski
2014-09-03 21:18 ` [PATCH 02/24] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig Andrew Pinski
2014-09-03 21:18 ` [PATCH 03/24] ARM64: Change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead Andrew Pinski
2014-09-03 21:18 ` [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-09-03 21:18 ` [PATCH 05/24] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32 Andrew Pinski
2014-09-03 21:19 ` [PATCH 06/24] Allow for some signal structures to be the same between a 32bit ABI and the 64bit ABI Andrew Pinski
2014-09-03 21:19 ` [PATCH 07/24] ARM64:ILP32: Use the same size and layout of the signal structures for ILP32 as for LP64 Andrew Pinski
2014-09-18  3:41   ` zhangjian
2014-09-03 21:19 ` [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-09-04 10:11   ` Arnd Bergmann
2014-10-01 12:42     ` Catalin Marinas
2014-10-01 14:00       ` Arnd Bergmann
2014-10-02 11:19         ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 09/24] ARM64:ILP32: Use the same syscall names as LP64 Andrew Pinski
2014-10-01 12:48   ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 10/24] ARM64: Introduce is_a32_task/is_a32_thread and TIF_AARCH32 and use them in the correct locations Andrew Pinski
2014-09-03 21:19 ` [PATCH 11/24] ARM64: Add is_ilp32_compat_task and is_ilp32_compat_thread Andrew Pinski
2014-09-03 21:19 ` [PATCH 12/24] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 tasks Andrew Pinski
2014-09-03 21:19 ` [PATCH 13/24] ARM64:ILP32: Use the non compat HWCAP for ILP32 Andrew Pinski
2014-10-01 13:12   ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 14/24] ARM64:ILP32 use the standard start_thread for ILP32 so the processor state is not AARCH32 Andrew Pinski
2014-09-03 21:19 ` [PATCH 15/24] compat_binfmt_elf: coredump: Allow some core dump macros be overridden for compat Andrew Pinski
2014-09-03 21:19 ` [PATCH 16/24] ARM64:ILP32: Support core dump for ILP32 Andrew Pinski
2014-10-01 13:22   ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 17/24] ARM64: Add loading of ILP32 binaries Andrew Pinski
2014-09-03 21:19 ` [PATCH 18/24] ARM64: Add vdso for ILP32 and use it for the signal return Andrew Pinski
2014-09-10 14:31   ` Christopher Covington
2014-10-01 13:59   ` Catalin Marinas
2014-10-02 13:38   ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 19/24] ptrace: Allow compat to use the native siginfo Andrew Pinski
2014-10-02 14:13   ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 20/24] ARM64:ILP32: The native siginfo is used instead of the compat siginfo Andrew Pinski
2014-09-03 21:19 ` [PATCH 21/24] ARM64:ILP32: Use a seperate syscall table as a few syscalls need to be using the compat syscalls Andrew Pinski
2014-10-02 15:23   ` Catalin Marinas
2014-10-02 15:46   ` Catalin Marinas
2014-09-03 21:19 ` [PATCH 22/24] ARM64:ILP32: Fix signal return for ILP32 when the user modified the signal stack Andrew Pinski
2014-09-03 21:19 ` [PATCH 23/24] ARM64: Add ARM64_ILP32 to Kconfig Andrew Pinski
2014-09-03 21:19 ` [PATCH 24/24] Add documentation about ARM64 ILP32 ABI Andrew Pinski
2014-09-04 10:01   ` Arnd Bergmann
2014-10-02 15:52 ` [PATCHv3 00/24] ILP32 support in ARM64 Catalin Marinas
2015-02-10 18:13   ` Rich Felker
2015-02-11 17:39     ` Catalin Marinas
2015-02-11 19:05       ` [musl] " Szabolcs Nagy
2015-02-11 19:22         ` H.J. Lu
2015-02-11 19:50         ` arnd
2015-02-11 20:12           ` Rich Felker
     [not found]             ` <1383502854.512344.1423688575473.JavaMail.open-xchange@oxbaltgw09.schlund.de>
2015-02-11 21:09               ` arnd
2015-02-11 21:37               ` Rich Felker
2015-02-16 17:20                 ` Arnd Bergmann
2015-02-16 17:51                   ` Rich Felker
2015-02-16 19:38                     ` Arnd Bergmann
2015-02-12  8:12         ` Szabolcs Nagy
2015-02-12 17:07           ` Catalin Marinas
2015-02-11 19:21       ` Rich Felker
2015-02-12 18:17         ` Catalin Marinas
2015-02-12 18:59           ` arnd
2015-02-13 13:33             ` Catalin Marinas
2015-02-13 16:30               ` Rich Felker
2015-02-13 17:33                 ` Catalin Marinas
2015-02-13 18:37                   ` Rich Felker
2015-02-16 14:40                     ` Arnd Bergmann
2015-02-16 15:38                       ` Rich Felker
2015-02-16 16:54                         ` Arnd Bergmann
2015-02-11 18:33     ` H.J. Lu
2015-02-11 19:02       ` Rich Felker
2015-02-11 19:16         ` H.J. Lu
2015-02-11 19:25           ` Rich Felker
2015-02-11 19:34             ` H.J. Lu
2015-02-11 19:47               ` Rich Felker
2015-02-11 19:57                 ` H.J. Lu
2015-02-11 20:15                   ` Andy Lutomirski
2015-02-12 15:50                     ` Catalin Marinas
2015-02-12 16:13                       ` Rich Felker
2015-02-12 16:30                       ` H.J. Lu
2015-02-12 17:00                         ` Rich Felker
2015-02-11 21:41         ` Joseph Myers
  -- strict thread matches above, loose matches on Subject: below --
2014-05-24  7:01 [PATCHv2 00/24] ILP32 Support " 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-06-17 15:58   ` Catalin Marinas

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