From: Andrew Pinski apinski@cavium.com
maillist inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7WGZU CVE: NA
Reference: https://github.com/norov/linux/commits/ilp32-5.2
--------------------------------
In this patchset ILP32 ABI support is added. Additionally to AARCH32, which is binary-compatible with ARM, ILP32 is (mostly) ABI-compatible.
From now, AARCH32_EL0 (former COMPAT) config option means the support of AARCH32 userspace, and ARM64_ILP32 - support of ILP32 ABI (see following patches). COMPAT indicates that one of them or both is enabled.
Where needed, CONFIG_COMPAT is changed over to use CONFIG_AARCH32_EL0 instead.
Reviewed-by: David Daney ddaney@caviumnetworks.com Signed-off-by: Andrew Pinski Andrew.Pinski@caviumnetworks.com Signed-off-by: Yury Norov ynorov@caviumnetworks.com Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Signed-off-by: Christoph Muellner christoph.muellner@theobroma-systems.com Signed-off-by: Bamvor Jian Zhang bamv2005@gmail.com Signed-off-by: Yury Norov ynorov@marvell.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Chen Jun chenjun102@huawei.com
Conflicts: arch/arm64/Kconfig arch/arm64/include/asm/unistd.h arch/arm64/kernel/Makefile arch/arm64/kernel/asm-offsets.c arch/arm64/kernel/cpufeature.c arch/arm64/kernel/cpuinfo.c arch/arm64/kernel/entry-common.c arch/arm64/kernel/entry.S arch/arm64/kernel/head.S arch/arm64/kernel/perf_callchain.c arch/arm64/kernel/vdso.c [chenjiahao: simple context conflicts]
Signed-off-by: Chen Jiahao chenjiahao16@huawei.com --- arch/arm64/Kconfig | 11 ++++++++--- arch/arm64/include/asm/arch_timer.h | 2 +- arch/arm64/include/asm/fpsimd.h | 2 +- arch/arm64/include/asm/hwcap.h | 4 ++-- arch/arm64/include/asm/processor.h | 4 ++-- arch/arm64/include/asm/ptrace.h | 2 +- arch/arm64/include/asm/seccomp.h | 2 +- arch/arm64/include/asm/signal32.h | 4 ++-- arch/arm64/include/asm/syscall.h | 2 +- arch/arm64/include/asm/unistd.h | 2 +- arch/arm64/kernel/Makefile | 4 ++-- arch/arm64/kernel/asm-offsets.c | 2 +- arch/arm64/kernel/cpufeature.c | 10 +++++----- arch/arm64/kernel/cpuinfo.c | 8 ++++---- arch/arm64/kernel/entry-common.c | 6 +++--- arch/arm64/kernel/perf_callchain.c | 6 +++--- arch/arm64/kernel/ptrace.c | 10 ++++++---- arch/arm64/kernel/syscall.c | 4 ++-- arch/arm64/kernel/vdso.c | 4 ++-- 19 files changed, 48 insertions(+), 41 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 343e1e1cae10..d76be4b97a9c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -555,7 +555,7 @@ config ARM64_ERRATUM_1742098
config ARM64_ERRATUM_845719 bool "Cortex-A53: 845719: a load might read incorrect data" - depends on COMPAT + depends on AARCH32_EL0 default y help This option adds an alternative code sequence to work around ARM @@ -1587,7 +1587,7 @@ config ARM64_TAGGED_ADDR_ABI to system calls as pointer arguments. For details, see Documentation/arm64/tagged-address-abi.rst.
-menuconfig COMPAT +menuconfig AARCH32_EL0 bool "Kernel support for 32-bit EL0" depends on ARM64_4K_PAGES || EXPERT select HAVE_UID16 @@ -1605,7 +1605,7 @@ menuconfig COMPAT
If you want to execute 32-bit userspace applications, say Y.
-if COMPAT +if AARCH32_EL0
config KUSER_HELPERS bool "Enable kuser helpers page for 32-bit applications" @@ -1661,6 +1661,7 @@ config COMPAT_ALIGNMENT_FIXUPS
menuconfig ARMV8_DEPRECATED bool "Emulate deprecated/obsolete ARMv8 instructions" + depends on AARCH32_EL0 depends on SYSCTL help Legacy software support may require certain instructions @@ -2299,6 +2300,10 @@ config DMI
endmenu # "Boot options"
+config COMPAT + def_bool y + depends on AARCH32_EL0 + menu "Power management options"
source "kernel/power/Kconfig" diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index af1fafbe7e1d..78fb37d2e77b 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -223,7 +223,7 @@ static inline int arch_timer_arch_init(void) static inline void arch_timer_set_evtstrm_feature(void) { cpu_set_named_feature(EVTSTRM); -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; #endif } diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 67f2fb781f59..09d9bbf32514 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -21,7 +21,7 @@ #include <linux/stddef.h> #include <linux/types.h>
-#ifdef CONFIG_COMPAT +#ifdef 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 5d45f19fda7f..ceb8ed0c349a 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -145,7 +145,7 @@ #define ELF_HWCAP cpu_get_elf_hwcap() #define ELF_HWCAP2 cpu_get_elf_hwcap2()
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define COMPAT_ELF_HWCAP (compat_elf_hwcap) #define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) extern unsigned int compat_elf_hwcap, compat_elf_hwcap2; @@ -153,7 +153,7 @@ extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
enum { CAP_HWCAP = 1, -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 CAP_COMPAT_HWCAP, CAP_COMPAT_HWCAP2, #endif diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 3918f2a67970..49780fb472c1 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -256,7 +256,7 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset, *size = sizeof_field(struct thread_struct, uw); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define task_user_tls(t) \ ({ \ unsigned long *__tls; \ @@ -297,7 +297,7 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc, regs->sp = sp; }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 47ec58031f11..1ff9909e5169 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -217,7 +217,7 @@ static inline void forget_syscall(struct pt_regs *regs)
#define arch_has_single_step() (1)
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define compat_thumb_mode(regs) \ (((regs)->pstate & PSR_AA32_T_BIT)) #else diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h index 30256233788b..0f4cc9322eb4 100644 --- a/arch/arm64/include/asm/seccomp.h +++ b/arch/arm64/include/asm/seccomp.h @@ -10,7 +10,7 @@
#include <asm/unistd.h>
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define __NR_seccomp_read_32 __NR_compat_read #define __NR_seccomp_write_32 __NR_compat_write #define __NR_seccomp_exit_32 __NR_compat_exit diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h index 7e9f163d02ec..48ba6c7ab53e 100644 --- a/arch/arm64/include/asm/signal32.h +++ b/arch/arm64/include/asm/signal32.h @@ -5,7 +5,7 @@ #ifndef __ASM_SIGNAL32_H #define __ASM_SIGNAL32_H
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #include <linux/compat.h>
struct compat_sigcontext { @@ -77,5 +77,5 @@ 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 /* __ASM_SIGNAL32_H */ diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index 4cfe9b49709b..6a7b1804278b 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -13,7 +13,7 @@ typedef long (*syscall_fn_t)(const struct pt_regs *regs);
extern const syscall_fn_t sys_call_table[];
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 extern const syscall_fn_t compat_sys_call_table[]; #endif
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 037feba03a51..9dcffe4cfe23 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2012 ARM Ltd. */ -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define __ARCH_WANT_COMPAT_STAT #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 4a9bb9c651a9..96269015e509 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -36,9 +36,9 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ syscall.o proton-pack.o idreg-override.o idle.o \ patching.o ipi_nmi.o
-obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ +obj-$(CONFIG_AARCH32_EL0) += sys32.o signal32.o \ sys_compat.o -obj-$(CONFIG_COMPAT) += sigreturn32.o +obj-$(CONFIG_AARCH32_EL0) += sigreturn32.o obj-$(CONFIG_COMPAT_ALIGNMENT_FIXUPS) += compat_alignment.o obj-$(CONFIG_KUSER_HELPERS) += kuser32.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 0996094b0d22..5ecbcc61442c 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -99,7 +99,7 @@ int main(void) DEFINE(FREGS_SIZE, sizeof(struct ftrace_regs)); BLANK(); #endif -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 DEFINE(COMPAT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_sigframe, uc.uc_mcontext.arm_r0)); DEFINE(COMPAT_RT_SIGFRAME_REGS_OFFSET, offsetof(struct compat_rt_sigframe, sig.uc.uc_mcontext.arm_r0)); BLANK(); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 7d7128c65161..091512b1f8ad 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -95,7 +95,7 @@ /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly;
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define COMPAT_ELF_HWCAP_DEFAULT \ (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ @@ -2788,7 +2788,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { {}, };
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope) { /* @@ -2811,7 +2811,7 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope) #endif
static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON), HWCAP_CAP(MVFR1_EL1, SIMDFMAC, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4), /* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */ @@ -2840,7 +2840,7 @@ static void cap_set_elf_hwcap(const struct arm64_cpu_capabilities *cap) case CAP_HWCAP: cpu_set_feature(cap->hwcap); break; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 case CAP_COMPAT_HWCAP: compat_elf_hwcap |= (u32)cap->hwcap; break; @@ -2863,7 +2863,7 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap) case CAP_HWCAP: rc = cpu_have_feature(cap->hwcap); break; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 case CAP_COMPAT_HWCAP: rc = (compat_elf_hwcap & (u32)cap->hwcap) != 0; break; diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index eb4378c23b3c..a9cbb1cb64bb 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -127,7 +127,7 @@ static const char *const hwcap_str[] = { [KERNEL_HWCAP_SME_F16F16] = "smef16f16", };
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 #define COMPAT_KERNEL_HWCAP(x) const_ilog2(COMPAT_HWCAP_ ## x) static const char *const compat_hwcap_str[] = { [COMPAT_KERNEL_HWCAP(SWP)] = "swp", @@ -170,7 +170,7 @@ static const char *const compat_hwcap2_str[] = { [COMPAT_KERNEL_HWCAP2(SB)] = "sb", [COMPAT_KERNEL_HWCAP2(SSBS)] = "ssbs", }; -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_AARCH32_EL0 */
static int c_show(struct seq_file *m, void *v) { @@ -203,7 +203,7 @@ static int c_show(struct seq_file *m, void *v) */ seq_puts(m, "Features\t:"); if (compat) { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 for (j = 0; j < ARRAY_SIZE(compat_hwcap_str); j++) { if (compat_elf_hwcap & (1 << j)) { /* @@ -220,7 +220,7 @@ static int c_show(struct seq_file *m, void *v) for (j = 0; j < ARRAY_SIZE(compat_hwcap2_str); j++) if (compat_elf_hwcap2 & (1 << j)) seq_printf(m, " %s", compat_hwcap2_str[j]); -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_AARCH32_EL0 */ } else { for (j = 0; j < ARRAY_SIZE(hwcap_str); j++) if (cpu_have_feature(j)) diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 3af3c01c93a6..7e3a378c0115 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -757,7 +757,7 @@ asmlinkage void noinstr el0t_64_error_handler(struct pt_regs *regs) __el0_error_handler_common(regs); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr) { enter_from_user_mode(regs); @@ -832,12 +832,12 @@ asmlinkage void noinstr el0t_32_error_handler(struct pt_regs *regs) { __el0_error_handler_common(regs); } -#else /* CONFIG_COMPAT */ +#else /* CONFIG_AARCH32_EL0 */ UNHANDLED(el0t, 32, sync) UNHANDLED(el0t, 32, irq) UNHANDLED(el0t, 32, fiq) UNHANDLED(el0t, 32, error) -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_AARCH32_EL0 */
#ifdef CONFIG_VMAP_STACK asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs) diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c index 6d157f32187b..d5cddb150d39 100644 --- a/arch/arm64/kernel/perf_callchain.c +++ b/arch/arm64/kernel/perf_callchain.c @@ -52,7 +52,7 @@ user_backtrace(struct frame_tail __user *tail, return buftail.fp; }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 /* * The registers we're interested in are at the end of the variable * length saved register structure. The fp points at the end of this @@ -97,7 +97,7 @@ compat_user_backtrace(struct compat_frame_tail __user *tail,
return (struct compat_frame_tail __user *)compat_ptr(buftail.fp) - 1; } -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_AARCH32_EL0 */
void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) @@ -119,7 +119,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, tail && !((unsigned long)tail & 0x7)) tail = user_backtrace(tail, entry); } else { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 /* AARCH32 compat mode */ struct compat_frame_tail __user *tail;
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index d7f4f0d1ae12..824f8fec9869 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -173,7 +173,7 @@ static void ptrace_hbptriggered(struct perf_event *bp, struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp); const char *desc = "Hardware breakpoint trap (ptrace)";
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 if (is_compat_task()) { int si_errno = 0; int i; @@ -1575,7 +1575,9 @@ static const struct user_regset_view user_aarch64_view = { .regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets) };
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 +#include <linux/compat.h> + enum compat_regset { REGSET_COMPAT_GPR, REGSET_COMPAT_VFP, @@ -2089,11 +2091,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
return ret; } -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_AARCH32_EL0 */
const struct user_regset_view *task_user_regset_view(struct task_struct *task) { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 /* * Core dumping of 32-bit tasks or compat ptrace requests must use the * user_aarch32_view compatible with arm32. Native ptrace requests on diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index da84cf855c44..5e0f66a28353 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -21,7 +21,7 @@ long sys_ni_syscall(void);
static long do_ni_syscall(struct pt_regs *regs, int scno) { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 long ret; if (is_compat_task()) { ret = compat_arm_syscall(regs, scno); @@ -193,7 +193,7 @@ void do_el0_svc(struct pt_regs *regs) el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 void do_el0_svc_compat(struct pt_regs *regs) { el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls, diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index d9e1355730ef..47c2eb75f591 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -231,7 +231,7 @@ static int __setup_additional_pages(enum vdso_abi abi, return PTR_ERR(ret); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 /* * Create and map the vectors page for AArch32 tasks. */ @@ -409,7 +409,7 @@ int aarch32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) mmap_write_unlock(mm); return ret; } -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_AARCH32_EL0 */
enum aarch64_map { AA64_MAP_VVAR,