Currently in arm64 the start_thread() function is used to initialise registers for both native and compat64 binaries. This is now split into a separate function for both native and compat64 binaries.
Signed-off-by: Sherwin da Cruz sherwin.dacruz@arm.com --- arch/arm64/include/asm/elf.h | 3 ++- arch/arm64/include/asm/processor.h | 20 +++++++++++++++++++- fs/compat_binfmt_elf.c | 28 ++++++++++++++-------------- 3 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 9eb86b4cb691..5802ddd1d28a 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -224,6 +224,8 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#ifdef CONFIG_COMPAT
+#define compat_start_thread compat_start_thread + #ifdef CONFIG_COMPAT64
#define compat_elf_check_arch(x) ((x)->e_machine == EM_AARCH64 && \ @@ -260,7 +262,6 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; #define EF_ARM_EABI_MASK 0xff000000 int compat_elf_check_arch(const struct elf32_hdr *); #define compat_elf_check_arch compat_elf_check_arch -#define compat_start_thread compat_start_thread /* * Unlike the native SET_PERSONALITY macro, the compat version maintains * READ_IMPLIES_EXEC across an execve() since this is the behaviour on diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 5bdecb185f63..cf317203edc2 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -261,6 +261,22 @@ static inline void start_thread(struct pt_regs *regs, unsigned long pc, }
#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT64 + +static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, + unsigned long sp) +{ + start_thread_common(regs, pc); + regs->pstate = PSR_MODE_EL0t; + spectre_v4_enable_task_mitigation(current); + regs->sp = sp; + + if (system_supports_morello()) + morello_thread_start(regs, pc); +} + +#else /* CONFIG_COMPAT64 */ + static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { @@ -276,7 +292,9 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc, spectre_v4_enable_task_mitigation(current); regs->compat_sp = sp; } -#endif + +#endif /* !CONFIG_COMPAT64 */ +#endif /* CONFIG_COMPAT */
static inline bool is_ttbr0_addr(unsigned long addr) { diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index 247b9ebd8fbb..b6b453b35946 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c @@ -120,20 +120,6 @@ #define ELF_PLAT_INIT COMPAT_ELF_PLAT_INIT #endif
-#ifdef compat_start_thread -#define COMPAT_START_THREAD(ex, regs, new_ip, new_sp) \ - compat_start_thread(regs, new_ip, new_sp) -#endif - -#ifdef COMPAT_START_THREAD -#undef START_THREAD -#define START_THREAD(elf_ex, regs, elf_entry, bprm) \ -({ \ - COMPAT_START_THREAD(elf_ex, regs, elf_entry, bprm->p); \ - 0; /* binfmt_elf return value */ \ -}) -#endif - #ifdef compat_arch_setup_additional_pages #define COMPAT_ARCH_SETUP_ADDITIONAL_PAGES(bprm, ex, interpreter) \ compat_arch_setup_additional_pages(bprm, interpreter) @@ -177,6 +163,20 @@ #define SET_PERSONALITY COMPAT_SET_PERSONALITY #endif
+#ifdef compat_start_thread +#define COMPAT_START_THREAD(ex, regs, new_ip, new_sp) \ + compat_start_thread(regs, new_ip, new_sp) +#endif + +#ifdef COMPAT_START_THREAD +#undef START_THREAD +#define START_THREAD(elf_ex, regs, elf_entry, bprm) \ +({ \ + COMPAT_START_THREAD(elf_ex, regs, elf_entry, bprm->p); \ + 0; /* binfmt_elf return value */ \ +}) +#endif + /* * We share all the actual code with the native (64-bit) version. */