diff options
author | Andrey Konovalov <andrey.konovalov@linaro.org> | 2015-02-03 19:25:04 +0300 |
---|---|---|
committer | Andrey Konovalov <andrey.konovalov@linaro.org> | 2015-02-03 19:25:04 +0300 |
commit | fb3bc36699ac976b0c3e1d27811272a40cee07f5 (patch) | |
tree | ed7119ecdcc84b37f3a1aeb51819e084c231497b /arch/arm64/include/asm | |
parent | 8ba792103c60eed2e093d2866441f430d7e306a8 (diff) | |
parent | 0b5ed2617ffc868673c7916e7469294e5cc2128d (diff) |
Merge branch 'tracking-ilp32' into merge-linux-linaroll-20150203.0
Diffstat (limited to 'arch/arm64/include/asm')
-rw-r--r-- | arch/arm64/include/asm/compat.h | 59 | ||||
-rw-r--r-- | arch/arm64/include/asm/elf.h | 100 | ||||
-rw-r--r-- | arch/arm64/include/asm/fpsimd.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/hwcap.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/processor.h | 11 | ||||
-rw-r--r-- | arch/arm64/include/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/signal32.h | 4 | ||||
-rw-r--r-- | arch/arm64/include/asm/stat.h | 4 | ||||
-rw-r--r-- | arch/arm64/include/asm/syscalls.h | 4 | ||||
-rw-r--r-- | arch/arm64/include/asm/thread_info.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/unistd.h | 6 | ||||
-rw-r--r-- | arch/arm64/include/asm/vdso.h | 4 |
12 files changed, 181 insertions, 18 deletions
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index 3fb053fa6e98..e74a629570da 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; @@ -215,6 +218,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 @@ -300,6 +306,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); @@ -318,5 +334,48 @@ 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 + +#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 */ diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 1f65be393139..e9f3891fd68a 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> /* @@ -135,7 +136,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 { \ @@ -171,23 +176,100 @@ 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 -typedef unsigned int compat_elf_greg_t; -typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; +#define COMPAT_A32_ELF_NGREG 18 +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 -#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 -#define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT); -#define COMPAT_ARCH_DLINFO +#define COMPAT_A32_SET_PERSONALITY(ex) \ +do { \ + set_thread_flag(TIF_AARCH32); \ + set_thread_flag(TIF_32BIT); \ +} while (0) +#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_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 + +/* + * 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 + +#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 */ diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 50f559f574fe..63b19f128c6c 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/hwcap.h b/arch/arm64/include/asm/hwcap.h index 0ad735166d9f..8b09fd1620dd 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -47,8 +47,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 diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 760ad22fd3e4..a5a2c3252357 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -105,6 +105,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) diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 41ed9e13795e..690a380e2cdf 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 eeaa97559bab..522c3456141e 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 15e35598ac40..e3b5865be66d 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/syscalls.h b/arch/arm64/include/asm/syscalls.h index 48fe7c600e98..b58dad785c29 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/thread_info.h b/arch/arm64/include/asm/thread_info.h index 459bf8e53208..a1851057162b 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/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 23e9432ac112..0b583c9a53b9 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -13,7 +13,11 @@ * 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_ARM64_ILP32 +#define __ARCH_WANT_COMPAT_SYS_PREADV64 +#define __ARCH_WANT_COMPAT_SYS_PWRITEV64 +#endif +#ifdef CONFIG_AARCH32_EL0 #define __ARCH_WANT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 839ce0031bd5..84050c613cc3 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)); \ |