2015-11-17 21:17:24

by Yury Norov

[permalink] [raw]
Subject: [RFC2 PATCH v6 00/19] ILP32 for ARM64

------8<-----
Colleagues, I'm gonna to send it to list.
Please, take a look.
------8<-----

This is still RFC because ~20 tests still fail,
and because it's based on 4.3 kernel version, and
some work is needed to rebase on 4.4. I'd preffer
to do it later.

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

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

Testing is performed using LTP with scenario 'ltplite'.
Tested on QEMU + vanilla defconfig kernel.
Regressions are mostly related to core dump genereation,
readdir(), and futex(). Some tests fail both in ILP32, and LP64.

The full regression table is:
ILP32 LP64

float_bessel FAIL 134 PASSED 0
float_exp_log FAIL 134 PASSED 0
float_iperb FAIL 134 PASSED 0
float_power FAIL 134 PASSED 0
float_trigo FAIL 134 PASSED 0
abort01 FAIL 2 FAIL 2
fcntl14 FAIL 2 FAIL 2
kill11 FAIL 2 FAIL 2
mmap16 FAIL 6 PASSED 0
open12 FAIL 2 PASSED 0
pause01 PASSED 0 FAIL 9
pipe07 FAIL 2 PASSED 0
readdir01 FAIL 1 PASSED 0
rename11 FAIL 2 PASSED 0
rmdir02 FAIL 2 PASSED 0
setregid02 FAIL 1 FAIL 1
settimeofday01 FAIL 1 FAIL 1
umount2_01 FAIL 2 PASSED 0
umount2_02 FAIL 2 PASSED 0
umount2_03 FAIL 2 PASSED 0
utime06 FAIL 2 PASSED 0

Kernel with this patchset, and corresponding
version of glibc is here:
https://github.com/norov/

Andrew Pinski (14):
arm64: ensure the kernel is compiled for LP64
arm64: rename COMPAT to AARCH32_EL0 in Kconfig
arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
instead
arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
arm64:ilp32: share signal structures between ILP32 and LP64 ABIs
arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
arm64:ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
arm64:ilp32: share HWCAP between LP64 and ILP32
arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
arm64:ilp32: support core dump generation for ILP32
ptrace: Allow compat to use the native siginfo
arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
it
arm64:ilp32: use the native siginfo instead of the compat siginfo
arm64:ilp32: add ARM64_ILP32 to Kconfig

Jan Dakinevich (2):
ilp32: common 32-bit wrappers
arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

Philipp Tomsich (2):
arm64:ilp32: add documentation on the ILP32 ABI for ARM64
arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for
ILP32

Yury Norov (1):
aarch64: ilp32: use generic stat64 structure

Documentation/arm64/ilp32.txt | 47 +++++++
arch/arm64/Kconfig | 12 ++
arch/arm64/Makefile | 5 +
arch/arm64/include/asm/compat.h | 70 +++++++++-
arch/arm64/include/asm/elf.h | 105 ++++++++++++--
arch/arm64/include/asm/fpsimd.h | 2 +-
arch/arm64/include/asm/hwcap.h | 12 +-
arch/arm64/include/asm/memory.h | 2 +-
arch/arm64/include/asm/processor.h | 18 ++-
arch/arm64/include/asm/ptrace.h | 2 +-
arch/arm64/include/asm/signal32.h | 19 +++
arch/arm64/include/asm/stat.h | 2 +
arch/arm64/include/asm/thread_info.h | 3 +-
arch/arm64/include/asm/unistd.h | 11 +-
arch/arm64/include/uapi/asm/bitsperlong.h | 9 +-
arch/arm64/include/uapi/asm/siginfo.h | 21 +++
arch/arm64/include/uapi/asm/signal.h | 31 +++++
arch/arm64/kernel/Makefile | 4 +-
arch/arm64/kernel/asm-offsets.c | 2 +-
arch/arm64/kernel/entry.S | 18 ++-
arch/arm64/kernel/entry32-common.S | 37 +++++
arch/arm64/kernel/entry32.S | 29 ----
arch/arm64/kernel/head.S | 2 +-
arch/arm64/kernel/hw_breakpoint.c | 7 +-
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/process.c | 4 +-
arch/arm64/kernel/ptrace.c | 47 ++++---
arch/arm64/kernel/signal.c | 21 ++-
arch/arm64/kernel/sys_ilp32.c | 223 ++++++++++++++++++++++++++++++
arch/arm64/kernel/traps.c | 4 +-
arch/arm64/kernel/vdso.c | 12 +-
include/linux/compat.h | 4 +
include/uapi/asm-generic/siginfo.h | 17 ++-
include/uapi/asm-generic/signal.h | 27 +++-
kernel/ptrace.c | 24 +++-
35 files changed, 745 insertions(+), 110 deletions(-)
create mode 100644 Documentation/arm64/ilp32.txt
create mode 100644 arch/arm64/kernel/entry32-common.S
create mode 100644 arch/arm64/kernel/sys_ilp32.c

--
2.1.4


2015-11-17 21:17:42

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 01/19] arm64:ilp32: add documentation on the ILP32 ABI for ARM64

From: Philipp Tomsich <[email protected]>

Based on Andrew Pinski's original patch-series and adapted with changes
to reduce the duplication of code-paths and resolve issue found during
LTP testing.

Reviewed-by: David Daney <[email protected]>


Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
Documentation/arm64/ilp32.txt | 47 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 Documentation/arm64/ilp32.txt

diff --git a/Documentation/arm64/ilp32.txt b/Documentation/arm64/ilp32.txt
new file mode 100644
index 0000000..93c09f2
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,47 @@
+ILP32 AARCH64 SYSCALL ABI
+=========================
+Written by Andrew Pinski <[email protected]>
+Updated by Philipp Tomsich <[email protected]>
+Updated by Yury Norov <[email protected]>
+
+
+This document describes the ILP32 syscall ABI and where it differs
+from the generic linux syscall interface.
+
+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, including:
+ * 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 Conversion is handled in the userland (glibc), as the
+ userland data structures are defined in glibc anyway.
+
+A number of structures differ between ILP32 and LP64, including:
+ * 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
+ * fd_set This is done to avoid endian issues between ILP32 and
+ LP64. Syscalls consuming fd_set use timespec.
+ * struct msgbuf The specification of 'struct msgbuf' defines the 'mtype'
+ field as a 'long' (i.e. 32bit for ILP32, but 64bit for
+ LP64). Functions that operate on 'struct msgbuf' need
+ to be passed through the compat-syscalls to resolve
+ this.
+ * stack_t contains pointers (handled in the compatibility layer)
+
+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 LP64 syscalls reused by ILP32 clients, and syscalls having
+ILP32-specific handlers is in arch/arm64/kernel/sys_ilp32.c
+
--
2.1.4

2015-11-17 21:17:54

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 02/19] arm64: ensure the kernel is compiled for LP64

From: Andrew Pinski <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/Makefile | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index d10b5d4..432b69a 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -29,14 +29,19 @@ endif
KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr)
KBUILD_AFLAGS += $(lseinstr)

+KBUILD_CFLAGS += $(call cc-option,-mabi=lp64)
+KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
+
ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
LD += -EB
+LDFLAGS += -maarch64linuxb
else
KBUILD_CPPFLAGS += -mlittle-endian
AS += -EL
LD += -EL
+LDFLAGS += -maarch64linux
endif

CHECKFLAGS += -D__aarch64__
--
2.1.4

2015-11-17 21:18:20

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 03/19] arm64: rename COMPAT to AARCH32_EL0 in Kconfig

From: Andrew Pinski <[email protected]>

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/Kconfig | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 07d1811..4753d435 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -679,6 +679,11 @@ menu "Userspace binary formats"
source "fs/Kconfig.binfmt"

config COMPAT
+ def_bool y
+ depends on AARCH32_EL0
+ select COMPAT_BINFMT_ELF
+
+config AARCH32_EL0
bool "Kernel support for 32-bit EL0"
depends on !ARM64_64K_PAGES || EXPERT
select COMPAT_BINFMT_ELF
--
2.1.4

2015-11-17 21:18:33

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 04/19] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead

From: Andrew Pinski <[email protected]>

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/elf.h | 20 +++++++++++++++++---
arch/arm64/include/asm/fpsimd.h | 2 +-
arch/arm64/include/asm/processor.h | 4 ++--
arch/arm64/include/asm/ptrace.h | 2 +-
arch/arm64/include/asm/signal32.h | 19 +++++++++++++++++++
arch/arm64/include/asm/stat.h | 2 ++
arch/arm64/include/asm/unistd.h | 4 +++-
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/asm-offsets.c | 2 +-
arch/arm64/kernel/entry.S | 6 +++---
arch/arm64/kernel/head.S | 2 +-
arch/arm64/kernel/ptrace.c | 27 ++++++++++++++++++++-------
arch/arm64/kernel/signal.c | 16 ++++++++++++++++
arch/arm64/kernel/traps.c | 2 +-
arch/arm64/kernel/vdso.c | 4 ++--
15 files changed, 90 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..663f25d 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -166,14 +166,16 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,

#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)

+#ifdef CONFIG_AARCH32_EL0
+
/* AArch32 registers. */
-#define COMPAT_ELF_NGREG 18
+#define COMPAT_A32_ELF_NGREG 18
typedef unsigned int compat_elf_greg_t;
-typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
+typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];

/* AArch32 EABI. */
#define EF_ARM_EABI_MASK 0xff000000
-#define compat_elf_check_arch(x) (((x)->e_machine == EM_ARM) && \
+#define compat_a32_elf_check_arch(x) (((x)->e_machine == EM_ARM) && \
((x)->e_flags & EF_ARM_EABI_MASK))

#define compat_start_thread compat_start_thread
@@ -184,6 +186,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/processor.h b/arch/arm64/include/asm/processor.h
index 98f3235..ff4abec 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -79,7 +79,7 @@ struct cpu_context {
struct thread_struct {
struct cpu_context cpu_context; /* cpu context */
unsigned long tp_value; /* TLS register */
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
unsigned long tp2_value;
#endif
struct fpsimd_state fpsimd_state;
@@ -88,7 +88,7 @@ struct thread_struct {
struct debug_info debug; /* debugging */
};

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
#define task_user_tls(t) \
({ \
unsigned long *__tls; \
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 536274e..1059b3f 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -120,7 +120,7 @@ struct pt_regs {

#define arch_has_single_step() (1)

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
#define compat_thumb_mode(regs) \
(((regs)->pstate & COMPAT_PSR_T_BIT))
#else
diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h
index eeaa975..7097718 100644
--- a/arch/arm64/include/asm/signal32.h
+++ b/arch/arm64/include/asm/signal32.h
@@ -20,6 +20,7 @@
#ifdef CONFIG_COMPAT
#include <linux/compat.h>

+#ifdef CONFIG_AARCH32_EL0
#define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500

extern const compat_ulong_t aarch32_sigret_code[6];
@@ -47,6 +48,24 @@ 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_AARCH32_EL0 */
+#else
+static inline void compat_setup_restart_syscall(struct pt_regs *regs)
+{
+}
+
+static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+ struct pt_regs *regs)
+{
+ return -ENOSYS;
+}
+
+static inline int compat_setup_frame(int usid, struct ksignal *ksig,
+ sigset_t *set, struct pt_regs *regs)
+{
+ return -ENOSYS;
+}
+
#endif /* CONFIG_COMPAT */
#endif /* __KERNEL__ */
#endif /* __ASM_SIGNAL32_H */
diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h
index 15e3559..af04276 100644
--- a/arch/arm64/include/asm/stat.h
+++ b/arch/arm64/include/asm/stat.h
@@ -22,6 +22,7 @@

#include <asm/compat.h>

+#ifdef CONFIG_AARCH32_EL0
/*
* struct stat64 is needed for compat tasks only. Its definition is different
* from the generic struct stat64.
@@ -59,3 +60,4 @@ struct stat64 {

#endif
#endif
+#endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 41e58fe..4c2cbbc 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
@@ -26,7 +26,9 @@
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
+#endif

+#ifdef CONFIG_COMPAT
/*
* Compat syscall numbers used by the AArch64 kernel.
*/
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 22dc9bc..1470332 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,7 +20,7 @@ arm64-obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
cpufeature.o alternative.o cacheinfo.o \
smp.o smp_spin_table.o topology.o

-arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
+arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \
sys_compat.o entry32.o \
../../arm/kernel/opcodes.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 8d89cf8..e3bcf77 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -51,7 +51,7 @@ int main(void)
DEFINE(S_X7, offsetof(struct pt_regs, regs[7]));
DEFINE(S_LR, offsetof(struct pt_regs, regs[30]));
DEFINE(S_SP, offsetof(struct pt_regs, sp));
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
DEFINE(S_COMPAT_SP, offsetof(struct pt_regs, compat_sp));
#endif
DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 4306c93..52be5c8 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -212,7 +212,7 @@ ENTRY(vectors)
ventry el0_fiq_invalid // FIQ 64-bit EL0
ventry el0_error_invalid // Error 64-bit EL0

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
ventry el0_sync_compat // Synchronous 32-bit EL0
ventry el0_irq_compat // IRQ 32-bit EL0
ventry el0_fiq_invalid_compat // FIQ 32-bit EL0
@@ -252,7 +252,7 @@ el0_error_invalid:
inv_entry 0, BAD_ERROR
ENDPROC(el0_error_invalid)

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
el0_fiq_invalid_compat:
inv_entry 0, BAD_FIQ, 32
ENDPROC(el0_fiq_invalid_compat)
@@ -414,7 +414,7 @@ el0_sync:
b.ge el0_dbg
b el0_inv

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
.align 6
el0_sync_compat:
kernel_entry 0, 32
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 90d09ed..d11d0b2 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -519,7 +519,7 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems
mov x0, #0x33ff
msr cptr_el2, x0 // Disable copro. traps to EL2

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
msr hstr_el2, xzr // Disable CP15 traps to EL2
#endif

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 1971f49..2a39b5d 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -76,7 +76,7 @@ static void ptrace_hbptriggered(struct perf_event *bp,
.si_addr = (void __user *)(bkpt->trigger),
};

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
int i;

if (!is_compat_task())
@@ -651,7 +651,7 @@ static const struct user_regset_view user_aarch64_view = {
.regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets)
};

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
#include <linux/compat.h>

enum compat_regset {
@@ -853,7 +853,7 @@ static int compat_tls_set(struct task_struct *target,
static const struct user_regset aarch32_regsets[] = {
[REGSET_COMPAT_GPR] = {
.core_note_type = NT_PRSTATUS,
- .n = COMPAT_ELF_NGREG,
+ .n = COMPAT_A32_ELF_NGREG,
.size = sizeof(compat_elf_greg_t),
.align = sizeof(compat_elf_greg_t),
.get = compat_gpr_get,
@@ -877,7 +877,7 @@ static const struct user_regset_view user_aarch32_view = {
static const struct user_regset aarch32_ptrace_regsets[] = {
[REGSET_GPR] = {
.core_note_type = NT_PRSTATUS,
- .n = COMPAT_ELF_NGREG,
+ .n = COMPAT_A32_ELF_NGREG,
.size = sizeof(compat_elf_greg_t),
.align = sizeof(compat_elf_greg_t),
.get = compat_gpr_get,
@@ -1109,7 +1109,7 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
}
#endif /* CONFIG_HAVE_HW_BREAKPOINT */

-long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
unsigned long addr = caddr;
@@ -1186,11 +1186,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,

return ret;
}
-#endif /* CONFIG_COMPAT */
+#else /* !CONFIG_AARCH32_EL0 */
+#define compat_a32_arch_ptrace(child, request, caddr, cdata) (-1)
+#endif /* !CONFIG_AARCH32_EL0 */
+
+#ifdef CONFIG_COMPAT
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+ compat_ulong_t caddr, compat_ulong_t cdata)
+{
+ if (is_compat_task())
+ return compat_a32_arch_ptrace(child, request, caddr, cdata);
+ return compat_ptrace_request(child, request, caddr, cdata);
+}
+#endif
+

const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
/*
* Core dumping of 32-bit tasks or compat ptrace requests must use the
* user_aarch32_view compatible with arm32. Native ptrace requests on
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index e18c48c..1e3593c 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -414,3 +414,19 @@ 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 f93aae5..9ce9894 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -363,7 +363,7 @@ long compat_arm_syscall(struct pt_regs *regs);

asmlinkage long do_ni_syscall(struct pt_regs *regs)
{
-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
long ret;
if (is_compat_task()) {
ret = compat_arm_syscall(regs);
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 97bc68f..26352a6 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -49,7 +49,7 @@ static union {
} vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = &vdso_data_store.data;

-#ifdef CONFIG_COMPAT
+#ifdef CONFIG_AARCH32_EL0
/*
* Create and map the vectors page for AArch32 tasks.
*/
@@ -107,7 +107,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)

return PTR_ERR_OR_ZERO(ret);
}
-#endif /* CONFIG_COMPAT */
+#endif /* CONFIG_AARCH32_EL0 */

static struct vm_special_mapping vdso_spec[2];

--
2.1.4

2015-11-17 21:18:40

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 05/19] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64

From: Andrew Pinski <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
---
arch/arm64/include/uapi/asm/bitsperlong.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
index fce9c29..4265243 100644
--- a/arch/arm64/include/uapi/asm/bitsperlong.h
+++ b/arch/arm64/include/uapi/asm/bitsperlong.h
@@ -16,7 +16,14 @@
#ifndef __ASM_BITSPERLONG_H
#define __ASM_BITSPERLONG_H

-#define __BITS_PER_LONG 64
+#if defined(__LP64__)
+/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
+# define __BITS_PER_LONG 64
+#elif defined(__ILP32__)
+# define __BITS_PER_LONG 32
+#else
+# error "Neither LP64 nor ILP32: unsupported ABI in asm/bitsperlong.h"
+#endif

#include <asm-generic/bitsperlong.h>

--
2.1.4

2015-11-17 21:18:53

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 06/19] arm64:ilp32: share signal structures between ILP32 and LP64 ABIs

From: Andrew Pinski <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/uapi/asm/siginfo.h | 21 +++++++++++++++++++++
arch/arm64/include/uapi/asm/signal.h | 31 +++++++++++++++++++++++++++++++
include/uapi/asm-generic/siginfo.h | 17 +++++++++++++----
include/uapi/asm-generic/signal.h | 27 +++++++++++++++++++++++----
4 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h
index 5a74a08..d9ac7d4 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) 2015 Cavium Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -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 991bf5d..5053af4 100644
--- a/arch/arm64/include/uapi/asm/signal.h
+++ b/arch/arm64/include/uapi/asm/signal.h
@@ -22,6 +22,37 @@
#define MINSIGSTKSZ 5120
#define SIGSTKSZ 16384

+/* 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
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 1e35520..be640a9 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -4,9 +4,17 @@
#include <linux/compiler.h>
#include <linux/types.h>

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

/*
@@ -86,7 +94,7 @@ typedef struct siginfo {

/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
struct {
- void __user *_addr; /* faulting insn/memory ref. */
+ __SIGINFO_VOIDPOINTER(_addr); /* faulting insn/memory ref. */
#ifdef __ARCH_SI_TRAPNO
int _trapno; /* TRAP # which caused the signal */
#endif
@@ -99,13 +107,13 @@ typedef struct siginfo {

/* SIGPOLL */
struct {
- __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ __SIGINFO_BAND(_band); /* POLL_IN, POLL_OUT, POLL_MSG */
int _fd;
} _sigpoll;

/* SIGSYS */
struct {
- void __user *_call_addr; /* calling user insn */
+ __SIGINFO_VOIDPOINTER(_call_addr); /* calling user insn */
int _syscall; /* triggering system call number */
unsigned int _arch; /* AUDIT_ARCH_* of syscall */
} _sigsys;
@@ -290,6 +298,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 3094618..92d8ce3 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
@@ -85,9 +87,13 @@
#define SIGSTKSZ 8192
#endif

+#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 */
@@ -100,11 +106,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 */
};
--
2.1.4

2015-11-17 21:19:38

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 07/19] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)

From: Andrew Pinski <[email protected]>

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.

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/compat.h | 31 ++++++++++++++++++++++++++++---
arch/arm64/include/asm/elf.h | 2 +-
arch/arm64/include/asm/memory.h | 2 +-
arch/arm64/include/asm/processor.h | 4 ++--
arch/arm64/include/asm/thread_info.h | 2 +-
arch/arm64/kernel/hw_breakpoint.c | 7 ++++---
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/process.c | 4 ++--
arch/arm64/kernel/ptrace.c | 10 +++++-----
arch/arm64/kernel/signal.c | 5 +++--
arch/arm64/kernel/traps.c | 2 +-
11 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 7fbed69..9700e5e 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -299,19 +299,44 @@ struct compat_shmid64_ds {
compat_ulong_t __unused5;
};

-static inline int is_compat_task(void)
+#ifdef CONFIG_AARCH32_EL0
+
+static inline int is_a32_compat_task(void)
{
return test_thread_flag(TIF_32BIT);
}

-static inline int is_compat_thread(struct thread_info *thread)
+static inline int is_a32_compat_thread(struct thread_info *thread)
{
return test_ti_thread_flag(thread, TIF_32BIT);
}

+#else
+
+static inline int is_a32_compat_task(void)
+{
+ return 0;
+}
+
+static inline int is_a32_compat_thread(struct thread_info *thread)
+{
+ return 0;
+}
+#endif
+
+static inline int is_compat_task(void)
+{
+ return is_a32_compat_task();
+}
+
#else /* !CONFIG_COMPAT */

-static inline int is_compat_thread(struct thread_info *thread)
+static inline int is_a32_compat_thread(struct thread_info *thread)
+{
+ return 0;
+}
+
+static inline int is_a32_compat_task(void)
{
return 0;
}
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 663f25d..01e032c 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -149,7 +149,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,

/* 1GB of VA */
#ifdef CONFIG_COMPAT
-#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
+#define STACK_RND_MASK (is_compat_task() ? \
0x7ff >> (PAGE_SHIFT - 12) : \
0x3ffff >> (PAGE_SHIFT - 12))
#else
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 6b4c3ad..337f8e1 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -58,7 +58,7 @@

#ifdef CONFIG_COMPAT
#define TASK_SIZE_32 UL(0x100000000)
-#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
+#define TASK_SIZE (is_compat_task() ? \
TASK_SIZE_32 : TASK_SIZE_64)
#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT) ? \
TASK_SIZE_32 : TASK_SIZE_64)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index ff4abec..a415dd0 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -39,7 +39,7 @@
#define STACK_TOP_MAX TASK_SIZE_64
#ifdef CONFIG_COMPAT
#define AARCH32_VECTORS_BASE 0xffff0000
-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
+#define STACK_TOP (is_compat_task() ? \
AARCH32_VECTORS_BASE : STACK_TOP_MAX)
#else
#define STACK_TOP STACK_TOP_MAX
@@ -92,7 +92,7 @@ struct thread_struct {
#define task_user_tls(t) \
({ \
unsigned long *__tls; \
- if (is_compat_thread(task_thread_info(t))) \
+ if (is_a32_compat_thread(task_thread_info(t))) \
__tls = &(t)->thread.tp2_value; \
else \
__tls = &(t)->thread.tp_value; \
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index dcd06d1..7d03565 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -110,7 +110,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_FREEZE 19
#define TIF_RESTORE_SIGMASK 20
#define TIF_SINGLESTEP 21
-#define TIF_32BIT 22 /* 32bit process */
+#define TIF_32BIT 22 /* AARCH32 process */
#define TIF_SWITCH_MM 23 /* deferred switch_mm */

#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index bba85c8..854fc82 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>
@@ -420,7 +421,7 @@ static int arch_build_bp_info(struct perf_event *bp)
* Watchpoints can be of length 1, 2, 4 or 8 bytes.
*/
if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
- if (is_compat_task()) {
+ if (is_a32_compat_task()) {
if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
info->ctrl.len != ARM_BREAKPOINT_LEN_4)
return -EINVAL;
@@ -477,7 +478,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
* AArch32 tasks expect some simple alignment fixups, so emulate
* that here.
*/
- if (is_compat_task()) {
+ if (is_a32_compat_task()) {
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
alignment_mask = 0x7;
else
@@ -664,7 +665,7 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,

info = counter_arch_bp(wp);
/* AArch32 watchpoints are either 4 or 8 bytes aligned. */
- if (is_compat_task()) {
+ if (is_a32_compat_task()) {
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
alignment_mask = 0x7;
else
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c
index 3f62b35..a79058f 100644
--- a/arch/arm64/kernel/perf_regs.c
+++ b/arch/arm64/kernel/perf_regs.c
@@ -45,7 +45,7 @@ int perf_reg_validate(u64 mask)

u64 perf_reg_abi(struct task_struct *task)
{
- if (is_compat_thread(task_thread_info(task)))
+ if (is_a32_compat_thread(task_thread_info(task)))
return PERF_SAMPLE_REGS_ABI_32;
else
return PERF_SAMPLE_REGS_ABI_64;
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 223b093..a6b0251 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -259,7 +259,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
asm("mrs %0, tpidr_el0" : "=r" (*task_user_tls(p)));

if (stack_start) {
- if (is_compat_thread(task_thread_info(p)))
+ if (is_a32_compat_thread(task_thread_info(p)))
childregs->compat_sp = stack_start;
/* 16-byte aligned stack mandatory on AArch64 */
else if (stack_start & 15)
@@ -296,7 +296,7 @@ static void tls_thread_switch(struct task_struct *next)
*task_user_tls(current) = tpidr;

tpidr = *task_user_tls(next);
- tpidrro = is_compat_thread(task_thread_info(next)) ?
+ tpidrro = is_a32_compat_thread(task_thread_info(next)) ?
next->thread.tp_value : 0;

asm(
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 2a39b5d..d2e428c 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) {
@@ -1194,7 +1194,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request,
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
- if (is_compat_task())
+ if (is_a32_compat_task())
return compat_a32_arch_ptrace(child, request, caddr, cdata);
return compat_ptrace_request(child, request, caddr, cdata);
}
@@ -1210,9 +1210,9 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
* 32-bit children use an extended user_aarch32_ptrace_view to allow
* access to the TLS register.
*/
- if (is_compat_task())
+ if (is_a32_compat_task())
return &user_aarch32_view;
- else if (is_compat_thread(task_thread_info(task)))
+ else if (is_a32_compat_thread(task_thread_info(task)))
return &user_aarch32_ptrace_view;
#endif
return &user_aarch64_view;
@@ -1239,7 +1239,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 1e3593c..f12f8a0 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -29,6 +29,7 @@
#include <asm/debug-monitors.h>
#include <asm/elf.h>
#include <asm/cacheflush.h>
+#include <asm/compat.h>
#include <asm/ucontext.h>
#include <asm/unistd.h>
#include <asm/fpsimd.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;
@@ -295,7 +296,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
/*
* Set up the stack frame
*/
- if (is_compat_task()) {
+ if (is_a32_compat_task()) {
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
else
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 9ce9894..bc973d0 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -365,7 +365,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
{
#ifdef CONFIG_AARCH32_EL0
long ret;
- if (is_compat_task()) {
+ if (is_a32_compat_task()) {
ret = compat_arm_syscall(regs);
if (ret != -ENOSYS)
return ret;
--
2.1.4

2015-11-17 21:19:49

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 08/19] arm64:ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64

From: Andrew Pinski <[email protected]>

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/compat.h | 38 +++++++++++++++++++++++++++++++++++-
arch/arm64/include/asm/thread_info.h | 1 +
2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 9700e5e..95d2d72 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -324,9 +324,35 @@ static inline int is_a32_compat_thread(struct thread_info *thread)
}
#endif

+#ifdef CONFIG_ARM64_ILP32
+
+static inline int is_ilp32_compat_task(void)
+{
+ return test_thread_flag(TIF_32BIT_AARCH64);
+}
+
+static inline int is_ilp32_compat_thread(struct thread_info *thread)
+{
+ return test_ti_thread_flag(thread, TIF_32BIT_AARCH64);
+}
+
+#else
+
+static inline int is_ilp32_compat_task(void)
+{
+ return 0;
+}
+
+static inline int is_ilp32_compat_thread(struct thread_info *thread)
+{
+ return 0;
+}
+
+#endif
+
static inline int is_compat_task(void)
{
- return is_a32_compat_task();
+ return is_a32_compat_task() || is_ilp32_compat_task();
}

#else /* !CONFIG_COMPAT */
@@ -341,6 +367,16 @@ static inline int is_a32_compat_task(void)
return 0;
}

+static inline int is_ilp32_compat_thread(struct thread_info *thread)
+{
+ return 0;
+}
+
+static inline int is_ilp32_compat_task(void)
+{
+ return 0;
+}
+
#endif /* CONFIG_COMPAT */
#endif /* __KERNEL__ */
#endif /* __ASM_COMPAT_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 7d03565..e72de74 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -112,6 +112,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SINGLESTEP 21
#define TIF_32BIT 22 /* AARCH32 process */
#define TIF_SWITCH_MM 23 /* deferred switch_mm */
+#define TIF_32BIT_AARCH64 24 /* 32 bit process on AArch64(ILP32) */

#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
--
2.1.4

2015-11-17 21:20:00

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 09/19] arm64:ilp32: share HWCAP between LP64 and ILP32

From: Andrew Pinski <[email protected]>

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/hwcap.h | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index 0ad7351..1e5361e 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -47,9 +47,17 @@
#define ELF_HWCAP (elf_hwcap)

#ifdef CONFIG_COMPAT
-#define COMPAT_ELF_HWCAP (compat_elf_hwcap)
-#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2)
extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
+#define COMPAT_ELF_HWCAP \
+ (is_a32_compat_task() \
+ ? compat_elf_hwcap \
+ : elf_hwcap)
+
+#define COMPAT_ELF_HWCAP2 \
+ (is_a32_compat_task() \
+ ? compat_elf_hwcap2 \
+ : 0)
+
#endif

extern unsigned long elf_hwcap;
--
2.1.4

2015-11-17 21:20:16

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 10/19] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads

From: Andrew Pinski <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/processor.h | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index a415dd0..e244cb4 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -28,6 +28,7 @@
#ifdef __KERNEL__

#include <linux/string.h>
+#include <linux/thread_info.h>

#include <asm/fpsimd.h>
#include <asm/hw_breakpoint.h>
@@ -123,6 +124,15 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc,
static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
unsigned long sp)
{
+#ifdef CONFIG_ARM64_ILP32
+ /* ILP32 thread are started the same way as LP64 threads.
+ Note we cannot use is_ilp32_compat_task here as that
+ would introduce a header depency issue. */
+ if (test_thread_flag(TIF_32BIT_AARCH64)) {
+ start_thread(regs, pc, sp);
+ return;
+ }
+#endif
start_thread_common(regs, pc);
regs->pstate = COMPAT_PSR_MODE_USR;
if (pc & 1)
--
2.1.4

2015-11-17 21:20:30

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 11/19] arm64:ilp32: support core dump generation for ILP32

From: Andrew Pinski <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/elf.h | 87 ++++++++++++++++++++++++++++++++++++++------
arch/arm64/kernel/ptrace.c | 12 +++---
arch/arm64/kernel/vdso.c | 8 ++++
3 files changed, 89 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 01e032c..8f13dac 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -134,7 +134,11 @@ typedef struct user_fpsimd_state elf_fpregset_t;
*/
#define ELF_PLAT_INIT(_r, load_addr) (_r)->regs[0] = 0

-#define SET_PERSONALITY(ex) clear_thread_flag(TIF_32BIT);
+#define SET_PERSONALITY(ex) \
+do { \
+ clear_thread_flag(TIF_32BIT_AARCH64); \
+ clear_thread_flag(TIF_32BIT); \
+} while (0)

#define ARCH_DLINFO \
do { \
@@ -166,12 +170,15 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,

#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)

+extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
+ int uses_interp);
+
#ifdef CONFIG_AARCH32_EL0

/* AArch32 registers. */
#define COMPAT_A32_ELF_NGREG 18
-typedef unsigned int compat_elf_greg_t;
-typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
+typedef unsigned int compat_a32_elf_greg_t;
+typedef compat_a32_elf_greg_t compat_a32_elf_gregset_t[COMPAT_A32_ELF_NGREG];

/* AArch32 EABI. */
#define EF_ARM_EABI_MASK 0xff000000
@@ -179,24 +186,80 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
((x)->e_flags & EF_ARM_EABI_MASK))

#define compat_start_thread compat_start_thread
-#define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT);
-#define COMPAT_ARCH_DLINFO
-extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
- int uses_interp);
-#define compat_arch_setup_additional_pages \
- aarch32_setup_vectors_page
+#define COMPAT_A32_SET_PERSONALITY(ex) \
+do { \
+ clear_thread_flag(TIF_32BIT_AARCH64); \
+ set_thread_flag(TIF_32BIT); \
+} while (0)
+#define COMPAT_A32_ARCH_DLINFO do {} while (0)

#else

typedef elf_greg_t compat_elf_greg_t;
typedef elf_gregset_t compat_elf_gregset_t;
#define compat_a32_elf_check_arch(x) 0
-#define COMPAT_SET_PERSONALITY(ex)
-#define COMPAT_ARCH_DLINFO
+#define COMPAT_A32_SET_PERSONALITY(ex) do {} while (0)
+#define COMPAT_A32_ARCH_DLINFO do {} while (0)
+#endif
+
+/* If ILP32 is turned on, we want to define the compat_elf_greg_t to the non compat
+ one and define PR_REG_SIZE/PRSTATUS_SIZE/SET_PR_FPVALID so we pick up the correct
+ ones for AARCH32. Note also the definition of the macros have to be correct for
+ LP64 as this file is included in the standard binfmt_elf.c. */
+#ifdef CONFIG_ARM64_ILP32
+typedef elf_greg_t compat_elf_greg_t;
+typedef elf_gregset_t compat_elf_gregset_t;
+#define PR_REG_SIZE(S) (is_a32_compat_task() ? 72 : 272)
+#define PRSTATUS_SIZE(S) (is_a32_compat_task() ? 124 : (is_ilp32_compat_task() ? 352 : 392))
+#define SET_PR_FPVALID(S, V) \
+do { \
+ *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE((S)->pr_reg)) = (V); \
+} while (0)
+#else
+typedef compat_a32_elf_greg_t compat_elf_greg_t;
+typedef compat_a32_elf_gregset_t compat_elf_gregset_t;
+#endif

+#ifdef CONFIG_ARM64_ILP32
+#define compat_ilp32_elf_check_arch(x) ((x)->e_machine == EM_AARCH64)
+#define COMPAT_ILP32_SET_PERSONALITY(ex) \
+do { \
+ set_thread_flag(TIF_32BIT_AARCH64); \
+ clear_thread_flag(TIF_32BIT); \
+} while (0)
+#define COMPAT_ILP32_ARCH_DLINFO \
+do { \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+ (elf_addr_t)(long)current->mm->context.vdso); \
+} while (0)
+#else
+#define compat_ilp32_elf_check_arch(x) 0
+#define COMPAT_ILP32_SET_PERSONALITY(ex) do {} while (0)
+#define COMPAT_ILP32_ARCH_DLINFO do {} while (0)
#endif

-#define compat_elf_check_arch(x) compat_a32_elf_check_arch(x)
+#define compat_elf_check_arch(x) (compat_a32_elf_check_arch(x) || compat_ilp32_elf_check_arch(x))
+#define COMPAT_SET_PERSONALITY(ex) \
+do { \
+ if (compat_a32_elf_check_arch(&ex)) \
+ COMPAT_A32_SET_PERSONALITY(ex); \
+ else \
+ COMPAT_ILP32_SET_PERSONALITY(ex); \
+} while (0)
+
+/* ILP32 uses the "LP64-like" vdso pages */
+#define compat_arch_setup_additional_pages \
+ (is_a32_compat_task() \
+ ? &aarch32_setup_vectors_page \
+ : &(arch_setup_additional_pages))
+
+#define COMPAT_ARCH_DLINFO \
+do { \
+ if (is_a32_compat_task()) \
+ COMPAT_A32_ARCH_DLINFO; \
+ else \
+ COMPAT_ILP32_ARCH_DLINFO; \
+} while (0)

#endif /* CONFIG_COMPAT */

diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index d2e428c..22d0d5e 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -854,8 +854,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
},
@@ -946,7 +946,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);
@@ -967,7 +967,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);
@@ -1130,7 +1130,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;

@@ -1138,7 +1138,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;

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 26352a6..b239b9b 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -107,6 +107,14 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)

return PTR_ERR_OR_ZERO(ret);
}
+#else
+int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
+{
+ (void) bprm;
+ (void) uses_interp;
+
+ return -EINVAL;
+}
#endif /* CONFIG_AARCH32_EL0 */

static struct vm_special_mapping vdso_spec[2];
--
2.1.4

2015-11-17 21:20:42

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 12/19] ptrace: Allow compat to use the native siginfo

From: Andrew Pinski <[email protected]>

Set COMPAT_USE_NATIVE_SIGINFO to be true for non AARCH32 tasks.

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.

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
include/linux/compat.h | 4 ++++
kernel/ptrace.c | 24 +++++++++++++++++-------
2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index a76c917..0a25d90 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 787320d..04799aa 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -652,7 +652,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) ||
@@ -1140,16 +1140,26 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,

case PTRACE_GETSIGINFO:
ret = ptrace_getsiginfo(child, &siginfo);
- if (!ret)
- ret = copy_siginfo_to_user32(
- (struct compat_siginfo __user *) datap,
- &siginfo);
+ if (!ret) {
+ if (COMPAT_USE_NATIVE_SIGINFO)
+ ret = copy_siginfo_to_user(
+ (struct siginfo __user *) datap,
+ &siginfo);
+ else
+ ret = copy_siginfo_to_user32(
+ (struct compat_siginfo __user *) datap,
+ &siginfo);
+ }
break;

case PTRACE_SETSIGINFO:
memset(&siginfo, 0, sizeof siginfo);
- if (copy_siginfo_from_user32(
- &siginfo, (struct compat_siginfo __user *) datap))
+ if (COMPAT_USE_NATIVE_SIGINFO)
+ ret = copy_from_user(&siginfo, datap, sizeof(siginfo));
+ else
+ ret = copy_siginfo_from_user32(
+ &siginfo, (struct compat_siginfo __user *) datap);
+ if (ret)
ret = -EFAULT;
else
ret = ptrace_setsiginfo(child, &siginfo);
--
2.1.4

2015-11-17 21:20:54

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 13/19] arm64: ilp32: common 32-bit wrappers

From: Jan Dakinevich <[email protected]>

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Jan Dakinevich <[email protected]>

---
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/entry32-common.S | 37 +++++++++++++++++++++++++++++++++++++
arch/arm64/kernel/entry32.S | 29 -----------------------------
3 files changed, 38 insertions(+), 29 deletions(-)
create mode 100644 arch/arm64/kernel/entry32-common.S

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 1470332..35a59af 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,6 +24,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \
sys_compat.o entry32.o \
../../arm/kernel/opcodes.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
+arm64-obj-$(CONFIG_COMPAT) += entry32-common.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
diff --git a/arch/arm64/kernel/entry32-common.S b/arch/arm64/kernel/entry32-common.S
new file mode 100644
index 0000000..2ad5912
--- /dev/null
+++ b/arch/arm64/kernel/entry32-common.S
@@ -0,0 +1,37 @@
+#include <linux/linkage.h>
+#include <linux/const.h>
+
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/errno.h>
+#include <asm/page.h>
+
+ENTRY(compat_sys_statfs64_wrapper)
+ mov w3, #84
+ cmp w1, #88
+ csel w1, w3, w1, eq
+ b compat_sys_statfs64
+ENDPROC(compat_sys_statfs64_wrapper)
+
+ENTRY(compat_sys_fstatfs64_wrapper)
+ mov w3, #84
+ cmp w1, #88
+ csel w1, w3, w1, eq
+ b compat_sys_fstatfs64
+ENDPROC(compat_sys_fstatfs64_wrapper)
+
+/*
+ * Note: off_4k (w5) is always in units of 4K. If we can't do the
+ * requested offset because it is not page-aligned, we return -EINVAL.
+ */
+ENTRY(compat_sys_mmap2_wrapper)
+#if PAGE_SHIFT > 12
+ tst w5, #~PAGE_MASK >> 12
+ b.ne 1f
+ lsr w5, w5, #PAGE_SHIFT - 12
+#endif
+ b sys_mmap_pgoff
+1: mov x0, #-EINVAL
+ ret
+ENDPROC(compat_sys_mmap2_wrapper)
+
diff --git a/arch/arm64/kernel/entry32.S b/arch/arm64/kernel/entry32.S
index f332d5d..8026129 100644
--- a/arch/arm64/kernel/entry32.S
+++ b/arch/arm64/kernel/entry32.S
@@ -40,35 +40,6 @@ ENTRY(compat_sys_rt_sigreturn_wrapper)
b compat_sys_rt_sigreturn
ENDPROC(compat_sys_rt_sigreturn_wrapper)

-ENTRY(compat_sys_statfs64_wrapper)
- mov w3, #84
- cmp w1, #88
- csel w1, w3, w1, eq
- b compat_sys_statfs64
-ENDPROC(compat_sys_statfs64_wrapper)
-
-ENTRY(compat_sys_fstatfs64_wrapper)
- mov w3, #84
- cmp w1, #88
- csel w1, w3, w1, eq
- b compat_sys_fstatfs64
-ENDPROC(compat_sys_fstatfs64_wrapper)
-
-/*
- * Note: off_4k (w5) is always in units of 4K. If we can't do the
- * requested offset because it is not page-aligned, we return -EINVAL.
- */
-ENTRY(compat_sys_mmap2_wrapper)
-#if PAGE_SHIFT > 12
- tst w5, #~PAGE_MASK >> 12
- b.ne 1f
- lsr w5, w5, #PAGE_SHIFT - 12
-#endif
- b sys_mmap_pgoff
-1: mov x0, #-EINVAL
- ret
-ENDPROC(compat_sys_mmap2_wrapper)
-
/*
* Wrappers for AArch32 syscalls that either take 64-bit parameters
* in registers or that take 32-bit parameters which require sign
--
2.1.4

2015-11-17 21:21:11

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

From: Andrew Pinski <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/unistd.h | 7 ++-
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/entry.S | 12 +++-
arch/arm64/kernel/sys_ilp32.c | 118 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 136 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/kernel/sys_ilp32.c

diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 4c2cbbc..696e638 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -13,13 +13,16 @@
* 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
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
@@ -39,6 +42,8 @@
#define __NR_compat_sigreturn 119
#define __NR_compat_rt_sigreturn 173

+#define __ARCH_WANT_SYS_LLSEEK
+
/*
* The following SVCs are ARM private.
*/
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 35a59af..837d730 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -24,6 +24,7 @@ arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \
sys_compat.o entry32.o \
../../arm/kernel/opcodes.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
+arm64-obj-$(CONFIG_ARM64_ILP32) += sys_ilp32.o
arm64-obj-$(CONFIG_COMPAT) += entry32-common.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 52be5c8..bcd921a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -664,9 +664,13 @@ ENDPROC(ret_from_fork)
*/
.align 6
el0_svc:
- adrp stbl, sys_call_table // load syscall table pointer
uxtw scno, w8 // syscall number in w8
mov sc_nr, #__NR_syscalls
+#ifdef CONFIG_ARM64_ILP32
+ ldr x16, [tsk, #TI_FLAGS]
+ tbnz x16, #TIF_32BIT_AARCH64, el0_ilp32_svc // We are using ILP32
+#endif
+ adrp stbl, sys_call_table // load syscall table pointer
el0_svc_naked: // compat entry point
stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number
enable_dbg_and_irq
@@ -686,6 +690,12 @@ ni_sys:
b ret_fast_syscall
ENDPROC(el0_svc)

+#ifdef CONFIG_ARM64_ILP32
+el0_ilp32_svc:
+ adrp stbl, sys_call_ilp32_table // load syscall table pointer
+ b el0_svc_naked
+#endif
+
/*
* This is the really slow path. We're going to be doing context
* switches, and waiting for our parent to respond.
diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
new file mode 100644
index 0000000..c366d92
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,118 @@
+/*
+ * AArch64- ILP32 specific system calls implementation
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Andrew Pinski <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/msg.h>
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/compat.h>
+
+/*
+ * Wrappers to pass the pt_regs argument.
+ */
+asmlinkage long sys_rt_sigreturn_wrapper(void);
+#define compat_sys_rt_sigreturn sys_rt_sigreturn_wrapper
+
+/* Using non-compat syscalls where necessary */
+#define compat_sys_fadvise64_64 sys_fadvise64_64
+#define compat_sys_fallocate sys_fallocate
+#define compat_sys_ftruncate64 sys_ftruncate
+#define compat_sys_pread64 sys_pread64
+#define compat_sys_pwrite64 sys_pwrite64
+#define compat_sys_readahead sys_readahead
+#define compat_sys_rt_sigaction sys_rt_sigaction
+#define compat_sys_shmat sys_shmat
+#define compat_sys_sync_file_range sys_sync_file_range
+#define compat_sys_truncate64 sys_truncate
+#define compat_sys_sigaltstack sys_sigaltstack
+
+#define compat_sys_io_getevents sys_io_getevents
+#define compat_sys_lookup_dcookie sys_lookup_dcookie
+#define compat_sys_epoll_pwait sys_epoll_pwait
+#define compat_sys_fcntl64 compat_sys_fcntl
+#define compat_sys_preadv compat_sys_preadv64
+#define compat_sys_signalfd4 sys_signalfd4
+
+#define compat_sys_rt_sigsuspend sys_rt_sigsuspend
+#define compat_sys_rt_sigprocmask sys_rt_sigprocmask
+#define compat_sys_rt_sigpending sys_rt_sigpending
+#define compat_sys_rt_sigqueueinfo sys_rt_sigqueueinfo
+#define compat_sys_semtimedop sys_semtimedop
+#define compat_sys_rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
+
+#define compat_sys_timer_create sys_timer_create
+#define compat_sys_timer_gettime sys_timer_gettime
+#define compat_sys_timer_settime sys_timer_settime
+#define compat_sys_rt_sigtimedwait sys_rt_sigtimedwait
+
+#define compat_sys_mq_open sys_mq_open
+#define compat_sys_mq_timedsend sys_mq_timedsend
+#define compat_sys_mq_timedreceive sys_mq_timedreceive
+#define compat_sys_mq_getsetattr sys_mq_getsetattr
+#define compat_sys_mq_open sys_mq_open
+
+#define compat_sys_open_by_handle_at sys_open_by_handle_at
+#define compat_sys_clock_adjtime sys_clock_adjtime
+
+#define compat_sys_openat sys_openat
+#define compat_sys_getdents64 sys_getdents64
+#define compat_sys_waitid sys_waitid
+#define compat_sys_timer_settime sys_timer_settime
+#define compat_sys_sched_rr_get_interval sys_sched_rr_get_interval
+#define compat_sys_execveat sys_execveat
+
+#define compat_sys_mq_notify sys_mq_notify
+#define compat_sys_clock_nanosleep sys_clock_nanosleep
+#define compat_sys_clock_getres sys_clock_getres
+
+#define sys_lseek sys_llseek
+
+asmlinkage long compat_sys_mmap2_wrapper(void);
+#define sys_mmap2 compat_sys_mmap2_wrapper
+
+asmlinkage long compat_sys_fstatfs64_wrapper(void);
+#define compat_sys_fstatfs64 compat_sys_fstatfs64_wrapper
+asmlinkage long compat_sys_statfs64_wrapper(void);
+#define compat_sys_statfs64 compat_sys_statfs64_wrapper
+
+#define compat_sys_pwritev compat_sys_pwritev64
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#undef __SC_COMP
+#undef __SC_3264
+#undef __SC_COMP_3264
+
+#define __SYSCALL_COMPAT
+#define __SYSCALL(nr, sym) [nr] = sym,
+
+/*
+ * The sys_call_ilp32_table array must be 4K aligned to be accessible from
+ * kernel/entry.S.
+ */
+void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = {
+ [0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
--
2.1.4

2015-11-17 21:21:49

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 15/19] arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

From: Jan Dakinevich <[email protected]>

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Jan Dakinevich <[email protected]>
---
arch/arm64/kernel/sys_ilp32.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index c366d92..a2596f4 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -98,6 +98,25 @@ asmlinkage long compat_sys_statfs64_wrapper(void);

#define compat_sys_pwritev compat_sys_pwritev64

+/* IPC_64 */
+asmlinkage long ilp32_sys_msgctl(int first, int second, void __user *uptr)
+{
+ return compat_sys_msgctl(first, second | IPC_64, uptr);
+}
+#define compat_sys_msgctl ilp32_sys_msgctl
+
+asmlinkage long ilp32_sys_shmctl(int first, int second, void __user *uptr)
+{
+ return compat_sys_shmctl(first, second | IPC_64, uptr);
+}
+#define compat_sys_shmctl ilp32_sys_shmctl
+
+asmlinkage long ilp32_sys_semctl(int first, int second, int third, int arg)
+{
+ return compat_sys_semctl(first, second, third | IPC_64, arg);
+}
+#define compat_sys_semctl ilp32_sys_semctl
+
#include <asm/syscall.h>

#undef __SYSCALL
--
2.1.4

2015-11-17 21:22:03

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 16/19] aarch64: ilp32: use generic stat64 structure

Generic 32-bit and AARCH32 stat64 structures has same names.
ILP32 needs generic stat64. So we can either make ILP32 mutual
exclusive with AARCH32, or duplicate generic cp_new_stat64 code
and struct stat64 to sys_ilp32.c. We choose second because it's
more flexible to have independend support for ABIs.

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Yury Norov <[email protected]>
---
arch/arm64/kernel/sys_ilp32.c | 86 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)

diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index a2596f4..c5bc712 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -117,6 +117,92 @@ asmlinkage long ilp32_sys_semctl(int first, int second, int third, int arg)
}
#define compat_sys_semctl ilp32_sys_semctl

+struct ilp32_stat {
+ unsigned long st_dev;
+
+ unsigned long st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned int st_uid;
+ unsigned int st_gid;
+
+ unsigned long st_rdev;
+ unsigned long __st_rdev_pad;
+
+ long st_size;
+
+ unsigned int st_blksize;
+ unsigned int __st_blksize_pad;
+
+ unsigned long st_blocks;
+
+ unsigned int st_atime;
+ unsigned int st_atime_nsec;
+
+ unsigned int st_mtime;
+ unsigned int st_mtime_nsec;
+
+ unsigned int st_ctime;
+ unsigned int st_ctime_nsec;
+
+ unsigned int __unused[2];
+};
+
+static long ilp32_cp_stat(struct kstat *stat,
+ struct ilp32_stat __user *statbuf)
+{
+ struct ilp32_stat tmp = {
+ .st_dev = huge_encode_dev(stat->dev),
+ .st_ino = stat->ino,
+ .st_mode = stat->mode,
+ .st_nlink = stat->nlink,
+ .st_uid = from_kuid_munged(current_user_ns(), stat->uid),
+ .st_gid = from_kgid_munged(current_user_ns(), stat->gid),
+ .st_rdev = huge_encode_dev(stat->rdev),
+ .__st_rdev_pad = 0,
+ .st_size = stat->size,
+ .st_blksize = stat->blksize,
+ .__st_blksize_pad = 0,
+ .st_blocks = stat->blocks,
+ .st_atime = stat->atime.tv_sec,
+ .st_atime_nsec = stat->atime.tv_nsec,
+ .st_mtime = stat->mtime.tv_sec,
+ .st_mtime_nsec = stat->mtime.tv_nsec,
+ .st_ctime = stat->ctime.tv_sec,
+ .st_ctime_nsec = stat->ctime.tv_nsec,
+ .__unused = { 0, 0 }
+ };
+
+ return copy_to_user(statbuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long ilp32_sys_fstat64(unsigned int fd,
+ struct ilp32_stat __user *statbuf)
+{
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
+
+ if (!error)
+ error = ilp32_cp_stat(&stat, statbuf);
+ return error;
+}
+#define sys_fstat64 ilp32_sys_fstat64
+
+asmlinkage long ilp32_sys_fstatat64(unsigned int dfd,
+ const char __user *filename,
+ struct ilp32_stat __user *statbuf, int flag)
+{
+ struct kstat stat;
+ int error = vfs_fstatat(dfd, filename, &stat, flag);
+
+ if (!error)
+ error = ilp32_cp_stat(&stat, statbuf);
+ return error;
+}
+#define sys_fstatat64 ilp32_sys_fstatat64
+
#include <asm/syscall.h>

#undef __SYSCALL
--
2.1.4

2015-11-17 21:22:15

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 17/19] arm64:ilp32: use the native siginfo instead of the compat siginfo

From: Andrew Pinski <[email protected]>

Set COMPAT_USE_NATIVE_SIGINFO to be true for non AARCH32 tasks.

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/compat.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 95d2d72..087f21b 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -214,6 +214,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

--
2.1.4

2015-11-17 21:23:42

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 18/19] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32

From: Philipp Tomsich <[email protected]>

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

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/include/asm/elf.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 8f13dac..3e79569 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -163,9 +163,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#ifdef CONFIG_COMPAT

#ifdef __AARCH64EB__
-#define COMPAT_ELF_PLATFORM ("v8b")
+#define COMPAT_ELF_PLATFORM (is_ilp32_compat_task() ? "aarch64_be:ilp32" : "v8b")
#else
-#define COMPAT_ELF_PLATFORM ("v8l")
+#define COMPAT_ELF_PLATFORM (is_ilp32_compat_task() ? "aarch64:ilp32" : "v8l")
#endif

#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
--
2.1.4

2015-11-17 21:22:32

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 19/19] arm64:ilp32: add ARM64_ILP32 to Kconfig

From: Andrew Pinski <[email protected]>

This patch adds the config option for ILP32.

Reviewed-by: David Daney <[email protected]>

Signed-off-by: Philipp Tomsich <[email protected]>
Signed-off-by: Christoph Muellner <[email protected]>
Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Andrew Pinski <[email protected]>
---
arch/arm64/Kconfig | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4753d435..deec37a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -680,7 +680,7 @@ source "fs/Kconfig.binfmt"

config COMPAT
def_bool y
- depends on AARCH32_EL0
+ depends on AARCH32_EL0 || ARM64_ILP32
select COMPAT_BINFMT_ELF

config AARCH32_EL0
@@ -702,6 +702,13 @@ config AARCH32_EL0

If you want to execute 32-bit userspace applications, say Y.

+config ARM64_ILP32
+ bool "Kernel support for ILP32"
+ help
+ This option enables support for AArch64 ILP32 user space. ILP32
+ is an ABI where long and pointers are 32bits but it uses the AARCH64
+ instruction set.
+
config SYSVIPC_COMPAT
def_bool y
depends on COMPAT && SYSVIPC
--
2.1.4

2015-11-17 22:05:45

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
> From: Andrew Pinski <[email protected]>
>
> Add a separate syscall-table for ILP32, which dispatches either to native
> LP64 system call implementation or to compat-syscalls, as appropriate.

I like it much better than the previous version, thanks for the rework!

However, it seems that you accidentally have a lot more redirects
than you should have:

> +/* Using non-compat syscalls where necessary */
> +#define compat_sys_fadvise64_64 sys_fadvise64_64
> +#define compat_sys_fallocate sys_fallocate
> +#define compat_sys_ftruncate64 sys_ftruncate
> +#define compat_sys_pread64 sys_pread64
> +#define compat_sys_pwrite64 sys_pwrite64
> +#define compat_sys_readahead sys_readahead

Makes sense. These of course all require the respective changes
in glibc as discussed in the thread regarding loff_t handling.

> +#define compat_sys_rt_sigaction sys_rt_sigaction
> +#define compat_sys_shmat sys_shmat

What's special about compat_sys_shmat?

> +#define compat_sys_sync_file_range sys_sync_file_range
> +#define compat_sys_truncate64 sys_truncate
> +#define compat_sys_sigaltstack sys_sigaltstack
> +
> +#define compat_sys_io_getevents sys_io_getevents

io_getevents seems wrong, you are passing the wrong timespec and
aio_context_t here.

> +#define compat_sys_lookup_dcookie sys_lookup_dcookie
> +#define compat_sys_epoll_pwait sys_epoll_pwait

epoll_pwait takes sigset_t, which I'd assume is different between
ilp32 and lp64, so this is probably wrong too, at least on big-endian.

> +#define compat_sys_fcntl64 compat_sys_fcntl

This uses compat_off_t, not compat_loff_t, and needs to be changed.

> +#define compat_sys_signalfd4 sys_signalfd4
> +#define compat_sys_rt_sigsuspend sys_rt_sigsuspend
> +#define compat_sys_rt_sigprocmask sys_rt_sigprocmask
> +#define compat_sys_rt_sigpending sys_rt_sigpending

sigset_t again, all four of these.

> +#define compat_sys_rt_sigqueueinfo sys_rt_sigqueueinfo

this looks ok though, as you have the 64-bit siginfo

> +#define compat_sys_semtimedop sys_semtimedop

timespec again

> +#define compat_sys_rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
> +
> +#define compat_sys_timer_create sys_timer_create
> +#define compat_sys_timer_gettime sys_timer_gettime
> +#define compat_sys_timer_settime sys_timer_settime

timespec again for gettime/settime. create seems fine if you require
the use of the 64-bit sigevent (why?)

> +#define compat_sys_rt_sigtimedwait sys_rt_sigtimedwait

This one probably needs a custom wrapper as you have the 64-bit
siginfo, but the 32-bit sigset and timespec.

> +#define compat_sys_mq_open sys_mq_open
> +#define compat_sys_mq_timedsend sys_mq_timedsend
> +#define compat_sys_mq_timedreceive sys_mq_timedreceive
> +#define compat_sys_mq_getsetattr sys_mq_getsetattr
> +#define compat_sys_mq_open sys_mq_open

You have compat_sys_mq_open twice, and they all look wrong because
you get the wrong struct mq_attr.

> +#define compat_sys_open_by_handle_at sys_open_by_handle_at

The only difference here is the forced O_LARGEFILE, but that
is set by glibc anyway, right?

> +#define compat_sys_clock_adjtime sys_clock_adjtime

wrong timex structure

> +#define compat_sys_openat sys_openat

same as open_by_handle_at

> +#define compat_sys_getdents64 sys_getdents64

glibc uses linux_dirent64 for 32-bit architectures, so this looks wrong

> +#define compat_sys_waitid sys_waitid

This will probably need a separate wrapper to convert rusage but not siginfo

> +#define compat_sys_timer_settime sys_timer_settime
> +#define compat_sys_sched_rr_get_interval sys_sched_rr_get_interval

timespec again

> +#define compat_sys_execveat sys_execveat

This probably gives you the wrong struct user_arg_ptr

> +#define compat_sys_mq_notify sys_mq_notify

ok.

> +#define compat_sys_clock_nanosleep sys_clock_nanosleep
> +#define compat_sys_clock_getres sys_clock_getres

timespec

> +#define sys_lseek sys_llseek

This seems pointless, as there is no sys_lseek

> +asmlinkage long compat_sys_mmap2_wrapper(void);
> +#define sys_mmap2 compat_sys_mmap2_wrapper
> +
> +asmlinkage long compat_sys_fstatfs64_wrapper(void);
> +#define compat_sys_fstatfs64 compat_sys_fstatfs64_wrapper
> +asmlinkage long compat_sys_statfs64_wrapper(void);
> +#define compat_sys_statfs64 compat_sys_statfs64_wrapper

What are the wrappers for again? Maybe add a comment here.

> +#define compat_sys_preadv compat_sys_preadv64
> +#define compat_sys_pwritev compat_sys_pwritev64

wrong iovec.

Arnd

2015-11-17 22:08:16

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 15/19] arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

On Wednesday 18 November 2015 00:16:55 Yury Norov wrote:
>
> +/* IPC_64 */
> +asmlinkage long ilp32_sys_msgctl(int first, int second, void __user *uptr)
> +{
> + return compat_sys_msgctl(first, second | IPC_64, uptr);
> +}
> +#define compat_sys_msgctl ilp32_sys_msgctl
> +
> +asmlinkage long ilp32_sys_shmctl(int first, int second, void __user *uptr)
> +{
> + return compat_sys_shmctl(first, second | IPC_64, uptr);
> +}
> +#define compat_sys_shmctl ilp32_sys_shmctl
> +
> +asmlinkage long ilp32_sys_semctl(int first, int second, int third, int arg)
> +{
> + return compat_sys_semctl(first, second, third | IPC_64, arg);
> +}
> +#define compat_sys_semctl ilp32_sys_semctl
>

I wonder if this would be any simpler by changing compat_ipc_parse_version()

Arnd

2015-11-17 22:09:58

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 16/19] aarch64: ilp32: use generic stat64 structure

On Wednesday 18 November 2015 00:16:56 Yury Norov wrote:
> Generic 32-bit and AARCH32 stat64 structures has same names.
> ILP32 needs generic stat64. So we can either make ILP32 mutual
> exclusive with AARCH32, or duplicate generic cp_new_stat64 code
> and struct stat64 to sys_ilp32.c. We choose second because it's
> more flexible to have independend support for ABIs.
>

I commented on the previous version, but you have not replied to that,
or changed anything.

Arnd

2015-11-17 22:15:58

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 06/19] arm64:ilp32: share signal structures between ILP32 and LP64 ABIs

On Wednesday 18 November 2015 00:16:46 Yury Norov wrote:
>
> +/* 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

Ah, I missed that in the comments for patch 14. I would think that
it makes sense to share siginfo_t with the 64-bit version, when the
normal compat_siginfo_t doesn't work, but I see no point in
changing compat_sigset_t: There is nothing architecture specific
in that, so you can just use the arm32 version of that, which simplifies
both the kernel and libc sides.

Arnd

2015-11-18 08:00:13

by Zhangjian (Bamvor)

[permalink] [raw]
Subject: Re: [RFC2 PATCH v6 00/19] ILP32 for ARM64

Hi, Yury

Glad to see the new version of ilp32. Here is some general questions:

On 2015/11/18 5:16, Yury Norov wrote:
> ------8<-----
> Colleagues, I'm gonna to send it to list.
> Please, take a look.
> ------8<-----
>
> This is still RFC because ~20 tests still fail,
> and because it's based on 4.3 kernel version, and
> some work is needed to rebase on 4.4. I'd preffer
> to do it later.
>
> v3: https://lkml.org/lkml/2014/9/3/704
> v4: https://lkml.org/lkml/2015/4/13/691
> v5: https://lkml.org/lkml/2015/9/29/911
>
> v6:
> - time_t, __kenel_off_t and other types turned to be 32-bit
> for compatibility reasons (after v5 discussion);
Is there any performance comparison between v6 and v5, especially for
these changes? Compatibility is important for us, meanwhile we need to
take performance into account.
> - related changes applied to ILP32 syscall table and handlers;
> - ILP32 VDSO code excluded. It's not mandatory, and caused questions
> during review process. We definitely make sure we will follow up
> with a VDSO later on because it is needed for performance reasons;
> - fixed build issues with different combinations of AARCH32 / ILP32
> enabling in config;
> - ILP32 TLS bug fixed;
> - entry32-common.S introduced to hold wrappers needed for both ILP32
> and AARCH32_EL0;
> - documentation updated according to latest changes;
> - rebased to the current head;
> - coding style re-checked;
> - ILP32 syscall table turned around.
>
> Testing is performed using LTP with scenario 'ltplite'.
> Tested on QEMU + vanilla defconfig kernel.
Do you tested on both big endian and little endian?

Regards

Bamvor
> Regressions are mostly related to core dump genereation,
> readdir(), and futex(). Some tests fail both in ILP32, and LP64.
>
> The full regression table is:
> ILP32 LP64
>
> float_bessel FAIL 134 PASSED 0
> float_exp_log FAIL 134 PASSED 0
> float_iperb FAIL 134 PASSED 0
> float_power FAIL 134 PASSED 0
> float_trigo FAIL 134 PASSED 0
> abort01 FAIL 2 FAIL 2
> fcntl14 FAIL 2 FAIL 2
> kill11 FAIL 2 FAIL 2
> mmap16 FAIL 6 PASSED 0
> open12 FAIL 2 PASSED 0
> pause01 PASSED 0 FAIL 9
> pipe07 FAIL 2 PASSED 0
> readdir01 FAIL 1 PASSED 0
> rename11 FAIL 2 PASSED 0
> rmdir02 FAIL 2 PASSED 0
> setregid02 FAIL 1 FAIL 1
> settimeofday01 FAIL 1 FAIL 1
> umount2_01 FAIL 2 PASSED 0
> umount2_02 FAIL 2 PASSED 0
> umount2_03 FAIL 2 PASSED 0
> utime06 FAIL 2 PASSED 0
>
> Kernel with this patchset, and corresponding
> version of glibc is here:
> https://github.com/norov/
>
> Andrew Pinski (14):
> arm64: ensure the kernel is compiled for LP64
> arm64: rename COMPAT to AARCH32_EL0 in Kconfig
> arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0
> instead
> arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64
> arm64:ilp32: share signal structures between ILP32 and LP64 ABIs
> arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)
> arm64:ilp32: add is_ilp32_compat_{task,thread} and TIF_32BIT_AARCH64
> arm64:ilp32: share HWCAP between LP64 and ILP32
> arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads
> arm64:ilp32: support core dump generation for ILP32
> ptrace: Allow compat to use the native siginfo
> arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use
> it
> arm64:ilp32: use the native siginfo instead of the compat siginfo
> arm64:ilp32: add ARM64_ILP32 to Kconfig
>
> Jan Dakinevich (2):
> ilp32: common 32-bit wrappers
> arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl
>
> Philipp Tomsich (2):
> arm64:ilp32: add documentation on the ILP32 ABI for ARM64
> arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for
> ILP32
>
> Yury Norov (1):
> aarch64: ilp32: use generic stat64 structure
>
> Documentation/arm64/ilp32.txt | 47 +++++++
> arch/arm64/Kconfig | 12 ++
> arch/arm64/Makefile | 5 +
> arch/arm64/include/asm/compat.h | 70 +++++++++-
> arch/arm64/include/asm/elf.h | 105 ++++++++++++--
> arch/arm64/include/asm/fpsimd.h | 2 +-
> arch/arm64/include/asm/hwcap.h | 12 +-
> arch/arm64/include/asm/memory.h | 2 +-
> arch/arm64/include/asm/processor.h | 18 ++-
> arch/arm64/include/asm/ptrace.h | 2 +-
> arch/arm64/include/asm/signal32.h | 19 +++
> arch/arm64/include/asm/stat.h | 2 +
> arch/arm64/include/asm/thread_info.h | 3 +-
> arch/arm64/include/asm/unistd.h | 11 +-
> arch/arm64/include/uapi/asm/bitsperlong.h | 9 +-
> arch/arm64/include/uapi/asm/siginfo.h | 21 +++
> arch/arm64/include/uapi/asm/signal.h | 31 +++++
> arch/arm64/kernel/Makefile | 4 +-
> arch/arm64/kernel/asm-offsets.c | 2 +-
> arch/arm64/kernel/entry.S | 18 ++-
> arch/arm64/kernel/entry32-common.S | 37 +++++
> arch/arm64/kernel/entry32.S | 29 ----
> arch/arm64/kernel/head.S | 2 +-
> arch/arm64/kernel/hw_breakpoint.c | 7 +-
> arch/arm64/kernel/perf_regs.c | 2 +-
> arch/arm64/kernel/process.c | 4 +-
> arch/arm64/kernel/ptrace.c | 47 ++++---
> arch/arm64/kernel/signal.c | 21 ++-
> arch/arm64/kernel/sys_ilp32.c | 223 ++++++++++++++++++++++++++++++
> arch/arm64/kernel/traps.c | 4 +-
> arch/arm64/kernel/vdso.c | 12 +-
> include/linux/compat.h | 4 +
> include/uapi/asm-generic/siginfo.h | 17 ++-
> include/uapi/asm-generic/signal.h | 27 +++-
> kernel/ptrace.c | 24 +++-
> 35 files changed, 745 insertions(+), 110 deletions(-)
> create mode 100644 Documentation/arm64/ilp32.txt
> create mode 100644 arch/arm64/kernel/entry32-common.S
> create mode 100644 arch/arm64/kernel/sys_ilp32.c
>

2015-11-18 08:16:31

by Zhangjian (Bamvor)

[permalink] [raw]
Subject: Re: [PATCH v6 01/19] arm64:ilp32: add documentation on the ILP32 ABI for ARM64

Hi, Yury

On 2015/11/18 5:16, Yury Norov wrote:
> From: Philipp Tomsich <[email protected]>
>
> Based on Andrew Pinski's original patch-series and adapted with changes
> to reduce the duplication of code-paths and resolve issue found during
> LTP testing.
>
> Reviewed-by: David Daney <[email protected]>
>
>
> Signed-off-by: Philipp Tomsich <[email protected]>
> Signed-off-by: Christoph Muellner <[email protected]>
> Signed-off-by: Yury Norov <[email protected]>
> Signed-off-by: Andrew Pinski <[email protected]>
> ---
> Documentation/arm64/ilp32.txt | 47 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
> create mode 100644 Documentation/arm64/ilp32.txt
>
> diff --git a/Documentation/arm64/ilp32.txt b/Documentation/arm64/ilp32.txt
> new file mode 100644
> index 0000000..93c09f2
> --- /dev/null
> +++ b/Documentation/arm64/ilp32.txt
> @@ -0,0 +1,47 @@
> +ILP32 AARCH64 SYSCALL ABI
> +=========================
> +Written by Andrew Pinski <[email protected]>
> +Updated by Philipp Tomsich <[email protected]>
> +Updated by Yury Norov <[email protected]>
> +
> +
> +This document describes the ILP32 syscall ABI and where it differs
> +from the generic linux syscall interface.
> +
> +Some structures are changed to reduce the difference in the code path
> +for both ILP32 and LP64 ABIs for signal handling.
Given that user may upgrade from aarch32 to ILP32. How about add abi
comparison between aarch32 and aarch64 ilp32?

Regards

Bamvor

2015-11-18 08:11:07

by Zhangjian (Bamvor)

[permalink] [raw]
Subject: Re: [PATCH v6 18/19] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32

Hi, Yury

On 2015/11/18 5:16, Yury Norov wrote:
> From: Philipp Tomsich <[email protected]>
>
> To make life for tools (such as gdb) easier when dealing with ILP32 processes,
> we report a proper subarchitecture for ILP32 in the ELF auxiliary vectors.
I saw some ilp32 relative patches in binutils mailing list. Does gdb
fully support ilp32?

Regards

Bamvor

2015-11-18 08:15:52

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tuesday 17 November 2015 22:57:52 Arnd Bergmann wrote:
> > +#define compat_sys_open_by_handle_at sys_open_by_handle_at
>
> The only difference here is the forced O_LARGEFILE, but that
> is set by glibc anyway, right?
>
> > +#define compat_sys_openat sys_openat
>
> same as open_by_handle_at
>

I gave it some more thought, and I think we should actually stay
with sys_open_by_handle_at and sys_openat, but do it a little differently:

Forcing O_LARGEFILE is probably what we want for all architectures
going forward, so we should change asm-generic/unistd.h to use sys_openat
for compat mode, and override it for tile32 compat, which is the only
existing user of this table at the moment and which needs to
retain the existing behavior.

Arnd

2015-11-18 08:25:45

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH v6 15/19] arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

Arnd Bergmann <[email protected]> writes:

> On Wednesday 18 November 2015 00:16:55 Yury Norov wrote:
>>
>> +/* IPC_64 */
>> +asmlinkage long ilp32_sys_msgctl(int first, int second, void __user *uptr)
>> +{
>> + return compat_sys_msgctl(first, second | IPC_64, uptr);
>> +}
>> +#define compat_sys_msgctl ilp32_sys_msgctl
>> +
>> +asmlinkage long ilp32_sys_shmctl(int first, int second, void __user *uptr)
>> +{
>> + return compat_sys_shmctl(first, second | IPC_64, uptr);
>> +}
>> +#define compat_sys_shmctl ilp32_sys_shmctl
>> +
>> +asmlinkage long ilp32_sys_semctl(int first, int second, int third, int arg)
>> +{
>> + return compat_sys_semctl(first, second, third | IPC_64, arg);
>> +}
>> +#define compat_sys_semctl ilp32_sys_semctl
>>
>
> I wonder if this would be any simpler by changing compat_ipc_parse_version()

This cries for a generic solution. Other archs migrating to separate
ipc syscalls will want to avoid the whole IPC_64 business for them, even
if they need to retain [compat_]ipc_parse_version for sys_ipc
compatibility.

Andreas.

--
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

2015-11-18 09:26:30

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 15/19] arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

On Wednesday 18 November 2015 09:25:40 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > On Wednesday 18 November 2015 00:16:55 Yury Norov wrote:
> >>
> >> +/* IPC_64 */
> >> +asmlinkage long ilp32_sys_msgctl(int first, int second, void __user *uptr)
> >> +{
> >> + return compat_sys_msgctl(first, second | IPC_64, uptr);
> >> +}
> >> +#define compat_sys_msgctl ilp32_sys_msgctl
> >> +
> >> +asmlinkage long ilp32_sys_shmctl(int first, int second, void __user *uptr)
> >> +{
> >> + return compat_sys_shmctl(first, second | IPC_64, uptr);
> >> +}
> >> +#define compat_sys_shmctl ilp32_sys_shmctl
> >> +
> >> +asmlinkage long ilp32_sys_semctl(int first, int second, int third, int arg)
> >> +{
> >> + return compat_sys_semctl(first, second, third | IPC_64, arg);
> >> +}
> >> +#define compat_sys_semctl ilp32_sys_semctl
> >>
> >
> > I wonder if this would be any simpler by changing compat_ipc_parse_version()
>
> This cries for a generic solution. Other archs migrating to separate
> ipc syscalls will want to avoid the whole IPC_64 business for them, even
> if they need to retain [compat_]ipc_parse_version for sys_ipc
> compatibility.

Agreed. I think all architectures are moving that way now, so we should
really try to get all cases right now.

I've done a complete list of what the architectures (see
https://docs.google.com/spreadsheets/d/18GxXEHE2ywnSr-SPoGFd1ABz6wEM1ex-JMu5lEraaH8/ )

We have these categories:

1. uses IPC_PARSE_VERSION with sys_ipc, and has just introduced
separate syscalls:

arm, avr32, powerpc, x86-32

2. uses IPC_PARSE_VERSION with sys_ipc, and has not yet introduced
separate syscalls (currently producing a compile warning):

cris, frv, m32r, m68k, mips (o32), mn10300, s390, sh32, sparc

3. uses IPC_PARSE_VERSION with separate syscalls:

alpha, blackfin, microblaze, mips (n32/64), xtensa

4a. only new-style IPC with separate syscalls:

ia64, parisc, sh64

4b. only new-style IPC with separate syscalls, using generic syscall
table:

arc, arm64, c6x, h8300, hexagon, metag, nios2, openrisc, score,
tile, unicore32

So we should probably fix 1. and 2. before it's too late, but make
sure we don't break 3. in the process.

Arnd

2015-11-18 10:07:31

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v6 15/19] arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

On Wed, Nov 18, 2015 at 10:23 AM, Arnd Bergmann <[email protected]> wrote:
> On Wednesday 18 November 2015 09:25:40 Andreas Schwab wrote:
>> Arnd Bergmann <[email protected]> writes:
>>
>> > On Wednesday 18 November 2015 00:16:55 Yury Norov wrote:
>> >>
>> >> +/* IPC_64 */
>> >> +asmlinkage long ilp32_sys_msgctl(int first, int second, void __user *uptr)
>> >> +{
>> >> + return compat_sys_msgctl(first, second | IPC_64, uptr);
>> >> +}
>> >> +#define compat_sys_msgctl ilp32_sys_msgctl
>> >> +
>> >> +asmlinkage long ilp32_sys_shmctl(int first, int second, void __user *uptr)
>> >> +{
>> >> + return compat_sys_shmctl(first, second | IPC_64, uptr);
>> >> +}
>> >> +#define compat_sys_shmctl ilp32_sys_shmctl
>> >> +
>> >> +asmlinkage long ilp32_sys_semctl(int first, int second, int third, int arg)
>> >> +{
>> >> + return compat_sys_semctl(first, second, third | IPC_64, arg);
>> >> +}
>> >> +#define compat_sys_semctl ilp32_sys_semctl
>> >>
>> >
>> > I wonder if this would be any simpler by changing compat_ipc_parse_version()
>>
>> This cries for a generic solution. Other archs migrating to separate
>> ipc syscalls will want to avoid the whole IPC_64 business for them, even
>> if they need to retain [compat_]ipc_parse_version for sys_ipc
>> compatibility.
>
> Agreed. I think all architectures are moving that way now, so we should
> really try to get all cases right now.
>
> I've done a complete list of what the architectures (see
> https://docs.google.com/spreadsheets/d/18GxXEHE2ywnSr-SPoGFd1ABz6wEM1ex-JMu5lEraaH8/ )
>
> We have these categories:
>
> 1. uses IPC_PARSE_VERSION with sys_ipc, and has just introduced
> separate syscalls:
>
> arm, avr32, powerpc, x86-32

x86-32, where?

> 2. uses IPC_PARSE_VERSION with sys_ipc, and has not yet introduced
> separate syscalls (currently producing a compile warning):
>
> cris, frv, m32r, m68k, mips (o32), mn10300, s390, sh32, sparc
>
> 3. uses IPC_PARSE_VERSION with separate syscalls:
>
> alpha, blackfin, microblaze, mips (n32/64), xtensa
>
> 4a. only new-style IPC with separate syscalls:
>
> ia64, parisc, sh64

and x86-64?

> 4b. only new-style IPC with separate syscalls, using generic syscall
> table:
>
> arc, arm64, c6x, h8300, hexagon, metag, nios2, openrisc, score,
> tile, unicore32
>
> So we should probably fix 1. and 2. before it's too late, but make
> sure we don't break 3. in the process.

(Fortunately?) x86-32 doesn't seem to be converted in next yet?

I was hoping for them to do the heavy lifting for the generic solution ;-)

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

2015-11-18 11:21:13

by Andrew Pinski

[permalink] [raw]
Subject: Re: [PATCH v6 18/19] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32



> On Nov 18, 2015, at 12:11 AM, Zhangjian (Bamvor) <[email protected]> wrote:
>
> Hi, Yury
>
>> On 2015/11/18 5:16, Yury Norov wrote:
>> From: Philipp Tomsich <[email protected]>
>>
>> To make life for tools (such as gdb) easier when dealing with ILP32 processes,
>> we report a proper subarchitecture for ILP32 in the ELF auxiliary vectors.
> I saw some ilp32 relative patches in binutils mailing list. Does gdb
> fully support ilp32?

I have a patch set but I have not tested them with the latest kernel patch set yet. The branch is located in the binutils-gdb git is https://sourceware.org/git/?p=binutils-gdb.git;a=shortlog;h=refs/heads/users/pinskia/gdb-aarch64-ilp32 .
I think it will mostly work except for core support might need to be changed slightly.

Thanks,
Andrew
>
> Regards
>
> Bamvor
>

2015-11-18 12:05:23

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 15/19] arm64: ilp32: force IPC_64 in msgctl, shmctl, semctl

On Wednesday 18 November 2015 11:07:26 Geert Uytterhoeven wrote:
> >
> > I've done a complete list of what the architectures (see
> > https://docs.google.com/spreadsheets/d/18GxXEHE2ywnSr-SPoGFd1ABz6wEM1ex-JMu5lEraaH8/ )
> >
> > We have these categories:
> >
> > 1. uses IPC_PARSE_VERSION with sys_ipc, and has just introduced
> > separate syscalls:
> >
> > arm, avr32, powerpc, x86-32
>
> x86-32, where?

My mistake. x86 uses a different way to do this, so I didn't see it
using grep and just assumed that Andy Lutomirski had patched it already
based on my memory of

https://sourceware.org/ml/libc-alpha/2015-09/msg00323.html

> > 2. uses IPC_PARSE_VERSION with sys_ipc, and has not yet introduced
> > separate syscalls (currently producing a compile warning):
> >
> > cris, frv, m32r, m68k, mips (o32), mn10300, s390, sh32, sparc
> >
> > 3. uses IPC_PARSE_VERSION with separate syscalls:
> >
> > alpha, blackfin, microblaze, mips (n32/64), xtensa
> >
> > 4a. only new-style IPC with separate syscalls:
> >
> > ia64, parisc, sh64
>
> and x86-64?

right, that too. I got it in my spreadsheet by copied it wrong.

> > 4b. only new-style IPC with separate syscalls, using generic syscall
> > table:
> >
> > arc, arm64, c6x, h8300, hexagon, metag, nios2, openrisc, score,
> > tile, unicore32
> >
> > So we should probably fix 1. and 2. before it's too late, but make
> > sure we don't break 3. in the process.
>
> (Fortunately?) x86-32 doesn't seem to be converted in next yet?
>
> I was hoping for them to do the heavy lifting for the generic solution

yes, that would be nice ;-)

Arnd

2015-11-18 20:25:59

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 18/19] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32

On Wed, Nov 18, 2015 at 03:21:05AM -0800, [email protected] wrote:
>
>
> > On Nov 18, 2015, at 12:11 AM, Zhangjian (Bamvor) <[email protected]> wrote:
> >
> > Hi, Yury
> >
> >> On 2015/11/18 5:16, Yury Norov wrote:
> >> From: Philipp Tomsich <[email protected]>
> >>
> >> To make life for tools (such as gdb) easier when dealing with ILP32 processes,
> >> we report a proper subarchitecture for ILP32 in the ELF auxiliary vectors.
> > I saw some ilp32 relative patches in binutils mailing list. Does gdb
> > fully support ilp32?
>
> I have a patch set but I have not tested them with the latest kernel patch set yet. The branch is located in the binutils-gdb git is https://sourceware.org/git/?p=binutils-gdb.git;a=shortlog;h=refs/heads/users/pinskia/gdb-aarch64-ilp32 .
> I think it will mostly work except for core support might need to be changed slightly.
>
> Thanks,
> Andrew
> >

Yes, it works mostly. I can read and modify text/data, set breakpoints
etc.

> > Regards
> >
> > Bamvor
> >

2015-11-18 20:36:45

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 16/19] aarch64: ilp32: use generic stat64 structure

On Tue, Nov 17, 2015 at 11:09:05PM +0100, Arnd Bergmann wrote:
> On Wednesday 18 November 2015 00:16:56 Yury Norov wrote:
> > Generic 32-bit and AARCH32 stat64 structures has same names.
> > ILP32 needs generic stat64. So we can either make ILP32 mutual
> > exclusive with AARCH32, or duplicate generic cp_new_stat64 code
> > and struct stat64 to sys_ilp32.c. We choose second because it's
> > more flexible to have independend support for ABIs.
> >
>
> I commented on the previous version, but you have not replied to that,
> or changed anything.
>
> Arnd

Hi Arnd,

It seems I misunderstood you.

Are you OK if we'll enable __ARCH_WANT_COMPAT_STAT64
for ILP32, as for AARCH32_EL0, and turn glibc to use
struct stat from sysdeps/unix/sysv/linux/bits/stat.h
with this calls? It seems, this is how ARM ABI works.

Yury.

---
arch/arm64/include/asm/stat.h | 2 --
arch/arm64/include/asm/unistd.h | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)

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

#include <asm/compat.h>

-#ifdef CONFIG_AARCH32_EL0
/*
* struct stat64 is needed for compat tasks only. Its definition is different
* from the generic struct stat64.
@@ -60,4 +59,3 @@ struct stat64 {

#endif
#endif
-#endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 696e638..3b196f3 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -19,7 +19,6 @@
#endif
#ifdef CONFIG_AARCH32_EL0
#define __ARCH_WANT_COMPAT_SYS_GETDENTS64
-#define __ARCH_WANT_COMPAT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_GETPGRP
@@ -42,6 +41,7 @@
#define __NR_compat_sigreturn 119
#define __NR_compat_rt_sigreturn 173

+#define __ARCH_WANT_COMPAT_STAT64
#define __ARCH_WANT_SYS_LLSEEK

/*
--
2.1.4

2015-11-18 20:51:23

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 16/19] aarch64: ilp32: use generic stat64 structure

On Wednesday 18 November 2015 23:36:20 Yury Norov wrote:
> On Tue, Nov 17, 2015 at 11:09:05PM +0100, Arnd Bergmann wrote:
> > On Wednesday 18 November 2015 00:16:56 Yury Norov wrote:
> > > Generic 32-bit and AARCH32 stat64 structures has same names.
> > > ILP32 needs generic stat64. So we can either make ILP32 mutual
> > > exclusive with AARCH32, or duplicate generic cp_new_stat64 code
> > > and struct stat64 to sys_ilp32.c. We choose second because it's
> > > more flexible to have independend support for ABIs.
> > >
> >
> > I commented on the previous version, but you have not replied to that,
> > or changed anything.
> >
> > Arnd
>
> Hi Arnd,
>
> It seems I misunderstood you.
>
> Are you OK if we'll enable __ARCH_WANT_COMPAT_STAT64
> for ILP32, as for AARCH32_EL0, and turn glibc to use
> struct stat from sysdeps/unix/sysv/linux/bits/stat.h
> with this calls? It seems, this is how ARM ABI works.

Yes, that's fine. The other approach I suggested was to define a stat64
structure in arch/arm64/include/uapi/asm/stat.h that has the same binary
layout as 'struct stat' on arm64, and then use sys_newstat.

We are doing it that way in the 64-bit time_t patch set for most
architectures, and will assign a new system call number at that
point as well.

The only two differences between the arm32 'struct stat64' and the
arm64 'struct stat' are the size of the time members and the broken
__st_ino field on arm32, but that is already handled in glibc.

Arnd

2015-11-18 22:05:04

by Philipp Tomsich

[permalink] [raw]
Subject: Re: [PATCH v6 18/19] arm64:ilp32: change COMPAT_ELF_PLATFORM to report a a subplatform for ILP32

Yury,

We had implemented gdb-support against the the earlier ILP32 incarnation.
I’ll take a look with the latest patch-set and see whether these still apply.

Best,
Philipp.

> On 18 Nov 2015, at 21:25, Yury Norov <[email protected]> wrote:
>
> On Wed, Nov 18, 2015 at 03:21:05AM -0800, [email protected] wrote:
>>
>>
>>> On Nov 18, 2015, at 12:11 AM, Zhangjian (Bamvor) <[email protected]> wrote:
>>>
>>> Hi, Yury
>>>
>>>> On 2015/11/18 5:16, Yury Norov wrote:
>>>> From: Philipp Tomsich <[email protected]>
>>>>
>>>> To make life for tools (such as gdb) easier when dealing with ILP32 processes,
>>>> we report a proper subarchitecture for ILP32 in the ELF auxiliary vectors.
>>> I saw some ilp32 relative patches in binutils mailing list. Does gdb
>>> fully support ilp32?
>>
>> I have a patch set but I have not tested them with the latest kernel patch set yet. The branch is located in the binutils-gdb git is https://sourceware.org/git/?p=binutils-gdb.git;a=shortlog;h=refs/heads/users/pinskia/gdb-aarch64-ilp32 .
>> I think it will mostly work except for core support might need to be changed slightly.
>>
>> Thanks,
>> Andrew
>>>
>
> Yes, it works mostly. I can read and modify text/data, set breakpoints
> etc.
>
>>> Regards
>>>
>>> Bamvor
>>>

2015-11-19 13:21:23

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

Arnd Bergmann <[email protected]> writes:

> On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
>> +#define sys_lseek sys_llseek
>
> This seems pointless, as there is no sys_lseek

I think it should be the other way round. Why would you want to use
llseek if you can pass loff_t in a single register?

Andreas.

--
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

2015-11-19 13:33:15

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Thursday 19 November 2015 14:21:16 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
> >> +#define sys_lseek sys_llseek
> >
> > This seems pointless, as there is no sys_lseek
>
> I think it should be the other way round. Why would you want to use
> llseek if you can pass loff_t in a single register?

Right, it makes more sense the other way round.

Arnd

2015-11-23 16:49:34

by Andreas Schwab

[permalink] [raw]
Subject: Re: [RFC2 PATCH v6 00/19] ILP32 for ARM64

Yury Norov <[email protected]> writes:

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

For some reason signal frame setup has been broken with this
incarnation. I'm seeing x30 == 0 on entry to the signal handler.

Andreas.

--
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

2015-11-30 15:35:32

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tuesday 17 November 2015 22:57:52 Arnd Bergmann wrote:
> On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
> > From: Andrew Pinski <[email protected]>
> >
> > Add a separate syscall-table for ILP32, which dispatches either to native
> > LP64 system call implementation or to compat-syscalls, as appropriate.
>
> I like it much better than the previous version, thanks for the rework!

Hi Yuri,

you must have missed my reply below. Are you still working on ilp32
or did you drop this thread because you got distracted with something
else?

Arnd

> However, it seems that you accidentally have a lot more redirects
> than you should have:
>
> > +/* Using non-compat syscalls where necessary */
> > +#define compat_sys_fadvise64_64 sys_fadvise64_64
> > +#define compat_sys_fallocate sys_fallocate
> > +#define compat_sys_ftruncate64 sys_ftruncate
> > +#define compat_sys_pread64 sys_pread64
> > +#define compat_sys_pwrite64 sys_pwrite64
> > +#define compat_sys_readahead sys_readahead
>
> Makes sense. These of course all require the respective changes
> in glibc as discussed in the thread regarding loff_t handling.
>
> > +#define compat_sys_rt_sigaction sys_rt_sigaction
> > +#define compat_sys_shmat sys_shmat
>
> What's special about compat_sys_shmat?
>
> > +#define compat_sys_sync_file_range sys_sync_file_range
> > +#define compat_sys_truncate64 sys_truncate
> > +#define compat_sys_sigaltstack sys_sigaltstack
> > +
> > +#define compat_sys_io_getevents sys_io_getevents
>
> io_getevents seems wrong, you are passing the wrong timespec and
> aio_context_t here.
>
> > +#define compat_sys_lookup_dcookie sys_lookup_dcookie
> > +#define compat_sys_epoll_pwait sys_epoll_pwait
>
> epoll_pwait takes sigset_t, which I'd assume is different between
> ilp32 and lp64, so this is probably wrong too, at least on big-endian.
>
> > +#define compat_sys_fcntl64 compat_sys_fcntl
>
> This uses compat_off_t, not compat_loff_t, and needs to be changed.
>
> > +#define compat_sys_signalfd4 sys_signalfd4
> > +#define compat_sys_rt_sigsuspend sys_rt_sigsuspend
> > +#define compat_sys_rt_sigprocmask sys_rt_sigprocmask
> > +#define compat_sys_rt_sigpending sys_rt_sigpending
>
> sigset_t again, all four of these.
>
> > +#define compat_sys_rt_sigqueueinfo sys_rt_sigqueueinfo
>
> this looks ok though, as you have the 64-bit siginfo
>
> > +#define compat_sys_semtimedop sys_semtimedop
>
> timespec again
>
> > +#define compat_sys_rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
> > +
> > +#define compat_sys_timer_create sys_timer_create
> > +#define compat_sys_timer_gettime sys_timer_gettime
> > +#define compat_sys_timer_settime sys_timer_settime
>
> timespec again for gettime/settime. create seems fine if you require
> the use of the 64-bit sigevent (why?)
>
> > +#define compat_sys_rt_sigtimedwait sys_rt_sigtimedwait
>
> This one probably needs a custom wrapper as you have the 64-bit
> siginfo, but the 32-bit sigset and timespec.
>
> > +#define compat_sys_mq_open sys_mq_open
> > +#define compat_sys_mq_timedsend sys_mq_timedsend
> > +#define compat_sys_mq_timedreceive sys_mq_timedreceive
> > +#define compat_sys_mq_getsetattr sys_mq_getsetattr
> > +#define compat_sys_mq_open sys_mq_open
>
> You have compat_sys_mq_open twice, and they all look wrong because
> you get the wrong struct mq_attr.
>
> > +#define compat_sys_open_by_handle_at sys_open_by_handle_at
>
> The only difference here is the forced O_LARGEFILE, but that
> is set by glibc anyway, right?
>
> > +#define compat_sys_clock_adjtime sys_clock_adjtime
>
> wrong timex structure
>
> > +#define compat_sys_openat sys_openat
>
> same as open_by_handle_at
>
> > +#define compat_sys_getdents64 sys_getdents64
>
> glibc uses linux_dirent64 for 32-bit architectures, so this looks wrong
>
> > +#define compat_sys_waitid sys_waitid
>
> This will probably need a separate wrapper to convert rusage but not siginfo
>
> > +#define compat_sys_timer_settime sys_timer_settime
> > +#define compat_sys_sched_rr_get_interval sys_sched_rr_get_interval
>
> timespec again
>
> > +#define compat_sys_execveat sys_execveat
>
> This probably gives you the wrong struct user_arg_ptr
>
> > +#define compat_sys_mq_notify sys_mq_notify
>
> ok.
>
> > +#define compat_sys_clock_nanosleep sys_clock_nanosleep
> > +#define compat_sys_clock_getres sys_clock_getres
>
> timespec
>
> > +#define sys_lseek sys_llseek
>
> This seems pointless, as there is no sys_lseek
>
> > +asmlinkage long compat_sys_mmap2_wrapper(void);
> > +#define sys_mmap2 compat_sys_mmap2_wrapper
> > +
> > +asmlinkage long compat_sys_fstatfs64_wrapper(void);
> > +#define compat_sys_fstatfs64 compat_sys_fstatfs64_wrapper
> > +asmlinkage long compat_sys_statfs64_wrapper(void);
> > +#define compat_sys_statfs64 compat_sys_statfs64_wrapper
>
> What are the wrappers for again? Maybe add a comment here.
>
> > +#define compat_sys_preadv compat_sys_preadv64
> > +#define compat_sys_pwritev compat_sys_pwritev64
>
> wrong iovec.
>
> Arnd
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

2015-11-30 20:24:15

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Mon, Nov 30, 2015 at 04:34:22PM +0100, Arnd Bergmann wrote:
> On Tuesday 17 November 2015 22:57:52 Arnd Bergmann wrote:
> > On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
> > > From: Andrew Pinski <[email protected]>
> > >
> > > Add a separate syscall-table for ILP32, which dispatches either to native
> > > LP64 system call implementation or to compat-syscalls, as appropriate.
> >
> > I like it much better than the previous version, thanks for the rework!
>
> Hi Yuri,
>
> you must have missed my reply below. Are you still working on ilp32
> or did you drop this thread because you got distracted with something
> else?
>
> Arnd
>

Hi Arnd,

I didn't miss it, and I continue with ILP32. I really appreciate your
attention and time you spend on ILP32.

There's a tricky bug with signal stack, that Andreas also discovered.
It makes almost all tests that use posix threads crash. I want to fix
it and other bugs before next submission.

I also update glibc to follow all recommendations, and I want to
upload it together with kernel patches.

BR,
Yury.

2015-11-30 21:50:51

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Monday 30 November 2015 23:21:41 Yury Norov wrote:
> On Mon, Nov 30, 2015 at 04:34:22PM +0100, Arnd Bergmann wrote:
> > On Tuesday 17 November 2015 22:57:52 Arnd Bergmann wrote:
> > > On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
> > > > From: Andrew Pinski <[email protected]>
> > > >
> > > > Add a separate syscall-table for ILP32, which dispatches either to native
> > > > LP64 system call implementation or to compat-syscalls, as appropriate.
> > >
> > > I like it much better than the previous version, thanks for the rework!
> >
> > Hi Yuri,
> >
> > you must have missed my reply below. Are you still working on ilp32
> > or did you drop this thread because you got distracted with something
> > else?
> >
>
> I didn't miss it, and I continue with ILP32. I really appreciate your
> attention and time you spend on ILP32.
>
> There's a tricky bug with signal stack, that Andreas also discovered.
> It makes almost all tests that use posix threads crash. I want to fix
> it and other bugs before next submission.
>
> I also update glibc to follow all recommendations, and I want to
> upload it together with kernel patches.

Ok. As a reviewer, I find long waits between submissions a bit annoying
because that means I have already forgotten everything I commented on
the previous time.

Could we try to get consensus on how the syscall ABI should look
before you start adapting glibc to another intermediate version?
I think that would also save you duplicate work, as it's always
possible that we misunderstand each other in the review. Also,
when someone asks you questions during a review, please reply to
those questions so we can get a common understanding of the facts
and document that in the mail archives.

Arnd

2015-12-01 00:21:02

by Andrew Pinski

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Mon, Nov 30, 2015 at 1:49 PM, Arnd Bergmann <[email protected]> wrote:
> On Monday 30 November 2015 23:21:41 Yury Norov wrote:
>> On Mon, Nov 30, 2015 at 04:34:22PM +0100, Arnd Bergmann wrote:
>> > On Tuesday 17 November 2015 22:57:52 Arnd Bergmann wrote:
>> > > On Wednesday 18 November 2015 00:16:54 Yury Norov wrote:
>> > > > From: Andrew Pinski <[email protected]>
>> > > >
>> > > > Add a separate syscall-table for ILP32, which dispatches either to native
>> > > > LP64 system call implementation or to compat-syscalls, as appropriate.
>> > >
>> > > I like it much better than the previous version, thanks for the rework!
>> >
>> > Hi Yuri,
>> >
>> > you must have missed my reply below. Are you still working on ilp32
>> > or did you drop this thread because you got distracted with something
>> > else?
>> >
>>
>> I didn't miss it, and I continue with ILP32. I really appreciate your
>> attention and time you spend on ILP32.
>>
>> There's a tricky bug with signal stack, that Andreas also discovered.
>> It makes almost all tests that use posix threads crash. I want to fix
>> it and other bugs before next submission.
>>
>> I also update glibc to follow all recommendations, and I want to
>> upload it together with kernel patches.
>
> Ok. As a reviewer, I find long waits between submissions a bit annoying
> because that means I have already forgotten everything I commented on
> the previous time.
>
> Could we try to get consensus on how the syscall ABI should look
> before you start adapting glibc to another intermediate version?

Sounds good. I have asked Yury to do that just that and change the
patches according to the current reviews without testing them with a
newer version of glibc. Note getting consensus would be nice soon as
possible so I can start working again on glibc patches and make sure
the changes that are made to support a slightly different ABI on the
userland side is ok with them.

Thanks,
Andrew

> I think that would also save you duplicate work, as it's always
> possible that we misunderstand each other in the review. Also,
> when someone asks you questions during a review, please reply to
> those questions so we can get a common understanding of the facts
> and document that in the mail archives.
>
> Arnd

2015-12-01 00:40:41

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Mon, Nov 30, 2015 at 10:49:43PM +0100, Arnd Bergmann wrote:
>
> Could we try to get consensus on how the syscall ABI should look
> before you start adapting glibc to another intermediate version?
> I think that would also save you duplicate work, as it's always
> possible that we misunderstand each other in the review. Also,
> when someone asks you questions during a review, please reply to
> those questions so we can get a common understanding of the facts
> and document that in the mail archives.
>
> Arnd

This is full syscall table for ILP32, how it looks right now.
I collected all comments here and do rework according it.
Any comments?

BR,
Yury.

[0] = compat_sys_io_setup,
[1] = sys_io_destroy,
[2] = compat_sys_io_submit,
[3] = sys_io_cancel,
[4] = sys_io_getevents, wrong timespec_t and aio_context_t here
[5] = sys_setxattr,
[6] = sys_lsetxattr,
[7] = sys_fsetxattr,
[8] = sys_getxattr,
[9] = sys_lgetxattr,
[10] = sys_fgetxattr,
[11] = sys_listxattr,
[12] = sys_llistxattr,
[13] = sys_flistxattr,
[14] = sys_removexattr,
[15] = sys_lremovexattr,
[16] = sys_fremovexattr,
[17] = sys_getcwd,
[18] = sys_lookup_dcookie,
[19] = sys_eventfd2,
[20] = sys_epoll_create1,
[21] = sys_epoll_ctl,
[22] = sys_epoll_pwait, way round: takes sigset_t check BE
[23] = sys_dup,
[24] = sys_dup3,
[25] = compat_sys_fcntl, uses compat_off_t, not compat_loff_t
[26] = sys_inotify_init1,
[27] = sys_inotify_add_watch,
[28] = sys_inotify_rm_watch,
[29] = compat_sys_ioctl,
[30] = sys_ioprio_set,
[31] = sys_ioprio_get,
[32] = sys_flock,
[33] = sys_mknodat,
[34] = sys_mkdirat,
[35] = sys_unlinkat,
[36] = sys_symlinkat,
[37] = sys_linkat,
[38] = sys_renameat,
[39] = sys_umount,
[40] = compat_sys_mount,
[41] = sys_pivot_root,
[42] = sys_ni_syscall,
[43] = compat_sys_statfs64_wrapper, check wrappers, maybe just statfs64
[44] = compat_sys_fstatfs64_wrapper, fstatfs64
[45] = sys_truncate,
[46] = sys_ftruncate,
[47] = sys_fallocate,
[48] = sys_faccessat,
[49] = sys_chdir,
[50] = sys_fchdir,
[51] = sys_chroot,
[52] = sys_fchmod,
[53] = sys_fchmodat,
[54] = sys_fchownat,
[55] = sys_fchown,
[56] = sys_openat, force O_LARGEFILE in asm-generic/unistd.h
make tile32 to use compat
[57] = sys_close,
[58] = sys_vhangup,
[59] = sys_pipe2,
[60] = sys_quotactl,
[61] = sys_getdents64, check: glibc uses linux_dirent64 for
32-bit architectures, so this looks wrong
[62] = sys_llseek, use 3-argument lseek
[63] = sys_read,
[64] = sys_write,
[65] = compat_sys_readv,
[66] = compat_sys_writev,
[67] = sys_pread64,
[68] = sys_pwrite64,
[69] = compat_sys_preadv64, use noncompat
[70] = compat_sys_pwritev64, use noncompat
[71] = sys_sendfile64,
[72] = compat_sys_pselect6,
[73] = compat_sys_ppoll,
[74] = sys_signalfd4, takes sigset_t, check BE
[75] = compat_sys_vmsplice,
[76] = sys_splice,
[77] = sys_tee,
[78] = sys_readlinkat,
[79] = ilp32_sys_fstatat64, use compat. fix glibc
[80] = ilp32_sys_fstat64, use compat. fix glibc
[81] = sys_sync,
[82] = sys_fsync,
[83] = sys_fdatasync,
[84] = sys_sync_file_range,
[85] = sys_timerfd_create,
[86] = compat_sys_timerfd_settime,
[87] = compat_sys_timerfd_gettime,
[88] = compat_sys_utimensat,
[89] = sys_acct,
[90] = sys_capget,
[91] = sys_capset,
[92] = sys_personality,
[93] = sys_exit,
[94] = sys_exit_group,
[95] = sys_waitid, check: need a separate wrapper
to convert rusage but not siginfo
[96] = sys_set_tid_address,
[97] = sys_unshare,
[98] = compat_sys_futex,
[99] = compat_sys_set_robust_list,
[100] = compat_sys_get_robust_list,
[101] = compat_sys_nanosleep,
[102] = compat_sys_getitimer,
[103] = compat_sys_setitimer,
[104] = compat_sys_kexec_load,
[105] = sys_init_module,
[106] = sys_delete_module,
[107] = sys_timer_create, check 64-bit sigevent, maybe use compat
[108] = sys_timer_gettime, timespec
[109] = sys_timer_getoverrun,
[110] = sys_timer_settime, timespec
[111] = sys_timer_delete,
[112] = compat_sys_clock_settime,
[113] = compat_sys_clock_gettime,
[114] = sys_clock_getres, timespec
[115] = sys_clock_nanosleep, timespec (?)
[116] = sys_syslog,
[117] = sys_ptrace,
[118] = sys_sched_setparam,
[119] = sys_sched_setscheduler,
[120] = sys_sched_getscheduler,
[121] = sys_sched_getparam,
[122] = compat_sys_sched_setaffinity,
[123] = compat_sys_sched_getaffinity,
[124] = sys_sched_yield,
[125] = sys_sched_get_priority_max,
[126] = sys_sched_get_priority_min,
[127] = sys_sched_rr_get_interval, timespec
[128] = sys_restart_syscall,
[129] = sys_kill,
[130] = sys_tkill,
[131] = sys_tgkill,
[132] = sys_sigaltstack,
[133] = sys_rt_sigsuspend, takes sigset_t check BE
[134] = sys_rt_sigaction,
[135] = sys_rt_sigprocmask, takes sigset_t check BE
[136] = sys_rt_sigpending, takes sigset_t check BE
[137] = sys_rt_sigtimedwait, wrapper? 64-bit siginfo but
32-bit sigset and timespec
[138] = sys_rt_sigqueueinfo, this is OK (?)
[139] = sys_rt_sigreturn_wrapper,
[140] = sys_setpriority,
[141] = sys_getpriority,
[142] = sys_reboot,
[143] = sys_setregid,
[144] = sys_setgid,
[145] = sys_setreuid,
[146] = sys_setuid,
[147] = sys_setresuid,
[148] = sys_getresuid,
[149] = sys_setresgid,
[150] = sys_getresgid,
[151] = sys_setfsuid,
[152] = sys_setfsgid,
[153] = compat_sys_times,
[154] = sys_setpgid,
[155] = sys_getpgid,
[156] = sys_getsid,
[157] = sys_setsid,
[158] = sys_getgroups,
[159] = sys_setgroups,
[160] = sys_newuname,
[161] = sys_sethostname,
[162] = sys_setdomainname,
[163] = compat_sys_getrlimit,
[164] = compat_sys_setrlimit,
[165] = compat_sys_getrusage,
[166] = sys_umask,
[167] = sys_prctl,
[168] = sys_getcpu,
[169] = compat_sys_gettimeofday,
[170] = compat_sys_settimeofday,
[171] = compat_sys_adjtimex,
[172] = sys_getpid,
[173] = sys_getppid,
[174] = sys_getuid,
[175] = sys_geteuid,
[176] = sys_getgid,
[177] = sys_getegid,
[178] = sys_gettid,
[179] = compat_sys_sysinfo,
[180] = sys_mq_open, wrong struct mq_attr
[181] = sys_mq_unlink,
[182] = sys_mq_timedsend, wrong struct mq_attr
[183] = sys_mq_timedreceive, wrong struct mq_attr
[184] = sys_mq_notify,
[185] = sys_mq_getsetattr, wrong struct mq_attr
[186] = sys_msgget,
[187] = ilp32_sys_msgctl, as is, waiting for generic fix (?)
[188] = compat_sys_msgrcv,
[189] = compat_sys_msgsnd,
[190] = sys_semget,
[191] = ilp32_sys_semctl, as is, waiting for generic fix (?)
[192] = sys_semtimedop, timespec_t
[193] = sys_semop,
[194] = sys_shmget,
[195] = ilp32_sys_shmctl, as is, waiting for generic fix (?)
[196] = sys_shmat, check (shmat01 test fails if compat)
[197] = sys_shmdt,
[198] = sys_socket,
[199] = sys_socketpair,
[200] = sys_bind,
[201] = sys_listen,
[202] = sys_accept,
[203] = sys_connect,
[204] = sys_getsockname,
[205] = sys_getpeername,
[206] = sys_sendto,
[207] = compat_sys_recvfrom,
[208] = compat_sys_setsockopt,
[209] = compat_sys_getsockopt,
[210] = sys_shutdown,
[211] = compat_sys_sendmsg,
[212] = compat_sys_recvmsg,
[213] = sys_readahead,
[214] = sys_brk,
[215] = sys_munmap,
[216] = sys_mremap,
[217] = sys_add_key,
[218] = sys_request_key,
[219] = compat_sys_keyctl,
[220] = sys_clone,
[221] = compat_sys_execve,
[222] = compat_sys_mmap2_wrapper, check. maybe just mmap2
[223] = sys_fadvise64_64,
[224] = sys_swapon,
[225] = sys_swapoff,
[226] = sys_mprotect,
[227] = sys_msync,
[228] = sys_mlock,
[229] = sys_munlock,
[230] = sys_mlockall,
[231] = sys_munlockall,
[232] = sys_mincore,
[233] = sys_madvise,
[234] = sys_remap_file_pages,
[235] = compat_sys_mbind,
[236] = compat_sys_get_mempolicy,
[237] = compat_sys_set_mempolicy,
[238] = compat_sys_migrate_pages,
[239] = compat_sys_move_pages,
[240] = sys_rt_tgsigqueueinfo,
[241] = sys_perf_event_open,
[242] = sys_accept4,
[243] = compat_sys_recvmmsg,
[260] = compat_sys_wait4,
[261] = sys_prlimit64,
[262] = sys_fanotify_init,
[263] = sys_fanotify_mark,
[264] = sys_name_to_handle_at,
[265] = sys_open_by_handle_at, force O_LARGEFILE in asm-generic/unistd.h
make tile32 to use compat
[266] = sys_clock_adjtime, wrong timex structure
[267] = sys_syncfs,
[268] = sys_setns,
[269] = compat_sys_sendmmsg,
[270] = compat_sys_process_vm_readv,
[271] = compat_sys_process_vm_writev,
[272] = sys_kcmp,
[273] = sys_finit_module,
[274] = sys_sched_setattr,
[275] = sys_sched_getattr,
[276] = sys_renameat2,
[277] = sys_seccomp,
[278] = sys_getrandom,
[279] = sys_memfd_create,
[280] = sys_bpf,
[281] = sys_execveat, check: wrong struct user_arg_ptr
[282] = sys_userfaultfd,
[283] = sys_membarrier,

2015-12-01 09:21:08

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

Yury Norov <[email protected]> writes:

> There's a tricky bug with signal stack, that Andreas also discovered.

That was only a confusion about the compat state of sys_rt_sigaction.
It just requires making sure glibc uses the correct (64bit layout)
struct kernel_sigaction.

Andreas.

--
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

2015-12-01 10:23:02

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tuesday 01 December 2015 10:20:59 Andreas Schwab wrote:
> Yury Norov <[email protected]> writes:
>
> > There's a tricky bug with signal stack, that Andreas also discovered.
>
> That was only a confusion about the compat state of sys_rt_sigaction.
> It just requires making sure glibc uses the correct (64bit layout)
> struct kernel_sigaction.

I don't think we need to use the 64-bit version of sigaction, both
kernel and libc are simpler if we use the normal 32-bit version.

We should always default to using the generic 32-bit structures
unless there is a strong reason not to.

Arnd

2015-12-01 10:29:00

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tuesday 01 December 2015 03:40:09 Yury Norov wrote:
> On Mon, Nov 30, 2015 at 10:49:43PM +0100, Arnd Bergmann wrote:
> >
> > Could we try to get consensus on how the syscall ABI should look
> > before you start adapting glibc to another intermediate version?
> > I think that would also save you duplicate work, as it's always
> > possible that we misunderstand each other in the review. Also,
> > when someone asks you questions during a review, please reply to
> > those questions so we can get a common understanding of the facts
> > and document that in the mail archives.
> >
> > Arnd
>
> This is full syscall table for ILP32, how it looks right now.
> I collected all comments here and do rework according it.
> Any comments?

It might be easier to start the other way round: rather than
annotating the things that might be wrong, remove all the overrides
and add back only the 64-bit syscalls that we want instead of the
32-bit variants when you find that they are absolutely needed.

> [0] = compat_sys_io_setup,
> [1] = sys_io_destroy,
> [2] = compat_sys_io_submit,
> [3] = sys_io_cancel,
> [4] = sys_io_getevents, wrong timespec_t and aio_context_t here
> [5] = sys_setxattr,
> [6] = sys_lsetxattr,
> [7] = sys_fsetxattr,
> [8] = sys_getxattr,
> [9] = sys_lgetxattr,
> [10] = sys_fgetxattr,
> [11] = sys_listxattr,
> [12] = sys_llistxattr,
> [13] = sys_flistxattr,
> [14] = sys_removexattr,
> [15] = sys_lremovexattr,
> [16] = sys_fremovexattr,
> [17] = sys_getcwd,
> [18] = sys_lookup_dcookie,
> [19] = sys_eventfd2,
> [20] = sys_epoll_create1,
> [21] = sys_epoll_ctl,
> [22] = sys_epoll_pwait, way round: takes sigset_t check BE
> [23] = sys_dup,
> [24] = sys_dup3,
> [25] = compat_sys_fcntl, uses compat_off_t, not compat_loff_t
> [26] = sys_inotify_init1,
> [27] = sys_inotify_add_watch,

I was looking for your latest arch/arm64/kernel/sys_ilp32.c version. I'm
not that interested in the ones that are just using the normal compat API,
just the ones that you still think we have to override, and why that
override is required.

Arnd

2015-12-01 11:01:20

by Andreas Schwab

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

Arnd Bergmann <[email protected]> writes:

> On Tuesday 01 December 2015 10:20:59 Andreas Schwab wrote:
>> Yury Norov <[email protected]> writes:
>>
>> > There's a tricky bug with signal stack, that Andreas also discovered.
>>
>> That was only a confusion about the compat state of sys_rt_sigaction.
>> It just requires making sure glibc uses the correct (64bit layout)
>> struct kernel_sigaction.
>
> I don't think we need to use the 64-bit version of sigaction, both
> kernel and libc are simpler if we use the normal 32-bit version.

Since glibc has to do the conversion anyway (due to sigset_t), using the
64bit layout avoids a second conversion in the kernel.

> We should always default to using the generic 32-bit structures
> unless there is a strong reason not to.

The goal should be to avoid conversion layers where it makes sense.

Andreas.

--
Andreas Schwab, SUSE Labs, [email protected]
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

2015-12-01 11:31:59

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tuesday 01 December 2015 12:01:12 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > On Tuesday 01 December 2015 10:20:59 Andreas Schwab wrote:
> >> Yury Norov <[email protected]> writes:
> >>
> >> > There's a tricky bug with signal stack, that Andreas also discovered.
> >>
> >> That was only a confusion about the compat state of sys_rt_sigaction.
> >> It just requires making sure glibc uses the correct (64bit layout)
> >> struct kernel_sigaction.
> >
> > I don't think we need to use the 64-bit version of sigaction, both
> > kernel and libc are simpler if we use the normal 32-bit version.
>
> Since glibc has to do the conversion anyway (due to sigset_t), using the
> 64bit layout avoids a second conversion in the kernel.

I don't get the part about sigset_t. Why would glibc want to use the
64-bit layout? This one looks like one of the cases where we absolutely
want to use the 32-bit layout or otherwise get into big trouble if
we ever want to support native ILP32 kernels.

Arnd

2015-12-01 21:30:37

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

> > +#define compat_sys_shmat sys_shmat
>
> What's special about compat_sys_shmat?
>

It's about SHMLBA definition.
For aarch32 glibc defines it as (__getpagesize () << 2).
For ILP32 there's no definition, and so generic one is used: (__getpagesize ()).

In kernel, for ARM64, COMPAT_SHMLBA defined just as 0x4000. Both
compat and non-compat shmat syscalls pass identical arguments to
do_shmat, except shmlba. Effectively, library expects shmlba to
be 0x1000, as sys_shmat does. And compat_sys_shmat expects 0x4000.

I think, both kernel and library parts are to be fixed. In library
we'd use definition identical to ARM. For kernel we'd use compat
syscall.

My question. Why aarch64 defines COMPAT_SHMLBA as 0x4000? If there's
no specific reason for it, it looks like a bug, and we should
define it like in arch/arm:
#define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */

Maybe that's why AARCH32 is limited to 4K pages in config.

2015-12-01 22:40:36

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 02 December 2015 00:29:04 Yury Norov wrote:
> > > +#define compat_sys_shmat sys_shmat
> >
> > What's special about compat_sys_shmat?
> >
>
> It's about definition.
> For aarch32 glibc defines it as (__getpagesize () << 2).
> For ILP32 there's no definition, and so generic one is used: (__getpagesize ()).

Ok, got it.

> In kernel, for ARM64, COMPAT_SHMLBA defined just as 0x4000. Both
> compat and non-compat shmat syscalls pass identical arguments to
> do_shmat, except shmlba. Effectively, library expects shmlba to
> be 0x1000, as sys_shmat does. And compat_sys_shmat expects 0x4000.
>
> I think, both kernel and library parts are to be fixed. In library
> we'd use definition identical to ARM. For kernel we'd use compat
> syscall.

I'm not sure I understand this part. What changes specifically do we need?

It sounds like shmat is one of the cases we an override makes sense
and we should use sys_shmat with PAGE_SIZE for aarch64 ilp32 mode.

> My question. Why aarch64 defines COMPAT_SHMLBA as 0x4000? If there's
> no specific reason for it, it looks like a bug, and we should
> define it like in arch/arm:
> #define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */
>
> Maybe that's why AARCH32 is limited to 4K pages in config.

The reason why AARCH32 is limited to 4K pages is the alignment of
ELF sections, and with newer binutils versions, that is no longer
a problem, other than the bug you just found.

We normally assume that the page size on ARM is fixed to 4K, so
there might be user space that just hardcodes 16K SHMLBA rather
than using the glibc (__getpagesize () << 2) definition. Changing
the kernel would break those programs, but you can also argue that
they are already broken today.

Arnd

2015-12-01 23:35:44

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tue, Dec 01, 2015 at 11:39:42PM +0100, Arnd Bergmann wrote:
> On Wednesday 02 December 2015 00:29:04 Yury Norov wrote:
> > > > +#define compat_sys_shmat sys_shmat
> > >
> > > What's special about compat_sys_shmat?
> > >
> >
> > It's about definition.
> > For aarch32 glibc defines it as (__getpagesize () << 2).
> > For ILP32 there's no definition, and so generic one is used: (__getpagesize ()).
>
> Ok, got it.
>
> > In kernel, for ARM64, COMPAT_SHMLBA defined just as 0x4000. Both
> > compat and non-compat shmat syscalls pass identical arguments to
> > do_shmat, except shmlba. Effectively, library expects shmlba to
> > be 0x1000, as sys_shmat does. And compat_sys_shmat expects 0x4000.
> >
> > I think, both kernel and library parts are to be fixed. In library
> > we'd use definition identical to ARM. For kernel we'd use compat
> > syscall.
>
> I'm not sure I understand this part. What changes specifically do we need?
>

For kernel:

diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
index 4df608a..e368a55 100644
--- a/arch/arm64/include/asm/shmparam.h
+++ b/arch/arm64/include/asm/shmparam.h
@@ -21,7 +21,7 @@
* alignment value. Since we don't have aliasing D-caches, the rest of
* the time we can safely use PAGE_SIZE.
*/
-#define COMPAT_SHMLBA 0x4000
+#define COMPAT_SHMLBA (4 * PAGE_SIZE)

#include <asm-generic/shmparam.h>

diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index c5bc712..877bedf 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -42,15 +42,12 @@ asmlinkage long sys_rt_sigreturn_wrapper(void);
#define compat_sys_pwrite64 sys_pwrite64
#define compat_sys_readahead sys_readahead
#define compat_sys_rt_sigaction sys_rt_sigaction
-#define compat_sys_shmat sys_shmat
#define compat_sys_sync_file_range sys_sync_file_range
#define compat_sys_truncate64 sys_truncate
#define compat_sys_sigaltstack sys_sigaltstack

For library - just create a header in ilp32 directory that defines
SHMLBA exactly as arm: __getpagesize () << 2

> It sounds like shmat is one of the cases we an override makes sense
> and we should use sys_shmat with PAGE_SIZE for aarch64 ilp32 mode.
>

[...]

> We normally assume that the page size on ARM is fixed to 4K, so
> there might be user space that just hardcodes 16K SHMLBA

It means that we should use compat_sys_shmat because hardcoded
userspace may have a chance to work for 4K pages. If we'll use
sys_shmat (and so 4K SHMLBA), we'll definitely make hardcoded
userspace broken. Non-hardcoded userspace will work anyway.

We can describe in documentation that 4k pages are prefferable.

Yury

2015-12-02 00:25:41

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tue, Dec 01, 2015 at 12:30:56PM +0100, Arnd Bergmann wrote:
> On Tuesday 01 December 2015 12:01:12 Andreas Schwab wrote:
> > Arnd Bergmann <[email protected]> writes:
> >
> > > On Tuesday 01 December 2015 10:20:59 Andreas Schwab wrote:
> > >> Yury Norov <[email protected]> writes:
> > >>
> > >> > There's a tricky bug with signal stack, that Andreas also discovered.
> > >>
> > >> That was only a confusion about the compat state of sys_rt_sigaction.
> > >> It just requires making sure glibc uses the correct (64bit layout)
> > >> struct kernel_sigaction.
> > >
> > > I don't think we need to use the 64-bit version of sigaction, both
> > > kernel and libc are simpler if we use the normal 32-bit version.
> >
> > Since glibc has to do the conversion anyway (due to sigset_t), using the
> > 64bit layout avoids a second conversion in the kernel.
>
> I don't get the part about sigset_t. Why would glibc want to use the
> 64-bit layout? This one looks like one of the cases where we absolutely
> want to use the 32-bit layout or otherwise get into big trouble if
> we ever want to support native ILP32 kernels.
>
> Arnd

So, we drop patch #6, and use 32-bit layout for all signal structures.

Correct?

2015-12-02 08:38:08

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 02 December 2015 02:35:03 Yury Norov wrote:
> On Tue, Dec 01, 2015 at 11:39:42PM +0100, Arnd Bergmann wrote:
> > On Wednesday 02 December 2015 00:29:04 Yury Norov wrote:
> > I'm not sure I understand this part. What changes specifically do we need?
> >
>
> For kernel:
>
> diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
> index 4df608a..e368a55 100644
> --- a/arch/arm64/include/asm/shmparam.h
> +++ b/arch/arm64/include/asm/shmparam.h
> @@ -21,7 +21,7 @@
> * alignment value. Since we don't have aliasing D-caches, the rest of
> * the time we can safely use PAGE_SIZE.
> */
> -#define COMPAT_SHMLBA 0x4000
> +#define COMPAT_SHMLBA (4 * PAGE_SIZE)
>
> #include <asm-generic/shmparam.h>
>
> diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> index c5bc712..877bedf 100644
> --- a/arch/arm64/kernel/sys_ilp32.c
> +++ b/arch/arm64/kernel/sys_ilp32.c
> @@ -42,15 +42,12 @@ asmlinkage long sys_rt_sigreturn_wrapper(void);
> #define compat_sys_pwrite64 sys_pwrite64
> #define compat_sys_readahead sys_readahead
> #define compat_sys_rt_sigaction sys_rt_sigaction
> -#define compat_sys_shmat sys_shmat
> #define compat_sys_sync_file_range sys_sync_file_range
> #define compat_sys_truncate64 sys_truncate
> #define compat_sys_sigaltstack sys_sigaltstack
>
> For library - just create a header in ilp32 directory that defines
> SHMLBA exactly as arm: __getpagesize () << 2

I think we both reversed our positions here ;-)

The 4*PAGE_SIZE on ARM is an architecture specific oddity, I believe
to work around aliasing caches on ARMv6. As no other architecture does
this, we're probably better off not duplicating it for aarch64-ilp32
and just use sys_shmat as your v6 patch does.

> > It sounds like shmat is one of the cases we an override makes sense
> > and we should use sys_shmat with PAGE_SIZE for aarch64 ilp32 mode.
> >
>
> [...]
>
> > We normally assume that the page size on ARM is fixed to 4K, so
> > there might be user space that just hardcodes 16K SHMLBA
>
> It means that we should use compat_sys_shmat because hardcoded
> userspace may have a chance to work for 4K pages. If we'll use
> sys_shmat (and so 4K SHMLBA), we'll definitely make hardcoded
> userspace broken. Non-hardcoded userspace will work anyway.
>
> We can describe in documentation that 4k pages are prefferable.

The hardcoded user space would only apply to old source code that
specifically tries to adapt to what ARM does, but gets it wrong,
If we have source code that is converted from x86 or mips and
hardcodes anything, it's more likely to be the normal __getpagesize().

Arnd

2015-12-02 09:16:08

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wed, Dec 02, 2015 at 09:37:05AM +0100, Arnd Bergmann wrote:
> On Wednesday 02 December 2015 02:35:03 Yury Norov wrote:
> > On Tue, Dec 01, 2015 at 11:39:42PM +0100, Arnd Bergmann wrote:
> > > On Wednesday 02 December 2015 00:29:04 Yury Norov wrote:
> > > I'm not sure I understand this part. What changes specifically do we need?
> > >
> >
> > For kernel:
> >
> > diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
> > index 4df608a..e368a55 100644
> > --- a/arch/arm64/include/asm/shmparam.h
> > +++ b/arch/arm64/include/asm/shmparam.h
> > @@ -21,7 +21,7 @@
> > * alignment value. Since we don't have aliasing D-caches, the rest of
> > * the time we can safely use PAGE_SIZE.
> > */
> > -#define COMPAT_SHMLBA 0x4000
> > +#define COMPAT_SHMLBA (4 * PAGE_SIZE)
> >
> > #include <asm-generic/shmparam.h>
> >
> > diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
> > index c5bc712..877bedf 100644
> > --- a/arch/arm64/kernel/sys_ilp32.c
> > +++ b/arch/arm64/kernel/sys_ilp32.c
> > @@ -42,15 +42,12 @@ asmlinkage long sys_rt_sigreturn_wrapper(void);
> > #define compat_sys_pwrite64 sys_pwrite64
> > #define compat_sys_readahead sys_readahead
> > #define compat_sys_rt_sigaction sys_rt_sigaction
> > -#define compat_sys_shmat sys_shmat
> > #define compat_sys_sync_file_range sys_sync_file_range
> > #define compat_sys_truncate64 sys_truncate
> > #define compat_sys_sigaltstack sys_sigaltstack
> >
> > For library - just create a header in ilp32 directory that defines
> > SHMLBA exactly as arm: __getpagesize () << 2
>
> I think we both reversed our positions here ;-)
>
> The 4*PAGE_SIZE on ARM is an architecture specific oddity, I believe
> to work around aliasing caches on ARMv6. As no other architecture does
> this, we're probably better off not duplicating it for aarch64-ilp32
> and just use sys_shmat as your v6 patch does.
>
> > > It sounds like shmat is one of the cases we an override makes sense
> > > and we should use sys_shmat with PAGE_SIZE for aarch64 ilp32 mode.
> > >
> >
> > [...]
> >
> > > We normally assume that the page size on ARM is fixed to 4K, so
> > > there might be user space that just hardcodes 16K SHMLBA
> >
> > It means that we should use compat_sys_shmat because hardcoded
> > userspace may have a chance to work for 4K pages. If we'll use
> > sys_shmat (and so 4K SHMLBA), we'll definitely make hardcoded
> > userspace broken. Non-hardcoded userspace will work anyway.
> >
> > We can describe in documentation that 4k pages are prefferable.
>
> The hardcoded user space would only apply to old source code that
> specifically tries to adapt to what ARM does, but gets it wrong,
> If we have source code that is converted from x86 or mips and
> hardcodes anything, it's more likely to be the normal __getpagesize().
>
> Arnd

Hmm... OK. Let's have non-compat shmat here...

2015-12-02 10:02:37

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Tue, Nov 17, 2015 at 10:57:52PM +0100, Arnd Bergmann wrote:

It looks, all them are needed.

> > +asmlinkage long compat_sys_mmap2_wrapper(void);
> > +#define sys_mmap2 compat_sys_mmap2_wrapper

This wrapper checks alignement of pgoff, if page sise is greater than
4K

> > +asmlinkage long compat_sys_fstatfs64_wrapper(void);
> > +#define compat_sys_fstatfs64 compat_sys_fstatfs64_wrapper
> > +asmlinkage long compat_sys_statfs64_wrapper(void);
> > +#define compat_sys_statfs64 compat_sys_statfs64_wrapper

This two hacks fix an alignment issue. I didn't check all details but
it looks like sizeof(compat_statfs64) is different in kernel and library.
And this size is passed as 2nd argument to compat syscalls. We can
handle it in userspace but I don't see any advantage.

All this handlers are shared between ilp32 and aarch32.
This is best we came up, as it doesn't add new hacks, but reuses old
ones...

2015-12-02 10:05:13

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 02 December 2015 03:24:30 Yury Norov wrote:
> On Tue, Dec 01, 2015 at 12:30:56PM +0100, Arnd Bergmann wrote:
> > On Tuesday 01 December 2015 12:01:12 Andreas Schwab wrote:
> > > Arnd Bergmann <[email protected]> writes:
> > >
> > > > On Tuesday 01 December 2015 10:20:59 Andreas Schwab wrote:
> > > >> Yury Norov <[email protected]> writes:
> > > >>
> > > >> > There's a tricky bug with signal stack, that Andreas also discovered.
> > > >>
> > > >> That was only a confusion about the compat state of sys_rt_sigaction.
> > > >> It just requires making sure glibc uses the correct (64bit layout)
> > > >> struct kernel_sigaction.
> > > >
> > > > I don't think we need to use the 64-bit version of sigaction, both
> > > > kernel and libc are simpler if we use the normal 32-bit version.
> > >
> > > Since glibc has to do the conversion anyway (due to sigset_t), using the
> > > 64bit layout avoids a second conversion in the kernel.
> >
> > I don't get the part about sigset_t. Why would glibc want to use the
> > 64-bit layout? This one looks like one of the cases where we absolutely
> > want to use the 32-bit layout or otherwise get into big trouble if
> > we ever want to support native ILP32 kernels.
> >
> > Arnd
>
> So, we drop patch #6, and use 32-bit layout for all signal structures.
>
> Correct?

If the 32-bit layout is sane, yes. Andrew can surely judge this better
than I can. The goal should be to have the most straightforward
implementation for both kernel and libc, and reuse either the compat
signal handling or the native one as much as we can.

Looking at the API, I find that ARM fortunately uses all the standard
definitions for sigset_t, struct siginfo/siginfo_t, union sigval/sigval_t,
struct sigaction, struct sigaltstack/stack_t. It took me a while to
figure out that the definitions in the uapi headers are different but
actually unused (probably remaining from libc5 days or earlier).
The signal numbers are all the same, and so are the

The SA_* flags are all the same too, except for SA_THIRTYTWO, but
that is not implemented by the compat handling because we do not
support 26 bit tasks anyway.

struct sigcontext is obviously different because of the changed
register set, and we will have to deal with that in some form in the
compat code. struct ucontext and struct rt_sigframe includes that,
which I assume is the main part we need to handle correctly
by having ilp32 specific setup_rt_frame/sys_rt_sigreturn functions.

One small difference is the handling of MINSIGSTKSZ, which would
currently work for ilp32, but I noticed that commit c9692657c032
("arm64: Fix MINSIGSTKSZ and SIGSTKSZ") from Manjeet Pawar broke
compat mode: Any 32-bit (aarch32) task that passes an altstack smaller
than 5120 bytes now gets rejected by the kernel, whereas the native
32-bit kernel checks for 2048 bytes instead. We need to fix the
existing compat case here without breaking the ilp32 case.

With all that said, I would assume that just having separate
sigcontext/ucontext/rt_sigframe and reusing the compat code otherwise,
we are overall better off than with using the native 64-bit signal
handling with everything that ties in (waitid, epoll_pwait,
signalfd, ppoll, ...), but we can discuss this further if someone
sees major downsides of that compared to your existing approach.
In particular, I don't know what the difference means for gdb,
glibc or strace.


Arnd

2015-12-02 10:36:09

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wed, Dec 02, 2015 at 09:37:05AM +0100, Arnd Bergmann wrote:
> The 4*PAGE_SIZE on ARM is an architecture specific oddity, I believe
> to work around aliasing caches on ARMv6. As no other architecture does
> this, we're probably better off not duplicating it for aarch64-ilp32
> and just use sys_shmat as your v6 patch does.
> Arnd

If you feel ARMv6 fix for caches will come soon, just ignore it.
Otherwise, please pull it because compat_sys_shmat is broken now
for 64K pages.

Signed-off-by: Yury Norov <[email protected]>
---
arch/arm64/include/asm/shmparam.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
index 4df608a..e368a55 100644
--- a/arch/arm64/include/asm/shmparam.h
+++ b/arch/arm64/include/asm/shmparam.h
@@ -21,7 +21,7 @@
* alignment value. Since we don't have aliasing D-caches, the rest of
* the time we can safely use PAGE_SIZE.
*/
-#define COMPAT_SHMLBA 0x4000
+#define COMPAT_SHMLBA (4 * PAGE_SIZE)

#include <asm-generic/shmparam.h>

--
2.5.0

2015-12-02 11:04:53

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 02 December 2015 13:01:53 Yury Norov wrote:
> On Tue, Nov 17, 2015 at 10:57:52PM +0100, Arnd Bergmann wrote:
>
> It looks, all them are needed.
>
> > > +asmlinkage long compat_sys_mmap2_wrapper(void);
> > > +#define sys_mmap2 compat_sys_mmap2_wrapper
>
> This wrapper checks alignement of pgoff, if page sise is greater than
> 4K

Ok.

> > > +asmlinkage long compat_sys_fstatfs64_wrapper(void);
> > > +#define compat_sys_fstatfs64 compat_sys_fstatfs64_wrapper
> > > +asmlinkage long compat_sys_statfs64_wrapper(void);
> > > +#define compat_sys_statfs64 compat_sys_statfs64_wrapper
>
> This two hacks fix an alignment issue. I didn't check all details but
> it looks like sizeof(compat_statfs64) is different in kernel and library.
> And this size is passed as 2nd argument to compat syscalls. We can
> handle it in userspace but I don't see any advantage.

Ah, so it's a hack for OABI compatibility. I wonder if we can just
drop the wrapper and the ARCH_PACK_COMPAT_STATFS64 definition
on arm64 as we don't handle OABI user space anyway.

Maybe it's too risky, when there is someone that added the packing
in user space on EABI after all.

> All this handlers are shared between ilp32 and aarch32.
> This is best we came up, as it doesn't add new hacks, but reuses old
> ones...

Ok.

Arnd

2015-12-02 13:47:32

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 02 December 2015 13:35:22 Yury Norov wrote:
> On Wed, Dec 02, 2015 at 09:37:05AM +0100, Arnd Bergmann wrote:
> > The 4*PAGE_SIZE on ARM is an architecture specific oddity, I believe
> > to work around aliasing caches on ARMv6. As no other architecture does
> > this, we're probably better off not duplicating it for aarch64-ilp32
> > and just use sys_shmat as your v6 patch does.
> > Arnd
>
> If you feel ARMv6 fix for caches will come soon, just ignore it.
> Otherwise, please pull it because compat_sys_shmat is broken now
> for 64K pages.
>
> Signed-off-by: Yury Norov <[email protected]>
>

Sounds good. Will, do you want to take this for the arm64 tree.

Acked-by: Arnd Bergmann <[email protected]>

2015-12-02 13:55:19

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wednesday 02 December 2015 14:46:32 Arnd Bergmann wrote:
> On Wednesday 02 December 2015 13:35:22 Yury Norov wrote:
> > On Wed, Dec 02, 2015 at 09:37:05AM +0100, Arnd Bergmann wrote:
> > > The 4*PAGE_SIZE on ARM is an architecture specific oddity, I believe
> > > to work around aliasing caches on ARMv6. As no other architecture does
> > > this, we're probably better off not duplicating it for aarch64-ilp32
> > > and just use sys_shmat as your v6 patch does.
> > > Arnd
> >
> > If you feel ARMv6 fix for caches will come soon, just ignore it.
> > Otherwise, please pull it because compat_sys_shmat is broken now
> > for 64K pages.
> >
> > Signed-off-by: Yury Norov <[email protected]>
> >
>
> Sounds good. Will, do you want to take this for the arm64 tree.
>
> Acked-by: Arnd Bergmann <[email protected]>

(actually Cc Will Deacon)

Will or Catalin, does this look ok to you?

8<----
Subject: fix COMPAT_SHMLBA definition for large pages
From: Yury Norov <[email protected]>

ARM glibc uses (4 * __getpagesize()) for SHMLBA, which is correct for 4KB pages
and works fine for 64KB pages, but the kernel uses a hardcoded 16KB that
is too small for 64KB page based kernels. This changes the definition to
what user space sees when using 64KB pages.

Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Arnd Bergmann <[email protected]>
---
arch/arm64/include/asm/shmparam.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/shmparam.h b/arch/arm64/include/asm/shmparam.h
index 4df608a..e368a55 100644
--- a/arch/arm64/include/asm/shmparam.h
+++ b/arch/arm64/include/asm/shmparam.h
@@ -21,7 +21,7 @@
* alignment value. Since we don't have aliasing D-caches, the rest of
* the time we can safely use PAGE_SIZE.
*/
-#define COMPAT_SHMLBA 0x4000
+#define COMPAT_SHMLBA (4 * PAGE_SIZE)

#include <asm-generic/shmparam.h>

--

2015-12-02 13:58:02

by Will Deacon

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wed, Dec 02, 2015 at 02:54:18PM +0100, Arnd Bergmann wrote:
> On Wednesday 02 December 2015 14:46:32 Arnd Bergmann wrote:
> > On Wednesday 02 December 2015 13:35:22 Yury Norov wrote:
> > > On Wed, Dec 02, 2015 at 09:37:05AM +0100, Arnd Bergmann wrote:
> > > > The 4*PAGE_SIZE on ARM is an architecture specific oddity, I believe
> > > > to work around aliasing caches on ARMv6. As no other architecture does
> > > > this, we're probably better off not duplicating it for aarch64-ilp32
> > > > and just use sys_shmat as your v6 patch does.
> > > > Arnd
> > >
> > > If you feel ARMv6 fix for caches will come soon, just ignore it.
> > > Otherwise, please pull it because compat_sys_shmat is broken now
> > > for 64K pages.
> > >
> > > Signed-off-by: Yury Norov <[email protected]>
> > >
> >
> > Sounds good. Will, do you want to take this for the arm64 tree.
> >
> > Acked-by: Arnd Bergmann <[email protected]>
>
> (actually Cc Will Deacon)
>
> Will or Catalin, does this look ok to you?

Looks ok on the face of it (although I haven't tried compat w/ 64k pages).

I'll take it via the arm64 tree with your ack.

Cheers,

Will

2015-12-03 11:32:06

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 05/19] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64

On Wed, Nov 18, 2015 at 12:16:45AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h
> index fce9c29..4265243 100644
> --- a/arch/arm64/include/uapi/asm/bitsperlong.h
> +++ b/arch/arm64/include/uapi/asm/bitsperlong.h
> @@ -16,7 +16,14 @@
> #ifndef __ASM_BITSPERLONG_H
> #define __ASM_BITSPERLONG_H
>
> -#define __BITS_PER_LONG 64
> +#if defined(__LP64__)
> +/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */
> +# define __BITS_PER_LONG 64
> +#elif defined(__ILP32__)
> +# define __BITS_PER_LONG 32
> +#else
> +# error "Neither LP64 nor ILP32: unsupported ABI in asm/bitsperlong.h"
> +#endif

Quick question: IIRC, earlier aarch64 gcc versions did not generate
__ILP32__ when -mabi=ilp32, they only removed __LP64__. When did the
change happen? Could we assume that all compiler versions used to
generate ILP32 would define this?

--
Catalin

2015-12-03 11:36:58

by Philipp Tomsich

[permalink] [raw]
Subject: Re: [PATCH v6 05/19] arm64:uapi: set __BITS_PER_LONG correctly for ILP32 and LP64

Catalin,

> Quick question: IIRC, earlier aarch64 gcc versions did not generate
> __ILP32__ when -mabi=ilp32, they only removed __LP64__. When did the
> change happen? Could we assume that all compiler versions used to
> generate ILP32 would define this?

The __ILP32__ define has been supported since
> commit b01b37f5768911598640cf8a8c82beacb4200c13
> Author: yufeng <yufeng@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date: Tue Jul 23 12:26:33 2013 +0000
>
> [AArch64, ILP32] 4/6 Define _ILP32 and __ILP32__.
>
> gcc/
>
> * config/aarch64/aarch64.h (TARGET_CPU_CPP_BUILTINS): Define _ILP32
> and __ILP32__ when the ILP32 model is in use.
>
>
> git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201167 138bc75d-0d04-0410-961f-82ee72b054a4

Best regards,
Philipp.-

2015-12-03 12:02:34

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 04/19] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead

On Wed, Nov 18, 2015 at 12:16:44AM +0300, Yury Norov wrote:
> From: Andrew Pinski <[email protected]>
>
> Reviewed-by: David Daney <[email protected]>
>
> Signed-off-by: Philipp Tomsich <[email protected]>
> Signed-off-by: Christoph Muellner <[email protected]>
> Signed-off-by: Yury Norov <[email protected]>
> Signed-off-by: Andrew Pinski <[email protected]>

Please add a long description to every patch, even if it is trivial.

And a nitpick: remove the empty lines between Reviewed-by and
Signed-off-by. These tags usually come in the same block.

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

Do you need these definitions here? I guess they may be used later by
the ILP32 code paths but for A32 compat they don't make much sense (I
haven't made it to the end of the series yet).

--
Catalin

2015-12-03 12:13:11

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 07/19] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)

On Wed, Nov 18, 2015 at 12:16:47AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index 7fbed69..9700e5e 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -299,19 +299,44 @@ struct compat_shmid64_ds {
> compat_ulong_t __unused5;
> };
>
> -static inline int is_compat_task(void)
> +#ifdef CONFIG_AARCH32_EL0
> +
> +static inline int is_a32_compat_task(void)
> {
> return test_thread_flag(TIF_32BIT);
> }
>
> -static inline int is_compat_thread(struct thread_info *thread)
> +static inline int is_a32_compat_thread(struct thread_info *thread)
> {
> return test_ti_thread_flag(thread, TIF_32BIT);
> }
>
> +#else
> +
> +static inline int is_a32_compat_task(void)
> +{
> + return 0;
> +}
> +
> +static inline int is_a32_compat_thread(struct thread_info *thread)
> +{
> + return 0;
> +}
> +#endif
> +
> +static inline int is_compat_task(void)
> +{
> + return is_a32_compat_task();
> +}
> +
> #else /* !CONFIG_COMPAT */
>
> -static inline int is_compat_thread(struct thread_info *thread)
> +static inline int is_a32_compat_thread(struct thread_info *thread)
> +{
> + return 0;
> +}
> +
> +static inline int is_a32_compat_task(void)
> {
> return 0;
> }

My main worry with this patch is a potential #include mess. I can see
that you already had to include asm/compat.h explicitly in
hw_breakpoint.c even though linux/compat.h was already included. In
subsequent files (asm/elf.h, asm/memory.h) you check is_compat_task()
without explicitly including asm/compat.h and hope that it won't break.

A solution would be to add these functions in a separate header file
that gets included where needed (also by asm/compat.h).

--
Catalin

2015-12-03 12:21:03

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 10/19] arm64:ilp32 use the native LP64 'start_thread' for ILP32 threads

On Wed, Nov 18, 2015 at 12:16:50AM +0300, Yury Norov wrote:
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -28,6 +28,7 @@
> #ifdef __KERNEL__
>
> #include <linux/string.h>
> +#include <linux/thread_info.h>
>
> #include <asm/fpsimd.h>
> #include <asm/hw_breakpoint.h>
> @@ -123,6 +124,15 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc,
> static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
> unsigned long sp)
> {
> +#ifdef CONFIG_ARM64_ILP32
> + /* ILP32 thread are started the same way as LP64 threads.
> + Note we cannot use is_ilp32_compat_task here as that
> + would introduce a header depency issue. */
> + if (test_thread_flag(TIF_32BIT_AARCH64)) {
> + start_thread(regs, pc, sp);
> + return;
> + }

Nitpicks: use IS_ENABLED(CONFIG_ARM64_ILP32) instead of #ifdef. Also
follow the coding style for multi-line comments:

/*
* .....
* .....
*/

--
Catalin

2015-12-03 16:40:07

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 11/19] arm64:ilp32: support core dump generation for ILP32

On Wed, Nov 18, 2015 at 12:16:51AM +0300, Yury Norov wrote:
> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index 01e032c..8f13dac 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -134,7 +134,11 @@ typedef struct user_fpsimd_state elf_fpregset_t;
[...]
> @@ -179,24 +186,80 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG];
> ((x)->e_flags & EF_ARM_EABI_MASK))
>
> #define compat_start_thread compat_start_thread
> -#define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT);
> -#define COMPAT_ARCH_DLINFO
> -extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
> - int uses_interp);
> -#define compat_arch_setup_additional_pages \
> - aarch32_setup_vectors_page
> +#define COMPAT_A32_SET_PERSONALITY(ex) \
> +do { \
> + clear_thread_flag(TIF_32BIT_AARCH64); \
> + set_thread_flag(TIF_32BIT); \
> +} while (0)
> +#define COMPAT_A32_ARCH_DLINFO do {} while (0)
>
> #else
>
> typedef elf_greg_t compat_elf_greg_t;
> typedef elf_gregset_t compat_elf_gregset_t;
> #define compat_a32_elf_check_arch(x) 0
> -#define COMPAT_SET_PERSONALITY(ex)
> -#define COMPAT_ARCH_DLINFO
> +#define COMPAT_A32_SET_PERSONALITY(ex) do {} while (0)
> +#define COMPAT_A32_ARCH_DLINFO do {} while (0)
> +#endif
> +
> +/* If ILP32 is turned on, we want to define the compat_elf_greg_t to the non compat
> + one and define PR_REG_SIZE/PRSTATUS_SIZE/SET_PR_FPVALID so we pick up the correct
> + ones for AARCH32. Note also the definition of the macros have to be correct for
> + LP64 as this file is included in the standard binfmt_elf.c. */
> +#ifdef CONFIG_ARM64_ILP32
> +typedef elf_greg_t compat_elf_greg_t;
> +typedef elf_gregset_t compat_elf_gregset_t;
> +#define PR_REG_SIZE(S) (is_a32_compat_task() ? 72 : 272)
> +#define PRSTATUS_SIZE(S) (is_a32_compat_task() ? 124 : (is_ilp32_compat_task() ? 352 : 392))

Can you be more specific about these numbers, what they represent, how
they are calculated? Can you not use some sizeof()?

> +#define SET_PR_FPVALID(S, V) \
> +do { \
> + *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE((S)->pr_reg)) = (V); \
> +} while (0)
> +#else
> +typedef compat_a32_elf_greg_t compat_elf_greg_t;
> +typedef compat_a32_elf_gregset_t compat_elf_gregset_t;
> +#endif
>
> +#ifdef CONFIG_ARM64_ILP32
> +#define compat_ilp32_elf_check_arch(x) ((x)->e_machine == EM_AARCH64)
> +#define COMPAT_ILP32_SET_PERSONALITY(ex) \
> +do { \
> + set_thread_flag(TIF_32BIT_AARCH64); \
> + clear_thread_flag(TIF_32BIT); \
> +} while (0)
> +#define COMPAT_ILP32_ARCH_DLINFO \
> +do { \
> + NEW_AUX_ENT(AT_SYSINFO_EHDR, \
> + (elf_addr_t)(long)current->mm->context.vdso); \
> +} while (0)
> +#else
> +#define compat_ilp32_elf_check_arch(x) 0
> +#define COMPAT_ILP32_SET_PERSONALITY(ex) do {} while (0)
> +#define COMPAT_ILP32_ARCH_DLINFO do {} while (0)
> #endif
>
> -#define compat_elf_check_arch(x) compat_a32_elf_check_arch(x)
> +#define compat_elf_check_arch(x) (compat_a32_elf_check_arch(x) || compat_ilp32_elf_check_arch(x))
> +#define COMPAT_SET_PERSONALITY(ex) \
> +do { \
> + if (compat_a32_elf_check_arch(&ex)) \
> + COMPAT_A32_SET_PERSONALITY(ex); \
> + else \
> + COMPAT_ILP32_SET_PERSONALITY(ex); \
> +} while (0)
> +
> +/* ILP32 uses the "LP64-like" vdso pages */
> +#define compat_arch_setup_additional_pages \
> + (is_a32_compat_task() \
> + ? &aarch32_setup_vectors_page \
> + : &(arch_setup_additional_pages))

I thought vdso is not yet supported for ILP32. Do you still want to
insert the special mapping?

BTW, what do you do for sigreturn? It's handled by the vdso code on
AArch64.

> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index 26352a6..b239b9b 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -107,6 +107,14 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
>
> return PTR_ERR_OR_ZERO(ret);
> }
> +#else
> +int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
> +{
> + (void) bprm;
> + (void) uses_interp;

Do you get a warning for unused function arguments?

> +
> + return -EINVAL;
> +}

A BUG() would be useful here.

Alternatively, you can define this aarch32_setup_vectors_page as NULL
when !AARCH32_EL0.

--
Catalin

2015-12-03 17:17:39

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wed, Dec 02, 2015 at 03:24:30AM +0300, Yury Norov wrote:
> On Tue, Dec 01, 2015 at 12:30:56PM +0100, Arnd Bergmann wrote:
> > On Tuesday 01 December 2015 12:01:12 Andreas Schwab wrote:
> > > Arnd Bergmann <[email protected]> writes:
> > >
> > > > On Tuesday 01 December 2015 10:20:59 Andreas Schwab wrote:
> > > >> Yury Norov <[email protected]> writes:
> > > >>
> > > >> > There's a tricky bug with signal stack, that Andreas also discovered.
> > > >>
> > > >> That was only a confusion about the compat state of sys_rt_sigaction.
> > > >> It just requires making sure glibc uses the correct (64bit layout)
> > > >> struct kernel_sigaction.
> > > >
> > > > I don't think we need to use the 64-bit version of sigaction, both
> > > > kernel and libc are simpler if we use the normal 32-bit version.
> > >
> > > Since glibc has to do the conversion anyway (due to sigset_t), using the
> > > 64bit layout avoids a second conversion in the kernel.
> >
> > I don't get the part about sigset_t. Why would glibc want to use the
> > 64-bit layout? This one looks like one of the cases where we absolutely
> > want to use the 32-bit layout or otherwise get into big trouble if
> > we ever want to support native ILP32 kernels.
> >
> > Arnd
>
> So, we drop patch #6, and use 32-bit layout for all signal structures.
>
> Correct?

I would vote for this as well. I think it probably removes patch 12 as
well (COMPAT_USE_NATIVE_SIGINFO).

--
Catalin

2015-12-03 17:47:16

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Wed, Dec 02, 2015 at 12:29:04AM +0300, Yury Norov wrote:
> My question. Why aarch64 defines COMPAT_SHMLBA as 0x4000?

This was done to match the arch/arm value of 4 * 4K. The historical
32-bit reason for 4 pages is to cope with aliasing VIPT caches (see
https://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit?id=4197692eef113eeb8e3e413cc70993a5e667e5b8)

> If there's
> no specific reason for it, it looks like a bug, and we should
> define it like in arch/arm:
> #define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */

I guess you meant COMPAT_SHMLBA. I'm not sure there is much value in
keeping 4*PAGE_SIZE for larger page sizes but I agree that the current
16K value doesn't work well with 64K pages.

--
Catalin

2015-12-03 18:00:06

by Catalin Marinas

[permalink] [raw]
Subject: Re: [RFC2 PATCH v6 00/19] ILP32 for ARM64

On Wed, Nov 18, 2015 at 12:16:40AM +0300, Yury Norov wrote:
> - ILP32 VDSO code excluded. It's not mandatory, and caused questions
> during review process. We definitely make sure we will follow up
> with a VDSO later on because it is needed for performance reasons;

I already asked in one of the patches, don't you need a VDSO for
sigreturn?

> The full regression table is:
> ILP32 LP64
>
> float_bessel FAIL 134 PASSED 0
> float_exp_log FAIL 134 PASSED 0
> float_iperb FAIL 134 PASSED 0
> float_power FAIL 134 PASSED 0
> float_trigo FAIL 134 PASSED 0
> abort01 FAIL 2 FAIL 2
> fcntl14 FAIL 2 FAIL 2
> kill11 FAIL 2 FAIL 2
> mmap16 FAIL 6 PASSED 0
> open12 FAIL 2 PASSED 0
> pause01 PASSED 0 FAIL 9
> pipe07 FAIL 2 PASSED 0
> readdir01 FAIL 1 PASSED 0
> rename11 FAIL 2 PASSED 0
> rmdir02 FAIL 2 PASSED 0
> setregid02 FAIL 1 FAIL 1
> settimeofday01 FAIL 1 FAIL 1
> umount2_01 FAIL 2 PASSED 0
> umount2_02 FAIL 2 PASSED 0
> umount2_03 FAIL 2 PASSED 0
> utime06 FAIL 2 PASSED 0

Have you run any AArch32 LTP with these patches? The results should also
be included in your table above.

--
Catalin

2015-12-03 18:15:43

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Thu, Dec 03, 2015 at 05:47:08PM +0000, Catalin Marinas wrote:
> On Wed, Dec 02, 2015 at 12:29:04AM +0300, Yury Norov wrote:
> > My question. Why aarch64 defines COMPAT_SHMLBA as 0x4000?
>
> This was done to match the arch/arm value of 4 * 4K. The historical
> 32-bit reason for 4 pages is to cope with aliasing VIPT caches (see
> https://git.kernel.org/cgit/linux/kernel/git/tglx/history.git/commit?id=4197692eef113eeb8e3e413cc70993a5e667e5b8)
>
> > If there's
> > no specific reason for it, it looks like a bug, and we should
> > define it like in arch/arm:
> > #define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */
>
> I guess you meant COMPAT_SHMLBA.

I citated arm code here. In aarch64 it's COMPAT_SHMLBA, of course.

> I'm not sure there is much value in
> keeping 4*PAGE_SIZE for larger page sizes but I agree that the current
> 16K value doesn't work well with 64K pages.

Arnd told there will be a workaround for arm v6 caches. Than this
header will not be needed at all. Until that, this is simpliest
fix as it doesn't affect userspace.

>
> --
> Catalin

2015-12-03 20:43:19

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 14/19] arm64:ilp32: add sys_ilp32.c and a separate table (in entry.S) to use it

On Thursday 03 December 2015 21:14:41 Yury Norov wrote:
>
> > I'm not sure there is much value in
> > keeping 4*PAGE_SIZE for larger page sizes but I agree that the current
> > 16K value doesn't work well with 64K pages.
>
> Arnd told there will be a workaround for arm v6 caches. Than this
> header will not be needed at all. Until that, this is simpliest
> fix as it doesn't affect userspace.

I think we should do whatever matches user space: There is no harm
in going to 256KB instead of 64KB if current glibc already uses
4*getpagetsize() for a kernel with native 64K pages.

Arnd

2015-12-04 15:38:34

by Yury Norov

[permalink] [raw]
Subject: Re: [RFC2 PATCH v6 00/19] ILP32 for ARM64

On Thu, Dec 03, 2015 at 05:59:55PM +0000, Catalin Marinas wrote:
> On Wed, Nov 18, 2015 at 12:16:40AM +0300, Yury Norov wrote:
> > - ILP32 VDSO code excluded. It's not mandatory, and caused questions
> > during review process. We definitely make sure we will follow up
> > with a VDSO later on because it is needed for performance reasons;
>
> I already asked in one of the patches, don't you need a VDSO for
> sigreturn?
>

I didn't realise it's mandatory for ARMv8 when removed it. I'll back
it, but I think rework required anyway.

>
> Have you run any AArch32 LTP with these patches? The results should also
> be included in your table above.
>

The full regression table is:
ILP32 LP64 AARCH32 (v4.3 & v4.3 + ILP32)

float_bessel FAIL 134 PASSED 0 PASSED 0
float_exp_log FAIL 134 PASSED 0 PASSED 0
float_iperb FAIL 134 PASSED 0 PASSED 0
float_power FAIL 134 PASSED 0 PASSED 0
float_trigo FAIL 134 PASSED 0 PASSED 0
abort01 FAIL 2 FAIL 2 FAIL 2
fcntl14 FAIL 2 FAIL 2 PASSED 0
kill11 FAIL 2 FAIL 2 FAIL 2
mmap16 FAIL 6 PASSED 0 PASSED 0
open12 FAIL 2 PASSED 0 PASSED 0
pause01 PASSED 0 FAIL 9 FAIL 9
pipe07 FAIL 2 PASSED 0 PASSED 0
readdir01 FAIL 1 PASSED 0 PASSED 0
rename11 FAIL 2 PASSED 0 PASSED 0
rmdir02 FAIL 2 PASSED 0 PASSED 0
setregid02 FAIL 1 FAIL 1 PASSED 0
settimeofday01 FAIL 1 FAIL 1 FAIL 5
umount2_01 FAIL 2 PASSED 0 PASSED 0
umount2_02 FAIL 2 PASSED 0 PASSED 0
umount2_03 FAIL 2 PASSED 0 PASSED 0
utime06 FAIL 2 PASSED 0 PASSED 0

Fortunately, there's no aarch32 regression. Note that pause01 and
setregid02 are not stable.

2015-12-04 17:06:58

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 07/19] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)

On Thu, Dec 03, 2015 at 12:13:03PM +0000, Catalin Marinas wrote:
> On Wed, Nov 18, 2015 at 12:16:47AM +0300, Yury Norov wrote:
> > diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> > index 7fbed69..9700e5e 100644
> > --- a/arch/arm64/include/asm/compat.h
> > +++ b/arch/arm64/include/asm/compat.h
> > @@ -299,19 +299,44 @@ struct compat_shmid64_ds {
> > compat_ulong_t __unused5;
> > };
> >
> > -static inline int is_compat_task(void)
> > +#ifdef CONFIG_AARCH32_EL0
> > +
> > +static inline int is_a32_compat_task(void)
> > {
> > return test_thread_flag(TIF_32BIT);
> > }
> >
> > -static inline int is_compat_thread(struct thread_info *thread)
> > +static inline int is_a32_compat_thread(struct thread_info *thread)
> > {
> > return test_ti_thread_flag(thread, TIF_32BIT);
> > }
> >
> > +#else
> > +
> > +static inline int is_a32_compat_task(void)
> > +{
> > + return 0;
> > +}
> > +
> > +static inline int is_a32_compat_thread(struct thread_info *thread)
> > +{
> > + return 0;
> > +}
> > +#endif
> > +
> > +static inline int is_compat_task(void)
> > +{
> > + return is_a32_compat_task();
> > +}
> > +
> > #else /* !CONFIG_COMPAT */
> >
> > -static inline int is_compat_thread(struct thread_info *thread)
> > +static inline int is_a32_compat_thread(struct thread_info *thread)
> > +{
> > + return 0;
> > +}
> > +
> > +static inline int is_a32_compat_task(void)
> > {
> > return 0;
> > }
>
> My main worry with this patch is a potential #include mess. I can see
> that you already had to include asm/compat.h explicitly in
> hw_breakpoint.c even though linux/compat.h was already included. In
> subsequent files (asm/elf.h, asm/memory.h) you check is_compat_task()
> without explicitly including asm/compat.h and hope that it won't break.
>
> A solution would be to add these functions in a separate header file
> that gets included where needed (also by asm/compat.h).

Thank you for pointing that. I don't see big advantage in moving that
to new file, only if you insist. What about just fixing that mess?

2015-12-04 17:19:04

by Catalin Marinas

[permalink] [raw]
Subject: Re: [RFC2 PATCH v6 00/19] ILP32 for ARM64

On Fri, Dec 04, 2015 at 06:35:50PM +0300, Yury Norov wrote:
> On Thu, Dec 03, 2015 at 05:59:55PM +0000, Catalin Marinas wrote:
> > On Wed, Nov 18, 2015 at 12:16:40AM +0300, Yury Norov wrote:
> > > - ILP32 VDSO code excluded. It's not mandatory, and caused questions
> > > during review process. We definitely make sure we will follow up
> > > with a VDSO later on because it is needed for performance reasons;
> >
> > I already asked in one of the patches, don't you need a VDSO for
> > sigreturn?
>
> I didn't realise it's mandatory for ARMv8 when removed it. I'll back
> it, but I think rework required anyway.

The alternative is to use SA_RESTORER but AFAIK, its use has been
deprecated. I don't know what aarch64 glibc does if it doesn't have a
vdso.

--
Catalin

2015-12-04 21:59:35

by Yury Norov

[permalink] [raw]
Subject: Re: [PATCH v6 04/19] arm64: change some CONFIG_COMPAT over to use CONFIG_AARCH32_EL0 instead

On Thu, Dec 03, 2015 at 12:02:27PM +0000, Catalin Marinas wrote:
> On Wed, Nov 18, 2015 at 12:16:44AM +0300, Yury Norov wrote:
> > From: Andrew Pinski <[email protected]>
> >
> > Reviewed-by: David Daney <[email protected]>
> >
> > Signed-off-by: Philipp Tomsich <[email protected]>
> > Signed-off-by: Christoph Muellner <[email protected]>
> > Signed-off-by: Yury Norov <[email protected]>
> > Signed-off-by: Andrew Pinski <[email protected]>
>
> Please add a long description to every patch, even if it is trivial.
>
> And a nitpick: remove the empty lines between Reviewed-by and
> Signed-off-by. These tags usually come in the same block.
>
> > +#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
>
> Do you need these definitions here? I guess they may be used later by
> the ILP32 code paths but for A32 compat they don't make much sense (I
> haven't made it to the end of the series yet).
>

It should have been attached to patch "support core dump generation for
ILP32". I'll fix.

> --
> Catalin

2015-12-05 11:00:38

by Catalin Marinas

[permalink] [raw]
Subject: Re: [PATCH v6 07/19] arm64: introduce is_a32_task and is_a32_thread (for AArch32 compat)

On Fri, Dec 04, 2015 at 08:05:23PM +0300, Yury Norov wrote:
> On Thu, Dec 03, 2015 at 12:13:03PM +0000, Catalin Marinas wrote:
> > On Wed, Nov 18, 2015 at 12:16:47AM +0300, Yury Norov wrote:
> > > diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> > > index 7fbed69..9700e5e 100644
> > > --- a/arch/arm64/include/asm/compat.h
> > > +++ b/arch/arm64/include/asm/compat.h
> > > @@ -299,19 +299,44 @@ struct compat_shmid64_ds {
> > > compat_ulong_t __unused5;
> > > };
> > >
> > > -static inline int is_compat_task(void)
> > > +#ifdef CONFIG_AARCH32_EL0
> > > +
> > > +static inline int is_a32_compat_task(void)
> > > {
> > > return test_thread_flag(TIF_32BIT);
> > > }
> > >
> > > -static inline int is_compat_thread(struct thread_info *thread)
> > > +static inline int is_a32_compat_thread(struct thread_info *thread)
> > > {
> > > return test_ti_thread_flag(thread, TIF_32BIT);
> > > }
> > >
> > > +#else
> > > +
> > > +static inline int is_a32_compat_task(void)
> > > +{
> > > + return 0;
> > > +}
> > > +
> > > +static inline int is_a32_compat_thread(struct thread_info *thread)
> > > +{
> > > + return 0;
> > > +}
> > > +#endif
> > > +
> > > +static inline int is_compat_task(void)
> > > +{
> > > + return is_a32_compat_task();
> > > +}
> > > +
> > > #else /* !CONFIG_COMPAT */
> > >
> > > -static inline int is_compat_thread(struct thread_info *thread)
> > > +static inline int is_a32_compat_thread(struct thread_info *thread)
> > > +{
> > > + return 0;
> > > +}
> > > +
> > > +static inline int is_a32_compat_task(void)
> > > {
> > > return 0;
> > > }
> >
> > My main worry with this patch is a potential #include mess. I can see
> > that you already had to include asm/compat.h explicitly in
> > hw_breakpoint.c even though linux/compat.h was already included. In
> > subsequent files (asm/elf.h, asm/memory.h) you check is_compat_task()
> > without explicitly including asm/compat.h and hope that it won't break.
> >
> > A solution would be to add these functions in a separate header file
> > that gets included where needed (also by asm/compat.h).
>
> Thank you for pointing that. I don't see big advantage in moving that
> to new file, only if you insist. What about just fixing that mess?

As I said above, you use is_compat_task() in asm/elf.h for example
without including asm/compat.h. At some point, you may get a build error
in some unrelated C file. You could wait until it happens and then sort
it out (by either including asm/compat.h in asm/elf.h or creating a new
header file). My preference is to prevent such build errors early.

--
Catalin