The only difference is that non-compat version forces O_LARGEFILE,
and it should be the default behaviour for all architectures, as
we don't support 32-bit off_t. The only exception is tile32, that
continues with compat version of syscalls.
Signed-off-by: Yury Norov <redacted>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Chris Metcalf <redacted> [for tile]
---
arch/tile/kernel/compat.c | 3 +++
1 file changed, 3 insertions(+)
All new 32-bit architectures should have 64-bit off_t type, but existing
architectures has 32-bit ones.
To handle it, new config option is added to arch/Kconfig that defaults
ARCH_32BIT_OFF_T to be disabled for non-64 bit architectures. All existing
32-bit architectures enable it explicitly here.
New option affects force_o_largefile() behaviour. Namely, if off_t is
64-bits long, we have no reason to reject user to open big files.
Note that even if architectures has only 64-bit off_t in the kernel
(arc, c6x, h8300, hexagon, metag, nios2, openrisc, tile32 and unicore32),
a libc may use 32-bit off_t, and therefore want to limit the file size
to 4GB unless specified differently in the open flags.
Signed-off-by: Yury Norov <redacted>
---
arch/Kconfig | 4 ++++
arch/arc/Kconfig | 1 +
arch/arm/Kconfig | 1 +
arch/blackfin/Kconfig | 1 +
arch/cris/Kconfig | 1 +
arch/frv/Kconfig | 1 +
arch/h8300/Kconfig | 1 +
arch/hexagon/Kconfig | 1 +
arch/m32r/Kconfig | 1 +
arch/m68k/Kconfig | 1 +
arch/metag/Kconfig | 1 +
arch/microblaze/Kconfig | 1 +
arch/mips/Kconfig | 1 +
arch/mn10300/Kconfig | 1 +
arch/nios2/Kconfig | 1 +
arch/openrisc/Kconfig | 1 +
arch/parisc/Kconfig | 1 +
arch/powerpc/Kconfig | 1 +
arch/score/Kconfig | 1 +
arch/sh/Kconfig | 1 +
arch/sparc/Kconfig | 1 +
arch/tile/Kconfig | 1 +
arch/unicore32/Kconfig | 1 +
arch/x86/Kconfig | 1 +
arch/x86/um/Kconfig | 1 +
arch/xtensa/Kconfig | 1 +
include/linux/fcntl.h | 2 +-
27 files changed, 30 insertions(+), 1 deletion(-)
@@ -0,0 +1,54 @@+ILP32 AARCH64 SYSCALL ABI+=========================++This document describes the ILP32 syscall ABI and where it differs+from the generic compat linux syscall interface.++AARCH64/ILP32 userspace can potentially access top halves of registers that+are passed as syscall arguments, so such registers (w0-w7) are deloused.++AARCH64/ILP32 provides next types turned to 64-bit (comparing to AARCH32):+ino_t is u64 type.+off_t is s64 type.+blkcnt_t is s64 type.+fsblkcnt_t is u64 type.+fsfilcnt_t is u64 type.++AARCH64/ILP32 ABI uses standard syscall table which can be found at+include/uapi/asm-generic/unistd.h, with the exceptions listed below.++Syscalls which pass 64bit values are handled by the code shared from+AARCH32 and pass that value as a pair. Next syscalls are affected:+fadvise64_64()+fallocate()+ftruncate64() +pread64 ()+pwrite64()+readahead()+sync_file_range()+truncate64()+sys_mmap()++ptrace() syscall is handled by compat version.++fcntl64() syscall is handled by non-compat handler as struct flock for ilp32+is the same as for lp64++shmat() syscall is handled by non-compat handler as aarch64/ilp32 has no+limitation on 4-pages alignement for shared memory.++Syscalls which take a pointer to stat, stat64, statfs, statfs64+structures are now routed to native handlers directly, as aarch64/ilp32+defines userspace ino_t, off_t, blkcnt_t, fsblkcnt_t, fsfilcnt_t types+as 64-bit and it makes that structures have same layout as lp64.+Next syscalls are affected:+fstatat64()+fstat64()+statfs64()+fstatfs64()++struct rt_sigframe is redefined and contains struct compat_siginfo,+as compat syscalls expects, and struct ilp32_sigframe, to handle+AARCH64 register set and 32-bit userspace register representation.h++elf_gregset_t is taken from lp64 to handle registers properly.
From: Andrew Pinski <redacted>
The kernel needs to be compiled as a LP64 binary for ARM64, even when
using a compiler that defaults to code-generation for the ILP32 ABI.
Consequently, we need to explicitly pass '-mabi=lp64' (supported on
gcc-4.9 and newer).
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Yury Norov <redacted>
Reviewed-by: David Daney <redacted>
---
arch/arm64/Makefile | 5 +++++
1 file changed, 5 insertions(+)
They may be accessed from low-level code, so isolating is a measure to
avoid circular dependencies in header files.
The exact reason for circular dependency is WARN_ON() macro added by Al
Viro in patch [edd63a27] "set_restore_sigmask() is never called without
SIGPENDING (and never should be)"
Signed-off-by: Yury Norov <redacted>
---
include/linux/thread_bits.h | 55 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/thread_info.h | 44 +-----------------------------------
2 files changed, 56 insertions(+), 43 deletions(-)
create mode 100644 include/linux/thread_bits.h
As we support more than one compat formats, it looks more reasonable
to not use fs/compat_binfmt.c. Custom binfmt_elf32.c allows to move aarch32
specific definitions there and make code more maintainable and readable.
Signed-off-by: Yury Norov <redacted>
---
arch/arm64/Kconfig | 1 -
arch/arm64/include/asm/hwcap.h | 2 --
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/binfmt_elf32.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 32 insertions(+), 4 deletions(-)
create mode 100644 arch/arm64/kernel/binfmt_elf32.c
From: Andrew Pinski <redacted>
Add a separate syscall-table for ILP32, which dispatches either to native
LP64 system call implementation or to compat-syscalls, as appropriate.
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Yury Norov <redacted>
---
arch/arm64/include/asm/unistd.h | 6 ++-
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/entry.S | 29 +++++++++++++-
arch/arm64/kernel/sys_ilp32.c | 84 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 4 deletions(-)
create mode 100644 arch/arm64/kernel/sys_ilp32.c
@@ -717,15 +735,22 @@ ENDPROC(ret_from_fork).align6el0_svc:adrpstbl,sys_call_table//loadsyscalltablepointer+ldrx16,[tsk,#TI_FLAGS]uxtwscno,w8//syscallnumberinw8movsc_nr,#__NR_syscalls+#ifdef CONFIG_ARM64_ILP32+adrpx17,sys_call_ilp32_table//loadilp32syscalltablepointer+tstx16,#_TIF_32BIT_AARCH64+b.eqel0_svc_naked//WeareusingLP64syscalltable+movstbl,x17//WeareusingILP32syscalltable+delouse_input_regs+#endifel0_svc_naked://compatentrypointstpx0,scno,[sp,#S_ORIG_X0] // save the original x0 and syscall numberenable_dbg_and_irqct_user_exit1-ldrx16,[tsk,#TI_FLAGS] // check for syscall hooks-tstx16,#_TIF_SYSCALL_WORK+tstx16,#_TIF_SYSCALL_WORK // check for syscall hooksb.ne__sys_tracecmpscno,sc_nr//checkuppersyscalllimitb.hsni_sys
On Sat, Jun 18, 2016 at 02:54:23AM +0300, Yury Norov wrote:
quoted hunk
From: Andrew Pinski <redacted>
Add a separate syscall-table for ILP32, which dispatches either to native
LP64 system call implementation or to compat-syscalls, as appropriate.
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Yury Norov <redacted>
---
arch/arm64/include/asm/unistd.h | 6 ++-
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/entry.S | 29 +++++++++++++-
arch/arm64/kernel/sys_ilp32.c | 84 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 4 deletions(-)
create mode 100644 arch/arm64/kernel/sys_ilp32.c
It should be like this:
#ifdef CONFIG_ARM64_ILP32
tst x16, #_TIF_32BIT_AARCH64
b.eq el0_svc_naked // We are using LP64 syscall table
adrp stbl, sys_call_ilp32_table // load ilp32 syscall table pointer
delouse_input_regs
#endif
quoted hunk
el0_svc_naked: // compat entry point
stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number
enable_dbg_and_irq
ct_user_exit 1
- ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
- tst x16, #_TIF_SYSCALL_WORK
+ tst x16, #_TIF_SYSCALL_WORK // check for syscall hooks
b.ne __sys_trace
cmp scno, sc_nr // check upper syscall limit
b.hs ni_sys
@@ -125,91 +125,6 @@ static inline int get_sigset_t(sigset_t *set,return0;}-intcopy_siginfo_to_user32(compat_siginfo_t__user*to,constsiginfo_t*from)-{-interr;--if(!access_ok(VERIFY_WRITE,to,sizeof(*to)))-return-EFAULT;--/* If you change siginfo_t structure, please be sure-*thiscodeisfixedaccordingly.-*Itshouldnevercopyanypadcontainedinthestructure-*toavoidsecurityleaks,butmustcopythegeneric-*3intsplustherelevantunionmember.-*Thisroutinemustconvertsiginfofrom64bitto32bitaswell-*atthesametime.-*/-err=__put_user(from->si_signo,&to->si_signo);-err|=__put_user(from->si_errno,&to->si_errno);-err|=__put_user((short)from->si_code,&to->si_code);-if(from->si_code<0)-err|=__copy_to_user(&to->_sifields._pad,&from->_sifields._pad,-SI_PAD_SIZE);-elseswitch(from->si_code&__SI_MASK){-case__SI_KILL:-err|=__put_user(from->si_pid,&to->si_pid);-err|=__put_user(from->si_uid,&to->si_uid);-break;-case__SI_TIMER:-err|=__put_user(from->si_tid,&to->si_tid);-err|=__put_user(from->si_overrun,&to->si_overrun);-err|=__put_user(from->si_int,&to->si_int);-break;-case__SI_POLL:-err|=__put_user(from->si_band,&to->si_band);-err|=__put_user(from->si_fd,&to->si_fd);-break;-case__SI_FAULT:-err|=__put_user((compat_uptr_t)(unsignedlong)from->si_addr,-&to->si_addr);-#ifdef BUS_MCEERR_AO-/*-*Othercallersmightnotinitializethesi_lsbfield,-*socheckexplicitlyfortherightcodeshere.-*/-if(from->si_signo==SIGBUS&&-(from->si_code==BUS_MCEERR_AR||from->si_code==BUS_MCEERR_AO))-err|=__put_user(from->si_addr_lsb,&to->si_addr_lsb);-#endif-break;-case__SI_CHLD:-err|=__put_user(from->si_pid,&to->si_pid);-err|=__put_user(from->si_uid,&to->si_uid);-err|=__put_user(from->si_status,&to->si_status);-err|=__put_user(from->si_utime,&to->si_utime);-err|=__put_user(from->si_stime,&to->si_stime);-break;-case__SI_RT:/* This is not generated by the kernel as of now. */-case__SI_MESGQ:/* But this is */-err|=__put_user(from->si_pid,&to->si_pid);-err|=__put_user(from->si_uid,&to->si_uid);-err|=__put_user(from->si_int,&to->si_int);-break;-case__SI_SYS:-err|=__put_user((compat_uptr_t)(unsignedlong)-from->si_call_addr,&to->si_call_addr);-err|=__put_user(from->si_syscall,&to->si_syscall);-err|=__put_user(from->si_arch,&to->si_arch);-break;-default:/* this is just in case for now ... */-err|=__put_user(from->si_pid,&to->si_pid);-err|=__put_user(from->si_uid,&to->si_uid);-break;-}-returnerr;-}--intcopy_siginfo_from_user32(siginfo_t*to,compat_siginfo_t__user*from)-{-if(copy_from_user(to,from,__ARCH_SI_PREAMBLE_SIZE)||-copy_from_user(to->_sifields._pad,-from->_sifields._pad,SI_PAD_SIZE))-return-EFAULT;--return0;-}-/**VFPsave/restorecode.*
@@ -0,0 +1,115 @@+/*+*Basedonarch/arm/kernel/signal.c+*+*Copyright(C)1995-2009RussellKing+*Copyright(C)2012ARMLtd.+*ModifiedbyWillDeacon<will.deacon@arm.com>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodify+*itunderthetermsoftheGNUGeneralPublicLicenseversion2as+*publishedbytheFreeSoftwareFoundation.+*+*Thisprogramisdistributedinthehopethatitwillbeuseful,+*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof+*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe+*GNUGeneralPublicLicenseformoredetails.+*+*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense+*alongwiththisprogram.Ifnot,see<http://www.gnu.org/licenses/>.+*/++#include<linux/compat.h>+#include<linux/signal.h>+#include<linux/ratelimit.h>++#include<asm/esr.h>+#include<asm/fpsimd.h>+#include<asm/signal32_common.h>+#include<asm/uaccess.h>+#include<asm/unistd.h>++intcopy_siginfo_to_user32(compat_siginfo_t__user*to,constsiginfo_t*from)+{+interr;++if(!access_ok(VERIFY_WRITE,to,sizeof(*to)))+return-EFAULT;++/* If you change siginfo_t structure, please be sure+*thiscodeisfixedaccordingly.+*Itshouldnevercopyanypadcontainedinthestructure+*toavoidsecurityleaks,butmustcopythegeneric+*3intsplustherelevantunionmember.+*Thisroutinemustconvertsiginfofrom64bitto32bitaswell+*atthesametime.+*/+err=__put_user(from->si_signo,&to->si_signo);+err|=__put_user(from->si_errno,&to->si_errno);+err|=__put_user((short)from->si_code,&to->si_code);+if(from->si_code<0)+err|=__copy_to_user(&to->_sifields._pad,&from->_sifields._pad,+SI_PAD_SIZE);+elseswitch(from->si_code&__SI_MASK){+case__SI_KILL:+err|=__put_user(from->si_pid,&to->si_pid);+err|=__put_user(from->si_uid,&to->si_uid);+break;+case__SI_TIMER:+err|=__put_user(from->si_tid,&to->si_tid);+err|=__put_user(from->si_overrun,&to->si_overrun);+err|=__put_user(from->si_int,&to->si_int);+break;+case__SI_POLL:+err|=__put_user(from->si_band,&to->si_band);+err|=__put_user(from->si_fd,&to->si_fd);+break;+case__SI_FAULT:+err|=__put_user((compat_uptr_t)(unsignedlong)from->si_addr,+&to->si_addr);+#ifdef BUS_MCEERR_AO+/*+*Othercallersmightnotinitializethesi_lsbfield,+*socheckexplicitlyfortherightcodeshere.+*/+if(from->si_signo==SIGBUS&&+(from->si_code==BUS_MCEERR_AR||from->si_code==BUS_MCEERR_AO))+err|=__put_user(from->si_addr_lsb,&to->si_addr_lsb);+#endif+break;+case__SI_CHLD:+err|=__put_user(from->si_pid,&to->si_pid);+err|=__put_user(from->si_uid,&to->si_uid);+err|=__put_user(from->si_status,&to->si_status);+err|=__put_user(from->si_utime,&to->si_utime);+err|=__put_user(from->si_stime,&to->si_stime);+break;+case__SI_RT:/* This is not generated by the kernel as of now. */+case__SI_MESGQ:/* But this is */+err|=__put_user(from->si_pid,&to->si_pid);+err|=__put_user(from->si_uid,&to->si_uid);+err|=__put_user(from->si_int,&to->si_int);+break;+case__SI_SYS:+err|=__put_user((compat_uptr_t)(unsignedlong)+from->si_call_addr,&to->si_call_addr);+err|=__put_user(from->si_syscall,&to->si_syscall);+err|=__put_user(from->si_arch,&to->si_arch);+break;+default:/* this is just in case for now ... */+err|=__put_user(from->si_pid,&to->si_pid);+err|=__put_user(from->si_uid,&to->si_uid);+break;+}+returnerr;+}++intcopy_siginfo_from_user32(siginfo_t*to,compat_siginfo_t__user*from)+{+if(copy_from_user(to,from,__ARCH_SI_PREAMBLE_SIZE)||+copy_from_user(to->_sifields._pad,+from->_sifields._pad,SI_PAD_SIZE))+return-EFAULT;++return0;+}+
@@ -58,3 +59,9 @@ 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++ifeq ($(CONFIG_ARM64_ILP32),y)+# 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+endif
@@ -0,0 +1,74 @@+#+# 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.onote-ilp32.osigreturn-ilp32.o++# Build rules+targets:=$(obj-ilp32-vdso)vdso-ilp32.sovdso-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\+$(callcc-ldoption,-Wl$(comma)--hash-style=sysv)++obj-y+=vdso-ilp32.o+extra-y+=vdso-ilp32.ldsvdso-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)+$(callif_changed,vdso-ilp32ld)++# Strip rule for the .so file+$(obj)/%.so:OBJCOPYFLAGS := -S+$(obj)/%.so:$(obj)/%.so.dbgFORCE+$(callif_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=Csort>$@&&\+cp$@include/generated/+endef++$(obj)/vdso-ilp32-offsets.h:$(obj)/vdso-ilp32.so.dbgFORCE+$(callif_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+$(callif_changed_dep,vdso-ilp32as)++$(obj)/note-ilp32.o:$(src)/../vdso/note.S+$(callif_changed_dep,vdso-ilp32as)++# This one should be fine because ILP32 uses the same generic+# __NR_rt_sigreturn syscall number.+$(obj)/sigreturn-ilp32.o:$(src)/../vdso/sigreturn.S+$(callif_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+$(callcmd,vdso_install)++vdso_install:vdso-ilp32.so
@@ -110,24 +116,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)}#endif /* CONFIG_AARCH32_EL0 */-staticstructvm_special_mappingvdso_spec[2];--staticint__initvdso_init(void)+staticint__initvdso_init_common(char*vdso_start,char*vdso_end,+unsignedlong*vdso_pagesp,+structpage***vdso_pagelistp,+structvm_special_mapping*vdso_spec){inti;+unsignedlongvdso_pages;+structpage**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(structpage*),GFP_KERNEL);+*vdso_pagelistp=vdso_pagelist;if(vdso_pagelist==NULL)return-ENOMEM;
@@ -136,7 +147,7 @@ static int __init vdso_init(void)/* Grab the vDSO code pages. */for(i=0;i<vdso_pages;i++)-vdso_pagelist[i+1]=pfn_to_page(PHYS_PFN(__pa(&vdso_start))+i);+vdso_pagelist[i+1]=pfn_to_page(PHYS_PFN(__pa(vdso_start))+i);/* Populate the special mapping structures */vdso_spec[0]=(structvm_special_mapping){
@@ -151,16 +162,46 @@ static int __init vdso_init(void)return0;}++staticstructvm_special_mappingvdso_spec[2];++staticint__initvdso_init(void)+{+returnvdso_init_common(&vdso_start,&vdso_end,+&vdso_pages,&vdso_pagelist,+vdso_spec);+}arch_initcall(vdso_init);+#ifdef CONFIG_ARM64_ILP32+staticstructvm_special_mappingvdso_ilp32_spec[2];++staticint__initvdso_ilp32_init(void)+{+returnvdso_init_common(&vdso_ilp32_start,&vdso_ilp32_end,+&vdso_ilp32_pages,&vdso_ilp32_pagelist,+vdso_ilp32_spec);+}+arch_initcall(vdso_ilp32_init);+#endif+intarch_setup_additional_pages(structlinux_binprm*bprm,intuses_interp){structmm_struct*mm=current->mm;unsignedlongvdso_base,vdso_text_len,vdso_mapping_len;void*ret;+unsignedlongpages=vdso_pages;+structvm_special_mapping*spec=vdso_spec;++#ifdef CONFIG_ARM64_ILP32+if(is_ilp32_compat_task()){+pages=vdso_ilp32_pages;+spec=vdso_ilp32_spec;+}+#endif-vdso_text_len=vdso_pages<<PAGE_SHIFT;+vdso_text_len=pages<<PAGE_SHIFT;/* Be sure to map the data page */vdso_mapping_len=vdso_text_len+PAGE_SIZE;
@@ -173,7 +214,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]);+&spec[0]);if(IS_ERR(ret))gotoup_fail;
@@ -182,7 +223,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]);+&spec[1]);if(IS_ERR(ret))gotoup_fail;
@@ -972,7 +972,7 @@ source "fs/Kconfig.binfmt"configCOMPATbool-depends onAARCH32_EL0+depends onAARCH32_EL0||ARM64_ILP32configAARCH32_EL0bool"Kernel support for 32-bit EL0"
@@ -994,6 +994,14 @@ config AARCH32_EL0Ifyouwanttoexecute32-bituserspaceapplications,sayY.+configARM64_ILP32+bool"Kernel support for ILP32"+selectCOMPAT+help+ThisoptionenablessupportforAArch64ILP32userspace.ILP32+isanABIwherelongandpointersare32bitsbutitusestheAARCH64+instructionset.+configSYSVIPC_COMPATdef_boolydepends onCOMPAT&&SYSVIPC
From: Andrew Pinski <redacted>
ILP32 uses AARCH32 compat structures and syscall handlers for signals.
But ILP32 struct rt_sigframe and ucontext differs from both LP64 and
AARCH32. So some specific mechanism is needed to take care of it.
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Yury Norov <redacted>
---
arch/arm64/include/asm/signal_ilp32.h | 34 ++++++
arch/arm64/kernel/Makefile | 3 +-
arch/arm64/kernel/entry_ilp32.S | 23 ++++
arch/arm64/kernel/signal.c | 3 +
arch/arm64/kernel/signal_ilp32.c | 194 ++++++++++++++++++++++++++++++++++
5 files changed, 256 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/include/asm/signal_ilp32.h
create mode 100644 arch/arm64/kernel/entry_ilp32.S
create mode 100644 arch/arm64/kernel/signal_ilp32.c
@@ -0,0 +1,194 @@+/*+*Basedonarch/arm/kernel/signal.c+*+*Copyright(C)1995-2009RussellKing+*Copyright(C)2012ARMLtd.+*Copyright(C)2016CaviumNetworks.+*YuryNorov<ynorov@caviumnetworks.com>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodify+*itunderthetermsoftheGNUGeneralPublicLicenseversion2as+*publishedbytheFreeSoftwareFoundation.+*+*Thisprogramisdistributedinthehopethatitwillbeuseful,+*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof+*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe+*GNUGeneralPublicLicenseformoredetails.+*+*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense+*alongwiththisprogram.Ifnot,see<http://www.gnu.org/licenses/>.+*/++#include<linux/compat.h>+#include<linux/signal.h>+#include<linux/syscalls.h>+#include<linux/ratelimit.h>++#include<asm/esr.h>+#include<asm/fpsimd.h>+#include<asm/signal32_common.h>+#include<asm/signal_common.h>+#include<asm/uaccess.h>+#include<asm/unistd.h>+#include<asm/ucontext.h>+++#define ILP32_RT_SIGFRAME_FP_POS (offsetof(struct ilp32_rt_sigframe, sig) \++offsetof(structilp32_sigframe,fp))++structilp32_ucontext{+u32uc_flags;+u32uc_link;+compat_stack_tuc_stack;+compat_sigset_tuc_sigmask;+/* glibc uses a 1024-bit sigset_t */+__u8__unused[1024/8-sizeof(compat_sigset_t)];+/* last for future expansion */+structsigcontextuc_mcontext;+};++structilp32_sigframe{+structilp32_ucontextuc;+u64fp;+u64lr;+};++structilp32_rt_sigframe{+structcompat_siginfoinfo;+structilp32_sigframesig;+};++staticinlineintput_sigset_t(compat_sigset_t__user*uset,sigset_t*set)+{+compat_sigset_tcset;++cset.sig[0]=set->sig[0]&0xffffffffull;+cset.sig[1]=set->sig[0]>>32;++returncopy_to_user(uset,&cset,sizeof(*uset));+}++staticinlineintget_sigset_t(sigset_t*set,+constcompat_sigset_t__user*uset)+{+compat_sigset_ts32;++if(copy_from_user(&s32,uset,sizeof(*uset)))+return-EFAULT;++set->sig[0]=s32.sig[0]|(((long)s32.sig[1])<<32);+return0;+}++staticintrestore_ilp32_sigframe(structpt_regs*regs,+structilp32_sigframe__user*sf)+{+sigset_tset;+interr;+err=get_sigset_t(&set,&sf->uc.uc_sigmask);+if(err==0)+set_current_blocked(&set);+err|=restore_sigcontext(regs,&sf->uc.uc_mcontext);+returnerr;+}++staticintsetup_ilp32_sigframe(structilp32_sigframe__user*sf,+structpt_regs*regs,sigset_t*set)+{+interr=0;+/* set up the stack frame for unwinding */+__put_user_error(regs->regs[29],&sf->fp,err);+__put_user_error(regs->regs[30],&sf->lr,err);++err|=put_sigset_t(&sf->uc.uc_sigmask,set);+err|=setup_sigcontext(&sf->uc.uc_mcontext,regs);+returnerr;+}++asmlinkagelongilp32_sys_rt_sigreturn(structpt_regs*regs)+{+structilp32_rt_sigframe__user*frame;++/* Always make any pending restarted system calls return -EINTR */+current->restart_block.fn=do_no_restart_syscall;++/*+*Sincewestackedthesignalona128-bitboundary,+*then'sp'shouldbewordalignedhere.Ifit's+*not,thentheuseristryingtomesswithus.+*/+if(regs->sp&15)+gotobadframe;++frame=(structilp32_rt_sigframe__user*)regs->sp;++if(!access_ok(VERIFY_READ,frame,sizeof(*frame)))+gotobadframe;++if(restore_ilp32_sigframe(regs,&frame->sig))+gotobadframe;++if(compat_restore_altstack(&frame->sig.uc.uc_stack))+gotobadframe;++returnregs->regs[0];++badframe:+if(show_unhandled_signals)+pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n",+current->comm,task_pid_nr(current),__func__,+regs->pc,regs->sp);+force_sig(SIGSEGV,current);+return0;+}++staticstructilp32_rt_sigframe__user*ilp32_get_sigframe(structksignal*ksig,+structpt_regs*regs)+{+unsignedlongsp,sp_top;+structilp32_rt_sigframe__user*frame;++sp=sp_top=sigsp(regs->sp,ksig);++sp=(sp-sizeof(structilp32_rt_sigframe))&~15;+frame=(structilp32_rt_sigframe__user*)sp;++/*+*Checkthatwecanactuallywritetothesignalframe.+*/+if(!access_ok(VERIFY_WRITE,frame,sp_top-sp))+frame=NULL;++returnframe;+}++/*+*ILP32signalhandlingroutinescalledfromsignal.c+*/+intilp32_setup_rt_frame(intusig,structksignal*ksig,+sigset_t*set,structpt_regs*regs)+{+structilp32_rt_sigframe__user*frame;+interr=0;++frame=ilp32_get_sigframe(ksig,regs);++if(!frame)+return1;++err|=copy_siginfo_to_user32(&frame->info,&ksig->info);++__put_user_error(0,&frame->sig.uc.uc_flags,err);+__put_user_error(0,&frame->sig.uc.uc_link,err);++err|=__compat_save_altstack(&frame->sig.uc.uc_stack,regs->sp);+err|=setup_ilp32_sigframe(&frame->sig,regs,set);+if(err==0){+setup_return(regs,&ksig->ka,frame,ILP32_RT_SIGFRAME_FP_POS,usig);+regs->regs[1]=(unsignedlong)&frame->info;+regs->regs[2]=(unsignedlong)&frame->sig.uc;+}++returnerr;+}+
After that, it will be possible to reuse it in ilp32.
Signed-off-by: Yury Norov <redacted>
---
arch/arm64/include/asm/signal_common.h | 33 ++++++++++++
arch/arm64/kernel/signal.c | 93 +++++++++++++++++++++-------------
2 files changed, 92 insertions(+), 34 deletions(-)
create mode 100644 arch/arm64/include/asm/signal_common.h
@@ -65,7 +73,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)returnerr?-EFAULT:0;}-staticintrestore_fpsimd_context(structfpsimd_context__user*ctx)+intrestore_fpsimd_context(structfpsimd_context__user*ctx){structfpsimd_statefpsimd;__u32magic,size;
@@ -93,22 +101,30 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)}staticintrestore_sigframe(structpt_regs*regs,-structrt_sigframe__user*sf)+structsigframe__user*sf){sigset_tset;-inti,err;-void*aux=sf->uc.uc_mcontext.__reserved;-+interr;err=__copy_from_user(&set,&sf->uc.uc_sigmask,sizeof(set));if(err==0)set_current_blocked(&set);+err|=restore_sigcontext(regs,&sf->uc.uc_mcontext);+returnerr;+}+++intrestore_sigcontext(structpt_regs*regs,structsigcontext__user*uc_mcontext)+{+inti,err=0;+void*aux=uc_mcontext->__reserved;+for(i=0;i<31;i++)-__get_user_error(regs->regs[i],&sf->uc.uc_mcontext.regs[i],+__get_user_error(regs->regs[i],&uc_mcontext->regs[i],err);-__get_user_error(regs->sp,&sf->uc.uc_mcontext.sp,err);-__get_user_error(regs->pc,&sf->uc.uc_mcontext.pc,err);-__get_user_error(regs->pstate,&sf->uc.uc_mcontext.pstate,err);+__get_user_error(regs->sp,&uc_mcontext->sp,err);+__get_user_error(regs->pc,&uc_mcontext->pc,err);+__get_user_error(regs->pstate,&uc_mcontext->pstate,err);/**Avoidsys_rt_sigreturn()restarting.
@@ -145,10 +161,10 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)if(!access_ok(VERIFY_READ,frame,sizeof(*frame)))gotobadframe;-if(restore_sigframe(regs,frame))+if(restore_sigframe(regs,&frame->sig))gotobadframe;-if(restore_altstack(&frame->uc.uc_stack))+if(restore_altstack(&frame->sig.uc.uc_stack))gotobadframe;returnregs->regs[0];
@@ -162,27 +178,36 @@ badframe:return0;}-staticintsetup_sigframe(structrt_sigframe__user*sf,+staticintsetup_sigframe(structsigframe__user*sf,structpt_regs*regs,sigset_t*set){-inti,err=0;-void*aux=sf->uc.uc_mcontext.__reserved;-struct_aarch64_ctx*end;+interr=0;/* set up the stack frame for unwinding */__put_user_error(regs->regs[29],&sf->fp,err);__put_user_error(regs->regs[30],&sf->lr,err);+err|=__copy_to_user(&sf->uc.uc_sigmask,set,sizeof(*set));+err|=setup_sigcontext(&sf->uc.uc_mcontext,regs);++returnerr;+}++intsetup_sigcontext(structsigcontext__user*uc_mcontext,+structpt_regs*regs)+{+void*aux=uc_mcontext->__reserved;+struct_aarch64_ctx*end;+inti,err=0;for(i=0;i<31;i++)-__put_user_error(regs->regs[i],&sf->uc.uc_mcontext.regs[i],+__put_user_error(regs->regs[i],&uc_mcontext->regs[i],err);-__put_user_error(regs->sp,&sf->uc.uc_mcontext.sp,err);-__put_user_error(regs->pc,&sf->uc.uc_mcontext.pc,err);-__put_user_error(regs->pstate,&sf->uc.uc_mcontext.pstate,err);-__put_user_error(current->thread.fault_address,&sf->uc.uc_mcontext.fault_address,err);+__put_user_error(regs->sp,&uc_mcontext->sp,err);+__put_user_error(regs->pc,&uc_mcontext->pc,err);+__put_user_error(regs->pstate,&uc_mcontext->pstate,err);-err|=__copy_to_user(&sf->uc.uc_sigmask,set,sizeof(*set));+__put_user_error(current->thread.fault_address,&uc_mcontext->fault_address,err);if(err==0){structfpsimd_context*fpsimd_ctx=
@@ -1056,7 +1056,7 @@ int ptrace_request(struct task_struct *child, long request,returnret;}-staticstructtask_struct*ptrace_get_task_struct(pid_tpid)+structtask_struct*ptrace_get_task_struct(pid_tpid){structtask_struct*child;
The {GET,SET}SIGMASK request of ptrace on ilp32 is wrong, it's handled
by ptrace_request(like aarch64). So I write a patch to fix it(just for
ilp32). I will send the patch next.
Thanks!
On 2016/6/18 7:54, Yury Norov wrote:
quoted hunk
Here new aarch32 ptrace syscall handler is introsuced to avoid run-time
detection of the task type.
Signed-off-by: Yury Norov<redacted>
---
arch/arm64/include/asm/unistd32.h | 2 +-
arch/arm64/kernel/ptrace.c | 50 ++++++++++++++++++++++++++++++++++++++-
arch/arm64/kernel/sys32.c | 1 +
include/linux/ptrace.h | 6 +++++
kernel/ptrace.c | 10 ++++----
5 files changed, 62 insertions(+), 7 deletions(-)
@@ -1056,7 +1056,7 @@ int ptrace_request(struct task_struct *child, long request,returnret;}-staticstructtask_struct*ptrace_get_task_struct(pid_tpid)+structtask_struct*ptrace_get_task_struct(pid_tpid){structtask_struct*child;
The function compat_ptrace_request(used by ilp32) don't handle
{GET,SET}SIGMASK request, so it will be handled by ptrace_request.
But it's wrong because the compat_sigset_t of ilp32 differs from
the sigset_t of aarch64. The patch fixes it.
Signed-off-by: Zhou Chengming <redacted>
---
arch/arm64/include/asm/signal_ilp32.h | 22 ++++++++++++
arch/arm64/kernel/ptrace.c | 62
+++++++++++++++++++++++++++++++++
arch/arm64/kernel/signal_ilp32.c | 23 +------------
3 files changed, 85 insertions(+), 22 deletions(-)
Hi Zhou,
Thank you for the patch. The idea is ok, but patch format got broken
for some reason. Could you re-send it?
Yury.
On Mon, Jun 27, 2016 at 12:49:05PM +0800, zhouchengming wrote:
atus: RO
Content-Length: 4732
Lines: 181
The function compat_ptrace_request(used by ilp32) don't handle
{GET,SET}SIGMASK request, so it will be handled by ptrace_request.
But it's wrong because the compat_sigset_t of ilp32 differs from
the sigset_t of aarch64. The patch fixes it.
Signed-off-by: Zhou Chengming <redacted>
---
arch/arm64/include/asm/signal_ilp32.h | 22 ++++++++++++
arch/arm64/kernel/ptrace.c | 62
+++++++++++++++++++++++++++++++++
Hi Zhou,
Thank you for the patch. The idea is ok, but patch format got broken
for some reason. Could you re-send it?
Yury.
Sorry for the broken patch, maybe my mail guest has some problems. So
I send the patch as an attachment.
Thanks!
On Mon, Jun 27, 2016 at 12:49:05PM +0800, zhouchengming wrote:
quoted
atus: RO
Content-Length: 4732
Lines: 181
The function compat_ptrace_request(used by ilp32) don't handle
{GET,SET}SIGMASK request, so it will be handled by ptrace_request.
But it's wrong because the compat_sigset_t of ilp32 differs from
the sigset_t of aarch64. The patch fixes it.
Signed-off-by: Zhou Chengming<redacted>
---
arch/arm64/include/asm/signal_ilp32.h | 22 ++++++++++++
arch/arm64/kernel/ptrace.c | 62
+++++++++++++++++++++++++++++++++
From 06f5abeca59069cb41b0b4fdfa06240d3f78910d Mon Sep 17 00:00:00 2001
From: Zhou Chengming <redacted>
Date: Mon, 27 Jun 2016 12:57:02 +0800
Subject: [PATCH] ilp32: fix {GET,SET}SIGMASK request for ptrace
The function compat_ptrace_request(used by ilp32) don't handle
{GET,SET}SIGMASK request, so it will be handled by ptrace_request.
But it's wrong because the compat_sigset_t of ilp32 differs from
the sigset_t of aarch64. The patch fixes it.
Signed-off-by: Zhou Chengming <redacted>
---
arch/arm64/include/asm/signal_ilp32.h | 22 ++++++++++++
arch/arm64/kernel/ptrace.c | 62 +++++++++++++++++++++++++++++++++
arch/arm64/kernel/signal_ilp32.c | 23 +------------
3 files changed, 85 insertions(+), 22 deletions(-)
On Mon, Jun 27, 2016 at 12:49:05PM +0800, zhouchengming wrote:
The function compat_ptrace_request(used by ilp32) don't handle
{GET,SET}SIGMASK request, so it will be handled by ptrace_request.
But it's wrong because the compat_sigset_t of ilp32 differs from
the sigset_t of aarch64. The patch fixes it.
Hi Zhou, all,
Reviewing your patch I found that we have 2 identical declarations of
put_sigset_t() and get_sigset_t(). So I moved it under
arch/arm64/include/asm/signal32_common.h
I also reworked related code to remove unneeded function and variable
declarations. With all that your patch is looking like below. You can
try latest series here: https://github.com/norov/linux/tree/ilp32-4.8
It's based on v4.8, and addresses some comments. I'm going to meld
this patch with current patchset as it basicly the bugfux and update
submission when I'll finish with all comments.
Yury.
From 6a023da977713e9eade0a404c4f000d432d1fd67 Mon Sep 17 00:00:00 2001
ILP32 tasks are needed to be distinguished from lp64 and aarch32.
This patch adds helper functions is_ilp32_compat_{task,thread} and
thread flag TIF_32BIT_AARCH64 to address it. This is a preparation
for following patches in ilp32 patchset.
For consistency, SET_PERSONALITY is changed here accordingly.
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Yury Norov <redacted>
Reviewed-by: David Daney <redacted>
---
arch/arm64/include/asm/elf.h | 13 +++++++++++--
arch/arm64/include/asm/is_compat.h | 30 ++++++++++++++++++++++++++++--
arch/arm64/include/asm/thread_info.h | 2 ++
3 files changed, 41 insertions(+), 4 deletions(-)
Based on patch of Andrew Pinski.
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.
Corresponding functions are located in <asm/is_compat.h> to avoid mess in
headers.
Some files include both <linux/compat.h> and <asm/compat.h>,
and this is wrong because <linux/compat.h> has <asm/compat.h> already
included. It was fixed too.
Signed-off-by: Yury Norov <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Andrew Pinski <redacted>
Reviewed-by: David Daney <redacted>
---
arch/arm64/include/asm/compat.h | 19 ++---------
arch/arm64/include/asm/elf.h | 10 +++---
arch/arm64/include/asm/ftrace.h | 2 +-
arch/arm64/include/asm/is_compat.h | 64 ++++++++++++++++++++++++++++++++++++
arch/arm64/include/asm/memory.h | 5 +--
arch/arm64/include/asm/processor.h | 5 +--
arch/arm64/include/asm/syscall.h | 2 +-
arch/arm64/include/asm/thread_info.h | 2 +-
arch/arm64/kernel/hw_breakpoint.c | 10 +++---
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/process.c | 7 ++--
arch/arm64/kernel/ptrace.c | 11 +++----
arch/arm64/kernel/signal.c | 4 +--
arch/arm64/kernel/traps.c | 3 +-
14 files changed, 98 insertions(+), 48 deletions(-)
create mode 100644 arch/arm64/include/asm/is_compat.h
@@ -175,7 +175,7 @@ static int is_compat_bp(struct perf_event *bp)*deprecatedbehaviourifweuseunalignedwatchpointsin*AArch64state.*/-returntsk&&is_compat_thread(task_thread_info(tsk));+returntsk&&is_a32_compat_thread(task_thread_info(tsk));}/**
@@ -435,7 +435,7 @@ static int arch_build_bp_info(struct perf_event *bp)*Watchpointscanbeoflength1,2,4or8bytes.*/if(info->ctrl.type==ARM_BREAKPOINT_EXECUTE){-if(is_compat_bp(bp)){+if(is_a32_compat_bp(bp)){if(info->ctrl.len!=ARM_BREAKPOINT_LEN_2&&info->ctrl.len!=ARM_BREAKPOINT_LEN_4)return-EINVAL;
@@ -492,7 +492,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)*AArch32tasksexpectsomesimplealignmentfixups,soemulate*thathere.*/-if(is_compat_bp(bp)){+if(is_a32_compat_bp(bp)){if(info->ctrl.len==ARM_BREAKPOINT_LEN_8)alignment_mask=0x7;else
@@ -679,7 +679,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
@@ -256,7 +255,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,asm("mrs %0, tpidr_el0":"=r"(*task_user_tls(p)));if(stack_start){-if(is_compat_thread(task_thread_info(p)))+if(is_a32_compat_thread(task_thread_info(p)))childregs->compat_sp=stack_start;elsechildregs->sp=stack_start;
Based on patch of Andrew Pinski.
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.
Corresponding functions are located in <asm/is_compat.h> to avoid mess in
headers.
Some files include both <linux/compat.h> and <asm/compat.h>,
and this is wrong because <linux/compat.h> has <asm/compat.h> already
included. It was fixed too.
Signed-off-by: Yury Norov <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Andrew Pinski <redacted>
Reviewed-by: David Daney <redacted>
---
arch/arm64/include/asm/compat.h | 19 ++---------
arch/arm64/include/asm/elf.h | 10 +++---
arch/arm64/include/asm/ftrace.h | 2 +-
arch/arm64/include/asm/is_compat.h | 64 ++++++++++++++++++++++++++++++++++++
arch/arm64/include/asm/memory.h | 5 +--
arch/arm64/include/asm/processor.h | 5 +--
arch/arm64/include/asm/syscall.h | 2 +-
arch/arm64/include/asm/thread_info.h | 2 +-
arch/arm64/kernel/hw_breakpoint.c | 10 +++---
arch/arm64/kernel/perf_regs.c | 2 +-
arch/arm64/kernel/process.c | 7 ++--
arch/arm64/kernel/ptrace.c | 11 +++----
arch/arm64/kernel/signal.c | 4 +--
arch/arm64/kernel/traps.c | 3 +-
14 files changed, 98 insertions(+), 48 deletions(-)
create mode 100644 arch/arm64/include/asm/is_compat.h
@@ -175,7 +175,7 @@ static int is_compat_bp(struct perf_event *bp)*deprecatedbehaviourifweuseunalignedwatchpointsin*AArch64state.*/-returntsk&&is_compat_thread(task_thread_info(tsk));+returntsk&&is_a32_compat_thread(task_thread_info(tsk));}/**
@@ -435,7 +435,7 @@ static int arch_build_bp_info(struct perf_event *bp)*Watchpointscanbeoflength1,2,4or8bytes.*/if(info->ctrl.type==ARM_BREAKPOINT_EXECUTE){-if(is_compat_bp(bp)){+if(is_a32_compat_bp(bp)){if(info->ctrl.len!=ARM_BREAKPOINT_LEN_2&&info->ctrl.len!=ARM_BREAKPOINT_LEN_4)return-EINVAL;
@@ -492,7 +492,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)*AArch32tasksexpectsomesimplealignmentfixups,soemulate*thathere.*/-if(is_compat_bp(bp)){+if(is_a32_compat_bp(bp)){if(info->ctrl.len==ARM_BREAKPOINT_LEN_8)alignment_mask=0x7;else
@@ -679,7 +679,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
@@ -256,7 +255,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,asm("mrs %0, tpidr_el0":"=r"(*task_user_tls(p)));if(stack_start){-if(is_compat_thread(task_thread_info(p)))+if(is_a32_compat_thread(task_thread_info(p)))childregs->compat_sp=stack_start;elsechildregs->sp=stack_start;
From: Andrew Pinski <redacted>
Define __BITS_PER_LONG depending on the ABI used (i.e. check whether
__ILP32__ or __LP64__ is defined). This is necessary for glibc to
determine the appropriate type definitions for the system call interface.
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Yury Norov <redacted>
Reviewed-by: David Daney <redacted>
---
arch/arm64/include/uapi/asm/bitsperlong.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
@@ -16,7 +16,14 @@#ifndef __ASM_BITSPERLONG_H#define __ASM_BITSPERLONG_H-#define __BITS_PER_LONG 64+#if defined(__LP64__)+/* Assuming __LP64__ will be defined for native ELF64's and not for ILP32. */+# define __BITS_PER_LONG 64+#elif defined(__ILP32__)+# define __BITS_PER_LONG 32+#else+# error "Neither LP64 nor ILP32: unsupported ABI in asm/bitsperlong.h"+#endif#include<asm-generic/bitsperlong.h>
From: Andrew Pinski <redacted>
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, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and 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 <redacted>
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Bamvor Jian Zhang <redacted>
Signed-off-by: Yury Norov <redacted>
---
arch/arm64/Kconfig | 10 ++++++++--
arch/arm64/include/asm/fpsimd.h | 2 +-
arch/arm64/include/asm/hwcap.h | 4 ++--
arch/arm64/include/asm/processor.h | 6 +++---
arch/arm64/include/asm/ptrace.h | 2 +-
arch/arm64/include/asm/signal32.h | 6 ++++--
arch/arm64/include/asm/unistd.h | 2 +-
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/asm-offsets.c | 2 +-
arch/arm64/kernel/cpufeature.c | 8 ++++----
arch/arm64/kernel/cpuinfo.c | 20 +++++++++++---------
arch/arm64/kernel/entry.S | 6 +++---
arch/arm64/kernel/head.S | 2 +-
arch/arm64/kernel/ptrace.c | 8 ++++----
arch/arm64/kernel/traps.c | 2 +-
arch/arm64/kernel/vdso.c | 4 ++--
drivers/clocksource/arm_arch_timer.c | 2 +-
17 files changed, 49 insertions(+), 39 deletions(-)
@@ -971,8 +971,14 @@ menu "Userspace binary formats"source"fs/Kconfig.binfmt"configCOMPAT+bool+depends onAARCH32_EL0++configAARCH32_EL0bool"Kernel support for 32-bit EL0"+def_boolydepends onARM64_4K_PAGES||EXPERT+selectCOMPATselectCOMPAT_BINFMT_ELFselectHAVE_UID16selectOLD_SIGSUSPEND3
From: Andrew Pinski <redacted>
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, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and 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 <redacted>
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Bamvor Jian Zhang <redacted>
Signed-off-by: Yury Norov <redacted>
On Thursday, August 11, 2016 3:35:01 PM CEST Zhangjian (Bamvor) wrote:
On 2016/6/18 7:54, Yury Norov wrote:
quoted
From: Andrew Pinski <redacted>
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, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and 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 <redacted>
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Bamvor Jian Zhang <redacted>
Signed-off-by: Yury Norov <redacted>
I saw that compat_hwcap_str and compat_hwcap2_str is defined when
"CONFIG_COMPAT" is true. Why we only change it to CONFIG_AARCH32_EL0
in c show()?
quoted
+ if (personality(current->personality) == PER_LINUX32) {
And "compat" is "personality(current->personality) == PER_LINUX32;",
it seems that there is no need to add this twice.
I think it would be best to remove the #ifdef here completely,
the PER_LINUX32 concept is not strictly tied to the emulation
of ARM binaries, it literally just changes the output of
/proc/cpuinfo and 'uname', and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
Arnd
On Thu, Aug 11, 2016 at 10:53:01AM +0200, Arnd Bergmann wrote:
On Thursday, August 11, 2016 3:35:01 PM CEST Zhangjian (Bamvor) wrote:
quoted
On 2016/6/18 7:54, Yury Norov wrote:
quoted
From: Andrew Pinski <redacted>
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, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and 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 <redacted>
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Bamvor Jian Zhang <redacted>
Signed-off-by: Yury Norov <redacted>
I saw that compat_hwcap_str and compat_hwcap2_str is defined when
"CONFIG_COMPAT" is true. Why we only change it to CONFIG_AARCH32_EL0
in c show()?
quoted
+ if (personality(current->personality) == PER_LINUX32) {
And "compat" is "personality(current->personality) == PER_LINUX32;",
it seems that there is no need to add this twice.
I think it would be best to remove the #ifdef here completely,
the PER_LINUX32 concept is not strictly tied to the emulation
of ARM binaries, it literally just changes the output of
/proc/cpuinfo and 'uname',
It's not strictly related to ARM binaries, however it is related to
AArch32 CPU features being supported and detected by the kernel.
Currently, with CONFIG_COMPAT disabled, we won't have access to a
(meaningful) compat_elf_hwcap.
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
--
Catalin
On Thursday, August 11, 2016 3:50:00 PM CEST Catalin Marinas wrote:
On Thu, Aug 11, 2016 at 10:53:01AM +0200, Arnd Bergmann wrote:
quoted
On Thursday, August 11, 2016 3:35:01 PM CEST Zhangjian (Bamvor) wrote:
quoted
On 2016/6/18 7:54, Yury Norov wrote:
quoted
From: Andrew Pinski <redacted>
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, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and 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 <redacted>
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Bamvor Jian Zhang <redacted>
Signed-off-by: Yury Norov <redacted>
I saw that compat_hwcap_str and compat_hwcap2_str is defined when
"CONFIG_COMPAT" is true. Why we only change it to CONFIG_AARCH32_EL0
in c show()?
quoted
+ if (personality(current->personality) == PER_LINUX32) {
And "compat" is "personality(current->personality) == PER_LINUX32;",
it seems that there is no need to add this twice.
I think it would be best to remove the #ifdef here completely,
the PER_LINUX32 concept is not strictly tied to the emulation
of ARM binaries, it literally just changes the output of
/proc/cpuinfo and 'uname',
It's not strictly related to ARM binaries, however it is related to
AArch32 CPU features being supported and detected by the kernel.
Currently, with CONFIG_COMPAT disabled, we won't have access to a
(meaningful) compat_elf_hwcap.
Ah, makes sense. In that case, using CONFIG_AARCH32_EL0 sounds like
the right thing to do here, though I guess we can just drop the
"if (compat)" check, as we specifically want to print the supported
features of the CPU, and they are still present even if a
process with PER_LINUX reads them.
quoted
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
Hmm, I thought I saw the thread and didn't have any good idea for
the uname information, but didn't notice it was for /proc/cpuinfo.
What's wrong with always showing both the 32-bit and the 64-bit
hwcap strings here (minus the duplicates, which hopefully have
the same meaning here)?
Arnd
On Thu, Aug 11, 2016 at 05:16:45PM +0200, Arnd Bergmann wrote:
On Thursday, August 11, 2016 3:50:00 PM CEST Catalin Marinas wrote:
quoted
On Thu, Aug 11, 2016 at 10:53:01AM +0200, Arnd Bergmann wrote:
quoted
On Thursday, August 11, 2016 3:35:01 PM CEST Zhangjian (Bamvor) wrote:
quoted
On 2016/6/18 7:54, Yury Norov wrote:
quoted
From: Andrew Pinski <redacted>
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, ARM64_ILP32 - support of ILP32 ABI (see next patches),
and 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 <redacted>
Signed-off-by: Andrew Pinski <redacted>
Signed-off-by: Philipp Tomsich <redacted>
Signed-off-by: Christoph Muellner <redacted>
Signed-off-by: Bamvor Jian Zhang <redacted>
Signed-off-by: Yury Norov <redacted>
I saw that compat_hwcap_str and compat_hwcap2_str is defined when
"CONFIG_COMPAT" is true. Why we only change it to CONFIG_AARCH32_EL0
in c show()?
quoted
+ if (personality(current->personality) == PER_LINUX32) {
And "compat" is "personality(current->personality) == PER_LINUX32;",
it seems that there is no need to add this twice.
I think it would be best to remove the #ifdef here completely,
the PER_LINUX32 concept is not strictly tied to the emulation
of ARM binaries, it literally just changes the output of
/proc/cpuinfo and 'uname',
It's not strictly related to ARM binaries, however it is related to
AArch32 CPU features being supported and detected by the kernel.
Currently, with CONFIG_COMPAT disabled, we won't have access to a
(meaningful) compat_elf_hwcap.
Ah, makes sense. In that case, using CONFIG_AARCH32_EL0 sounds like
the right thing to do here, though I guess we can just drop the
"if (compat)" check, as we specifically want to print the supported
features of the CPU, and they are still present even if a
process with PER_LINUX reads them.
Do you mean always printing both compat and native hwcaps in
/proc/cpuinfo? We discussed this in the past and it's not something we
can easily fix at this stage without breaking the ABI. If we noticed
this before, we could have used distinct feature strings for AArch32 and
AArch64 (e.g. crypto stuff like aes32 and aes64 but we only have aes for
both).
quoted
quoted
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
Hmm, I thought I saw the thread and didn't have any good idea for
the uname information, but didn't notice it was for /proc/cpuinfo.
What's wrong with always showing both the 32-bit and the 64-bit
hwcap strings here (minus the duplicates, which hopefully have
the same meaning here)?
As I said above, some of them have the same name (which may be a good
thing at a first look) but we don't have an architecture guarantee that
the feature is present in both AArch32 and AArch64 modes (e.g. AES may
only be available in AArch64).
--
Catalin
On Thursday, August 11, 2016 5:30:03 PM CEST Catalin Marinas wrote:
quoted
quoted
quoted
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
Hmm, I thought I saw the thread and didn't have any good idea for
the uname information, but didn't notice it was for /proc/cpuinfo.
What's wrong with always showing both the 32-bit and the 64-bit
hwcap strings here (minus the duplicates, which hopefully have
the same meaning here)?
As I said above, some of them have the same name (which may be a good
thing at a first look) but we don't have an architecture guarantee that
the feature is present in both AArch32 and AArch64 modes (e.g. AES may
only be available in AArch64).
Is this the case on actual implementations that exist today? If they
are actually always both present, we might be able to get away with it.
Arnd
On Thu, Aug 11, 2016 at 10:29:03PM +0200, Arnd Bergmann wrote:
On Thursday, August 11, 2016 5:30:03 PM CEST Catalin Marinas wrote:
quoted
quoted
quoted
quoted
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
Hmm, I thought I saw the thread and didn't have any good idea for
the uname information, but didn't notice it was for /proc/cpuinfo.
What's wrong with always showing both the 32-bit and the 64-bit
hwcap strings here (minus the duplicates, which hopefully have
the same meaning here)?
As I said above, some of them have the same name (which may be a good
thing at a first look) but we don't have an architecture guarantee that
the feature is present in both AArch32 and AArch64 modes (e.g. AES may
only be available in AArch64).
Is this the case on actual implementations that exist today? If they
are actually always both present, we might be able to get away with it.
It may be fine on current implementations but what would we do when/if
we actually find such discrepancy? It's not just ARM Ltd designing the
chips, so as long as the architecture doesn't mandate it you may find
strange implementations.
Imposing such restriction in the architecture doesn't make sense if the
only reason is the /proc/cpuinfo file (and I can't think of any other
reason why this should be enforced).
What I'm worried about is 32-bit apps running on an arm64 kernel and
making use of the 64-bit /proc/cpuinfo without any guarantee that the
AArch32 state has such features. In my patch proposal linked above I
wanted to always force the compat /proc/cpuinfo for 32-bit tasks.
--
Catalin
On Fri, Aug 12, 2016 at 03:36:12PM +0100, Catalin Marinas wrote:
On Thu, Aug 11, 2016 at 10:29:03PM +0200, Arnd Bergmann wrote:
quoted
On Thursday, August 11, 2016 5:30:03 PM CEST Catalin Marinas wrote:
quoted
quoted
quoted
quoted
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
Hmm, I thought I saw the thread and didn't have any good idea for
the uname information, but didn't notice it was for /proc/cpuinfo.
What's wrong with always showing both the 32-bit and the 64-bit
hwcap strings here (minus the duplicates, which hopefully have
the same meaning here)?
As I said above, some of them have the same name (which may be a good
thing at a first look) but we don't have an architecture guarantee that
the feature is present in both AArch32 and AArch64 modes (e.g. AES may
only be available in AArch64).
Is this the case on actual implementations that exist today? If they
are actually always both present, we might be able to get away with it.
It may be fine on current implementations but what would we do when/if
we actually find such discrepancy? It's not just ARM Ltd designing the
chips, so as long as the architecture doesn't mandate it you may find
strange implementations.
Imposing such restriction in the architecture doesn't make sense if the
only reason is the /proc/cpuinfo file (and I can't think of any other
reason why this should be enforced).
What I'm worried about is 32-bit apps running on an arm64 kernel and
making use of the 64-bit /proc/cpuinfo without any guarantee that the
AArch32 state has such features. In my patch proposal linked above I
wanted to always force the compat /proc/cpuinfo for 32-bit tasks.
The link doesn't work for me. Is there other link, or what's the
maillist there?
So, what we decided finally? Is my understanding correct that we leave
everything as is in ilp32 series, and it will be resolved separately?
Yury.
On Sat, Aug 13, 2016 at 06:17:03PM +0300, Yury Norov wrote:
On Fri, Aug 12, 2016 at 03:36:12PM +0100, Catalin Marinas wrote:
quoted
On Thu, Aug 11, 2016 at 10:29:03PM +0200, Arnd Bergmann wrote:
quoted
On Thursday, August 11, 2016 5:30:03 PM CEST Catalin Marinas wrote:
quoted
quoted
quoted
quoted
and you can have ARM binaries with
PER_LINUX (using the arm64 uname) just like you can have
arm64 binaries running with PER_LINUX32.
I was actually looking to enforce the 32-bit binaries to only see
PER_LINUX32, though with a risk of breaking the ABI. OTOH, people are
abusing this and write 32-bit apps relying on the 64-bit /proc/cpuinfo:
http://lkml.kernel.org/g/1464706504-25224-3-git-send-email-catalin.marinas at arm.com
(you were summoned on that discussion couple of times ;))
Hmm, I thought I saw the thread and didn't have any good idea for
the uname information, but didn't notice it was for /proc/cpuinfo.
What's wrong with always showing both the 32-bit and the 64-bit
hwcap strings here (minus the duplicates, which hopefully have
the same meaning here)?
As I said above, some of them have the same name (which may be a good
thing at a first look) but we don't have an architecture guarantee that
the feature is present in both AArch32 and AArch64 modes (e.g. AES may
only be available in AArch64).
Is this the case on actual implementations that exist today? If they
are actually always both present, we might be able to get away with it.
It may be fine on current implementations but what would we do when/if
we actually find such discrepancy? It's not just ARM Ltd designing the
chips, so as long as the architecture doesn't mandate it you may find
strange implementations.
Imposing such restriction in the architecture doesn't make sense if the
only reason is the /proc/cpuinfo file (and I can't think of any other
reason why this should be enforced).
What I'm worried about is 32-bit apps running on an arm64 kernel and
making use of the 64-bit /proc/cpuinfo without any guarantee that the
AArch32 state has such features. In my patch proposal linked above I
wanted to always force the compat /proc/cpuinfo for 32-bit tasks.
The link doesn't work for me. Is there other link, or what's the
maillist there?
So, what we decided finally? Is my understanding correct that we leave
everything as is in ilp32 series, and it will be resolved separately?
ILP32 is not affected by this since the hwcap for ILP32 should match
native. It was more a question about whether AArch32 tasks should ever
have access to AArch64 hwcaps (and potential misuse).
--
Catalin