2015-11-02 23:31:13

by Yury Norov

[permalink] [raw]
Subject: [RFC PATCH v6 00/17] ILP32 for ARM64

V6 addresses comments collected for v5 series.
This is RFC because LTP tests fail (63 of 779).
But I don't expect that major changes are required
to fix regressions.

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.

Andrew Pinski (13):
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: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 (1):
ilp32: common 32-bit wrappers

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 | 55 +++++++
arch/arm64/Kconfig | 14 +-
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/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 | 278 ++++++++++++++++++++++++++++++++++
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 +++-
include/uapi/asm-generic/stat.h | 8 +-
kernel/ptrace.c | 24 ++-
35 files changed, 806 insertions(+), 113 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-02 23:31:27

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 01/17] 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.

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]>
Reviewed-by: David Daney <[email protected]>
---
Documentation/arm64/ilp32.txt | 55 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 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..4f6860b
--- /dev/null
+++ b/Documentation/arm64/ilp32.txt
@@ -0,0 +1,55 @@
+ILP32 AARCH64 SYSCALL ABI
+=========================
+Written by Andrew Pinski <[email protected]>
+Updated by Philipp Tomsich <[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 these LP64 syscalls reused by ILP32 clients is:
+ * fcntl
+ * statfs
+ * fstatfs
+ * truncate
+ * ftruncate
+ * lseek
+ * sendfile
+ * newfstatat
+ * fstat
+ * mmap
+ * fadvise64
+
--
2.1.4

2015-11-02 23:31:44

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 02/17] 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).

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]>
Reviewed-by: David Daney <[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-02 23:31:56

by Yury Norov

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

From: Andrew Pinski <[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]>
Reviewed-by: David Daney <[email protected]>
---
arch/arm64/Kconfig | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 07d1811..d1dc605 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
@@ -699,7 +704,7 @@ config COMPAT

config SYSVIPC_COMPAT
def_bool y
- depends on COMPAT && SYSVIPC
+ depends on AARCH32_EL0 && SYSVIPC

endmenu

--
2.1.4

2015-11-02 23:32:13

by Yury Norov

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

From: Andrew Pinski <[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]>
Reviewed-by: David Daney <[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-02 23:32:25

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 05/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:32:38

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 06/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:32:59

by Yury Norov

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

From: Andrew Pinski <[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]>
Reviewed-by: David Daney <[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-02 23:33:08

by Yury Norov

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

From: Andrew Pinski <[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]>
Reviewed-by: David Daney <[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-02 23:33:42

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 09/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:33:31

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 10/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:35:39

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 11/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:33:55

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 12/17] ilp32: common 32-bit wrappers

From: Jan Dakinevich <[email protected]>

Signed-off-by: Yury Norov <[email protected]>
Signed-off-by: Jan Dakinevich <[email protected]>
Reviewed-by: David Daney <[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-02 23:34:08

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 13/17] 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.

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]>
Reviewed-by: David Daney <[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 | 221 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 239 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..6c7d274
--- /dev/null
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -0,0 +1,221 @@
+/*
+ * 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 sys_rt_sigreturn sys_rt_sigreturn_wrapper
+#define sys_rt_sigsuspend compat_sys_rt_sigsuspend
+#define sys_rt_sigaction compat_sys_rt_sigaction
+#define sys_rt_sigprocmask compat_sys_rt_sigprocmask
+#define sys_rt_sigpending compat_sys_rt_sigpending
+#define sys_rt_sigtimedwait compat_sys_rt_sigtimedwait
+#define sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
+#define sys_rt_sigpending compat_sys_rt_sigpending
+
+/* Using Compat syscalls where necessary */
+#define sys_ioctl compat_sys_ioctl
+/* iovec */
+#define sys_readv compat_sys_readv
+#define sys_writev compat_sys_writev
+#define sys_preadv compat_sys_preadv64
+#define sys_pwritev compat_sys_pwritev64
+#define sys_vmsplice compat_sys_vmsplice
+/* robust_list_head */
+#define sys_set_robust_list compat_sys_set_robust_list
+#define sys_get_robust_list compat_sys_get_robust_list
+
+/* kexec_segment */
+#define sys_kexec_load compat_sys_kexec_load
+
+/* Ptrace has some structures which are different between ILP32 and LP64 */
+#define sys_ptrace compat_sys_ptrace
+
+/* struct msghdr */
+#define sys_msgctl compat_sys_msgctl
+#define sys_recvfrom compat_sys_recvfrom
+#define sys_recvmmsg compat_sys_recvmmsg
+#define sys_sendmmsg compat_sys_sendmmsg
+#define sys_sendmsg compat_sys_sendmsg
+#define sys_recvmsg compat_sys_recvmsg
+#define sys_msgsnd compat_sys_msgsnd
+#define sys_msgrcv compat_sys_msgrcv
+
+#define sys_setsockopt compat_sys_setsockopt
+#define sys_getsockopt compat_sys_getsockopt
+
+/* Array of pointers */
+#define sys_execve compat_sys_execve
+#define sys_move_pages compat_sys_move_pages
+
+/* iovec */
+#define sys_process_vm_readv compat_sys_process_vm_readv
+#define sys_process_vm_writev compat_sys_process_vm_writev
+
+/* Pointer in struct */
+#define sys_mount compat_sys_mount
+
+/* NUMA */
+/* unsigned long bitmaps */
+#define sys_get_mempolicy compat_sys_get_mempolicy
+#define sys_set_mempolicy compat_sys_set_mempolicy
+#define sys_mbind compat_sys_mbind
+/* array of pointers */
+/* unsigned long bitmaps */
+#define sys_migrate_pages compat_sys_migrate_pages
+
+/* Scheduler */
+/* unsigned long bitmaps */
+#define sys_sched_setaffinity compat_sys_sched_setaffinity
+#define sys_sched_getaffinity compat_sys_sched_getaffinity
+
+/* iov usage */
+#define sys_keyctl compat_sys_keyctl
+
+/* aio */
+/* Pointer to Pointer */
+#define sys_io_setup compat_sys_io_setup
+/* Array of pointers */
+#define sys_io_submit compat_sys_io_submit
+
+#define sys_nanosleep compat_sys_nanosleep
+
+#define sys_lseek sys_llseek
+
+#define sys_setitimer compat_sys_setitimer
+#define sys_getitimer compat_sys_getitimer
+
+#define sys_gettimeofday compat_sys_gettimeofday
+#define sys_settimeofday compat_sys_settimeofday
+#define sys_adjtimex compat_sys_adjtimex
+
+#define sys_clock_gettime compat_sys_clock_gettime
+#define sys_clock_settime compat_sys_clock_settime
+
+#define sys_timerfd_gettime compat_sys_timerfd_gettime
+#define sys_timerfd_settime compat_sys_timerfd_settime
+#define sys_utimensat compat_sys_utimensat
+
+#define sys_getrlimit compat_sys_getrlimit
+#define sys_setrlimit compat_sys_setrlimit
+#define sys_getrusage compat_sys_getrusage
+
+#define sys_futex compat_sys_futex
+#define sys_get_robust_list compat_sys_get_robust_list
+#define sys_set_robust_list compat_sys_set_robust_list
+
+#define sys_pselect6 compat_sys_pselect6
+#define sys_ppoll compat_sys_ppoll
+
+asmlinkage long compat_sys_mmap2_wrapper(void);
+#define sys_mmap compat_sys_mmap2_wrapper
+
+asmlinkage long compat_sys_fstatfs64_wrapper(void);
+#define sys_fstatfs compat_sys_fstatfs64_wrapper
+asmlinkage long compat_sys_statfs64_wrapper(void);
+#define sys_statfs compat_sys_statfs64_wrapper
+
+/* We need to make sure the pointer gets copied correctly. */
+asmlinkage long ilp32_sys_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
+{
+ struct sigevent __user *p = NULL;
+ if (u_notification) {
+ struct sigevent n;
+ p = compat_alloc_user_space(sizeof(*p));
+ if (copy_from_user(&n, u_notification, sizeof(*p)))
+ return -EFAULT;
+ if (n.sigev_notify == SIGEV_THREAD)
+ n.sigev_value.sival_ptr = compat_ptr((uintptr_t)n.sigev_value.sival_ptr);
+ if (copy_to_user(p, &n, sizeof(*p)))
+ return -EFAULT;
+ }
+ return sys_mq_notify(mqdes, p);
+}
+
+/* sigevent contains sigval_t which is now 64bit always
+ but need special handling due to padding for SIGEV_THREAD. */
+#define sys_mq_notify ilp32_sys_mq_notify
+
+/* sigaltstack needs some special handling as the
+ padding for stack_t might not be non-zero. */
+long ilp32_sys_sigaltstack(const stack_t __user *uss_ptr,
+ stack_t __user *uoss_ptr)
+{
+ stack_t uss, uoss;
+ int ret;
+ mm_segment_t seg;
+
+ if (uss_ptr) {
+ if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)))
+ return -EFAULT;
+ if (__get_user(uss.ss_sp, &uss_ptr->ss_sp) |
+ __get_user(uss.ss_flags, &uss_ptr->ss_flags) |
+ __get_user(uss.ss_size, &uss_ptr->ss_size))
+ return -EFAULT;
+ /* Zero extend the sp address and the size. */
+ uss.ss_sp = (void *)(uintptr_t)(unsigned int)(uintptr_t)uss.ss_sp;
+ uss.ss_size = (size_t)(unsigned int)uss.ss_size;
+ }
+ seg = get_fs();
+ set_fs(KERNEL_DS);
+ /* Note we need to use uoss as we have changed the segment to the
+ kernel one so passing an user one around is wrong. */
+ ret = sys_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
+ (stack_t __force __user *) &uoss);
+ set_fs(seg);
+ if (ret >= 0 && uoss_ptr) {
+ if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_t)) ||
+ __put_user(uoss.ss_sp, &uoss_ptr->ss_sp) ||
+ __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
+ __put_user(uoss.ss_size, &uoss_ptr->ss_size))
+ ret = -EFAULT;
+ }
+ return ret;
+}
+
+/* sigaltstack needs some special handling as the padding
+ for stack_t might not be non-zero. */
+#define sys_sigaltstack ilp32_sys_sigaltstack
+
+
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym) [nr] = sym,
+
+/*
+ * The sys_call_ilp32_table array must be 4K aligned to be accessible from
+ * kernel/entry.S.
+ */
+void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = {
+ [0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
--
2.1.4

2015-11-02 23:34:17

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 14/17] 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 introduce __stat64, and where needed,
cast stat64 to it with #define.

Second option requires to duplicate cp_new_stat64 code. But we
choose it, because it's more flexible to have independend support
for ABIs.

Signed-off-by: Yury Norov <[email protected]>
Reviewed-by: David Daney <[email protected]>
---
arch/arm64/kernel/sys_ilp32.c | 57 +++++++++++++++++++++++++++++++++++++++++
include/uapi/asm-generic/stat.h | 8 +++---
2 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c
index 6c7d274..889f1d3 100644
--- a/arch/arm64/kernel/sys_ilp32.c
+++ b/arch/arm64/kernel/sys_ilp32.c
@@ -205,6 +205,63 @@ long ilp32_sys_sigaltstack(const stack_t __user *uss_ptr,
for stack_t might not be non-zero. */
#define sys_sigaltstack ilp32_sys_sigaltstack

+/* fs */
+
+#define sys_fcntl compat_sys_fcntl
+
+static long __cp_new_stat64(struct kstat *stat, struct __stat64 __user *statbuf)
+{
+ struct __stat64 tmp;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.st_dev = huge_encode_dev(stat->dev);
+ tmp.st_rdev = huge_encode_dev(stat->rdev);
+
+ tmp.st_ino = stat->ino;
+ if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
+ return -EOVERFLOW;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
+ tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_atime_nsec = stat->atime.tv_nsec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+ tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+ tmp.st_ctime = stat->ctime.tv_sec;
+ tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+ tmp.st_size = stat->size;
+ tmp.st_blocks = stat->blocks;
+ tmp.st_blksize = stat->blksize;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+long ilp32_sys_fstat64(int fd, struct __stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
+
+ if (!error)
+ error = __cp_new_stat64(&stat, statbuf);
+
+ return error;
+}
+
+#define sys_newfstat ilp32_sys_fstat64
+
+long ilp32_sys_fstatat64(int dfd, const char __user * filename,
+ struct __stat64 __user * statbuf, int flag)
+{
+ struct kstat stat;
+ int error;
+
+ error = vfs_fstatat(dfd, filename, &stat, flag);
+ if (error)
+ return error;
+ return __cp_new_stat64(&stat, statbuf);
+}
+
+#define sys_newfstatat ilp32_sys_fstatat64

#include <asm/syscall.h>

diff --git a/include/uapi/asm-generic/stat.h b/include/uapi/asm-generic/stat.h
index bd8cad2..ae81e73 100644
--- a/include/uapi/asm-generic/stat.h
+++ b/include/uapi/asm-generic/stat.h
@@ -43,9 +43,7 @@ struct stat {
unsigned int __unused5;
};

-/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
-#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64)
-struct stat64 {
+struct __stat64 {
unsigned long long st_dev; /* Device. */
unsigned long long st_ino; /* File serial number. */
unsigned int st_mode; /* File mode. */
@@ -67,6 +65,10 @@ struct stat64 {
unsigned int __unused4;
unsigned int __unused5;
};
+
+#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64)
+/* This matches struct stat64 in glibc2.1. Only used for 32 bit. */
+#define stat64 __stat64
#endif

#endif /* __ASM_GENERIC_STAT_H */
--
2.1.4

2015-11-02 23:34:28

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 15/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:34:41

by Yury Norov

[permalink] [raw]
Subject: [PATCH v6 16/17] 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.

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]>
Reviewed-by: David Daney <[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-02 23:34:53

by Yury Norov

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

From: Andrew Pinski <[email protected]>

This patch adds the config option for ILP32.

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]>
Reviewed-by: David Daney <[email protected]>
---
arch/arm64/Kconfig | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d1dc605..afbde9c 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 AARCH32_EL0 && SYSVIPC
--
2.1.4

2015-11-05 11:36:44

by Andreas Schwab

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] 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);

Are the updated glibc patches available somewhere?

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-05 13:39:59

by Andrew Pinski

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

On Thu, Nov 5, 2015 at 7:36 PM, Andreas Schwab <[email protected]> wrote:
> 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);
>
> Are the updated glibc patches available somewhere?

Not in an useful form right now but i will try to get them in an
useful form sometime next week. I am traveling home on Saturday.

Thanks,
Andrew

>
> 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-05 13:51:19

by Arnd Bergmann

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

On Tuesday 03 November 2015 02:30:42 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.

The uapi/asm-generic/unistd.h already contains a list of compat syscalls
that should work by default, I think it would be better to use that
list and override only the ones that differ between normal compat
mode and the new mode, e.g. when you require a wrapper or want to
use the native syscall entry.

> +/* We need to make sure the pointer gets copied correctly. */
> +asmlinkage long ilp32_sys_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
> +{
> + struct sigevent __user *p = NULL;
> + if (u_notification) {
> + struct sigevent n;
> + p = compat_alloc_user_space(sizeof(*p));
> + if (copy_from_user(&n, u_notification, sizeof(*p)))
> + return -EFAULT;
> + if (n.sigev_notify == SIGEV_THREAD)
> + n.sigev_value.sival_ptr = compat_ptr((uintptr_t)n.sigev_value.sival_ptr);
> + if (copy_to_user(p, &n, sizeof(*p)))
> + return -EFAULT;
> + }
> + return sys_mq_notify(mqdes, p);
> +}

Could this be avoided by defining sigval_t in a way that is
compatible?

> +/* sigevent contains sigval_t which is now 64bit always
> + but need special handling due to padding for SIGEV_THREAD. */
> +#define sys_mq_notify ilp32_sys_mq_notify
> +
> +/* sigaltstack needs some special handling as the
> + padding for stack_t might not be non-zero. */
> +long ilp32_sys_sigaltstack(const stack_t __user *uss_ptr,
> + stack_t __user *uoss_ptr)

asmlinkage?

Arnd

2015-11-05 13:54:50

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH v6 11/17] ptrace: Allow compat to use the native siginfo

On Tuesday 03 November 2015 02:30:40 Yury Norov wrote:
> 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.

Why does this use compat_ptrace_request()? I assume there is
a good reason for it, but I'm surprised you don't use the native
64-bit ptrace syscall.

Arnd

2015-11-05 14:10:12

by Arnd Bergmann

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

On Tuesday 03 November 2015 02:30:43 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 introduce __stat64, and where needed,
> cast stat64 to it with #define.
>
> Second option requires to duplicate cp_new_stat64 code. But we
> choose it, because it's more flexible to have independend support
> for ABIs.
>
> Signed-off-by: Yury Norov <[email protected]>
> Reviewed-by: David Daney <[email protected]>

I'm sorry I screwed up with the definition for stat64 in asm-generic,
by defining it to have too short st_{a,m,c}time members.

This means we have to introduce another 'struct stat64' variant already
to solve the y2038 problem, and I have patches for it already, to make
that implementation use the same structure as the 64-bit 'struct stat'
with 64-bit timestamps. There is also an ongoing effort from David Howells
to create a new 'struct statx' (or maybe xstat) system call with a
completely new layout.

I think here it would be better to avoid adding yet another version
for ilp32 mode, and we are better off defining 'struct stat64' in
the arm64 headers, and share either the normal arm32 syscall entry
(with the default asm-generic syscall) or the normal arm64 syscall
entry (as we will do for the future replacement).

Arnd

2015-11-05 14:34:51

by Arnd Bergmann

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

On Tuesday 03 November 2015 02:30:30 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.
>
> 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]>
> Reviewed-by: David Daney <[email protected]>

Thanks for the updated version, I'm much happier with this, and only have
some comments on a few details to the later patches.

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

Right, makes sense.

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

As I commented, we might want to change this for 'stat', which doesn't
really time_t anyway.

> + * semid64_ds uses time_t.
> + * msqid64_ds uses time_t.
> + * shmid64_ds uses time_t.

These use the arm32 layout, right? That's good for consistency.
Fixing these for y2038 will be a bit ugly, but that code can be
shared across all architectures.

> + * 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 these LP64 syscalls reused by ILP32 clients is:
> + * fcntl
> + * statfs
> + * fstatfs

Did you forget to edit this list? I see fcntl and {f,}statfs use the compat
implementation, not the native one in your patches.

> + * truncate
> + * ftruncate
> + * lseek
> + * sendfile
> + * fadvise64

Makes sense. I think using the normal compat syscalls would have been
just as good here, to save a few lines in the syscall table, but I
agree that the calling conventions are rather silly when you pass
a 64-bit number in two registers.

> + * newfstatat
> + * fstat

This contradicts what you write above regarding separate 'struct stat'.

> + * mmap

Not direct reuse because of the wrapper to check the page size I guess.
Aside from the wrapper, the 32-bit and 64-bit system calls are basically
identical.

Arnd

2015-11-05 22:19:08

by Yury Norov

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

On Thu, Nov 05, 2015 at 09:39:51PM +0800, Andrew Pinski wrote:
> On Thu, Nov 5, 2015 at 7:36 PM, Andreas Schwab <[email protected]> wrote:
> > 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);
> >
> > Are the updated glibc patches available somewhere?
>
> Not in an useful form right now but i will try to get them in an
> useful form sometime next week. I am traveling home on Saturday.
>
> Thanks,
> Andrew
>
> >
> > 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."

Andreas,

This is what I run:
https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t

You can try it while Andrew works on patches.

BR,
Yury.

2015-11-09 10:02:01

by Andreas Schwab

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

Yury Norov <[email protected]> writes:

> This is what I run:
> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t

Thanks, rebootstrapping openSUSE Factory now.

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-09 13:24:07

by Andreas Schwab

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

Yury Norov <[email protected]> writes:

> This is what I run:
> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t

That doesn't work for me:

../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
ed (first use in this function)
../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)

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-09 14:22:36

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

On Monday 09 November 2015 14:23:59 Andreas Schwab wrote:
> Yury Norov <[email protected]> writes:
>
> > This is what I run:
> > https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
>
> That doesn't work for me:
>
> ../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
> ed (first use in this function)
> ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)
>

Did you re-export the kernel headers that you use as the base?

The earlier ABI used 64-bit off_t with 'lseek()' and no loff_t, while this
one does uses loff_t with 'llseek()' etc on the kernel side and does not
provide the off_t based syscalls.

Arnd

2015-11-09 14:33:56

by Andreas Schwab

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

Arnd Bergmann <[email protected]> writes:

> On Monday 09 November 2015 14:23:59 Andreas Schwab wrote:
>> Yury Norov <[email protected]> writes:
>>
>> > This is what I run:
>> > https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
>>
>> That doesn't work for me:
>>
>> ../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
>> ed (first use in this function)
>> ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)
>>
>
> Did you re-export the kernel headers that you use as the base?

I'm using the patched 4.3 kernel headers. Why is <asm/bitsperlong.h>
defining __BITS_PER_LONG to 64 unconditionally?

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-09 14:37:40

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

On Monday 09 November 2015 15:33:51 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > On Monday 09 November 2015 14:23:59 Andreas Schwab wrote:
> >> Yury Norov <[email protected]> writes:
> >>
> >> > This is what I run:
> >> > https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
> >>
> >> That doesn't work for me:
> >>
> >> ../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
> >> ed (first use in this function)
> >> ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)
> >>
> >
> > Did you re-export the kernel headers that you use as the base?
>
> I'm using the patched 4.3 kernel headers.

Ok.

> Why is <asm/bitsperlong.h> defining __BITS_PER_LONG to 64 unconditionally?

It should not, that is a bug. I don't know how Yury built his glibc,
but it can't work if __BITS_PER_LONG is wrong.

Arnd

2015-11-09 15:00:40

by Andrew Pinski

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64



> On Nov 9, 2015, at 10:36 PM, Arnd Bergmann <[email protected]> wrote:
>
>> On Monday 09 November 2015 15:33:51 Andreas Schwab wrote:
>> Arnd Bergmann <[email protected]> writes:
>>
>>>> On Monday 09 November 2015 14:23:59 Andreas Schwab wrote:
>>>> Yury Norov <[email protected]> writes:
>>>>
>>>>> This is what I run:
>>>>> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
>>>>
>>>> That doesn't work for me:
>>>>
>>>> ../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
>>>> ed (first use in this function)
>>>> ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)
>>>
>>> Did you re-export the kernel headers that you use as the base?
>>
>> I'm using the patched 4.3 kernel headers.
>
> Ok.
>
>> Why is <asm/bitsperlong.h> defining __BITS_PER_LONG to 64 unconditionally?
>
> It should not, that is a bug. I don't know how Yury built his glibc,
> but it can't work if __BITS_PER_LONG is wrong.


Looks like I had changed the header file manually for building glibc and Yury and myself missed that when he updated the patches.


Thanks,
Andrew

>
> Arnd

2015-11-09 15:51:01

by Yury Norov

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

On Mon, Nov 09, 2015 at 10:52:32PM +0800, [email protected] wrote:
>
>
> > On Nov 9, 2015, at 10:36 PM, Arnd Bergmann <[email protected]> wrote:
> >
> >> On Monday 09 November 2015 15:33:51 Andreas Schwab wrote:
> >> Arnd Bergmann <[email protected]> writes:
> >>
> >>>> On Monday 09 November 2015 14:23:59 Andreas Schwab wrote:
> >>>> Yury Norov <[email protected]> writes:
> >>>>
> >>>>> This is what I run:
> >>>>> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
> >>>>
> >>>> That doesn't work for me:
> >>>>
> >>>> ../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
> >>>> ed (first use in this function)
> >>>> ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)
> >>>
> >>> Did you re-export the kernel headers that you use as the base?
> >>
> >> I'm using the patched 4.3 kernel headers.
> >
> > Ok.
> >
> >> Why is <asm/bitsperlong.h> defining __BITS_PER_LONG to 64 unconditionally?
> >
> > It should not, that is a bug. I don't know how Yury built his glibc,
> > but it can't work if __BITS_PER_LONG is wrong.
>
>
> Looks like I had changed the header file manually for building glibc and Yury and myself missed that when he updated the patches.
>
>
> Thanks,
> Andrew
>
> >
> > Arnd


No, it's my fault. I forgot to add a patch that sets __BITS_PER_LONG
to 32. I'll send it here now.

2015-11-09 16:05:10

by Yury Norov

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

On Mon, Nov 09, 2015 at 06:50:42PM +0300, Yury Norov wrote:
> On Mon, Nov 09, 2015 at 10:52:32PM +0800, [email protected] wrote:
> >
> >
> > > On Nov 9, 2015, at 10:36 PM, Arnd Bergmann <[email protected]> wrote:
> > >
> > >> On Monday 09 November 2015 15:33:51 Andreas Schwab wrote:
> > >> Arnd Bergmann <[email protected]> writes:
> > >>
> > >>>> On Monday 09 November 2015 14:23:59 Andreas Schwab wrote:
> > >>>> Yury Norov <[email protected]> writes:
> > >>>>
> > >>>>> This is what I run:
> > >>>>> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
> > >>>>
> > >>>> That doesn't work for me:
> > >>>>
> > >>>> ../sysdeps/unix/sysv/linux/generic/sysdep.h:24:22: error: ‘__NR_llseek’ undeclar
> > >>>> ed (first use in this function)
> > >>>> ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:41:32: error: ‘__NR_fcntl64’ undeclared (first use in this function)
> > >>>
> > >>> Did you re-export the kernel headers that you use as the base?
> > >>
> > >> I'm using the patched 4.3 kernel headers.
> > >
> > > Ok.
> > >
> > >> Why is <asm/bitsperlong.h> defining __BITS_PER_LONG to 64 unconditionally?
> > >
> > > It should not, that is a bug. I don't know how Yury built his glibc,
> > > but it can't work if __BITS_PER_LONG is wrong.
> >
> >
> > Looks like I had changed the header file manually for building glibc and Yury and myself missed that when he updated the patches.
> >
> >
> > Thanks,
> > Andrew
> >
> > >
> > > Arnd
>
>
> No, it's my fault. I forgot to add a patch that sets __BITS_PER_LONG
> to 32. I'll send it here now.
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Attachments:
(No filename) (1.73 kB)
0001-arm64-uapi-set-__BITS_PER_LONG-correctly-for-ILP32-a.patch (1.38 kB)
Download all attachments

2015-11-11 07:24:36

by Zhangjian (Bamvor)

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

Hi, Andreas

On 2015/11/9 18:01, Andreas Schwab wrote:
> Yury Norov <[email protected]> writes:
>
>> This is what I run:
>> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
>
> Thanks, rebootstrapping openSUSE Factory now.
Where could I find them for testing? I could not find them in your
obs[1].

Best regards

Bamvor

[1] https://build.opensuse.org/package/show/home:Andreas_Schwab:XXX
>
> Andreas.
>

2015-11-11 08:44:20

by Andreas Schwab

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

"Zhangjian (Bamvor)" <[email protected]> writes:

> Hi, Andreas
>
> On 2015/11/9 18:01, Andreas Schwab wrote:
>> Yury Norov <[email protected]> writes:
>>
>>> This is what I run:
>>> https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t
>>
>> Thanks, rebootstrapping openSUSE Factory now.
> Where could I find them for testing? I could not find them in your
> obs[1].

It's built in a separate OBS instance, so it's not available publicly
yet.

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-11 17:54:07

by Andreas Schwab

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

Yury Norov <[email protected]> writes:

> +#define sys_clock_gettime compat_sys_clock_gettime
> +#define sys_clock_settime compat_sys_clock_settime

You also need to redirect sys_clock_nanosleep.

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-11 20:46:39

by Arnd Bergmann

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

On Wednesday 11 November 2015 18:54:00 Andreas Schwab wrote:
> Yury Norov <[email protected]> writes:
>
> > +#define sys_clock_gettime compat_sys_clock_gettime
> > +#define sys_clock_settime compat_sys_clock_settime
>
> You also need to redirect sys_clock_nanosleep.

Note that based on my comment, that table would be turned around, and
only the syscalls get overridden that do not have the normal
compat mode behavior (mostly the ones that pass a 64-bit register).

Arnd

2015-11-11 23:07:46

by Andreas Schwab

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

Arnd Bergmann <[email protected]> writes:

> On Wednesday 11 November 2015 18:54:00 Andreas Schwab wrote:
>> Yury Norov <[email protected]> writes:
>>
>> > +#define sys_clock_gettime compat_sys_clock_gettime
>> > +#define sys_clock_settime compat_sys_clock_settime
>>
>> You also need to redirect sys_clock_nanosleep.
>
> Note that based on my comment, that table would be turned around, and
> only the syscalls get overridden that do not have the normal
> compat mode behavior (mostly the ones that pass a 64-bit register).

Is it intented that _all_ off_t-like syscalls are implemented by the
64bit variants? Currently, this isn't fully implemented (lseek is
implemented by sys_llseek and mmap by an mmap2 wrapper).

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-11 23:24:54

by Arnd Bergmann

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

On Thursday 12 November 2015 00:07:41 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > On Wednesday 11 November 2015 18:54:00 Andreas Schwab wrote:
> >> Yury Norov <[email protected]> writes:
> >>
> >> > +#define sys_clock_gettime compat_sys_clock_gettime
> >> > +#define sys_clock_settime compat_sys_clock_settime
> >>
> >> You also need to redirect sys_clock_nanosleep.
> >
> > Note that based on my comment, that table would be turned around, and
> > only the syscalls get overridden that do not have the normal
> > compat mode behavior (mostly the ones that pass a 64-bit register).
>
> Is it intented that _all_ off_t-like syscalls are implemented by the
> 64bit variants? Currently, this isn't fully implemented (lseek is
> implemented by sys_llseek and mmap by an mmap2 wrapper).

I think either way is fine for the two examples. I think it's clear
that we want __NR_llseek as 62 and __NR_mmap2 as 222. Whether those
use the compat_sys_llseek/compat_sys_mmap2_wrapper or
sys_lseek/sys_mmap entry points is not overly important, we can use
whatever is more convenient to glibc: if we can kill off an
architecture specific wrapper function in glibc by adding one line
to the kernel, that seems worthwhile.

It's a bit confusing, because user space off_t matches the kernel's
off_t, loff_t, but not the __kernel_off_t from the uapi headers.

Arnd

2015-11-12 08:58:48

by Andreas Schwab

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

Arnd Bergmann <[email protected]> writes:

> I think either way is fine for the two examples. I think it's clear
> that we want __NR_llseek as 62 and __NR_mmap2 as 222. Whether those
> use the compat_sys_llseek/compat_sys_mmap2_wrapper or
> sys_lseek/sys_mmap entry points is not overly important, we can use
> whatever is more convenient to glibc: if we can kill off an
> architecture specific wrapper function in glibc by adding one line
> to the kernel, that seems worthwhile.

Currently most off_t-like syscalls need a new glibc wrapper since the
existing ones are either for 32bit off_t+off64_t (with split off64_t
syscall arguments) or pure 64bit off_t architectures. Since ilp32 now
(mostly) has 32bit off_t, but 64bit off_t-like syscalls neither of them
fit.

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-12 09:23:27

by Arnd Bergmann

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

On Thursday 12 November 2015 09:58:43 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > I think either way is fine for the two examples. I think it's clear
> > that we want __NR_llseek as 62 and __NR_mmap2 as 222. Whether those
> > use the compat_sys_llseek/compat_sys_mmap2_wrapper or
> > sys_lseek/sys_mmap entry points is not overly important, we can use
> > whatever is more convenient to glibc: if we can kill off an
> > architecture specific wrapper function in glibc by adding one line
> > to the kernel, that seems worthwhile.
>
> Currently most off_t-like syscalls need a new glibc wrapper since the
> existing ones are either for 32bit off_t+off64_t (with split off64_t
> syscall arguments) or pure 64bit off_t architectures. Since ilp32 now
> (mostly) has 32bit off_t, but 64bit off_t-like syscalls neither of them
> fit.

What do you mean with 32-bit off_t? Do you mean that glibc emulates
a 32-bit off_t on top of the 64-bit __kernel_loff_t? That sounds a bit
backwards. I would expect that all new architectures that only have
__kernel_loff_t based syscalls but not __kernel_off_t based ones only
ever use a 64-bit off_t in libc.

Arnd

2015-11-12 09:44:59

by Andreas Schwab

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

Arnd Bergmann <[email protected]> writes:

> What do you mean with 32-bit off_t?

An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.

> Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
> __kernel_loff_t?

Glibc is bridging the user-space ABI to the kernel ABI.

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-12 13:26:01

by Arnd Bergmann

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

On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > What do you mean with 32-bit off_t?
>
> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
>
> > Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
> > __kernel_loff_t?
>
> Glibc is bridging the user-space ABI to the kernel ABI.

Ok, but why?

The kernel headers for all recent architectures (arc, c6x, h8300,
hexagon, metag, nios2, openrisc, tile and unicore32) deliberately
leave out the __kernel_off_t based system calls to simplify the
ABI in a way that we never have to support a 32-bit off_t
in user space.

Are there programs that require using a 32-bit off_t by default
on 32-bit architectures but not on 64-bit architectures?
Did the previous version of the ilp32 patch set also emulate
this the same way?

Arnd

2015-11-12 13:47:23

by Andreas Schwab

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

Arnd Bergmann <[email protected]> writes:

> On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
>> Arnd Bergmann <[email protected]> writes:
>>
>> > What do you mean with 32-bit off_t?
>>
>> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
>>
>> > Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
>> > __kernel_loff_t?
>>
>> Glibc is bridging the user-space ABI to the kernel ABI.
>
> Ok, but why?

That's how the ABI is defined right now. I didn't make that up.

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-13 15:35:24

by Arnd Bergmann

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

On Thursday 12 November 2015 14:47:18 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
> >> Arnd Bergmann <[email protected]> writes:
> >>
> >> > What do you mean with 32-bit off_t?
> >>
> >> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
> >>
> >> > Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
> >> > __kernel_loff_t?
> >>
> >> Glibc is bridging the user-space ABI to the kernel ABI.
> >
> > Ok, but why?
>
> That's how the ABI is defined right now. I didn't make that up.

Ok, I guess it will remain a mystery then.

Should we perhaps define __ARCH_WANT_SYSCALL_OFF_T for the unistd.h
file then, so we provide both the off_t and the loff_t based syscalls?

That would avoid the extra wrapper in glibc when using a 32-bit
off_t if that is the preferred mode for user space.

Arnd

2015-11-13 15:38:52

by Andrew Pinski

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

On Fri, Nov 13, 2015 at 7:34 AM, Arnd Bergmann <[email protected]> wrote:
> On Thursday 12 November 2015 14:47:18 Andreas Schwab wrote:
>> Arnd Bergmann <[email protected]> writes:
>>
>> > On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
>> >> Arnd Bergmann <[email protected]> writes:
>> >>
>> >> > What do you mean with 32-bit off_t?
>> >>
>> >> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
>> >>
>> >> > Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
>> >> > __kernel_loff_t?
>> >>
>> >> Glibc is bridging the user-space ABI to the kernel ABI.
>> >
>> > Ok, but why?
>>
>> That's how the ABI is defined right now. I didn't make that up.
>
> Ok, I guess it will remain a mystery then.

The biggest question is here is how much compatibility do we want with
other 32bit ABIs?
Do we want off_t to be 32bit or 64bit?

>
> Should we perhaps define __ARCH_WANT_SYSCALL_OFF_T for the unistd.h
> file then, so we provide both the off_t and the loff_t based syscalls?

I think that is backwards ...

>
> That would avoid the extra wrapper in glibc when using a 32-bit
> off_t if that is the preferred mode for user space.


Other targets like tilegx does not do that and has a pure 32bit mode.
Only score does that.

Thanks,
Andrew

>
> Arnd

2015-11-13 16:11:47

by Arnd Bergmann

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

On Friday 13 November 2015 07:38:49 Andrew Pinski wrote:
> On Fri, Nov 13, 2015 at 7:34 AM, Arnd Bergmann <[email protected]> wrote:
> > On Thursday 12 November 2015 14:47:18 Andreas Schwab wrote:
> >> Arnd Bergmann <[email protected]> writes:
> >>
> >> > On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
> >> >> Arnd Bergmann <[email protected]> writes:
> >> >>
> >> >> > What do you mean with 32-bit off_t?
> >> >>
> >> >> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
> >> >>
> >> >> > Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
> >> >> > __kernel_loff_t?
> >> >>
> >> >> Glibc is bridging the user-space ABI to the kernel ABI.
> >> >
> >> > Ok, but why?
> >>
> >> That's how the ABI is defined right now. I didn't make that up.
> >
> > Ok, I guess it will remain a mystery then.
>
> The biggest question is here is how much compatibility do we want with
> other 32bit ABIs?
> Do we want off_t to be 32bit or 64bit?

I would much prefer off_t to be defined as __kernel_loff_t unconditionally,
with no support for _FILE_OFFSET_BITS == 32. This is at least what I had
in mind when I wrote the asm-generic/unistd.h header.

We should probably find out what happened for the other glibc ports that
were implemented for the architectures using this. It's possible that
there was a good reason for supporting _FILE_OFFSET_BITS == 32 at the
time, but I can't think of one and maybe it is one that is no longer
valid.

Do you know what x86/x32 does for off_t? Do they also implement both
_FILE_OFFSET_BITS == 32 and _FILE_OFFSET_BITS == 64 on top of the
64-bit __kernel_off_t?

> > Should we perhaps define __ARCH_WANT_SYSCALL_OFF_T for the unistd.h
> > file then, so we provide both the off_t and the loff_t based syscalls?
>
> I think that is backwards ...
>
> >
> > That would avoid the extra wrapper in glibc when using a 32-bit
> > off_t if that is the preferred mode for user space.
>
>
> Other targets like tilegx does not do that and has a pure 32bit mode.
> Only score does that.

score was unintentional, it was the first port that got done after we
introduced the generic headers, and they said at the time that they
would change their libc to remove the dependency on the legacy syscalls,
but when I tried to remove them later, they had already shipped it
with them enabled. After that, I told people to never enable the
symbols in an upstream port and only use them for porting their libc
internally. We could actually now move all the legacy syscall stuff
to arch/score/include/uapi/asm/unistd.h, to prevent anyone else from
using it any longer, as glibc works fine without them these days.

The __ARCH_WANT_SYSCALL_OFF_T define might be an exception. If the glibc
developers want to keep using 32-bit off_t by default on all new
architecture, we could include those calls again by default.

Arnd

2015-11-15 15:19:09

by Arnd Bergmann

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

On Friday 13 November 2015 17:10:44 Arnd Bergmann wrote:
> On Friday 13 November 2015 07:38:49 Andrew Pinski wrote:
> > On Fri, Nov 13, 2015 at 7:34 AM, Arnd Bergmann <[email protected]> wrote:
> > > On Thursday 12 November 2015 14:47:18 Andreas Schwab wrote:
> > >> Arnd Bergmann <[email protected]> writes:
> > >>
> > >> > On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
> > >> >> Arnd Bergmann <[email protected]> writes:
> > >> >>
> > >> >> > What do you mean with 32-bit off_t?
> > >> >>
> > >> >> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
> > >> >>
> > >> >> > Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
> > >> >> > __kernel_loff_t?
> > >> >>
> > >> >> Glibc is bridging the user-space ABI to the kernel ABI.
> > >> >
> > >> > Ok, but why?
> > >>
> > >> That's how the ABI is defined right now. I didn't make that up.
> > >
> > > Ok, I guess it will remain a mystery then.
> >
> > The biggest question is here is how much compatibility do we want with
> > other 32bit ABIs?
> > Do we want off_t to be 32bit or 64bit?
>
> I would much prefer off_t to be defined as __kernel_loff_t unconditionally,
> with no support for _FILE_OFFSET_BITS == 32. This is at least what I had
> in mind when I wrote the asm-generic/unistd.h header.
>
> We should probably find out what happened for the other glibc ports that
> were implemented for the architectures using this. It's possible that
> there was a good reason for supporting _FILE_OFFSET_BITS == 32 at the
> time, but I can't think of one and maybe it is one that is no longer
> valid.
>
> Do you know what x86/x32 does for off_t? Do they also implement both
> _FILE_OFFSET_BITS == 32 and _FILE_OFFSET_BITS == 64 on top of the
> 64-bit __kernel_off_t?

I just did a little bit of digging through glibc history and found that
Chris Metcalf added the files that are now in
sysdeps/unix/sysv/linux/generic/wordsize-32/ and that provide the
implementation for 32-bit off_t in glibc on top of the 64-bit
__kernel_off_t.

Chris, do you remember what led to that? Do you think we still need
to have 32-bit off_t on all new architectures, or could we move
on to making 64-bit off_t the default when adding a port?

Arnd

2015-11-15 16:42:27

by Chris Metcalf

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

On 11/15/2015 10:18 AM, Arnd Bergmann wrote:
> On Friday 13 November 2015 17:10:44 Arnd Bergmann wrote:
>> On Friday 13 November 2015 07:38:49 Andrew Pinski wrote:
>>> On Fri, Nov 13, 2015 at 7:34 AM, Arnd Bergmann <[email protected]> wrote:
>>>> On Thursday 12 November 2015 14:47:18 Andreas Schwab wrote:
>>>>> Arnd Bergmann <[email protected]> writes:
>>>>>
>>>>>> On Thursday 12 November 2015 10:44:55 Andreas Schwab wrote:
>>>>>>> Arnd Bergmann <[email protected]> writes:
>>>>>>>
>>>>>>>> What do you mean with 32-bit off_t?
>>>>>>> An ABI with 32-bit off_t, ie. all currently implemented 32-bit ABIs.
>>>>>>>
>>>>>>>> Do you mean that glibc emulates a 32-bit off_t on top of the 64-bit
>>>>>>>> __kernel_loff_t?
>>>>>>> Glibc is bridging the user-space ABI to the kernel ABI.
>>>>>> Ok, but why?
>>>>> That's how the ABI is defined right now. I didn't make that up.
>>>> Ok, I guess it will remain a mystery then.
>>> The biggest question is here is how much compatibility do we want with
>>> other 32bit ABIs?
>>> Do we want off_t to be 32bit or 64bit?
>> I would much prefer off_t to be defined as __kernel_loff_t unconditionally,
>> with no support for _FILE_OFFSET_BITS == 32. This is at least what I had
>> in mind when I wrote the asm-generic/unistd.h header.
>>
>> We should probably find out what happened for the other glibc ports that
>> were implemented for the architectures using this. It's possible that
>> there was a good reason for supporting _FILE_OFFSET_BITS == 32 at the
>> time, but I can't think of one and maybe it is one that is no longer
>> valid.
>>
>> Do you know what x86/x32 does for off_t? Do they also implement both
>> _FILE_OFFSET_BITS == 32 and _FILE_OFFSET_BITS == 64 on top of the
>> 64-bit __kernel_off_t?
> I just did a little bit of digging through glibc history and found that
> Chris Metcalf added the files that are now in
> sysdeps/unix/sysv/linux/generic/wordsize-32/ and that provide the
> implementation for 32-bit off_t in glibc on top of the 64-bit
> __kernel_off_t.
>
> Chris, do you remember what led to that? Do you think we still need
> to have 32-bit off_t on all new architectures, or could we move
> on to making 64-bit off_t the default when adding a port?

I think there are two questions here. The first is whether glibc will change the
default for _FILE_OFFSET_BITS to be 64. This has been discussed in the past, e.g.:

https://sourceware.org/ml/libc-alpha/2014-03/msg00351.html

I've added Rich, Paul, Joseph, and Mike to the cc's as they are probably a good
subset of libc-alpha to help comment on these issues. My sense is that right now,
it wouldn't be possible to add a 32-bit architecture with a non-32-bit default
for _FILE_OFFSET_BITS. And, obviously, this is why, when I added the tilegx32
APIs to glibc in 2011, I needed to provide _FILE_OFFSET_BITS=32 support.

As to the kernel APIs, certainly tilegx32 only has the stat64 API; I just arranged
that the userspace structures are file-offset-bits-agnostic by using ifdefs to
either put a 64-bit value or a (32-bit-value, 32-bit-pad) in the structure.
See sysdeps/unix/sysv/linux/generic/bits/stat.h for example. While the
__field64() macro is kind of nasty, it does provide the 32-bit off_t to those
programs that want it without any particular cost elsewhere in the code.

--
Chris Metcalf, EZChip Semiconductor
http://www.ezchip.com

2015-11-16 10:18:08

by Joseph Myers

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

On Sun, 15 Nov 2015, Chris Metcalf wrote:

> I've added Rich, Paul, Joseph, and Mike to the cc's as they are probably
> a good subset of libc-alpha to help comment on these issues. My sense
> is that right now, it wouldn't be possible to add a 32-bit architecture
> with a non-32-bit default for _FILE_OFFSET_BITS. And, obviously, this
> is why, when I added the tilegx32 APIs to glibc in 2011, I needed to
> provide _FILE_OFFSET_BITS=32 support.

x32 uses 64-bit off_t only. That's not a problem; the problems are
tv_nsec not of type long, a bug we should avoid for all new ports (padding
on tv_nsec is fine; treating that padding as a significant high part of a
64-bit value on input to glibc / kernel interfaces isn't), and maybe some
other types being 64-bit unnecessarily, although as far as I know the
suggested issues there
<https://sourceware.org/bugzilla/show_bug.cgi?id=16438> are all
theoretical.

It's true that we don't have a very clear notion of what "wordsize-64"
sysdeps directories mean in glibc for cases such as x32. See
<https://sourceware.org/bugzilla/show_bug.cgi?id=14116>.

--
Joseph S. Myers
[email protected]

2015-11-16 11:01:53

by Arnd Bergmann

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

On Monday 16 November 2015 10:16:35 Joseph Myers wrote:
> On Sun, 15 Nov 2015, Chris Metcalf wrote:
>
> > I've added Rich, Paul, Joseph, and Mike to the cc's as they are probably
> > a good subset of libc-alpha to help comment on these issues. My sense
> > is that right now, it wouldn't be possible to add a 32-bit architecture
> > with a non-32-bit default for _FILE_OFFSET_BITS. And, obviously, this
> > is why, when I added the tilegx32 APIs to glibc in 2011, I needed to
> > provide _FILE_OFFSET_BITS=32 support.
>
> x32 uses 64-bit off_t only. That's not a problem; the problems are
> tv_nsec not of type long, a bug we should avoid for all new ports (padding
> on tv_nsec is fine; treating that padding as a significant high part of a
> 64-bit value on input to glibc / kernel interfaces isn't), and maybe some
> other types being 64-bit unnecessarily, although as far as I know the
> suggested issues there
> <https://sourceware.org/bugzilla/show_bug.cgi?id=16438> are all
> theoretical.

Let's not get into the tv_nsec discussion today, that is not thankfully
not relevant for arm64 any more at this point. The system call ABI for
arm64/ilp32 is now the same as for any other 32-bit architecture using
the generic ABI, the question we're trying to solve here is only whether it
is ok for new 32-bit glibc ports to only offer a 64-bit off_t as the kernel
currently does (using __kernel_loff_t) or if we still need to support the
_FILE_OFFSET_BITS=32 case.

If I got you right, we can use 64-bit off_t now, so we just need someone
to figure out how to make that the default in glibc for new architectures
while keeping the existing 32-bit architectures unchanged.

Arnd

2015-11-16 11:13:36

by Joseph Myers

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

On Mon, 16 Nov 2015, Arnd Bergmann wrote:

> Let's not get into the tv_nsec discussion today, that is not thankfully
> not relevant for arm64 any more at this point. The system call ABI for
> arm64/ilp32 is now the same as for any other 32-bit architecture using
> the generic ABI, the question we're trying to solve here is only whether it
> is ok for new 32-bit glibc ports to only offer a 64-bit off_t as the kernel
> currently does (using __kernel_loff_t) or if we still need to support the
> _FILE_OFFSET_BITS=32 case.
>
> If I got you right, we can use 64-bit off_t now, so we just need someone
> to figure out how to make that the default in glibc for new architectures
> while keeping the existing 32-bit architectures unchanged.

It would be an entirely new combination. Presumably such a port would
want the "function X is an alias of function Y" aspects of wordsize-64
directories (where that relates to off_t, struct stat etc. as opposed to
long and long long), and the "registers are 64-bit so 64-bit operations
are efficient" aspects, but not all the "64-bit syscall interface"
aspects, so someone would need to review wordsize-64 sysdeps files and
figure out what is or is not relevant to this port.

--
Joseph S. Myers
[email protected]

2015-11-16 11:41:51

by Arnd Bergmann

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

On Monday 16 November 2015 11:12:08 Joseph Myers wrote:
> On Mon, 16 Nov 2015, Arnd Bergmann wrote:
>
> > Let's not get into the tv_nsec discussion today, that is not thankfully
> > not relevant for arm64 any more at this point. The system call ABI for
> > arm64/ilp32 is now the same as for any other 32-bit architecture using
> > the generic ABI, the question we're trying to solve here is only whether it
> > is ok for new 32-bit glibc ports to only offer a 64-bit off_t as the kernel
> > currently does (using __kernel_loff_t) or if we still need to support the
> > _FILE_OFFSET_BITS=32 case.
> >
> > If I got you right, we can use 64-bit off_t now, so we just need someone
> > to figure out how to make that the default in glibc for new architectures
> > while keeping the existing 32-bit architectures unchanged.
>
> It would be an entirely new combination. Presumably such a port would
> want the "function X is an alias of function Y" aspects of wordsize-64
> directories (where that relates to off_t, struct stat etc. as opposed to
> long and long long), and the "registers are 64-bit so 64-bit operations
> are efficient" aspects, but not all the "64-bit syscall interface"
> aspects, so someone would need to review wordsize-64 sysdeps files and
> figure out what is or is not relevant to this port.

There are two separate aspects here:

a) leave out the support for all __off_t based syscalls (__ftruncate,
__lseek, __lxstat, __pread, __preadv, __pwrite, __pwritev, __truncate,
__xstat) as they are no longer needed, and change the handling of
_FILE_OFFSET_BITS so that we default to 64 and error out for anything
else.
This needs to be done for all new 32-bit architectures if you think we
should use a 64-bit off_t from now on, it's not arm64 specific.

b) For an arbitrary subset of these, introduce optimized versions that
are architecture specific and take advantage of the fact that we can
pass 64-bit register arguments on arm64-ilp32.
This is only needed because we diverge from the generic ABI in order
to avoid the silliness of splitting up a 64-bit argument and then
re-assembling it in the kernel.
This should not be needed in the generic ABI and could just live in
sysdeps/unix/sysv/linux/aarch64/wordsize-32, just like we have
special handling for each one in the arm64 in the kernel code for them.

Arnd

2015-11-16 12:04:42

by Joseph Myers

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

On Mon, 16 Nov 2015, Arnd Bergmann wrote:

> There are two separate aspects here:
>
> a) leave out the support for all __off_t based syscalls (__ftruncate,
> __lseek, __lxstat, __pread, __preadv, __pwrite, __pwritev, __truncate,
> __xstat) as they are no longer needed, and change the handling of
> _FILE_OFFSET_BITS so that we default to 64 and error out for anything
> else.
> This needs to be done for all new 32-bit architectures if you think we
> should use a 64-bit off_t from now on, it's not arm64 specific.

It's not a matter of leaving anything out - these would simply use 64-bit
off_t (__off_t and __off64_t would be the same type) and the *64 versions
would be aliases, exactly the same as on 64-bit architectures. (And
_FILE_OFFSET_BITS handling would also be exactly the same as on 64-bit
architectures.) I see no reason for the set of off_t-related symbols that
exist, or which symbols are aliases of which others, to vary between pure
64-bit systems and ILP32 ABIs (for 32-bit or 64-bit architectures) that
simply happen to have had 64-bit off_t from the start.

--
Joseph S. Myers
[email protected]

2015-11-16 12:14:02

by Arnd Bergmann

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

On Monday 16 November 2015 12:03:09 Joseph Myers wrote:
> On Mon, 16 Nov 2015, Arnd Bergmann wrote:
>
> > There are two separate aspects here:
> >
> > a) leave out the support for all __off_t based syscalls (__ftruncate,
> > __lseek, __lxstat, __pread, __preadv, __pwrite, __pwritev, __truncate,
> > __xstat) as they are no longer needed, and change the handling of
> > _FILE_OFFSET_BITS so that we default to 64 and error out for anything
> > else.
> > This needs to be done for all new 32-bit architectures if you think we
> > should use a 64-bit off_t from now on, it's not arm64 specific.
>
> It's not a matter of leaving anything out - these would simply use 64-bit
> off_t (__off_t and __off64_t would be the same type) and the *64 versions
> would be aliases, exactly the same as on 64-bit architectures. (And
> _FILE_OFFSET_BITS handling would also be exactly the same as on 64-bit
> architectures.) I see no reason for the set of off_t-related symbols that
> exist, or which symbols are aliases of which others, to vary between pure
> 64-bit systems and ILP32 ABIs (for 32-bit or 64-bit architectures) that
> simply happen to have had 64-bit off_t from the start.

Ok, fair enough. So we just change the global __OFF_T_TYPE definition
in bits/typesizes.h and override it for all the existing 32-bit ports,
correct?

Arnd

2015-11-16 12:36:24

by Joseph Myers

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

On Mon, 16 Nov 2015, Arnd Bergmann wrote:

> > It's not a matter of leaving anything out - these would simply use 64-bit
> > off_t (__off_t and __off64_t would be the same type) and the *64 versions
> > would be aliases, exactly the same as on 64-bit architectures. (And
> > _FILE_OFFSET_BITS handling would also be exactly the same as on 64-bit
> > architectures.) I see no reason for the set of off_t-related symbols that
> > exist, or which symbols are aliases of which others, to vary between pure
> > 64-bit systems and ILP32 ABIs (for 32-bit or 64-bit architectures) that
> > simply happen to have had 64-bit off_t from the start.
>
> Ok, fair enough. So we just change the global __OFF_T_TYPE definition
> in bits/typesizes.h and override it for all the existing 32-bit ports,
> correct?

Well, it's sysdeps/unix/sysv/linux/generic/bits/typesizes.h that's
relevant - so if future generic architectures will use 64-bit off_t, I
suppose the existing file could be cloned for existing generic
architectures with 32-bit support. And all the types involved in struct
stat are affected (e.g. ino_t), not just off_t. And getting the aliases
right may involve disentangling the different meanings of wordsize-64 into
different sysdeps directories. ("off_t is off64_t" and "stat is stat64"
are not the same thing. See MIPS n64.) And the design work needs to be
done on libc-alpha, not in a random discussion elsewhere.

--
Joseph S. Myers
[email protected]

2015-11-16 13:17:37

by Arnd Bergmann

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

On Monday 16 November 2015 12:34:55 Joseph Myers wrote:
> On Mon, 16 Nov 2015, Arnd Bergmann wrote:
>
> > > It's not a matter of leaving anything out - these would simply use 64-bit
> > > off_t (__off_t and __off64_t would be the same type) and the *64 versions
> > > would be aliases, exactly the same as on 64-bit architectures. (And
> > > _FILE_OFFSET_BITS handling would also be exactly the same as on 64-bit
> > > architectures.) I see no reason for the set of off_t-related symbols that
> > > exist, or which symbols are aliases of which others, to vary between pure
> > > 64-bit systems and ILP32 ABIs (for 32-bit or 64-bit architectures) that
> > > simply happen to have had 64-bit off_t from the start.
> >
> > Ok, fair enough. So we just change the global __OFF_T_TYPE definition
> > in bits/typesizes.h and override it for all the existing 32-bit ports,
> > correct?
>
> Well, it's sysdeps/unix/sysv/linux/generic/bits/typesizes.h that's
> relevant - so if future generic architectures will use 64-bit off_t, I
> suppose the existing file could be cloned for existing generic
> architectures with 32-bit support.

Ok, got it.

> And all the types involved in struct stat are affected (e.g. ino_t),
> not just off_t.

ino_t seems to be the only other type in 'struct stat' that depends
on _FILE_OFFSET_BITS in glibc. On the kernel side, we don't care about
__kernel_ino_t any more, we just leave that defined as 'unsigned long'
while using a plain 'unsigned long long' for 'st_ino' in struct stat64
(and don't use __kernel_ino_t anywhere else either).

> And getting the aliases
> right may involve disentangling the different meanings of wordsize-64 into
> different sysdeps directories. ("off_t is off64_t" and "stat is stat64"
> are not the same thing. See MIPS n64.) And the design work needs to be
> done on libc-alpha, not in a random discussion elsewhere.

Sure. For the moment, we have all the information we need for the kernel
side at least: we will keep using only 64-bit __kernel_loff_t on the
system call side in new architecture ports and let you figure out how
to work with that on the glibc side whenever the next 32-bit port arrives,
which I assume will be arm64-ilp32.

The 'struct stat' discussion will of course come back soon when we get to
the 64-bit time_t patches, or when we introduce the extended stat syscall,
whichever happens first.

Thanks a lot for your help!

Arnd

2015-11-16 13:35:03

by Andreas Schwab

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

Arnd Bergmann <[email protected]> writes:

> ino_t seems to be the only other type in 'struct stat' that depends
> on _FILE_OFFSET_BITS in glibc.

There is also blkcnt_t, and then there is fsblkcnt_t, fsfilcnt_t and
fsword_t in struct statfs.

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-16 13:57:46

by Arnd Bergmann

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

On Monday 16 November 2015 14:34:50 Andreas Schwab wrote:
> Arnd Bergmann <[email protected]> writes:
>
> > ino_t seems to be the only other type in 'struct stat' that depends
> > on _FILE_OFFSET_BITS in glibc.
>
> There is also blkcnt_t, and then there is fsblkcnt_t, fsfilcnt_t and
> fsword_t in struct statfs.

Ok, got it.

Again these are just internal to glibc, the kernel just uses fixed width
types in

typedef struct {
int val[2];
} __kernel_fsid_t;

struct statfs64 {
__u32 f_type;
__u32 f_bsize;
__u64 f_blocks;
__u64 f_bfree;
__u64 f_bavail;
__u64 f_files;
__u64 f_ffree;
__kernel_fsid_t f_fsid;
__u32 f_namelen;
__u32 f_frsize;
__u32 f_flags;
__u32 f_spare[4];
};

so we need to be careful to define them in glibc to match the kernel
types, but the kernel definition doesn't need changes.

Arnd

2015-11-25 03:22:34

by Iosif Harutyunov

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

Sonicwall is very interested in ILP32, is there a way we can get access to the SuSe builds?

Iosif,_

2015-12-01 22:56:07

by Iosif Harutyunov

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64

Sonicwall is very interested in ILP32, is there a way we can get access to the SuSe builds?

Thanks
Iosif,_

2015-12-03 17:05:36

by Yury Norov

[permalink] [raw]
Subject: Re: [RFC PATCH v6 00/17] ILP32 for ARM64


[Please don't drop people from CC.]

On Tue, Dec 01, 2015 at 02:55:56PM -0800, Iosif Harutyunov wrote:
> Sonicwall is very interested in ILP32, is there a way we can get access to the SuSe builds?
>
> Thanks
> Iosif,_
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

You can build it by yourself.

Kernel:
https://github.com/norov/linux/tree/ilp32-v6-rfc3

Glibc:
https://github.com/norov/glibc/tree/thunderx-ilp32-32time_toff_t

>From Andrew:
GCC and binutils support is upstream already and has been for over a
year now. gdb support can be found on the
users/pinskia/gdb-aarch64-ilp32 branch of the binutils-gdb.git repo on
sourceware.org.
(https://sourceware.org/git/?p=binutils-gdb.git;a=shortlog;h=refs/heads/users/pinskia/gdb-aarch64-ilp32).

Latest discussion is here:
https://lkml.org/lkml/2015/11/17/802

BR,
Yury.

2016-04-20 03:27:51

by Yury Norov

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

On Wed, Nov 25, 2015 at 03:07:26AM +0000, Iosif Harutyunov wrote:
> Sonicwall is very interested in ILP32, is there a way we can get access to the SuSe builds?
>
> Iosif,_
>

Hi Iosif,

I just found your email in trash mailbox. Please add my email to CC
explicitly to avoid it. If you still interested in ILP32, find
RFC6 version here: http://www.spinics.net/lists/linux-s390/msg12272.html

There are also manuals for building glibc for it. I'm not sure
someone was building whole SUSE distro against ILP32, but I think
you can build kernel with my patches, and library, and do tests you
interested. Feel free to contact me in case of troubles.

Yury.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/