diff options
author | Koen Kooi <koen.kooi@linaro.org> | 2014-12-11 14:05:53 +0100 |
---|---|---|
committer | Koen Kooi <koen.kooi@linaro.org> | 2014-12-11 14:06:36 +0100 |
commit | a628df7e1e8e6767c6168e32398b902af4d58cc6 (patch) | |
tree | a2609d2e433657b8d871a3193c0b913d3963d93a | |
parent | 5fe176f4014ac30860e00db2d61214a1ef559e89 (diff) |
linux-libc-headers 3.18: add ILP32 patches
Change-Id: Ibd6b7f143012e3d649bf91f16c1c9f919472df98
Signed-off-by: Koen Kooi <koen.kooi@linaro.org>
26 files changed, 2623 insertions, 0 deletions
diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0001-ARM64-Force-LP64-to-compile-the-kernel.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0001-ARM64-Force-LP64-to-compile-the-kernel.patch new file mode 100644 index 00000000..7e203b43 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0001-ARM64-Force-LP64-to-compile-the-kernel.patch @@ -0,0 +1,38 @@ +From a774e70e50f898c7380f6cfb368d55a99ed71956 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:18:55 -0700 +Subject: [PATCH 01/25] ARM64: Force LP64 to compile the kernel + +Sometimes the compiler is set to default to ILP32 ABI so we want to make sure the kernel can compile in that case. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/Makefile | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile +index 20901ff..f3ef4a3 100644 +--- a/arch/arm64/Makefile ++++ b/arch/arm64/Makefile +@@ -20,14 +20,18 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) + KBUILD_DEFCONFIG := defconfig + + KBUILD_CFLAGS += -mgeneral-regs-only ++KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) ++KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) + ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) + KBUILD_CPPFLAGS += -mbig-endian + AS += -EB + LD += -EB ++LDFLAGS += -maarch64linuxb + else + KBUILD_CPPFLAGS += -mlittle-endian + AS += -EL + LD += -EL ++LDFLAGS += -maarch64linux + endif + + CHECKFLAGS += -D__aarch64__ +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0002-ARM64-Rename-COMPAT-to-AARCH32_EL0-in-Kconfig.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0002-ARM64-Rename-COMPAT-to-AARCH32_EL0-in-Kconfig.patch new file mode 100644 index 00000000..74f70ba7 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0002-ARM64-Rename-COMPAT-to-AARCH32_EL0-in-Kconfig.patch @@ -0,0 +1,44 @@ +From b82c6e533186cab8617838c403a2406961b1f73b Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:18:56 -0700 +Subject: [PATCH 02/25] ARM64: Rename COMPAT to AARCH32_EL0 in Kconfig + +We want to split CONFIG_COMPAT so we can use the COMPAT interface in some cases including +for compat binfmt. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/Kconfig | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 9532f8d..f28af3f 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -408,9 +408,13 @@ menu "Userspace binary formats" + source "fs/Kconfig.binfmt" + + config COMPAT ++ def_bool y ++ depends on AARCH32_EL0 ++ select COMPAT_BINFMT_ELF ++ ++config AARCH32_EL0 + bool "Kernel support for 32-bit EL0" + depends on !ARM64_64K_PAGES +- select COMPAT_BINFMT_ELF + select HAVE_UID16 + select OLD_SIGSUSPEND3 + select COMPAT_OLD_SIGACTION +@@ -424,7 +428,7 @@ config COMPAT + + config SYSVIPC_COMPAT + def_bool y +- depends on COMPAT && SYSVIPC ++ depends on AARCH32_EL0 && SYSVIPC + + endmenu + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0003-ARM64-Change-some-CONFIG_COMPAT-over-to-use-CONFIG_A.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0003-ARM64-Change-some-CONFIG_COMPAT-over-to-use-CONFIG_A.patch new file mode 100644 index 00000000..521558f0 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0003-ARM64-Change-some-CONFIG_COMPAT-over-to-use-CONFIG_A.patch @@ -0,0 +1,385 @@ +From 1b07bd82e000daf0755b0671cd7763bde5d76473 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:18:57 -0700 +Subject: [PATCH 03/25] ARM64: Change some CONFIG_COMPAT over to use + CONFIG_AARCH32_EL0 instead + +This patch changes CONFIG_COMPAT checks inside the arm64 which are AARCH32 specific + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/elf.h | 20 +++++++++++++++++--- + arch/arm64/include/asm/fpsimd.h | 2 +- + arch/arm64/include/asm/ptrace.h | 2 +- + arch/arm64/include/asm/signal32.h | 4 ++-- + arch/arm64/include/asm/stat.h | 4 ++-- + arch/arm64/include/asm/unistd.h | 2 +- + arch/arm64/kernel/Makefile | 2 +- + arch/arm64/kernel/asm-offsets.c | 2 +- + arch/arm64/kernel/entry.S | 6 +++--- + arch/arm64/kernel/head.S | 2 +- + arch/arm64/kernel/ptrace.c | 34 ++++++++++++++++++++++++++++------ + arch/arm64/kernel/signal.c | 15 +++++++++++++++ + arch/arm64/kernel/traps.c | 2 +- + arch/arm64/kernel/vdso.c | 5 +++-- + drivers/clocksource/arm_arch_timer.c | 2 +- + 15 files changed, 78 insertions(+), 26 deletions(-) + +diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h +index 1f65be3..afa0f43 100644 +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -171,14 +171,16 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm); + + #define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3) + ++#ifdef CONFIG_AARCH32_EL0 ++ + /* AArch32 registers. */ +-#define COMPAT_ELF_NGREG 18 ++#define COMPAT_A32_ELF_NGREG 18 + typedef unsigned int compat_elf_greg_t; +-typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; ++typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG]; + + /* AArch32 EABI. */ + #define EF_ARM_EABI_MASK 0xff000000 +-#define compat_elf_check_arch(x) (((x)->e_machine == EM_ARM) && \ ++#define compat_a32_elf_check_arch(x) (((x)->e_machine == EM_ARM) && \ + ((x)->e_flags & EF_ARM_EABI_MASK)) + + #define compat_start_thread compat_start_thread +@@ -189,6 +191,18 @@ extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, + #define compat_arch_setup_additional_pages \ + aarch32_setup_vectors_page + ++#else ++ ++typedef elf_greg_t compat_elf_greg_t; ++typedef elf_gregset_t compat_elf_gregset_t; ++#define compat_a32_elf_check_arch(x) 0 ++#define COMPAT_SET_PERSONALITY(ex) ++#define COMPAT_ARCH_DLINFO ++ ++#endif ++ ++#define compat_elf_check_arch(x) compat_a32_elf_check_arch(x) ++ + #endif /* CONFIG_COMPAT */ + + #endif +diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h +index 50f559f..63b19f1 100644 +--- a/arch/arm64/include/asm/fpsimd.h ++++ b/arch/arm64/include/asm/fpsimd.h +@@ -52,7 +52,7 @@ struct fpsimd_partial_state { + }; + + +-#if defined(__KERNEL__) && defined(CONFIG_COMPAT) ++#if defined(__KERNEL__) && defined(CONFIG_AARCH32_EL0) + /* Masks for extracting the FPSR and FPCR from the FPSCR */ + #define VFP_FPSCR_STAT_MASK 0xf800009f + #define VFP_FPSCR_CTRL_MASK 0x07f79f00 +diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h +index 41ed9e1..690a380 100644 +--- a/arch/arm64/include/asm/ptrace.h ++++ b/arch/arm64/include/asm/ptrace.h +@@ -113,7 +113,7 @@ struct pt_regs { + + #define arch_has_single_step() (1) + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + #define compat_thumb_mode(regs) \ + (((regs)->pstate & COMPAT_PSR_T_BIT)) + #else +diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h +index eeaa975..522c345 100644 +--- a/arch/arm64/include/asm/signal32.h ++++ b/arch/arm64/include/asm/signal32.h +@@ -17,7 +17,7 @@ + #define __ASM_SIGNAL32_H + + #ifdef __KERNEL__ +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + #include <linux/compat.h> + + #define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500 +@@ -47,6 +47,6 @@ static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t + static inline void compat_setup_restart_syscall(struct pt_regs *regs) + { + } +-#endif /* CONFIG_COMPAT */ ++#endif /* CONFIG_AARCH32_EL0 */ + #endif /* __KERNEL__ */ + #endif /* __ASM_SIGNAL32_H */ +diff --git a/arch/arm64/include/asm/stat.h b/arch/arm64/include/asm/stat.h +index 15e3559..e3b5865 100644 +--- a/arch/arm64/include/asm/stat.h ++++ b/arch/arm64/include/asm/stat.h +@@ -18,7 +18,7 @@ + + #include <uapi/asm/stat.h> + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + + #include <asm/compat.h> + +@@ -57,5 +57,5 @@ struct stat64 { + compat_u64 st_ino; + }; + +-#endif ++#endif /* CONFIG_AARCH32_EL0 */ + #endif +diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h +index 6d2bf41..70e5559 100644 +--- a/arch/arm64/include/asm/unistd.h ++++ b/arch/arm64/include/asm/unistd.h +@@ -13,7 +13,7 @@ + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + #define __ARCH_WANT_COMPAT_SYS_GETDENTS64 + #define __ARCH_WANT_COMPAT_STAT64 + #define __ARCH_WANT_SYS_GETHOSTNAME +diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile +index 5bd029b..f59d113 100644 +--- a/arch/arm64/kernel/Makefile ++++ b/arch/arm64/kernel/Makefile +@@ -17,7 +17,7 @@ arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ + hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \ + cpuinfo.o + +-arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ ++arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \ + sys_compat.o + arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o + arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c +index 9a9fce0..d9c429c 100644 +--- a/arch/arm64/kernel/asm-offsets.c ++++ b/arch/arm64/kernel/asm-offsets.c +@@ -53,7 +53,7 @@ int main(void) + DEFINE(S_X7, offsetof(struct pt_regs, regs[7])); + DEFINE(S_LR, offsetof(struct pt_regs, regs[30])); + DEFINE(S_SP, offsetof(struct pt_regs, sp)); +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + DEFINE(S_COMPAT_SP, offsetof(struct pt_regs, compat_sp)); + #endif + DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate)); +diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S +index 726b910..5a1430c 100644 +--- a/arch/arm64/kernel/entry.S ++++ b/arch/arm64/kernel/entry.S +@@ -196,7 +196,7 @@ ENTRY(vectors) + ventry el0_fiq_invalid // FIQ 64-bit EL0 + ventry el0_error_invalid // Error 64-bit EL0 + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + ventry el0_sync_compat // Synchronous 32-bit EL0 + ventry el0_irq_compat // IRQ 32-bit EL0 + ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 +@@ -236,7 +236,7 @@ el0_error_invalid: + inv_entry 0, BAD_ERROR + ENDPROC(el0_error_invalid) + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + el0_fiq_invalid_compat: + inv_entry 0, BAD_FIQ, 32 + ENDPROC(el0_fiq_invalid_compat) +@@ -398,7 +398,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 0a6e4f9..1934bc8 100644 +--- a/arch/arm64/kernel/head.S ++++ b/arch/arm64/kernel/head.S +@@ -323,7 +323,7 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems + mov x0, #0x33ff + msr cptr_el2, x0 // Disable copro. traps to EL2 + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + msr hstr_el2, xzr // Disable CP15 traps to EL2 + #endif + +diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c +index 8a4ae8e..04f32d7 100644 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -36,6 +36,7 @@ + #include <linux/regset.h> + #include <linux/tracehook.h> + #include <linux/elf.h> ++#include <linux/errno.h> + + #include <asm/compat.h> + #include <asm/debug-monitors.h> +@@ -75,7 +76,7 @@ static void ptrace_hbptriggered(struct perf_event *bp, + .si_addr = (void __user *)(bkpt->trigger), + }; + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + int i; + + if (!is_compat_task()) +@@ -617,6 +618,7 @@ static const struct user_regset_view user_aarch64_view = { + + #ifdef CONFIG_COMPAT + #include <linux/compat.h> ++#ifdef CONFIG_AARCH32_EL0 + + enum compat_regset { + REGSET_COMPAT_GPR, +@@ -793,7 +795,7 @@ static int compat_vfp_set(struct task_struct *target, + static const struct user_regset aarch32_regsets[] = { + [REGSET_COMPAT_GPR] = { + .core_note_type = NT_PRSTATUS, +- .n = COMPAT_ELF_NGREG, ++ .n = COMPAT_A32_ELF_NGREG, + .size = sizeof(compat_elf_greg_t), + .align = sizeof(compat_elf_greg_t), + .get = compat_gpr_get, +@@ -991,8 +993,8 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num, + } + #endif /* CONFIG_HAVE_HW_BREAKPOINT */ + +-long compat_arch_ptrace(struct task_struct *child, compat_long_t request, +- compat_ulong_t caddr, compat_ulong_t cdata) ++long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request, ++ compat_ulong_t caddr, compat_ulong_t cdata) + { + unsigned long addr = caddr; + unsigned long data = cdata; +@@ -1068,11 +1070,31 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + + return ret; + } +-#endif /* CONFIG_COMPAT */ ++#else /* !CONFIG_AARCH32_EL0 */ ++long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request, ++ compat_ulong_t caddr, compat_ulong_t cdata) ++{ ++ return -EINVAL; ++} ++#endif /* !CONFIG_AARCH32_EL0 */ ++ ++/* ++ * In ILP32, compat_arch_ptrace is used via the compat syscall, we don't need ++ * to do anything special for ILP32 though; only for AARCH32. ++ */ ++long compat_arch_ptrace(struct task_struct *child, compat_long_t request, ++ compat_ulong_t caddr, compat_ulong_t cdata) ++{ ++ if (is_compat_task()) ++ return compat_a32_arch_ptrace(child, request, caddr, cdata); ++ return compat_ptrace_request(child, request, caddr, cdata); ++} ++#endif ++ + + const struct user_regset_view *task_user_regset_view(struct task_struct *task) + { +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + if (is_compat_thread(task_thread_info(task))) + return &user_aarch32_view; + #endif +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index 6fa7921..8527d99 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -421,3 +421,18 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, + fpsimd_restore_current_state(); + + } ++ ++/* ++ * Some functions are needed for compat ptrace but we don't define ++ * them if we don't have AARCH32 support compiled in ++ */ ++#if defined CONFIG_COMPAT && !defined CONFIG_AARCH32_EL0 ++int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) ++{ ++ return -EFAULT; ++} ++int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) ++{ ++ return -EFAULT; ++} ++#endif +diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c +index de1b085..4fd16f3 100644 +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -287,7 +287,7 @@ long compat_arm_syscall(struct pt_regs *regs); + + asmlinkage long do_ni_syscall(struct pt_regs *regs) + { +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + long ret; + if (is_compat_task()) { + ret = compat_arm_syscall(regs); +diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c +index 32aeea0..a777ac3 100644 +--- a/arch/arm64/kernel/vdso.c ++++ b/arch/arm64/kernel/vdso.c +@@ -35,6 +35,7 @@ + #include <asm/signal32.h> + #include <asm/vdso.h> + #include <asm/vdso_datapage.h> ++#include <asm/compat.h> + + extern char vdso_start, vdso_end; + static unsigned long vdso_pages; +@@ -49,7 +50,7 @@ static union { + } vdso_data_store __page_aligned_data; + struct vdso_data *vdso_data = &vdso_data_store.data; + +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + /* + * Create and map the vectors page for AArch32 tasks. + */ +@@ -107,7 +108,7 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) + + return PTR_ERR_OR_ZERO(ret); + } +-#endif /* CONFIG_COMPAT */ ++#endif /* CONFIG_AARCH32_EL0 */ + + static struct vm_special_mapping vdso_spec[2]; + +diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c +index 43005d4..9d4e24c 100644 +--- a/drivers/clocksource/arm_arch_timer.c ++++ b/drivers/clocksource/arm_arch_timer.c +@@ -309,7 +309,7 @@ static void arch_timer_evtstrm_enable(int divider) + | ARCH_TIMER_VIRT_EVT_EN; + arch_timer_set_cntkctl(cntkctl); + elf_hwcap |= HWCAP_EVTSTRM; +-#ifdef CONFIG_COMPAT ++#ifdef CONFIG_AARCH32_EL0 + compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; + #endif + } +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0004-ARM64-ILP32-Set-kernel_long-to-long-long-so-we-can-r.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0004-ARM64-ILP32-Set-kernel_long-to-long-long-so-we-can-r.patch new file mode 100644 index 00000000..f9b67d88 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0004-ARM64-ILP32-Set-kernel_long-to-long-long-so-we-can-r.patch @@ -0,0 +1,34 @@ +From d95606261541cbd57ecf8a16d5b36541a12edaac Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:18:58 -0700 +Subject: [PATCH 04/25] ARM64:ILP32: Set kernel_long to long long so we can + reuse most of the same syscalls as LP64 + +Since we want time_t and some other userland types to be the same between ILP32 and LP64, we define __kernel_long_t to be long long. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/uapi/asm/posix_types.h | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h +index 7985ff6..0961945 100644 +--- a/arch/arm64/include/uapi/asm/posix_types.h ++++ b/arch/arm64/include/uapi/asm/posix_types.h +@@ -5,6 +5,12 @@ typedef unsigned short __kernel_old_uid_t; + typedef unsigned short __kernel_old_gid_t; + #define __kernel_old_uid_t __kernel_old_uid_t + ++#ifdef __ILP32__ ++typedef long long __kernel_long_t; ++typedef unsigned long long __kernel_ulong_t; ++#define __kernel_long_t __kernel_long_t ++#endif ++ + #include <asm-generic/posix_types.h> + +-#endif /* __ASM_POSIX_TYPES_H */ ++#endif /* __ASM_POSIX_TYPES_H */ +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0005-ARM64-UAPI-Set-the-correct-__BITS_PER_LONG-for-ILP32.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0005-ARM64-UAPI-Set-the-correct-__BITS_PER_LONG-for-ILP32.patch new file mode 100644 index 00000000..2fb9d760 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0005-ARM64-UAPI-Set-the-correct-__BITS_PER_LONG-for-ILP32.patch @@ -0,0 +1,35 @@ +From 77cac67f6e71bfe42253aaf674d5a49e17a5812e Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:18:59 -0700 +Subject: [PATCH 05/25] ARM64:UAPI: Set the correct __BITS_PER_LONG for ILP32 + +We need to say to the userland API that bits per long is 32bits for ILP32. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/uapi/asm/bitsperlong.h | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h +index fce9c29..bb716d0 100644 +--- a/arch/arm64/include/uapi/asm/bitsperlong.h ++++ b/arch/arm64/include/uapi/asm/bitsperlong.h +@@ -16,7 +16,14 @@ + #ifndef __ASM_BITSPERLONG_H + #define __ASM_BITSPERLONG_H + +-#define __BITS_PER_LONG 64 ++/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */ ++#ifdef __LP64__ ++# define __BITS_PER_LONG 64 ++#elif defined(__ILP32__) ++# define __BITS_PER_LONG 32 ++#else ++# error "Unknown ABI; not ILP32 or LP64" ++#endif + + #include <asm-generic/bitsperlong.h> + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0006-Allow-for-some-signal-structures-to-be-the-same-betw.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0006-Allow-for-some-signal-structures-to-be-the-same-betw.patch new file mode 100644 index 00000000..2795d6e5 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0006-Allow-for-some-signal-structures-to-be-the-same-betw.patch @@ -0,0 +1,133 @@ +From 22cc53f5d94dcc75af3e900e223dd870146490ae Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:00 -0700 +Subject: [PATCH 06/25] Allow for some signal structures to be the same between + a 32bit ABI and the 64bit ABI + +In ARM64, we want to allow the signal related structures to be same between the +32bit (ILP32) and the 64bit ABIs (LP64). We still want to use the generic +include files so we need some new defines that are used in UAPI; they +default to the same as it is before. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + include/uapi/asm-generic/siginfo.h | 17 +++++++++++++---- + include/uapi/asm-generic/signal.h | 27 +++++++++++++++++++++++---- + 2 files changed, 36 insertions(+), 8 deletions(-) + +diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h +index ba5be7f..cb44f86 100644 +--- a/include/uapi/asm-generic/siginfo.h ++++ b/include/uapi/asm-generic/siginfo.h +@@ -4,9 +4,17 @@ + #include <linux/compiler.h> + #include <linux/types.h> + ++#ifndef __SIGINFO_VOIDPTR ++#define __SIGINFO_VOIDPTR(field) void __user *field ++#endif ++ ++#ifndef __SIGINFO_BAND ++#define __SIGINFO_BAND(field) __ARCH_SI_BAND_T field ++#endif ++ + typedef union sigval { + int sival_int; +- void __user *sival_ptr; ++ __SIGINFO_VOIDPTR(sival_ptr); + } sigval_t; + + /* +@@ -86,7 +94,7 @@ typedef struct siginfo { + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { +- void __user *_addr; /* faulting insn/memory ref. */ ++ __SIGINFO_VOIDPTR(_addr); /* faulting insn/memory ref. */ + #ifdef __ARCH_SI_TRAPNO + int _trapno; /* TRAP # which caused the signal */ + #endif +@@ -95,13 +103,13 @@ typedef struct siginfo { + + /* SIGPOLL */ + struct { +- __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ ++ __SIGINFO_BAND(_band); /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + + /* SIGSYS */ + struct { +- void __user *_call_addr; /* calling user insn */ ++ __SIGINFO_VOIDPTR(_call_addr); /* calling user insn */ + int _syscall; /* triggering system call number */ + unsigned int _arch; /* AUDIT_ARCH_* of syscall */ + } _sigsys; +@@ -283,6 +291,7 @@ typedef struct sigevent { + int _pad[SIGEV_PAD_SIZE]; + int _tid; + ++ /* Note these two are handled only in userspace */ + struct { + void (*_function)(sigval_t); + void *_attribute; /* really pthread_attr_t */ +diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h +index 9df61f1..c4ce238 100644 +--- a/include/uapi/asm-generic/signal.h ++++ b/include/uapi/asm-generic/signal.h +@@ -4,7 +4,9 @@ + #include <linux/types.h> + + #define _NSIG 64 ++#ifndef _NSIG_BPW + #define _NSIG_BPW __BITS_PER_LONG ++#endif + #define _NSIG_WORDS (_NSIG / _NSIG_BPW) + + #define SIGHUP 1 +@@ -83,9 +85,13 @@ + #define MINSIGSTKSZ 2048 + #define SIGSTKSZ 8192 + ++#ifndef __SIGSET_INNER_TYPE ++#define __SIGSET_INNER_TYPE unsigned long ++#endif ++ + #ifndef __ASSEMBLY__ + typedef struct { +- unsigned long sig[_NSIG_WORDS]; ++ __SIGSET_INNER_TYPE sig[_NSIG_WORDS]; + } sigset_t; + + /* not actually used, but required for linux/syscalls.h */ +@@ -98,11 +104,24 @@ typedef unsigned long old_sigset_t; + #endif + + #ifndef __KERNEL__ ++ ++#ifndef __SIGACTION_HANDLER ++#define __SIGACTION_HANDLER(field) __sighandler_t field ++#endif ++ ++#ifndef __SIGACTION_FLAGS ++#define __SIGACTION_FLAGS(field) unsigned long field ++#endif ++ ++#ifndef __SIGACTION_RESTORER ++#define __SIGACTION_RESTORER(field) __sigrestore_t field ++#endif ++ + struct sigaction { +- __sighandler_t sa_handler; +- unsigned long sa_flags; ++ __SIGACTION_HANDLER(sa_handler); ++ __SIGACTION_FLAGS(sa_flags); + #ifdef SA_RESTORER +- __sigrestore_t sa_restorer; ++ __SIGACTION_RESTORER(sa_restorer); + #endif + sigset_t sa_mask; /* mask last for extensibility */ + }; +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0007-ARM64-ILP32-Use-the-same-size-and-layout-of-the-sign.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0007-ARM64-ILP32-Use-the-same-size-and-layout-of-the-sign.patch new file mode 100644 index 00000000..02e5b2d2 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0007-ARM64-ILP32-Use-the-same-size-and-layout-of-the-sign.patch @@ -0,0 +1,115 @@ +From d3813d97d5face12f9762a394e845fff7774c0dc Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:01 -0700 +Subject: [PATCH 07/25] ARM64:ILP32: Use the same size and layout of the signal + structures for ILP32 as for LP64 + +Defines the macros which allow the signal structures to be the same between ILP32 and LP64. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/uapi/asm/siginfo.h | 33 +++++++++++++++++++++++++++++++++ + arch/arm64/include/uapi/asm/signal.h | 34 ++++++++++++++++++++++++++++++++++ + 2 files changed, 67 insertions(+) + +diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h +index 5a74a08..c80c612 100644 +--- a/arch/arm64/include/uapi/asm/siginfo.h ++++ b/arch/arm64/include/uapi/asm/siginfo.h +@@ -1,5 +1,6 @@ + /* + * Copyright (C) 2012 ARM Ltd. ++ * Copyright (C) 2014 Cavium Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as +@@ -18,6 +19,38 @@ + + #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) + ++#ifdef __ILP32__ ++ ++/* ++ * For ILP32, the siginfo structures should share the same layout and ++ * alignement requirements as LP64 ABI. ++ * To do this, use an extra pad field and add aligned attribute ++ * to the structure. ++ */ ++ ++# ifdef __AARCH64EB__ ++# define __SIGINFO_INNER(type, field) \ ++ int __pad#field; \ ++ type field ++# else ++# define __SIGINFO_INNER(type, field) \ ++ type field; \ ++ int __pad#field ++# endif ++ ++# undef __SIGINFO_VOIDPTR ++# define __SIGINFO_VOIDPTR(field) \ ++ __SIGINFO_INNER(void __user*, field) ++# undef __SIGINFO_BAND ++ ++# define __SIGINFO_BAND(field) \ ++ __SIGINFO_INNER(long, field) ++ ++/* Make the alignment of siginfo always 8 byte aligned. */ ++#define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8))) ++ ++#endif ++ + #include <asm-generic/siginfo.h> + + #endif +diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h +index 8d1e723..d33a5f7 100644 +--- a/arch/arm64/include/uapi/asm/signal.h ++++ b/arch/arm64/include/uapi/asm/signal.h +@@ -16,9 +16,43 @@ + #ifndef __ASM_SIGNAL_H + #define __ASM_SIGNAL_H + ++#include <asm/posix-types.h> ++ + /* Required for AArch32 compatibility. */ + #define SA_RESTORER 0x04000000 + ++/* ++ * Since sigset is a bitmask, we need the same size fields for ILP32 ++ * and LP64. With big-endian, 32bit bitmask does not match up to ++ * 64bit bitmask (unlike with little-endian). ++ */ ++#ifdef __ILP32__ ++ ++#define __SIGSET_INNER_TYPE __kernel_ulong_t ++#define _NSIG_BPW 64 ++ ++# ifdef __AARCH64EB__ ++# define __SIGNAL_INNER(type, field) \ ++ int __pad_##field; \ ++ type field; ++# else ++# define __SIGNAL_INNER(type, field) \ ++ type field; \ ++ int __pad_##field; ++# endif ++ ++# define __SIGACTION_HANDLER(field) \ ++ __SIGNAL_INNER(__sighandler_t, field) ++ ++ ++#define __SIGACTION_FLAGS(field) \ ++ __kernel_ulong_t field ++ ++#define __SIGACTION_RESTORER(field) \ ++ __SIGNAL_INNER(__sigrestore_t, field) ++ ++#endif ++ + #include <asm-generic/signal.h> + + #endif +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0008-Allow-a-32bit-ABI-to-use-the-naming-of-the-64bit-ABI.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0008-Allow-a-32bit-ABI-to-use-the-naming-of-the-64bit-ABI.patch new file mode 100644 index 00000000..6252ee5d --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0008-Allow-a-32bit-ABI-to-use-the-naming-of-the-64bit-ABI.patch @@ -0,0 +1,36 @@ +From f7185bf731efd1015821f4153ac17d653dbd23c9 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:02 -0700 +Subject: [PATCH 08/25] Allow a 32bit ABI to use the naming of the 64bit ABI + syscalls to avoid confusion of not splitting the registers + +In the ARM64 ILP32 case, we want to say the syscalls that normally would pass +64bit as two arguments are now passing as one so want to use the 64bit +naming scheme. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + include/uapi/asm-generic/unistd.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h +index 22749c1..5996166 100644 +--- a/include/uapi/asm-generic/unistd.h ++++ b/include/uapi/asm-generic/unistd.h +@@ -883,8 +883,12 @@ __SYSCALL(__NR_fork, sys_ni_syscall) + * they take different names. + * Here we map the numbers so that both versions + * use the same syscall table layout. ++ * For 32bit abis where 64bit can be passed via one ++ * register, use the same naming as the 64bit ones ++ * as they will only have a 64 bit off_t. + */ +-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT) ++#if (__BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)) || \ ++ defined(__ARCH_WANT_64BIT_SYSCALLS) + #define __NR_fcntl __NR3264_fcntl + #define __NR_statfs __NR3264_statfs + #define __NR_fstatfs __NR3264_fstatfs +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0009-ARM64-ILP32-Use-the-same-syscall-names-as-LP64.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0009-ARM64-ILP32-Use-the-same-syscall-names-as-LP64.patch new file mode 100644 index 00000000..180e841e --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0009-ARM64-ILP32-Use-the-same-syscall-names-as-LP64.patch @@ -0,0 +1,30 @@ +From ed722513a020c655797eb855c2d6ccf525d1c10c Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:03 -0700 +Subject: [PATCH 09/25] ARM64:ILP32: Use the same syscall names as LP64 + +Define __SYSCALL_NONCOMPAT so we use the 64bit naming scheme for ILP32. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/uapi/asm/unistd.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h +index 1caadc2..13cbf8d 100644 +--- a/arch/arm64/include/uapi/asm/unistd.h ++++ b/arch/arm64/include/uapi/asm/unistd.h +@@ -13,4 +13,10 @@ + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ ++ ++/* For ILP32, we want to use the non compat names. */ ++#if defined(__ILP32__) ++#define __ARCH_WANT_64BIT_SYSCALLS ++#endif ++ + #include <asm-generic/unistd.h> +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0010-ARM64-Introduce-is_a32_task-is_a32_thread-and-TIF_AA.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0010-ARM64-Introduce-is_a32_task-is_a32_thread-and-TIF_AA.patch new file mode 100644 index 00000000..a8abde52 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0010-ARM64-Introduce-is_a32_task-is_a32_thread-and-TIF_AA.patch @@ -0,0 +1,246 @@ +From bfe2beb3a5384b06868a0ff6cff23a94825b81b7 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:04 -0700 +Subject: [PATCH 10/25] ARM64: Introduce is_a32_task/is_a32_thread and + TIF_AARCH32 and use them in the correct locations + +This patch introduces is_a32_compat_task and is_a32_thread so it is easier to say this is a a32 specific thread or a generic compat thread/task. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/compat.h | 21 +++++++++++++++++++++ + arch/arm64/include/asm/elf.h | 12 ++++++++++-- + arch/arm64/include/asm/thread_info.h | 1 + + arch/arm64/kernel/hw_breakpoint.c | 7 ++++--- + arch/arm64/kernel/process.c | 6 +++--- + arch/arm64/kernel/ptrace.c | 8 ++++---- + arch/arm64/kernel/signal.c | 5 +++-- + arch/arm64/kernel/traps.c | 2 +- + 8 files changed, 47 insertions(+), 15 deletions(-) + +diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h +index 56de5aa..91ccca6 100644 +--- a/arch/arm64/include/asm/compat.h ++++ b/arch/arm64/include/asm/compat.h +@@ -311,5 +311,26 @@ static inline int is_compat_thread(struct thread_info *thread) + } + + #endif /* CONFIG_COMPAT */ ++ ++#ifdef CONFIG_AARCH32_EL0 ++static inline int is_a32_compat_task(void) ++{ ++ return test_thread_flag(TIF_AARCH32); ++} ++static inline int is_a32_compat_thread(struct thread_info *thread) ++{ ++ return test_ti_thread_flag(thread, TIF_AARCH32); ++} ++#else ++static inline int is_a32_compat_task(void) ++{ ++ return 0; ++} ++static inline int is_a32_compat_thread(struct thread_info *thread) ++{ ++ return 0; ++} ++#endif ++ + #endif /* __KERNEL__ */ + #endif /* __ASM_COMPAT_H */ +diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h +index afa0f43..69291a0 100644 +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -135,7 +135,11 @@ extern unsigned long randomize_et_dyn(unsigned long base); + */ + #define ELF_PLAT_INIT(_r, load_addr) (_r)->regs[0] = 0 + +-#define SET_PERSONALITY(ex) clear_thread_flag(TIF_32BIT); ++#define SET_PERSONALITY(ex) \ ++do { \ ++ clear_thread_flag(TIF_AARCH32); \ ++ clear_thread_flag(TIF_32BIT); \ ++} while (0) + + #define ARCH_DLINFO \ + do { \ +@@ -184,7 +188,11 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG]; + ((x)->e_flags & EF_ARM_EABI_MASK)) + + #define compat_start_thread compat_start_thread +-#define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT); ++#define COMPAT_SET_PERSONALITY(ex) \ ++do { \ ++ set_thread_flag(TIF_AARCH32); \ ++ set_thread_flag(TIF_32BIT); \ ++} while (0) + #define COMPAT_ARCH_DLINFO + extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, + int uses_interp); +diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h +index 459bf8e..a185105 100644 +--- a/arch/arm64/include/asm/thread_info.h ++++ b/arch/arm64/include/asm/thread_info.h +@@ -119,6 +119,7 @@ static inline struct thread_info *current_thread_info(void) + #define TIF_SINGLESTEP 21 + #define TIF_32BIT 22 /* 32bit process */ + #define TIF_SWITCH_MM 23 /* deferred switch_mm */ ++#define TIF_AARCH32 24 /* AARCH32 process */ + + #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) + #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c +index df1cf15..8e46a67 100644 +--- a/arch/arm64/kernel/hw_breakpoint.c ++++ b/arch/arm64/kernel/hw_breakpoint.c +@@ -28,6 +28,7 @@ + #include <linux/ptrace.h> + #include <linux/smp.h> + ++#include <asm/compat.h> + #include <asm/current.h> + #include <asm/debug-monitors.h> + #include <asm/hw_breakpoint.h> +@@ -433,7 +434,7 @@ static int arch_build_bp_info(struct perf_event *bp) + * Watchpoints can be of length 1, 2, 4 or 8 bytes. + */ + if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { +- if (is_compat_task()) { ++ if (is_a32_compat_task()) { + if (info->ctrl.len != ARM_BREAKPOINT_LEN_2 && + info->ctrl.len != ARM_BREAKPOINT_LEN_4) + return -EINVAL; +@@ -490,7 +491,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) + * AArch32 tasks expect some simple alignment fixups, so emulate + * that here. + */ +- if (is_compat_task()) { ++ if (is_a32_compat_task()) { + if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) + alignment_mask = 0x7; + else +@@ -677,7 +678,7 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, + + info = counter_arch_bp(wp); + /* AArch32 watchpoints are either 4 or 8 bytes aligned. */ +- if (is_compat_task()) { ++ if (is_a32_compat_task()) { + if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) + alignment_mask = 0x7; + else +diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c +index fde9923..4ae5562 100644 +--- a/arch/arm64/kernel/process.c ++++ b/arch/arm64/kernel/process.c +@@ -253,7 +253,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, + if (likely(!(p->flags & PF_KTHREAD))) { + *childregs = *current_pt_regs(); + childregs->regs[0] = 0; +- if (is_compat_thread(task_thread_info(p))) { ++ if (is_a32_compat_thread(task_thread_info(p))) { + if (stack_start) + childregs->compat_sp = stack_start; + } else { +@@ -294,12 +294,12 @@ static void tls_thread_switch(struct task_struct *next) + { + unsigned long tpidr, tpidrro; + +- if (!is_compat_task()) { ++ if (!is_a32_compat_task()) { + asm("mrs %0, tpidr_el0" : "=r" (tpidr)); + current->thread.tp_value = tpidr; + } + +- if (is_compat_thread(task_thread_info(next))) { ++ if (is_a32_compat_thread(task_thread_info(next))) { + tpidr = 0; + tpidrro = next->thread.tp_value; + } else { +diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c +index 04f32d7..6d6f62d 100644 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -79,7 +79,7 @@ static void ptrace_hbptriggered(struct perf_event *bp, + #ifdef CONFIG_AARCH32_EL0 + int i; + +- if (!is_compat_task()) ++ if (!is_a32_compat_task()) + goto send_sig; + + for (i = 0; i < ARM_MAX_BRP; ++i) { +@@ -1085,7 +1085,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request, + long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + compat_ulong_t caddr, compat_ulong_t cdata) + { +- if (is_compat_task()) ++ if (is_a32_compat_task()) + return compat_a32_arch_ptrace(child, request, caddr, cdata); + return compat_ptrace_request(child, request, caddr, cdata); + } +@@ -1095,7 +1095,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + const struct user_regset_view *task_user_regset_view(struct task_struct *task) + { + #ifdef CONFIG_AARCH32_EL0 +- if (is_compat_thread(task_thread_info(task))) ++ if (is_a32_compat_thread(task_thread_info(task))) + return &user_aarch32_view; + #endif + return &user_aarch64_view; +@@ -1122,7 +1122,7 @@ static void tracehook_report_syscall(struct pt_regs *regs, + * A scratch register (ip(r12) on AArch32, x7 on AArch64) is + * used to denote syscall entry/exit: + */ +- regno = (is_compat_task() ? 12 : 7); ++ regno = (is_a32_compat_task() ? 12 : 7); + saved_reg = regs->regs[regno]; + regs->regs[regno] = dir; + +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index 8527d99..f47c064 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -26,6 +26,7 @@ + #include <linux/tracehook.h> + #include <linux/ratelimit.h> + ++#include <asm/compat.h> + #include <asm/debug-monitors.h> + #include <asm/elf.h> + #include <asm/cacheflush.h> +@@ -276,7 +277,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, + + static void setup_restart_syscall(struct pt_regs *regs) + { +- if (is_compat_task()) ++ if (is_a32_compat_task()) + compat_setup_restart_syscall(regs); + else + regs->regs[8] = __NR_restart_syscall; +@@ -302,7 +303,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) + /* + * Set up the stack frame + */ +- if (is_compat_task()) { ++ if (is_a32_compat_task()) { + if (ksig->ka.sa.sa_flags & SA_SIGINFO) + ret = compat_setup_rt_frame(usig, ksig, oldset, regs); + else +diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c +index 4fd16f3..dd21920 100644 +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -289,7 +289,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) + { + #ifdef CONFIG_AARCH32_EL0 + long ret; +- if (is_compat_task()) { ++ if (is_a32_compat_task()) { + ret = compat_arm_syscall(regs); + if (ret != -ENOSYS) + return ret; +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0011-ARM64-Add-is_ilp32_compat_task-and-is_ilp32_compat_t.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0011-ARM64-Add-is_ilp32_compat_task-and-is_ilp32_compat_t.patch new file mode 100644 index 00000000..93314a68 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0011-ARM64-Add-is_ilp32_compat_task-and-is_ilp32_compat_t.patch @@ -0,0 +1,49 @@ +From a7324076e52f254064f913d48b0ba75edfabbff7 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:05 -0700 +Subject: [PATCH 11/25] ARM64: Add is_ilp32_compat_task and + is_ilp32_compat_thread + +This patch adds the functions which returns if the current task is an +ILP32 task and one returns if the thread is an ILP32 thread. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/compat.h | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h +index 91ccca6..fe390b7 100644 +--- a/arch/arm64/include/asm/compat.h ++++ b/arch/arm64/include/asm/compat.h +@@ -332,5 +332,27 @@ static inline int is_a32_compat_thread(struct thread_info *thread) + } + #endif + ++#ifdef CONFIG_ARM64_ILP32 ++static inline int is_ilp32_compat_task(void) ++{ ++ return test_thread_flag(TIF_32BIT) && !is_a32_compat_task(); ++} ++static inline int is_ilp32_compat_thread(struct thread_info *thread) ++{ ++ return test_ti_thread_flag(thread, TIF_32BIT) && ++ !is_a32_compat_thread(thread); ++} ++#else ++static inline int is_ilp32_compat_task(void) ++{ ++ return 0; ++} ++static inline int is_ilp32_compat_thread(struct thread_info *thread) ++{ ++ return 0; ++} ++#endif ++ ++ + #endif /* __KERNEL__ */ + #endif /* __ASM_COMPAT_H */ +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0012-ARM64-ILP32-COMPAT_USE_64BIT_TIME-is-true-for-ILP32-.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0012-ARM64-ILP32-COMPAT_USE_64BIT_TIME-is-true-for-ILP32-.patch new file mode 100644 index 00000000..c99f2f3e --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0012-ARM64-ILP32-COMPAT_USE_64BIT_TIME-is-true-for-ILP32-.patch @@ -0,0 +1,33 @@ +From b0eeee72d3cb1ae38c676c3bb13e19928b0c5033 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:06 -0700 +Subject: [PATCH 12/25] ARM64:ILP32: COMPAT_USE_64BIT_TIME is true for ILP32 + tasks + +Since __kernel_long_t (time_t) is long long, we need to tell the rest of +kernel that we use 64bit time_t for compat when the task is not an +AARCH32 task. The reason why we check AARCH32 rather than ILP32 here is +because if we don't have AARCH32 compiled in (which is going to be the common case due to AARCH32 requiring 4k pages). + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/compat.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h +index fe390b7..074bcc3 100644 +--- a/arch/arm64/include/asm/compat.h ++++ b/arch/arm64/include/asm/compat.h +@@ -76,6 +76,9 @@ struct compat_timeval { + s32 tv_usec; + }; + ++/* ILP32 uses 64bit time_t and not the above compat structures */ ++#define COMPAT_USE_64BIT_TIME (!is_a32_compat_task()) ++ + struct compat_stat { + #ifdef __AARCH64EB__ + short st_dev; +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0013-ARM64-ILP32-Use-the-non-compat-HWCAP-for-ILP32.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0013-ARM64-ILP32-Use-the-non-compat-HWCAP-for-ILP32.patch new file mode 100644 index 00000000..da56b4d2 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0013-ARM64-ILP32-Use-the-non-compat-HWCAP-for-ILP32.patch @@ -0,0 +1,48 @@ +From d2848980dd76673d626b81acd23989bbcceb4fd4 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:07 -0700 +Subject: [PATCH 13/25] ARM64:ILP32: Use the non compat HWCAP for ILP32 + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/compat.h | 10 ++++++++++ + arch/arm64/include/asm/hwcap.h | 2 -- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h +index 074bcc3..0f4ecfe 100644 +--- a/arch/arm64/include/asm/compat.h ++++ b/arch/arm64/include/asm/compat.h +@@ -296,6 +296,16 @@ struct compat_shmid64_ds { + compat_ulong_t __unused5; + }; + ++#define COMPAT_ELF_HWCAP \ ++ (is_a32_compat_task() \ ++ ? compat_elf_hwcap \ ++ : elf_hwcap) ++ ++#define COMPAT_ELF_HWCAP2 \ ++ (is_a32_compat_task() \ ++ ? compat_elf_hwcap2 \ ++ : 0) ++ + static inline int is_compat_task(void) + { + return test_thread_flag(TIF_32BIT); +diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h +index 024c461..31e7e02 100644 +--- a/arch/arm64/include/asm/hwcap.h ++++ b/arch/arm64/include/asm/hwcap.h +@@ -46,8 +46,6 @@ + #define ELF_HWCAP (elf_hwcap) + + #ifdef CONFIG_COMPAT +-#define COMPAT_ELF_HWCAP (compat_elf_hwcap) +-#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) + extern unsigned int compat_elf_hwcap, compat_elf_hwcap2; + #endif + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0014-ARM64-ILP32-use-the-standard-start_thread-for-ILP32-.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0014-ARM64-ILP32-use-the-standard-start_thread-for-ILP32-.patch new file mode 100644 index 00000000..477f93c1 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0014-ARM64-ILP32-use-the-standard-start_thread-for-ILP32-.patch @@ -0,0 +1,39 @@ +From f2211ab8a3053b89db4ec8d1e9dbe8a2eaebde3b Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:08 -0700 +Subject: [PATCH 14/25] ARM64:ILP32 use the standard start_thread for ILP32 so + the processor state is not AARCH32 + +If we have both ILP32 and AARCH32 compiled in, we need use the non compat start +thread for ILP32. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/processor.h | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h +index 286b1be..7bd9f32 100644 +--- a/arch/arm64/include/asm/processor.h ++++ b/arch/arm64/include/asm/processor.h +@@ -104,6 +104,17 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc, + static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, + unsigned long sp) + { ++#ifdef CONFIG_ARM64_ILP32 ++ /* ++ * ILP32 thread are started the same way as LP64 threads. ++ * Note we cannot use is_ilp32_compat_task here as that ++ * would introduce a header depency issue. ++ */ ++ if (!test_thread_flag(TIF_AARCH32)) { ++ start_thread(regs, pc, sp); ++ return; ++ } ++#endif + start_thread_common(regs, pc); + regs->pstate = COMPAT_PSR_MODE_USR; + if (pc & 1) +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0015-compat_binfmt_elf-coredump-Allow-some-core-dump-macr.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0015-compat_binfmt_elf-coredump-Allow-some-core-dump-macr.patch new file mode 100644 index 00000000..102694b2 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0015-compat_binfmt_elf-coredump-Allow-some-core-dump-macr.patch @@ -0,0 +1,46 @@ +From 22718fe0b2005d61399c73be4d65c162d4a4cd6e Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:09 -0700 +Subject: [PATCH 15/25] compat_binfmt_elf: coredump: Allow some core dump + macros be overridden for compat. + +On some targets (x86 [32bit and x32] and arm64 [aarch32 and ilp32]), there are +two compat elf abis. This adds a few more "#define * COMPAT_*" for compat +targets to define if needed. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + fs/compat_binfmt_elf.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c +index 4d24d17..8307927 100644 +--- a/fs/compat_binfmt_elf.c ++++ b/fs/compat_binfmt_elf.c +@@ -130,6 +130,23 @@ static void cputime_to_compat_timeval(const cputime_t cputime, + #define arch_setup_additional_pages compat_arch_setup_additional_pages + #endif + ++ ++#ifdef COMPAT_PR_REG_SIZE ++#define PR_REG_SIZE COMPAT_PR_REG_SIZE ++#endif ++ ++#ifdef COMPAT_PRSTATUS_SIZE ++#define PRSTATUS_SIZE COMPAT_PRSTATUS_SIZE ++#endif ++ ++#ifdef COMPAT_PR_REG_PTR ++#define PR_REG_PTR COMPAT_PR_REG_PTR ++#endif ++ ++#ifdef COMPAT_SET_PR_FPVALID ++#define SET_PR_FPVALID COMPAT_SET_PR_FPVALID ++#endif ++ + /* + * Rename a few of the symbols that binfmt_elf.c will define. + * These are all local so the names don't really matter, but it +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0016-ARM64-ILP32-Support-core-dump-for-ILP32.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0016-ARM64-ILP32-Support-core-dump-for-ILP32.patch new file mode 100644 index 00000000..83b8129e --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0016-ARM64-ILP32-Support-core-dump-for-ILP32.patch @@ -0,0 +1,110 @@ +From 4aaf156c46c2a751aeeff02b2387a12cc5d34d97 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:10 -0700 +Subject: [PATCH 16/25] ARM64:ILP32: Support core dump for ILP32 + +This patch supports core dumping on ILP32. +We need a few extra macros (COMPAT_PR_REG_SIZE and COMPAT_PRSTATUS_SIZE) due +to size differences of the register sets. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/elf.h | 23 +++++++++++++++++++++-- + arch/arm64/kernel/ptrace.c | 12 ++++++------ + 2 files changed, 27 insertions(+), 8 deletions(-) + +diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h +index 69291a0..fdd3fdb 100644 +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -179,8 +179,8 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm); + + /* AArch32 registers. */ + #define COMPAT_A32_ELF_NGREG 18 +-typedef unsigned int compat_elf_greg_t; +-typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_A32_ELF_NGREG]; ++typedef unsigned int compat_a32_elf_greg_t; ++typedef compat_a32_elf_greg_t compat_a32_elf_gregset_t[COMPAT_A32_ELF_NGREG]; + + /* AArch32 EABI. */ + #define EF_ARM_EABI_MASK 0xff000000 +@@ -209,6 +209,25 @@ typedef elf_gregset_t compat_elf_gregset_t; + + #endif + ++/* ++ * If ILP32 is turned on, we want to define the compat_elf_greg_t to the non compat ++ * one and define PR_REG_SIZE/PRSTATUS_SIZE/SET_PR_FPVALID so we pick up the correct ++ * ones for AARCH32. ++ */ ++#ifdef CONFIG_ARM64_ILP32 ++typedef elf_greg_t compat_elf_greg_t; ++typedef elf_gregset_t compat_elf_gregset_t; ++#define COMPAT_PR_REG_SIZE(S) (is_a32_compat_task() ? 72 : 272) ++#define COMPAT_PRSTATUS_SIZE(S) (is_a32_compat_task() ? 124 : 352) ++#define COMPAT_SET_PR_FPVALID(S, V) \ ++do { \ ++ *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE((S)->pr_reg)) = (V); \ ++} while (0) ++#else ++typedef compat_a32_elf_greg_t compat_elf_greg_t; ++typedef compat_a32_elf_gregset_t compat_elf_gregset_t; ++#endif ++ + #define compat_elf_check_arch(x) compat_a32_elf_check_arch(x) + + #endif /* CONFIG_COMPAT */ +diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c +index 6d6f62d..6a9d395 100644 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -796,8 +796,8 @@ static const struct user_regset aarch32_regsets[] = { + [REGSET_COMPAT_GPR] = { + .core_note_type = NT_PRSTATUS, + .n = COMPAT_A32_ELF_NGREG, +- .size = sizeof(compat_elf_greg_t), +- .align = sizeof(compat_elf_greg_t), ++ .size = sizeof(compat_a32_elf_greg_t), ++ .align = sizeof(compat_a32_elf_greg_t), + .get = compat_gpr_get, + .set = compat_gpr_set + }, +@@ -830,7 +830,7 @@ static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off, + tmp = tsk->mm->start_data; + else if (off == COMPAT_PT_TEXT_END_ADDR) + tmp = tsk->mm->end_code; +- else if (off < sizeof(compat_elf_gregset_t)) ++ else if (off < sizeof(compat_a32_elf_gregset_t)) + return copy_regset_to_user(tsk, &user_aarch32_view, + REGSET_COMPAT_GPR, off, + sizeof(compat_ulong_t), ret); +@@ -851,7 +851,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off, + if (off & 3 || off >= COMPAT_USER_SZ) + return -EIO; + +- if (off >= sizeof(compat_elf_gregset_t)) ++ if (off >= sizeof(compat_a32_elf_gregset_t)) + return 0; + + set_fs(KERNEL_DS); +@@ -1014,7 +1014,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request, + ret = copy_regset_to_user(child, + &user_aarch32_view, + REGSET_COMPAT_GPR, +- 0, sizeof(compat_elf_gregset_t), ++ 0, sizeof(compat_a32_elf_gregset_t), + datap); + break; + +@@ -1022,7 +1022,7 @@ long compat_a32_arch_ptrace(struct task_struct *child, compat_long_t request, + ret = copy_regset_from_user(child, + &user_aarch32_view, + REGSET_COMPAT_GPR, +- 0, sizeof(compat_elf_gregset_t), ++ 0, sizeof(compat_a32_elf_gregset_t), + datap); + break; + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0017-ARM64-Add-loading-of-ILP32-binaries.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0017-ARM64-Add-loading-of-ILP32-binaries.patch new file mode 100644 index 00000000..d212539f --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0017-ARM64-Add-loading-of-ILP32-binaries.patch @@ -0,0 +1,108 @@ +From 942b8485587dedca256087f5f5dff54eb9793169 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:11 -0700 +Subject: [PATCH 17/25] ARM64: Add loading of ILP32 binaries + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/elf.h | 59 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 50 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h +index fdd3fdb..e9f3891 100644 +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -16,6 +16,7 @@ + #ifndef __ASM_ELF_H + #define __ASM_ELF_H + ++#include <asm/errno.h> + #include <asm/hwcap.h> + + /* +@@ -188,25 +189,26 @@ typedef compat_a32_elf_greg_t compat_a32_elf_gregset_t[COMPAT_A32_ELF_NGREG]; + ((x)->e_flags & EF_ARM_EABI_MASK)) + + #define compat_start_thread compat_start_thread +-#define COMPAT_SET_PERSONALITY(ex) \ ++#define COMPAT_A32_SET_PERSONALITY(ex) \ + do { \ + set_thread_flag(TIF_AARCH32); \ + set_thread_flag(TIF_32BIT); \ + } while (0) +-#define COMPAT_ARCH_DLINFO ++#define COMPAT_A32_ARCH_DLINFO do {} while (0) + extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, + int uses_interp); +-#define compat_arch_setup_additional_pages \ +- aarch32_setup_vectors_page + + #else +- + typedef elf_greg_t compat_elf_greg_t; + typedef elf_gregset_t compat_elf_gregset_t; + #define compat_a32_elf_check_arch(x) 0 +-#define COMPAT_SET_PERSONALITY(ex) +-#define COMPAT_ARCH_DLINFO +- ++#define COMPAT_A32_SET_PERSONALITY(ex) do {} while (0) ++#define COMPAT_A32_ARCH_DLINFO do {} while (0) ++static inline int aarch32_setup_vectors_page(struct linux_binprm *bprm, ++ int uses_interp) ++{ ++ return -EINVAL; ++} + #endif + + /* +@@ -228,7 +230,46 @@ typedef compat_a32_elf_greg_t compat_elf_greg_t; + typedef compat_a32_elf_gregset_t compat_elf_gregset_t; + #endif + +-#define compat_elf_check_arch(x) compat_a32_elf_check_arch(x) ++#ifdef CONFIG_ARM64_ILP32 ++#define compat_ilp32_elf_check_arch(x) ((x)->e_machine == EM_AARCH64) ++#define COMPAT_ILP32_SET_PERSONALITY(ex) \ ++do { \ ++ clear_thread_flag(TIF_AARCH32); \ ++ set_thread_flag(TIF_32BIT); \ ++} while (0) ++#define COMPAT_ILP32_ARCH_DLINFO \ ++do { \ ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ ++ (elf_addr_t)(long)current->mm->context.vdso); \ ++} while (0) ++#else ++#define compat_ilp32_elf_check_arch(x) 0 ++#define COMPAT_ILP32_SET_PERSONALITY(ex) do {} while (0) ++#define COMPAT_ILP32_ARCH_DLINFO do {} while (0) ++#endif ++ ++#define compat_elf_check_arch(x) (compat_a32_elf_check_arch(x) || compat_ilp32_elf_check_arch(x)) ++#define COMPAT_SET_PERSONALITY(ex) \ ++do { \ ++ if (compat_a32_elf_check_arch(&ex)) \ ++ COMPAT_A32_SET_PERSONALITY(ex); \ ++ else \ ++ COMPAT_ILP32_SET_PERSONALITY(ex); \ ++} while (0) ++ ++/* ILP32 uses the "LP64-like" vdso pages */ ++#define compat_arch_setup_additional_pages \ ++ (is_a32_compat_task() \ ++ ? &aarch32_setup_vectors_page \ ++ : &(arch_setup_additional_pages)) ++ ++#define COMPAT_ARCH_DLINFO \ ++do { \ ++ if (is_a32_compat_task()) \ ++ COMPAT_A32_ARCH_DLINFO; \ ++ else \ ++ COMPAT_ILP32_ARCH_DLINFO; \ ++} while (0) + + #endif /* CONFIG_COMPAT */ + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0018-ARM64-Add-vdso-for-ILP32-and-use-it-for-the-signal-r.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0018-ARM64-Add-vdso-for-ILP32-and-use-it-for-the-signal-r.patch new file mode 100644 index 00000000..1096f5c3 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0018-ARM64-Add-vdso-for-ILP32-and-use-it-for-the-signal-r.patch @@ -0,0 +1,452 @@ +From 31c359a223b271aa7ae1f06caebee50ae1e8c39e Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:12 -0700 +Subject: [PATCH 18/25] ARM64: Add vdso for ILP32 and use it for the signal + return + +This patch adds the VDSO for ILP32. We need to use a different +VDSO than LP64 since ILP32 uses ELF32 while LP64 uses ELF64. + +After this patch, signal handling works mostly. In that signals +go through their action and then returned correctly. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/vdso.h | 4 ++ + arch/arm64/kernel/Makefile | 5 ++ + arch/arm64/kernel/signal.c | 4 ++ + arch/arm64/kernel/vdso-ilp32/.gitignore | 2 + + arch/arm64/kernel/vdso-ilp32/Makefile | 72 ++++++++++++++++++++ + arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S | 33 +++++++++ + arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 98 +++++++++++++++++++++++++++ + arch/arm64/kernel/vdso.c | 69 +++++++++++++++---- + 8 files changed, 274 insertions(+), 13 deletions(-) + create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore + create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile + create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S + create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S + +diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h +index 839ce00..84050c6 100644 +--- a/arch/arm64/include/asm/vdso.h ++++ b/arch/arm64/include/asm/vdso.h +@@ -29,6 +29,10 @@ + + #include <generated/vdso-offsets.h> + ++#ifdef CONFIG_ARM64_ILP32 ++#include <generated/vdso-ilp32-offsets.h> ++#endif ++ + #define VDSO_SYMBOL(base, name) \ + ({ \ + (void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \ +diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile +index f59d113..ceb9bf7 100644 +--- a/arch/arm64/kernel/Makefile ++++ b/arch/arm64/kernel/Makefile +@@ -33,6 +33,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o + arm64-obj-$(CONFIG_PCI) += pci.o + + obj-y += $(arm64-obj-y) vdso/ ++obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/ + obj-m += $(arm64-obj-m) + head-y := head.o + extra-y := $(head-y) vmlinux.lds +@@ -40,3 +41,7 @@ extra-y := $(head-y) vmlinux.lds + # vDSO - this must be built first to generate the symbol offsets + $(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h + $(obj)/vdso/vdso-offsets.h: $(obj)/vdso ++ ++# vDSO - this must be built first to generate the symbol offsets ++$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h ++$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32 +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index f47c064..5311147 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -242,6 +242,10 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, + + if (ka->sa.sa_flags & SA_RESTORER) + sigtramp = ka->sa.sa_restorer; ++#ifdef CONFIG_ARM64_ILP32 ++ else if (is_ilp32_compat_task()) ++ sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32); ++#endif + else + sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); + +diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore +new file mode 100644 +index 0000000..61806c3 +--- /dev/null ++++ b/arch/arm64/kernel/vdso-ilp32/.gitignore +@@ -0,0 +1,2 @@ ++vdso-ilp32.lds ++vdso-ilp32-offsets.h +diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile +new file mode 100644 +index 0000000..c8f5472 +--- /dev/null ++++ b/arch/arm64/kernel/vdso-ilp32/Makefile +@@ -0,0 +1,72 @@ ++# ++# Building a vDSO image for AArch64. ++# ++# Author: Will Deacon <will.deacon@arm.com> ++# Heavily based on the vDSO Makefiles for other archs. ++# ++ ++obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o ++ ++# Build rules ++targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg ++obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso)) ++ ++ccflags-y := -shared -fno-common -fno-builtin ++ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \ ++ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) ++ ++obj-y += vdso-ilp32.o ++extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h ++CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32 ++ ++# Force dependency (incbin is bad) ++$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so ++ ++# Link rule for the .so file, .lds has to be first ++$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso) ++ $(call if_changed,vdso-ilp32ld) ++ ++# Strip rule for the .so file ++$(obj)/%.so: OBJCOPYFLAGS := -S ++$(obj)/%.so: $(obj)/%.so.dbg FORCE ++ $(call if_changed,objcopy) ++ ++# Generate VDSO offsets using helper script ++gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh ++quiet_cmd_vdsosym = VDSOSYM $@ ++define cmd_vdsosym ++ $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \ ++ cp $@ include/generated/ ++endef ++ ++$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE ++ $(call if_changed,vdsosym) ++ ++# Assembly rules for the .S files ++#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S) ++# $(call if_changed_dep,vdso-ilp32as) ++ ++$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S ++ $(call if_changed_dep,vdso-ilp32as) ++ ++$(obj)/note-ilp32.o: $(src)/../vdso/note.S ++ $(call if_changed_dep,vdso-ilp32as) ++ ++$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S ++ $(call if_changed_dep,vdso-ilp32as) ++ ++# Actual build commands ++quiet_cmd_vdso-ilp32ld = VDSOILP32L $@ ++ cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32 -Wl,-n -Wl,-T $^ -o $@ ++quiet_cmd_vdso-ilp32as = VDSOILP32A $@ ++ cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $< ++ ++# Install commands for the unstripped file ++quiet_cmd_vdso_install = INSTALL $@ ++ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ ++ ++vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg ++ @mkdir -p $(MODLIB)/vdso ++ $(call cmd,vdso_install) ++ ++vdso_install: vdso-ilp32.so +diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S +new file mode 100644 +index 0000000..46ac072 +--- /dev/null ++++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (C) 2012 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ * ++ * Author: Will Deacon <will.deacon@arm.com> ++ */ ++ ++#include <linux/init.h> ++#include <linux/linkage.h> ++#include <linux/const.h> ++#include <asm/page.h> ++ ++ __PAGE_ALIGNED_DATA ++ ++ .globl vdso_ilp32_start, vdso_ilp32_end ++ .balign PAGE_SIZE ++vdso_ilp32_start: ++ .incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so" ++ .balign PAGE_SIZE ++vdso_ilp32_end: ++ ++ .previous +diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S +new file mode 100644 +index 0000000..ac8029b +--- /dev/null ++++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S +@@ -0,0 +1,98 @@ ++/* ++ * GNU linker script for the VDSO library. ++ * ++ * Copyright (C) 2012 ARM Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ * ++ * Author: Will Deacon <will.deacon@arm.com> ++ * Heavily based on the vDSO linker scripts for other archs. ++ */ ++ ++#include <linux/const.h> ++#include <asm/page.h> ++#include <asm/vdso.h> ++ ++/*OUTPUT_FORMAT("elf32-littleaarch64", "elf32-bigaarch64", "elf32-littleaarch64") ++OUTPUT_ARCH(aarch64) ++*/ ++SECTIONS ++{ ++ PROVIDE(_vdso_data = . - PAGE_SIZE); ++ . = VDSO_LBASE + SIZEOF_HEADERS; ++ ++ .hash : { *(.hash) } :text ++ .gnu.hash : { *(.gnu.hash) } ++ .dynsym : { *(.dynsym) } ++ .dynstr : { *(.dynstr) } ++ .gnu.version : { *(.gnu.version) } ++ .gnu.version_d : { *(.gnu.version_d) } ++ .gnu.version_r : { *(.gnu.version_r) } ++ ++ .note : { *(.note.*) } :text :note ++ ++ . = ALIGN(16); ++ ++ .text : { *(.text*) } :text =0xd503201f ++ PROVIDE (__etext = .); ++ PROVIDE (_etext = .); ++ PROVIDE (etext = .); ++ ++ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr ++ .eh_frame : { KEEP (*(.eh_frame)) } :text ++ ++ .dynamic : { *(.dynamic) } :text :dynamic ++ ++ .rodata : { *(.rodata*) } :text ++ ++ _end = .; ++ PROVIDE(end = .); ++ ++ /DISCARD/ : { ++ *(.note.GNU-stack) ++ *(.data .data.* .gnu.linkonce.d.* .sdata*) ++ *(.bss .sbss .dynbss .dynsbss) ++ } ++} ++ ++/* ++ * We must supply the ELF program headers explicitly to get just one ++ * PT_LOAD segment, and set the flags explicitly to make segments read-only. ++ */ ++PHDRS ++{ ++ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */ ++ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ ++ note PT_NOTE FLAGS(4); /* PF_R */ ++ eh_frame_hdr PT_GNU_EH_FRAME; ++} ++ ++/* ++ * This controls what symbols we export from the DSO. ++ */ ++VERSION ++{ ++ LINUX_2.6.39 { ++ global: ++ __kernel_rt_sigreturn; ++ __kernel_gettimeofday; ++ __kernel_clock_gettime; ++ __kernel_clock_getres; ++ local: *; ++ }; ++} ++ ++/* ++ * Make the sigreturn code visible to the kernel. ++ */ ++VDSO_sigtramp_ilp32 = __kernel_rt_sigreturn; +diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c +index a777ac3..21b3726 100644 +--- a/arch/arm64/kernel/vdso.c ++++ b/arch/arm64/kernel/vdso.c +@@ -41,6 +41,12 @@ extern char vdso_start, vdso_end; + static unsigned long vdso_pages; + static struct page **vdso_pagelist; + ++#ifdef CONFIG_ARM64_ILP32 ++extern char vdso_ilp32_start, vdso_ilp32_end; ++static unsigned long vdso_ilp32_pages; ++static struct page **vdso_ilp32_pagelist; ++#endif ++ + /* + * The vDSO data page. + */ +@@ -110,24 +116,31 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) + } + #endif /* CONFIG_AARCH32_EL0 */ + +-static struct vm_special_mapping vdso_spec[2]; ++static struct vm_special_mapping vdso_spec[2][2]; + +-static int __init vdso_init(void) ++static inline int __init vdso_init_common(char *vdso_start, char *vdso_end, ++ unsigned long *vdso_pagesp, ++ struct page ***vdso_pagelistp, ++ bool ilp32) + { + int i; ++ unsigned long vdso_pages; ++ struct page **vdso_pagelist; + +- if (memcmp(&vdso_start, "\177ELF", 4)) { ++ if (memcmp(vdso_start, "\177ELF", 4)) { + pr_err("vDSO is not a valid ELF object!\n"); + return -EINVAL; + } + +- vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; ++ vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; ++ *vdso_pagesp = vdso_pages; + pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n", +- vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data); ++ vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data); + + /* Allocate the vDSO pagelist, plus a page for the data. */ + vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *), + GFP_KERNEL); ++ *vdso_pagelistp = vdso_pagelist; + if (vdso_pagelist == NULL) + return -ENOMEM; + +@@ -136,33 +149,63 @@ static int __init vdso_init(void) + + /* Grab the vDSO code pages. */ + for (i = 0; i < vdso_pages; i++) +- vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE); ++ vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE); + + /* Populate the special mapping structures */ +- vdso_spec[0] = (struct vm_special_mapping) { ++ vdso_spec[ilp32][0] = (struct vm_special_mapping) { + .name = "[vvar]", + .pages = vdso_pagelist, + }; + +- vdso_spec[1] = (struct vm_special_mapping) { ++ vdso_spec[ilp32][1] = (struct vm_special_mapping) { + .name = "[vdso]", + .pages = &vdso_pagelist[1], + }; + + return 0; + } ++ ++static int __init vdso_init(void) ++{ ++ return vdso_init_common(&vdso_start, &vdso_end, ++ &vdso_pages, &vdso_pagelist, 0); ++} + arch_initcall(vdso_init); + ++#ifdef CONFIG_ARM64_ILP32 ++static int __init vdso_ilp32_init(void) ++{ ++ return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end, ++ &vdso_ilp32_pages, &vdso_ilp32_pagelist, 1); ++} ++arch_initcall(vdso_ilp32_init); ++#endif ++ + int arch_setup_additional_pages(struct linux_binprm *bprm, + int uses_interp) + { + struct mm_struct *mm = current->mm; + unsigned long vdso_base, vdso_text_len, vdso_mapping_len; + void *ret; +- +- vdso_text_len = vdso_pages << PAGE_SHIFT; ++ struct page **pagelist; ++ unsigned long pages; ++ bool ilp32; ++ ++#ifdef CONFIG_ARM64_ILP32 ++ ilp32 = is_ilp32_compat_task(); ++ if (is_ilp32_compat_task()) { ++ pages = vdso_ilp32_pages; ++ pagelist = vdso_ilp32_pagelist; ++ } else ++#endif ++ { ++ ilp32 = false; ++ pages = vdso_pages; ++ pagelist = vdso_pagelist; ++ } ++ vdso_text_len = pages << PAGE_SHIFT; + /* Be sure to map the data page */ +- vdso_mapping_len = vdso_text_len + PAGE_SIZE; ++ vdso_mapping_len = (pages + 1) << PAGE_SHIFT; + + down_write(&mm->mmap_sem); + vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); +@@ -172,7 +215,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, + } + ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, + VM_READ|VM_MAYREAD, +- &vdso_spec[0]); ++ &vdso_spec[ilp32][0]); + if (IS_ERR(ret)) + goto up_fail; + +@@ -181,7 +224,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, + ret = _install_special_mapping(mm, vdso_base, vdso_text_len, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, +- &vdso_spec[1]); ++ &vdso_spec[ilp32][1]); + if (IS_ERR(ret)) + goto up_fail; + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0019-ptrace-Allow-compat-to-use-the-native-siginfo.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0019-ptrace-Allow-compat-to-use-the-native-siginfo.patch new file mode 100644 index 00000000..5811e4eb --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0019-ptrace-Allow-compat-to-use-the-native-siginfo.patch @@ -0,0 +1,82 @@ +From 13737c6712659357fde2e64fa6ed6830ea700dc0 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:13 -0700 +Subject: [PATCH 19/25] ptrace: Allow compat to use the native siginfo + +With ARM64 ILP32 ABI, we want to use the non-compat +siginfo as we want to simplify signal handling for this new ABI. +This patch just adds a new define COMPAT_USE_NATIVE_SIGINFO and +if it is true then read/write in the compat case as it was the +non-compat case. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + include/linux/compat.h | 4 ++++ + kernel/ptrace.c | 25 ++++++++++++++++++------- + 2 files changed, 22 insertions(+), 7 deletions(-) + +diff --git a/include/linux/compat.h b/include/linux/compat.h +index e649426..2d8c535 100644 +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -24,6 +24,10 @@ + #define COMPAT_USE_64BIT_TIME 0 + #endif + ++#ifndef COMPAT_USE_NATIVE_SIGINFO ++#define COMPAT_USE_NATIVE_SIGINFO 0 ++#endif ++ + #ifndef __SC_DELOUSE + #define __SC_DELOUSE(t,v) ((t)(unsigned long)(v)) + #endif +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index 54e7522..40ae023 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -657,7 +657,7 @@ static int ptrace_peek_siginfo(struct task_struct *child, + break; + + #ifdef CONFIG_COMPAT +- if (unlikely(is_compat_task())) { ++ if (unlikely(is_compat_task() && !COMPAT_USE_NATIVE_SIGINFO)) { + compat_siginfo_t __user *uinfo = compat_ptr(data); + + if (copy_siginfo_to_user32(uinfo, &info) || +@@ -1126,16 +1126,27 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, + + case PTRACE_GETSIGINFO: + ret = ptrace_getsiginfo(child, &siginfo); +- if (!ret) +- ret = copy_siginfo_to_user32( +- (struct compat_siginfo __user *) datap, +- &siginfo); ++ if (!ret) { ++ if (COMPAT_USE_NATIVE_SIGINFO) ++ ret = copy_siginfo_to_user( ++ (struct siginfo __user *) datap, ++ &siginfo); ++ else ++ ret = copy_siginfo_to_user32( ++ (struct compat_siginfo __user *) datap, ++ &siginfo); ++ } + break; + + case PTRACE_SETSIGINFO: + memset(&siginfo, 0, sizeof siginfo); +- if (copy_siginfo_from_user32( +- &siginfo, (struct compat_siginfo __user *) datap)) ++ if (COMPAT_USE_NATIVE_SIGINFO) ++ ret = copy_from_user(&siginfo, datap, sizeof(siginfo)); ++ else ++ ret = copy_siginfo_from_user32( ++ &siginfo, ++ (struct compat_siginfo __user *) datap); ++ if (ret) + ret = -EFAULT; + else + ret = ptrace_setsiginfo(child, &siginfo); +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0020-ARM64-ILP32-The-native-siginfo-is-used-instead-of-th.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0020-ARM64-ILP32-The-native-siginfo-is-used-instead-of-th.patch new file mode 100644 index 00000000..ca10f086 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0020-ARM64-ILP32-The-native-siginfo-is-used-instead-of-th.patch @@ -0,0 +1,30 @@ +From 3a33f13ccf73bf00fcbd5afc90ec22793c1c3d29 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:14 -0700 +Subject: [PATCH 20/25] ARM64:ILP32: The native siginfo is used instead of the + compat siginfo + +Set COMPAT_USE_NATIVE_SIGINFO to be true for non AARCH32 tasks. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/compat.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h +index 0f4ecfe..a8c4caf 100644 +--- a/arch/arm64/include/asm/compat.h ++++ b/arch/arm64/include/asm/compat.h +@@ -211,6 +211,9 @@ typedef struct compat_siginfo { + } _sifields; + } compat_siginfo_t; + ++/* ILP32 uses the native siginfo and not the compat struct */ ++#define COMPAT_USE_NATIVE_SIGINFO (!is_a32_compat_task()) ++ + #define COMPAT_OFF_T_MAX 0x7fffffff + #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0021-ARM64-ILP32-Use-a-seperate-syscall-table-as-a-few-sy.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0021-ARM64-ILP32-Use-a-seperate-syscall-table-as-a-few-sy.patch new file mode 100644 index 00000000..0a37fcb0 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0021-ARM64-ILP32-Use-a-seperate-syscall-table-as-a-few-sy.patch @@ -0,0 +1,301 @@ +From c167810daa92daa4dfcec57e3f9f996ee34ee000 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:15 -0700 +Subject: [PATCH 21/25] ARM64:ILP32: Use a seperate syscall table as a few + syscalls need to be using the compat syscalls + +Some syscalls are still need to use the compat versions. +So we need to have a seperate syscall table for ILP32. +This patch adds them including documentation on why we need to use each one. + +This list is based on the list from https://lkml.org/lkml/2013/9/11/478. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/include/asm/syscalls.h | 4 + + arch/arm64/include/asm/unistd.h | 4 + + arch/arm64/kernel/Makefile | 1 + + arch/arm64/kernel/entry.S | 13 ++- + arch/arm64/kernel/sys_ilp32.c | 195 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 216 insertions(+), 1 deletion(-) + create mode 100644 arch/arm64/kernel/sys_ilp32.c + +diff --git a/arch/arm64/include/asm/syscalls.h b/arch/arm64/include/asm/syscalls.h +index 48fe7c6..b58dad7 100644 +--- a/arch/arm64/include/asm/syscalls.h ++++ b/arch/arm64/include/asm/syscalls.h +@@ -25,6 +25,10 @@ + */ + asmlinkage long sys_rt_sigreturn_wrapper(void); + ++#ifdef CONFIG_ARM64_ILP32 ++long ilp32_sys_sigaltstack(const stack_t __user *, stack_t __user *); ++#endif ++ + #include <asm-generic/syscalls.h> + + #endif /* __ASM_SYSCALLS_H */ +diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h +index 70e5559..c99815a 100644 +--- a/arch/arm64/include/asm/unistd.h ++++ b/arch/arm64/include/asm/unistd.h +@@ -13,6 +13,10 @@ + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ ++#ifdef CONFIG_ARM64_ILP32 ++#define __ARCH_WANT_COMPAT_SYS_PREADV64 ++#define __ARCH_WANT_COMPAT_SYS_PWRITEV64 ++#endif + #ifdef CONFIG_AARCH32_EL0 + #define __ARCH_WANT_COMPAT_SYS_GETDENTS64 + #define __ARCH_WANT_COMPAT_STAT64 +diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile +index ceb9bf7..98c6c85 100644 +--- a/arch/arm64/kernel/Makefile ++++ b/arch/arm64/kernel/Makefile +@@ -19,6 +19,7 @@ arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ + + arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \ + sys_compat.o ++arm64-obj-$(CONFIG_ARM64_ILP32) += sys_ilp32.o + arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o + arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o + arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o +diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S +index 5a1430c..537be14 100644 +--- a/arch/arm64/kernel/entry.S ++++ b/arch/arm64/kernel/entry.S +@@ -642,9 +642,14 @@ ENDPROC(ret_from_fork) + */ + .align 6 + el0_svc: +- adrp stbl, sys_call_table // load syscall table pointer + uxtw scno, w8 // syscall number in w8 + mov sc_nr, #__NR_syscalls ++#ifdef CONFIG_ARM64_ILP32 ++ get_thread_info tsk ++ ldr x16, [tsk, #TI_FLAGS] ++ tbnz x16, #TIF_32BIT, el0_ilp32_svc // We are using ILP32 ++#endif ++ adrp stbl, sys_call_table // load syscall table pointer + el0_svc_naked: // compat entry point + stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number + enable_dbg_and_irq +@@ -663,6 +668,12 @@ ni_sys: + b do_ni_syscall + ENDPROC(el0_svc) + ++#ifdef CONFIG_ARM64_ILP32 ++el0_ilp32_svc: ++ adrp stbl, sys_call_ilp32_table // load syscall table pointer ++ b el0_svc_naked ++#endif ++ + /* + * This is the really slow path. We're going to be doing context + * switches, and waiting for our parent to respond. +diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c +new file mode 100644 +index 0000000..893f7d6 +--- /dev/null ++++ b/arch/arm64/kernel/sys_ilp32.c +@@ -0,0 +1,195 @@ ++/* ++ * AArch64- ILP32 specific system calls implementation ++ * ++ * Copyright (C) 2013 Cavium Inc. ++ * Author: Andrew Pinski <apinski@cavium.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/compiler.h> ++#include <linux/errno.h> ++#include <linux/fs.h> ++#include <linux/mm.h> ++#include <linux/export.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/syscalls.h> ++#include <linux/compat.h> ++ ++/* ++ * Wrappers to pass the pt_regs argument. ++ */ ++#define sys_rt_sigreturn sys_rt_sigreturn_wrapper ++ ++/* ++ * Note places where mention unsigned long bitmaps, could ++ * use the non compat version for little-endian but big-endian ++ * has issues to do layout of the bits in the bitmaps. ++ */ ++ ++/* Using Compat syscalls where necessary */ ++#define sys_ioctl compat_sys_ioctl ++/* iovec */ ++#define sys_readv compat_sys_readv ++#define sys_writev compat_sys_writev ++#define sys_preadv compat_sys_preadv64 ++#define sys_pwritev compat_sys_pwritev64 ++#define sys_vmsplice compat_sys_vmsplice ++/* robust_list_head */ ++#define sys_set_robust_list compat_sys_set_robust_list ++#define sys_get_robust_list compat_sys_get_robust_list ++ ++/* kexec_segment */ ++#define sys_kexec_load compat_sys_kexec_load ++ ++/* Ptrace has some structures which are different between ILP32 and LP64 */ ++#define sys_ptrace compat_sys_ptrace ++ ++/* struct msghdr */ ++#define sys_recvfrom compat_sys_recvfrom ++#define sys_recvmmsg compat_sys_recvmmsg ++#define sys_sendmmsg compat_sys_sendmmsg ++#define sys_sendmsg compat_sys_sendmsg ++#define sys_recvmsg compat_sys_recvmsg ++ ++/* ++ * Note the timeval is taken care by COMPAT_USE_64BIT_TIME ++ * being true. ++ */ ++#define sys_setsockopt compat_sys_setsockopt ++#define sys_getsockopt compat_sys_getsockopt ++ ++/* Array of pointers */ ++#define sys_execve compat_sys_execve ++#define sys_move_pages compat_sys_move_pages ++ ++/* iovec */ ++#define sys_process_vm_readv compat_sys_process_vm_readv ++#define sys_process_vm_writev compat_sys_process_vm_writev ++ ++/* ++ * The NFSv4 and ncpfs structures are depend on the long and ++ * pointer sizes. ++ */ ++#define sys_mount compat_sys_mount ++ ++/* NUMA */ ++/* unsigned long bitmaps */ ++#define sys_get_mempolicy compat_sys_get_mempolicy ++#define sys_set_mempolicy compat_sys_set_mempolicy ++#define sys_mbind compat_sys_mbind ++ ++/* array of pointers */ ++/* unsigned long bitmaps */ ++#define sys_migrate_pages compat_sys_migrate_pages ++ ++/* Scheduler */ ++/* unsigned long bitmaps */ ++#define sys_sched_setaffinity compat_sys_sched_setaffinity ++#define sys_sched_getaffinity compat_sys_sched_getaffinity ++ ++/* iov usage */ ++#define sys_keyctl compat_sys_keyctl ++ ++/* aio */ ++/* Array of pointers (iocb's) */ ++#define sys_io_submit compat_sys_io_submit ++ ++/* We need to make sure the pointer gets copied correctly. */ ++asmlinkage long ilp32_sys_mq_notify(mqd_t mqdes, ++ const struct sigevent __user *u_notification) ++{ ++ struct sigevent __user *p = NULL; ++ ++ if (u_notification) { ++ struct sigevent n; ++ ++ p = compat_alloc_user_space(sizeof(*p)); ++ if (copy_from_user(&n, u_notification, sizeof(*p))) ++ return -EFAULT; ++ if (n.sigev_notify == SIGEV_THREAD) ++ n.sigev_value.sival_ptr = compat_ptr((uintptr_t)n.sigev_value.sival_ptr); ++ if (copy_to_user(p, &n, sizeof(*p))) ++ return -EFAULT; ++ } ++ return sys_mq_notify(mqdes, p); ++} ++ ++/* ++ * sigevent contains sigval_t which is now 64bit always ++ * but need special handling due to padding for SIGEV_THREAD. ++ */ ++#define sys_mq_notify ilp32_sys_mq_notify ++ ++ ++/* ++ * sigaltstack needs some special handling as the ++ * padding for stack_t might not be non-zero. ++ */ ++long ilp32_sys_sigaltstack(const stack_t __user *uss_ptr, ++ stack_t __user *uoss_ptr) ++{ ++ stack_t uss, uoss; ++ int ret; ++ mm_segment_t seg; ++ ++ if (uss_ptr) { ++ if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr))) ++ return -EFAULT; ++ if (__get_user(uss.ss_sp, &uss_ptr->ss_sp) | ++ __get_user(uss.ss_flags, &uss_ptr->ss_flags) | ++ __get_user(uss.ss_size, &uss_ptr->ss_size)) ++ return -EFAULT; ++ /* Zero extend the sp address and the size. */ ++ uss.ss_sp = (void *)(uintptr_t)(unsigned int)(uintptr_t)uss.ss_sp; ++ uss.ss_size = (size_t)(unsigned int)uss.ss_size; ++ } ++ seg = get_fs(); ++ set_fs(KERNEL_DS); ++ /* ++ * Note we need to use uoss as we have changed the segment to the ++ * kernel one so passing an user one around is wrong. ++ */ ++ ret = sys_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL), ++ (stack_t __force __user *) &uoss); ++ set_fs(seg); ++ if (ret >= 0 && uoss_ptr) { ++ if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_t)) || ++ __put_user(uoss.ss_sp, &uoss_ptr->ss_sp) || ++ __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) || ++ __put_user(uoss.ss_size, &uoss_ptr->ss_size)) ++ ret = -EFAULT; ++ } ++ return ret; ++} ++ ++/* ++ * sigaltstack needs some special handling as the padding ++ * for stack_t might not be non-zero. ++ */ ++#define sys_sigaltstack ilp32_sys_sigaltstack ++ ++#include <asm/syscalls.h> ++ ++#undef __SYSCALL ++#define __SYSCALL(nr, sym) [nr] = sym, ++ ++/* ++ * The sys_call_ilp32_table array must be 4K aligned to be accessible from ++ * kernel/entry.S. ++ */ ++void *sys_call_ilp32_table[__NR_syscalls] __aligned(4096) = { ++ [0 ... __NR_syscalls - 1] = sys_ni_syscall, ++#include <asm/unistd.h> ++}; +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0022-ARM64-ILP32-Fix-signal-return-for-ILP32-when-the-use.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0022-ARM64-ILP32-Fix-signal-return-for-ILP32-when-the-use.patch new file mode 100644 index 00000000..c9d647e1 --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0022-ARM64-ILP32-Fix-signal-return-for-ILP32-when-the-use.patch @@ -0,0 +1,50 @@ +From 83c39e04015427c69d2f48735095a56c4aa63259 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:16 -0700 +Subject: [PATCH 22/25] ARM64:ILP32: Fix signal return for ILP32 when the user + modified the signal stack + +If the user decided to change the stack_t that was on the stack when returning +from the signal handler, the stack_t's padding for ILP32 might be not zero. +So we need to use the syscall version of restore_altstack (ilp32_sys_sigaltstack). + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/kernel/signal.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index 5311147..6316d54 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -35,6 +35,7 @@ + #include <asm/fpsimd.h> + #include <asm/signal32.h> + #include <asm/vdso.h> ++#include <asm/syscalls.h> + + /* + * Do a signal return; undo the signal stack. These are aligned to 128-bit. +@@ -149,6 +150,19 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) + if (restore_sigframe(regs, frame)) + goto badframe; + ++#ifdef CONFIG_ARM64_ILP32 ++ /* ++ * ILP32 has to be handled "special" due to maybe not zeroing out ++ * the upper 32bits of the pointer if the user changed the frame. ++ */ ++ if (is_ilp32_compat_task()) { ++ if (ilp32_sys_sigaltstack(&frame->uc.uc_stack, ++ NULL) == -EFAULT) ++ goto badframe; ++ return regs->regs[0]; ++ } ++#endif ++ + if (restore_altstack(&frame->uc.uc_stack)) + goto badframe; + +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0023-ARM64-Add-ARM64_ILP32-to-Kconfig.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0023-ARM64-Add-ARM64_ILP32-to-Kconfig.patch new file mode 100644 index 00000000..d61f526d --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0023-ARM64-Add-ARM64_ILP32-to-Kconfig.patch @@ -0,0 +1,42 @@ +From b5f1db849f9c2773d318f27091bb42dd0941af7b Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:17 -0700 +Subject: [PATCH 23/25] ARM64: Add ARM64_ILP32 to Kconfig + +This patch adds the config option for ILP32. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + arch/arm64/Kconfig | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index f28af3f..9b92318 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -409,7 +409,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 +@@ -426,6 +426,13 @@ config AARCH32_EL0 + + If you want to execute 32-bit userspace applications, say Y. + ++config ARM64_ILP32 ++ bool "Kernel support for ILP32" ++ help ++ This option enables support for AArch64 ILP32 user space. ILP32 ++ is an ABI where long and pointers are 32bits but it uses the AARCH64 ++ instruction set. ++ + config SYSVIPC_COMPAT + def_bool y + depends on AARCH32_EL0 && SYSVIPC +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0024-Add-documentation-about-ARM64-ILP32-ABI.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0024-Add-documentation-about-ARM64-ILP32-ABI.patch new file mode 100644 index 00000000..3e3ebe9a --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0024-Add-documentation-about-ARM64-ILP32-ABI.patch @@ -0,0 +1,79 @@ +From 912465ff3a6c600fbd9315533cf8d4ec8c570b63 Mon Sep 17 00:00:00 2001 +From: Andrew Pinski <apinski@cavium.com> +Date: Wed, 3 Sep 2014 14:19:18 -0700 +Subject: [PATCH 24/25] Add documentation about ARM64 ILP32 ABI + +This adds the documentation about the ILP32 ABI and what is difference between it and the normal generic 32bit ABI. + +Signed-off-by: Andrew Pinski <apinski@cavium.com> +--- + Documentation/arm64/ilp32.txt | 57 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 57 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..0863aa4 +--- /dev/null ++++ b/Documentation/arm64/ilp32.txt +@@ -0,0 +1,57 @@ ++ ILP32 AARCH64 SYSCALL ABI ++ ===================== ++ ++Author: Andrew Pinski <apinski@cavium.com> ++Date: May 23, 2014 ++ ++This document describes the ILP32 syscall ABI and where it differs ++from the generic linux syscall interface. ++ILP32 sets __kernel_long_t and __kernel_ulong_t both to 64bit ++(long long). This effects the following types: ++* time_t: unsigned long long ++* clock_t: unsigned long long ++* fsword_t: long long ++* suseconds_t: long long ++* swblk_t: long long ++* fd_mask_t: long long ++ ++Some structures are changed to reduce the difference in the code path ++for both ILP32 and LP64 ABIs for signal handling. ++ ++The following structures have been changed so the layout of the structures are the same between ILP32 and LP64 ABIs. ++* timespec: Uses time_t and suseconds_t ++* timeval: Uses time_t and suseconds_t ++* stat: Uses timespec/time_t. ++* semid64_ds: Uses time_t. ++* msqid64_ds: Uses time_t. ++* shmid64_ds: Uses time_t. ++* rt_sigframe: Uses siginfo and ucontext. ++* siginfo_t: Uses clock_t and sigval_t ++* ucontext: Uses stack_t and sigset_t ++* stack_t: NOTE special handling inside the kernel is done to make sure ++ the pointers are zero extended ++* sigval_t: Contains pointers ++* sigevent: Uses sigval_t which causes it to be the same. Special ++ handing is needed for reading; in the mq_notify syscall ++* sigaction: NOTE the userland structure inside glibc does ++ not match the kernel structure here (this causes issues with LTP). ++ Uses sigset_t. ++* fd_set: This is done to avoid endian issues between ILP32 and LP64 ++ Also the syscall which uses fd_set uses timespec ++ ++ ++Also the syscalls which normally would pass 64bit values as two ++arguments; now pass the 64bit value as one argument. Also they have ++been renamed (removing the 64 from the name) to avoid confusion. ++The list of these syscalls: ++* fcntl ++* statfs ++* fstatfs ++* truncate ++* ftruncate ++* lseek ++* sendfile ++* newfstatat ++* fstat ++* mmap ++* fadvise64 +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0025-ARM64-ILP32-fix-the-compilation-error-due-to-mistype.patch b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0025-ARM64-ILP32-fix-the-compilation-error-due-to-mistype.patch new file mode 100644 index 00000000..6d17221c --- /dev/null +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0025-ARM64-ILP32-fix-the-compilation-error-due-to-mistype.patch @@ -0,0 +1,30 @@ +From a33d84566e90cc279db7cc54de45ab92ce10bdf6 Mon Sep 17 00:00:00 2001 +From: Andrey Konovalov <andrey.konovalov@linaro.org> +Date: Wed, 15 Oct 2014 14:49:53 +0400 +Subject: [PATCH 25/25] ARM64:ILP32: fix the compilation error due to mistyped + header file name + +There is a misprint in the v3 patch "ARM64:ILP32: Use the same size and +layout of the signal structures for ILP32 as for LP64". + +Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> +--- + arch/arm64/include/uapi/asm/signal.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h +index d33a5f7..f378ff4 100644 +--- a/arch/arm64/include/uapi/asm/signal.h ++++ b/arch/arm64/include/uapi/asm/signal.h +@@ -16,7 +16,7 @@ + #ifndef __ASM_SIGNAL_H + #define __ASM_SIGNAL_H + +-#include <asm/posix-types.h> ++#include <asm/posix_types.h> + + /* Required for AArch32 compatibility. */ + #define SA_RESTORER 0x04000000 +-- +1.9.3 + diff --git a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers_3.18.bb b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers_3.18.bb index 7ce1a908..88df4378 100644 --- a/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers_3.18.bb +++ b/meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers_3.18.bb @@ -2,6 +2,34 @@ KORG_ARCHIVE_COMPRESSION = "xz" require recipes-kernel/linux-libc-headers/linux-libc-headers.inc +SRC_URI_append_aarchilp32 = " \ + file://0001-ARM64-Force-LP64-to-compile-the-kernel.patch \ + file://0002-ARM64-Rename-COMPAT-to-AARCH32_EL0-in-Kconfig.patch \ + file://0003-ARM64-Change-some-CONFIG_COMPAT-over-to-use-CONFIG_A.patch \ + file://0004-ARM64-ILP32-Set-kernel_long-to-long-long-so-we-can-r.patch \ + file://0005-ARM64-UAPI-Set-the-correct-__BITS_PER_LONG-for-ILP32.patch \ + file://0006-Allow-for-some-signal-structures-to-be-the-same-betw.patch \ + file://0007-ARM64-ILP32-Use-the-same-size-and-layout-of-the-sign.patch \ + file://0008-Allow-a-32bit-ABI-to-use-the-naming-of-the-64bit-ABI.patch \ + file://0009-ARM64-ILP32-Use-the-same-syscall-names-as-LP64.patch \ + file://0010-ARM64-Introduce-is_a32_task-is_a32_thread-and-TIF_AA.patch \ + file://0011-ARM64-Add-is_ilp32_compat_task-and-is_ilp32_compat_t.patch \ + file://0012-ARM64-ILP32-COMPAT_USE_64BIT_TIME-is-true-for-ILP32-.patch \ + file://0013-ARM64-ILP32-Use-the-non-compat-HWCAP-for-ILP32.patch \ + file://0014-ARM64-ILP32-use-the-standard-start_thread-for-ILP32-.patch \ + file://0015-compat_binfmt_elf-coredump-Allow-some-core-dump-macr.patch \ + file://0016-ARM64-ILP32-Support-core-dump-for-ILP32.patch \ + file://0017-ARM64-Add-loading-of-ILP32-binaries.patch \ + file://0018-ARM64-Add-vdso-for-ILP32-and-use-it-for-the-signal-r.patch \ + file://0019-ptrace-Allow-compat-to-use-the-native-siginfo.patch \ + file://0020-ARM64-ILP32-The-native-siginfo-is-used-instead-of-th.patch \ + file://0021-ARM64-ILP32-Use-a-seperate-syscall-table-as-a-few-sy.patch \ + file://0022-ARM64-ILP32-Fix-signal-return-for-ILP32-when-the-use.patch \ + file://0023-ARM64-Add-ARM64_ILP32-to-Kconfig.patch \ + file://0024-Add-documentation-about-ARM64-ILP32-ABI.patch \ + file://0025-ARM64-ILP32-fix-the-compilation-error-due-to-mistype.patch \ + " + SRC_URI[md5sum] = "9e854df51ca3fef8bfe566dbd7b89241" SRC_URI[sha256sum] = "becc413cc9e6d7f5cc52a3ce66d65c3725bc1d1cc1001f4ce6c32b69eb188cbd" |