aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoen Kooi <koen.kooi@linaro.org>2014-12-11 14:05:53 +0100
committerKoen Kooi <koen.kooi@linaro.org>2014-12-11 14:06:36 +0100
commita628df7e1e8e6767c6168e32398b902af4d58cc6 (patch)
treea2609d2e433657b8d871a3193c0b913d3963d93a
parent5fe176f4014ac30860e00db2d61214a1ef559e89 (diff)
downloadmeta-linaro-a628df7e1e8e6767c6168e32398b902af4d58cc6.tar.gz
linux-libc-headers 3.18: add ILP32 patches
Change-Id: Ibd6b7f143012e3d649bf91f16c1c9f919472df98 Signed-off-by: Koen Kooi <koen.kooi@linaro.org>
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0001-ARM64-Force-LP64-to-compile-the-kernel.patch38
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0002-ARM64-Rename-COMPAT-to-AARCH32_EL0-in-Kconfig.patch44
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0003-ARM64-Change-some-CONFIG_COMPAT-over-to-use-CONFIG_A.patch385
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0004-ARM64-ILP32-Set-kernel_long-to-long-long-so-we-can-r.patch34
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0005-ARM64-UAPI-Set-the-correct-__BITS_PER_LONG-for-ILP32.patch35
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0006-Allow-for-some-signal-structures-to-be-the-same-betw.patch133
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0007-ARM64-ILP32-Use-the-same-size-and-layout-of-the-sign.patch115
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0008-Allow-a-32bit-ABI-to-use-the-naming-of-the-64bit-ABI.patch36
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0009-ARM64-ILP32-Use-the-same-syscall-names-as-LP64.patch30
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0010-ARM64-Introduce-is_a32_task-is_a32_thread-and-TIF_AA.patch246
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0011-ARM64-Add-is_ilp32_compat_task-and-is_ilp32_compat_t.patch49
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0012-ARM64-ILP32-COMPAT_USE_64BIT_TIME-is-true-for-ILP32-.patch33
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0013-ARM64-ILP32-Use-the-non-compat-HWCAP-for-ILP32.patch48
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0014-ARM64-ILP32-use-the-standard-start_thread-for-ILP32-.patch39
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0015-compat_binfmt_elf-coredump-Allow-some-core-dump-macr.patch46
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0016-ARM64-ILP32-Support-core-dump-for-ILP32.patch110
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0017-ARM64-Add-loading-of-ILP32-binaries.patch108
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0018-ARM64-Add-vdso-for-ILP32-and-use-it-for-the-signal-r.patch452
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0019-ptrace-Allow-compat-to-use-the-native-siginfo.patch82
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0020-ARM64-ILP32-The-native-siginfo-is-used-instead-of-th.patch30
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0021-ARM64-ILP32-Use-a-seperate-syscall-table-as-a-few-sy.patch301
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0022-ARM64-ILP32-Fix-signal-return-for-ILP32-when-the-use.patch50
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0023-ARM64-Add-ARM64_ILP32-to-Kconfig.patch42
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0024-Add-documentation-about-ARM64-ILP32-ABI.patch79
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers/0025-ARM64-ILP32-fix-the-compilation-error-due-to-mistype.patch30
-rw-r--r--meta-aarch64/recipes-kernel/linux-libc-headers/linux-libc-headers_3.18.bb28
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"