Introduce the X32 binary format on x86, for v3.4
Subsystems (31)
Linus,
Please pull the latest x86-x32-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-x32-for-linus
HEAD: 31796ac4e8f0e88f5c10f1ad6dab8f19bebe44a4 x32: Fix alignment fail in struct compat_siginfo
This tree introduces the X32 binary format and execution mode for x86: 32-bit data space binaries using 64-bit instructions and 64-bit kernel syscalls.
This allows applications whose working set fits into a 32 bits address space to make use of 64-bit instructions while using a 32-bit address space with shorter pointers, more compressed data structures, etc.
out-of-topic modifications in x86-x32-for-linus:
------------------------------------------------
arch/alpha/include/asm/posix_types.h# cee1332: alpha: Use generic posix_types.h arch/arm/include/asm/posix_types.h # e7ca2e1: arm: Use generic posix_types.h arch/avr32/include/asm/posix_types.h# 0967504: avr32: Use generic posix_types.h arch/cris/include/asm/posix_types.h# 4d6232b: cris: Use generic posix_types.h arch/frv/include/asm/posix_types.h # 4fb16b5: frv: Use generic posix_types.h arch/h8300/include/asm/posix_types.h# e16deba: h8300: Use generic posix_types.h arch/ia64/include/asm/posix_types.h# f3ce4a0: ia64: Use generic posix_types.h arch/m32r/include/asm/posix_types.h# 86d10ea: m32r: Use generic posix_types.h arch/m68k/include/asm/posix_types.h# 08a655c: m68k: Use generic posix_types.h arch/mips/include/asm/posix_types.h# 86fcd10: mips: Use generic posix_types.harch/mips/kernel/kspd.c # 189017c: fs: Remove missed ->fds_bits from
arch/mn10300/include/asm/posix_types.h# e96d322: mn10300: Use generic posix_types. arch/parisc/include/asm/posix_types.h# f4f0727: parisc: Use generic posix_types.h arch/powerpc/include/asm/posix_types.h# fae89ee: powerpc: Use generic posix_types. arch/powerpc/platforms/cell/spufs/coredump.c# 1dce27c: Wrap accesses to the fd_sets in s arch/s390/include/asm/posix_types.h# 3b2a469: s390: Use generic posix_types.h arch/sh/include/asm/posix_types_32.h# 81620bb: sh: Remove unnecessary posix_type arch/sh/include/asm/posix_types_64.h# 81620bb: sh: Remove unnecessary posix_type arch/sparc/include/asm/posix_types.h# 8c4c7a9: sparc: Use generic posix_types.h arch/xtensa/include/asm/posix_types.h# 2759e65: xtensa: Use generic posix_types.h
drivers/char/lp.c # 9dd4cca: compat: Handle COMPAT_USE_64BIT_T
drivers/input/input-compat.c # f930a7a: compat: Use COMPAT_USE_64BIT_TIME
drivers/input/input-compat.h # f930a7a: compat: Use COMPAT_USE_64BIT_TIME
drivers/staging/android/binder.c # 189017c: fs: Remove missed ->fds_bits from
# 1dce27c: Wrap accesses to the fd_sets in s
fs/autofs4/dev-ioctl.c # 1dce27c: Wrap accesses to the fd_sets in s
fs/binfmt_elf.c # 0953f65: elf: Allow core dump-related fiel
fs/compat.c # 4ee5c0d: compat: Create compat_sys_p{read,
fs/exec.c # 1fd36ad: Replace the fd_sets in struct fdt # 1dce27c: Wrap accesses to the fd_sets in sfs/fcntl.c # 1dce27c: Wrap accesses to the fd_sets in sfs/file.c # f044db4: fs: Fix close_on_exec pointer in
# 1fd36ad: Replace the fd_sets in struct fdt # 1dce27c: Wrap accesses to the fd_sets in s
fs/open.c # 1dce27c: Wrap accesses to the fd_sets in s
fs/proc/base.c # 1dce27c: Wrap accesses to the fd_sets in s
fs/select.c # 1fd36ad: Replace the fd_sets in struct fdt
include/asm-generic/posix_types.h # afead38: posix_types: Introduce __kernel_[
# 8b3d1cd: posix_types: Remove fd_set macros
# 34e6f9e: posix_types: Make it possible to
# b4255ba: posix_types: Make __kernel_[ug]id
include/linux/Kbuild # d8e5dde: sysinfo: Move struct sysinfo to a
include/linux/aio_abi.h # ff88943: aio: Use __kernel_ulong_t to defi
include/linux/compat.h # 6684ba2: compat: Add helper functions to r
# 45e8778: compat: Introduce COMPAT_USE_64BIinclude/linux/fdtable.h # 1fd36ad: Replace the fd_sets in struct fdt
# 1dce27c: Wrap accesses to the fd_sets in sinclude/linux/kernel.h # d8e5dde: sysinfo: Move struct sysinfo to ainclude/linux/sysinfo.h # 109a1f3: sysinfo: Use explicit types in <l
# d8e5dde: sysinfo: Move struct sysinfo to ainclude/linux/time.h # cf42004: Delete the __FD_*() funcs for ope
# 8b3d1cd: posix_types: Remove fd_set macros
kernel/compat.c # 6684ba2: compat: Add helper functions to r kernel/exit.c # 1fd36ad: Replace the fd_sets in struct fdt net/bluetooth/hci_sock.c # da88cea: compat: Use COMPAT_USE_64BIT_TIME net/compat.c # ee4fa23: compat: Use COMPAT_USE_64BIT_TIME net/socket.c # 644595f: compat: Handle COMPAT_USE_64BIT_T security/selinux/hooks.c # 1fd36ad: Replace the fd_sets in struct fdt
Thanks,
Ingo
------------------>
Bobby Powers (3):
fs: Fix close_on_exec pointer in alloc_fdtable
x32: Make sure TS_COMPAT is cleared for x32 tasks
x32: Only clear TIF_X32 flag once
David Howells (4):
Wrap accesses to the fd_sets in struct fdtable
Replace the fd_sets in struct fdtable with an array of unsigned longs Delete the __FD_*() funcs for operating on fd_set from linux/time.h
fs: Remove missed ->fds_bits from cessation use of fd_set structs internally
H. J. Lu (10):
compat: Introduce COMPAT_USE_64BIT_TIME
compat: Use COMPAT_USE_64BIT_TIME in the input subsystem
compat: Use COMPAT_USE_64BIT_TIME in the Bluetooth subsystem
compat: Use COMPAT_USE_64BIT_TIME in net/compat.c
compat: Create compat_sys_p{read,write}v64
elf: Allow core dump-related fields to be overridden
x86-64: Add prototype for old_rsp to a header file
x32: Add struct ucontext_x32
x32: Allow x32 to be configured
x32: Add x32 VDSO support
H. Peter Anvin (52):
posix_types: Make __kernel_[ug]id32_t default to unsigned int
posix_types: Make it possible to override __kernel_fsid_t
alpha: Use generic posix_types.h
arm: Use generic posix_types.h
avr32: Use generic posix_types.h
cris: Use generic posix_types.h
frv: Use generic posix_types.h
h8300: Use generic posix_types.h
ia64: Use generic posix_types.h
m32r: Use generic posix_types.h
m68k: Use generic posix_types.h
mips: Use generic posix_types.h
mn10300: Use generic posix_types.h
parisc: Use generic posix_types.h
powerpc: Use generic posix_types.h
s390: Use generic posix_types.h
sh: Remove unnecessary posix_types.h type overrides
sparc: Use generic posix_types.h
x86: Use generic posix_types.h
xtensa: Use generic posix_types.h
posix_types: Remove fd_set macros
x86: Factor out TIF_IA32 from 32-bit address space
x86-64: Use explicit sizes in sigcontext.h, prepare for x32
sysinfo: Move struct sysinfo to a separate header file
posix_types: Introduce __kernel_[u]long_t
x32: Create posix_types_x32.h
sysinfo: Use explicit types in <linux/sysinfo.h>
compat: Add helper functions to read/write struct timeval, timespec
compat: Handle COMPAT_USE_64BIT_TIME in the lp driver
compat: Handle COMPAT_USE_64BIT_TIME in net/socket.c
aio: Use __kernel_ulong_t to define aio_context_t
x32: Add a thread flag for x32 processes
x86-64, ia32: Drop sys32_rt_sigprocmask
x32: Add x32 system calls to syscall/syscall_64.tbl
x32: Generate <asm/unistd_x32.h>
x32: Generate <asm/unistd_64_x32.h>
x86: Move some signal-handling definitions to a common header
x32: Export setup/restore_sigcontext from signal.c
x32: Add rt_sigframe_x32
x32: Handle the x32 system call flag
x86: Add #ifdef CONFIG_COMPAT to <asm/sys_ia32.h>
x32: Signal-related system calls
x32: Handle process creation
x32: If configured, add x32 system calls to system call tables
x32: Fix coding style violations in the x32 VDSO code
x32: Drop non-__vdso weak symbols from the x32 VDSO
x32: Warn and disable rather than error if binutils too old x86, mtrr: Use explicit sizing and padding for the 64-bit ioctls
x32: Provide separate is_ia32_task() and is_x32_task() predicates
x32: Switch to a 64-bit clock_t
x32: Fix stupid ia32/x32 inversion in the siginfo format
x32: Fix alignment fail in struct compat_siginfo
H.J. Lu (1):
x32: Add ptrace for x32
Ingo Molnar (1):
x86/x32: Fix the binutils auto-detect
Documentation/filesystems/files.txt | 4 +- arch/alpha/include/asm/posix_types.h | 113 +----- arch/arm/include/asm/posix_types.h | 55 +-- arch/avr32/include/asm/posix_types.h | 107 +----- arch/cris/include/asm/posix_types.h | 50 +-- arch/frv/include/asm/posix_types.h | 53 +-- arch/h8300/include/asm/posix_types.h | 49 +-- arch/ia64/include/asm/posix_types.h | 121 +------ arch/m32r/include/asm/posix_types.h | 108 +----- arch/m68k/include/asm/posix_types.h | 53 +-- arch/mips/include/asm/posix_types.h | 121 +----- arch/mips/kernel/kspd.c | 2 +- arch/mn10300/include/asm/posix_types.h | 111 +----- arch/parisc/include/asm/posix_types.h | 119 +----- arch/powerpc/include/asm/posix_types.h | 118 +----- arch/powerpc/platforms/cell/spufs/coredump.c | 2 +- arch/s390/include/asm/posix_types.h | 70 +--- arch/sh/include/asm/posix_types_32.h | 5 - arch/sh/include/asm/posix_types_64.h | 4 - arch/sparc/include/asm/posix_types.h | 133 +----- arch/x86/Kconfig | 21 +- arch/x86/Makefile | 16 + arch/x86/ia32/ia32_signal.c | 22 +- arch/x86/ia32/sys_ia32.c | 40 -- arch/x86/include/asm/Kbuild | 2 + arch/x86/include/asm/compat.h | 49 ++- arch/x86/include/asm/elf.h | 31 ++- arch/x86/include/asm/ia32.h | 18 + arch/x86/include/asm/mtrr.h | 28 +- arch/x86/include/asm/posix_types.h | 4 +- arch/x86/include/asm/posix_types_32.h | 75 +--- arch/x86/include/asm/posix_types_64.h | 106 +----- arch/x86/include/asm/posix_types_x32.h | 19 + arch/x86/include/asm/processor.h | 10 +- arch/x86/include/asm/ptrace.h | 1 - arch/x86/include/asm/sigcontext.h | 57 ++-- arch/x86/include/asm/sigframe.h | 13 + arch/x86/include/asm/sighandling.h | 24 + arch/x86/include/asm/sys_ia32.h | 7 +- arch/x86/include/asm/syscall.h | 5 +- arch/x86/include/asm/thread_info.h | 6 +- arch/x86/include/asm/unistd.h | 15 +- arch/x86/kernel/asm-offsets_64.c | 6 + arch/x86/kernel/cpu/mtrr/if.c | 10 +- arch/x86/kernel/cpu/perf_event.c | 4 +- arch/x86/kernel/entry_64.S | 44 ++ arch/x86/kernel/process_64.c | 27 +- arch/x86/kernel/ptrace.c | 99 +++++ arch/x86/kernel/signal.c | 138 ++++++- arch/x86/kernel/sys_x86_64.c | 6 +- arch/x86/kernel/syscall_64.c | 8 + arch/x86/oprofile/backtrace.c | 2 +- arch/x86/syscalls/Makefile | 22 +- arch/x86/syscalls/syscall_32.tbl | 2 +- arch/x86/syscalls/syscall_64.tbl | 579 ++++++++++++++------------ arch/x86/um/sys_call_table_64.c | 3 + arch/x86/um/user-offsets.c | 2 + arch/x86/vdso/.gitignore | 2 + arch/x86/vdso/Makefile | 46 ++- arch/x86/vdso/vdso32-setup.c | 5 + arch/x86/vdso/vdsox32.S | 22 + arch/x86/vdso/vdsox32.lds.S | 28 ++ arch/x86/vdso/vma.c | 78 +++- arch/xtensa/include/asm/posix_types.h | 97 +---- drivers/char/lp.c | 5 +- drivers/input/input-compat.c | 4 +- drivers/input/input-compat.h | 2 +- drivers/staging/android/binder.c | 13 +- fs/autofs4/dev-ioctl.c | 2 +- fs/binfmt_elf.c | 24 +- fs/compat.c | 26 +- fs/exec.c | 8 +- fs/fcntl.c | 18 +- fs/file.c | 52 ++-- fs/open.c | 4 +- fs/proc/base.c | 2 +- fs/select.c | 2 +- include/asm-generic/posix_types.h | 109 +---- include/linux/Kbuild | 1 + include/linux/aio_abi.h | 2 +- include/linux/compat.h | 20 + include/linux/fdtable.h | 46 ++- include/linux/kernel.h | 21 +- include/linux/sysinfo.h | 24 + include/linux/time.h | 1 + kernel/compat.c | 68 +++- kernel/exit.c | 2 +- net/bluetooth/hci_sock.c | 3 +- net/compat.c | 65 ++-- net/socket.c | 18 +- security/selinux/hooks.c | 2 +- 91 files changed, 1561 insertions(+), 2180 deletions(-) create mode 100644 arch/x86/include/asm/posix_types_x32.h create mode 100644 arch/x86/include/asm/sighandling.h create mode 100644 arch/x86/vdso/vdsox32.S create mode 100644 arch/x86/vdso/vdsox32.lds.S create mode 100644 include/linux/sysinfo.h
Documentation/filesystems/files.txt +2 -2
@@ -113,8 +113,8 @@ the fdtable structure - if (fd >= 0) { /* locate_fd() may have expanded fdtable, load the ptr */ fdt = files_fdtable(files); - FD_SET(fd, fdt->open_fds); - FD_CLR(fd, fdt->close_on_exec); + __set_open_fd(fd, fdt); + __clear_close_on_exec(fd, fdt); spin_unlock(&files->file_lock); .....
arch/alpha/include/asm/posix_types.h +5 -108
121 lines not on this page · raw message
arch/arm/include/asm/posix_types.h +9 -46
68 lines not on this page · raw message
arch/avr32/include/asm/posix_types.h +11 -96
123 lines not on this page · raw message
arch/cris/include/asm/posix_types.h +10 -40
65 lines not on this page · raw message
arch/frv/include/asm/posix_types.h +10 -43
66 lines not on this page · raw message
arch/h8300/include/asm/posix_types.h +9 -40
63 lines not on this page · raw message
arch/ia64/include/asm/posix_types.h +3 -118
129 lines not on this page · raw message
arch/m32r/include/asm/posix_types.h +9 -99
121 lines not on this page · raw message
arch/m68k/include/asm/posix_types.h +10 -43
65 lines not on this page · raw message
arch/mips/include/asm/posix_types.h +7 -114
135 lines not on this page · raw message
arch/mips/kernel/kspd.c +1 -1
@@ -326,7 +326,7 @@ static void sp_cleanup(void) i = j * __NFDBITS;if (i >= fdt->max_fds)break ; - set = fdt->open_fds->fds_bits[j++]; + set = fdt->open_fds[j++];while (set) {if (set &1 ) {struct file * file =xchg (&fdt->fd[i],NULL );
arch/mn10300/include/asm/posix_types.h +11 -100
130 lines not on this page · raw message
arch/parisc/include/asm/posix_types.h +9 -110
132 lines not on this page · raw message
arch/powerpc/include/asm/posix_types.h +9 -109
131 lines not on this page · raw message
arch/powerpc/platforms/cell/spufs/coredump.c +1 -1
@@ -122,7 +122,7 @@ static struct spu_context *coredump_next_context(int *fd)struct spu_context *ctx =NULL ;for (; *fd < fdt->max_fds; (*fd)++) { -if (!FD_ISSET (*fd, fdt->open_fds)) +if (!fd_is_open (*fd, fdt))continue ; file =fcheck (*fd);
arch/s390/include/asm/posix_types.h +10 -60
99 lines not on this page · raw message
arch/sh/include/asm/posix_types_32.h +0 -5
@@ -12,11 +12,6 @@ typedef unsigned short __kernel_uid_t;typedef unsigned short __kernel_gid_t ;#define __kernel_gid_t __kernel_gid_t -typedef unsigned int __kernel_uid32_t ; -#define __kernel_uid32_t __kernel_uid32_t -typedef unsigned int __kernel_gid32_t ; -#define __kernel_gid32_t __kernel_gid32_t -typedef unsigned short __kernel_old_uid_t ;#define __kernel_old_uid_t __kernel_old_uid_ttypedef unsigned short __kernel_old_gid_t ;
arch/sh/include/asm/posix_types_64.h +0 -4
@@ -17,10 +17,6 @@ typedef int __kernel_ssize_t;#define __kernel_ssize_t __kernel_ssize_ttypedef int __kernel_ptrdiff_t ;#define __kernel_ptrdiff_t __kernel_ptrdiff_t -typedef unsigned int __kernel_uid32_t ; -#define __kernel_uid32_t __kernel_uid32_t -typedef unsigned int __kernel_gid32_t ; -#define __kernel_gid32_t __kernel_gid32_ttypedef unsigned short __kernel_old_uid_t ;#define __kernel_old_uid_t __kernel_old_uid_t
arch/sparc/include/asm/posix_types.h +17 -116
161 lines not on this page · raw message
arch/x86/Kconfig +17 -4
@@ -2165,9 +2165,9 @@ config IA32_EMULATION depends on X86_64 select COMPAT_BINFMT_ELF ---help--- - Include code to run 32-bit programs under a 64-bit kernel. You should - likely turn this on, unless you're 100% sure that you don't have any - 32-bit programs left. + Include code to run legacy 32-bit programs under a + 64-bit kernel. You should likely turn this on, unless you're + 100% sure that you don't have any 32-bit programs left. config IA32_AOUT tristate "IA32 a.out support"
@@ -2175,9 +2175,22 @@ config IA32_AOUT ---help--- Support old a.out binaries in the 32bit emulation. +config X86_X32 + bool "x32 ABI for 64-bit mode (EXPERIMENTAL)" + depends on X86_64 && IA32_EMULATION && EXPERIMENTAL + ---help--- + Include code to run binaries for the x32 native 32-bit ABI + for 64-bit processors. An x32 process gets access to the + full 64-bit register file and wide data path while leaving + pointers at 32 bits for smaller memory footprint. + + You will need a recent binutils (2.22 or later) with + elf32_x86_64 support enabled to compile a kernel with this + option set. + config COMPAT def_bool y - depends on IA32_EMULATION + depends on IA32_EMULATION || X86_X32 config COMPAT_FOR_U64_ALIGNMENT def_bool COMPAT
arch/x86/Makefile +16 -0
@@ -82,6 +82,22 @@ ifdef CONFIG_CC_STACKPROTECTOR endif endif +ifdef CONFIG_X86_X32 + x32_ld_ok := $(call try-run,\ + /bin/echo -e '1: .quad 1b' | \ + $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" - && \ + $(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMPO" && \ + $(LD) -m elf32_x86_64 "$$TMPO" -o "$$TMP",y,n) + ifeq ($(x32_ld_ok),y) + CONFIG_X86_X32_ABI := y + KBUILD_AFLAGS += -DCONFIG_X86_X32_ABI + KBUILD_CFLAGS += -DCONFIG_X86_X32_ABI + else + $(warning CONFIG_X86_X32 enabled but no binutils support) + endif +endif +export CONFIG_X86_X32_ABI + # Don't unroll struct assignments with kmemcheck enabled ifeq ($(CONFIG_KMEMCHECK),y) KBUILD_CFLAGS += $(call cc-option,-fno-builtin-memcpy)
arch/x86/ia32/ia32_signal.c +10 -12
@@ -12,10 +12,8 @@#include <linux/mm.h> #include <linux/smp.h> #include <linux/kernel.h> -#include <linux/signal.h> #include <linux/errno.h> #include <linux/wait.h> -#include <linux/ptrace.h> #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/personality.h>
@@ -31,20 +29,15 @@#include <asm/proto.h> #include <asm/vdso.h> #include <asm/sigframe.h> +#include <asm/sighandling.h> #include <asm/sys_ia32.h> -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \ - X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \ - X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \ - X86_EFLAGS_CF) - -void signal_fault (struct pt_regs *regs,void __user *frame,char *where); +#define FIX_EFLAGS __FIX_EFLAGSint copy_siginfo_to_user32 (compat_siginfo_t __user *to,siginfo_t *from) {int err =0 ; +bool ia32 =is_ia32_task ();if (!access_ok (VERIFY_WRITE , to,sizeof (compat_siginfo_t)))return -EFAULT ;
@@ -74,8 +67,13 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)case __SI_FAULT >>16 :break ;case __SI_CHLD >>16 : -put_user_ex (from->si_utime, &to->si_utime); -put_user_ex (from->si_stime, &to->si_stime); +if (ia32) { +put_user_ex (from->si_utime, &to->si_utime); +put_user_ex (from->si_stime, &to->si_stime); + }else { +put_user_ex (from->si_utime, &to->_sifields._sigchld_x32._utime); +put_user_ex (from->si_stime, &to->_sifields._sigchld_x32._stime); + }put_user_ex (from->si_status, &to->si_status);/* FALL THROUGH */ default :
arch/x86/ia32/sys_ia32.c +0 -40
@@ -287,46 +287,6 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 __user *act,return ret; } -asmlinkage long sys32_rt_sigprocmask (int how,compat_sigset_t __user *set, -compat_sigset_t __user *oset, -unsigned int sigsetsize) -{ -sigset_t s; -compat_sigset_t s32; -int ret; -mm_segment_t old_fs =get_fs (); - -if (set) { -if (copy_from_user (&s32, set,sizeof (compat_sigset_t))) -return -EFAULT ; -switch (_NSIG_WORDS) { -case 4 : s.sig[3 ] = s32.sig[6 ] | (((long )s32.sig[7 ]) <<32 ); -case 3 : s.sig[2 ] = s32.sig[4 ] | (((long )s32.sig[5 ]) <<32 ); -case 2 : s.sig[1 ] = s32.sig[2 ] | (((long )s32.sig[3 ]) <<32 ); -case 1 : s.sig[0 ] = s32.sig[0 ] | (((long )s32.sig[1 ]) <<32 ); - } - } -set_fs (KERNEL_DS ); - ret =sys_rt_sigprocmask (how, - set ? (sigset_t __user *)&s :NULL , - oset ? (sigset_t __user *)&s :NULL , - sigsetsize); -set_fs (old_fs); -if (ret) -return ret; -if (oset) { -switch (_NSIG_WORDS) { -case 4 : s32.sig[7 ] = (s.sig[3 ] >>32 ); s32.sig[6 ] = s.sig[3 ]; -case 3 : s32.sig[5 ] = (s.sig[2 ] >>32 ); s32.sig[4 ] = s.sig[2 ]; -case 2 : s32.sig[3 ] = (s.sig[1 ] >>32 ); s32.sig[2 ] = s.sig[1 ]; -case 1 : s32.sig[1 ] = (s.sig[0 ] >>32 ); s32.sig[0 ] = s.sig[0 ]; - } -if (copy_to_user (oset, &s32,sizeof (compat_sigset_t))) -return -EFAULT ; - } -return 0 ; -} -asmlinkage long sys32_alarm (unsigned int seconds) {return alarm_setitimer (seconds);
arch/x86/include/asm/Kbuild +2 -0
@@ -14,6 +14,7 @@ header-y += msr.h header-y += mtrr.h header-y += posix_types_32.h header-y += posix_types_64.h +header-y += posix_types_x32.h header-y += prctl.h header-y += processor-flags.h header-y += ptrace-abi.h
@@ -24,3 +25,4 @@ header-y += vsyscall.h genhdr-y += unistd_32.h genhdr-y += unistd_64.h +genhdr-y += unistd_x32.h
arch/x86/include/asm/compat.h +45 -4
72 lines not on this page · raw message
arch/x86/include/asm/elf.h +25 -6
@@ -156,7 +156,12 @@ do { \#define elf_check_arch (x) \ ((x)->e_machine == EM_X86_64) -#define compat_elf_check_arch (x) elf_check_arch_ia32(x) +#define compat_elf_check_arch (x) \ + (elf_check_arch_ia32(x) || (x)->e_machine == EM_X86_64) + +#if __USER32_DS != __USER_DS +# error "The following code assumes __USER32_DS == __USER_DS" +#endif static inline void elf_common_init (struct thread_struct *t,struct pt_regs *regs,const u16 ds)
@@ -179,8 +184,9 @@ static inline void elf_common_init(struct thread_struct *t,void start_thread_ia32 (struct pt_regs *regs,u32 new_ip,u32 new_sp);#define compat_start_thread start_thread_ia32 -void set_personality_ia32 (void ); -#define COMPAT_SET_PERSONALITY (ex) set_personality_ia32() +void set_personality_ia32 (bool ); +#define COMPAT_SET_PERSONALITY (ex) \ + set_personality_ia32((ex).e_machine == EM_X86_64)#define COMPAT_ELF_PLATFORM ("i686")
@@ -287,7 +293,7 @@ do { \#define VDSO_HIGH_BASE 0xffffe000U/* CONFIG_COMPAT_VDSO address */ /* 1GB for 64bit, 8MB for 32bit */ -#define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff) +#define STACK_RND_MASK (test_thread_flag(TIF_ADDR32) ? 0x7ff : 0x3fffff)#define ARCH_DLINFO \ do { \
@@ -296,9 +302,20 @@ do { \ (unsigned long)current->mm->context.vdso); \ } while (0) +#define ARCH_DLINFO_X32 \ +do { \ + if (vdso_enabled) \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, \ + (unsigned long)current->mm->context.vdso); \ +} while (0) +#define AT_SYSINFO 32 -#define COMPAT_ARCH_DLINFO ARCH_DLINFO_IA32(sysctl_vsyscall32) +#define COMPAT_ARCH_DLINFO \ +if (test_thread_flag(TIF_X32)) \ + ARCH_DLINFO_X32; \ +else \ + ARCH_DLINFO_IA32(sysctl_vsyscall32)#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
@@ -314,6 +331,8 @@ struct linux_binprm;#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1extern int arch_setup_additional_pages (struct linux_binprm *bprm,int uses_interp); +extern int x32_setup_additional_pages (struct linux_binprm *bprm, +int uses_interp);extern int syscall32_setup_pages (struct linux_binprm *,int exstack);#define compat_arch_setup_additional_pages syscall32_setup_pages
@@ -330,7 +349,7 @@ static inline int mmap_is_ia32(void)return 1 ;#endif #ifdef CONFIG_IA32_EMULATION -if (test_thread_flag (TIF_IA32 )) +if (test_thread_flag (TIF_ADDR32 ))return 1 ;#endif return 0 ;
arch/x86/include/asm/ia32.h +18 -0
@@ -43,6 +43,15 @@ struct ucontext_ia32 {compat_sigset_t uc_sigmask;/* mask last for extensibility */ }; +struct ucontext_x32 { +unsigned int uc_flags; +unsigned int uc_link; +stack_ia32_t uc_stack; +unsigned int uc__pad0;/* needed for alignment */ +struct sigcontext uc_mcontext;/* the 64-bit sigcontext type */ +compat_sigset_t uc_sigmask;/* mask last for extensibility */ +}; +/* This matches struct stat64 in glibc2.2, hence the absolutely * insane amounts of padding around dev_t's. */
@@ -116,6 +125,15 @@ typedef struct compat_siginfo {compat_clock_t _stime; } _sigchld; +/* SIGCHLD (x32 version) */ +struct { +unsigned int _pid;/* which child */ +unsigned int _uid;/* sender's uid */ +int _status;/* exit code */ +compat_s64 _utime; +compat_s64 _stime; + } _sigchld_x32; +/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ struct {unsigned int _addr;/* faulting insn/memory ref. */
arch/x86/include/asm/mtrr.h +18 -10
@@ -29,18 +29,18 @@#define MTRR_IOCTL_BASE 'M' -struct mtrr_sentry { -unsigned long base;/* Base address */ -unsigned int size;/* Size of region */ -unsigned int type;/* Type of region */ -}; -/* Warning: this structure has a different order from i386 on x86-64. The 32bit emulation code takes care of that. But you need to use this for 64bit, otherwise your X server will break. */ #ifdef __i386__ +struct mtrr_sentry { + unsigned long base; /* Base address */ + unsigned int size; /* Size of region */ + unsigned int type; /* Type of region */ +}; + struct mtrr_gentry { unsigned int regnum; /* Register number */ unsigned long base; /* Base address */
@@ -50,12 +50,20 @@ struct mtrr_gentry {#else /* __i386__ */ +struct mtrr_sentry { +__u64 base;/* Base address */ +__u32 size;/* Size of region */ +__u32 type;/* Type of region */ +}; +struct mtrr_gentry { -unsigned long base;/* Base address */ -unsigned int size;/* Size of region */ -unsigned int regnum;/* Register number */ -unsigned int type;/* Type of region */ +__u64 base;/* Base address */ +__u32 size;/* Size of region */ +__u32 regnum;/* Register number */ +__u32 type;/* Type of region */ +__u32 _pad;/* Unused */ }; +#endif /* !__i386__ */ struct mtrr_var_range {
arch/x86/include/asm/posix_types.h +3 -1
@@ -7,7 +7,9 @@#else # ifdef __i386__# include "posix_types_32.h" -# else +# elif defined(__LP64__)# include "posix_types_64.h" +# else +# include "posix_types_x32.h" # endif #endif
arch/x86/include/asm/posix_types_32.h +9 -66
88 lines not on this page · raw message
arch/x86/include/asm/posix_types_64.h +3 -103
116 lines not on this page · raw message
arch/x86/include/asm/posix_types_x32.h new file +19 -0
@@ -0,0 +1,19 @@ +#ifndef _ASM_X86_POSIX_TYPES_X32_H +#define _ASM_X86_POSIX_TYPES_X32_H + +/* +* This file is only used by user-level software, so you need to +* be a little careful about namespace pollution etc. Also, we cannot +* assume GCC is being used. +* +* These types should generally match the ones used by the 64-bit kernel, +* +*/ + +typedef long long __kernel_long_t ; +typedef unsigned long long __kernel_ulong_t ; +#define __kernel_long_t __kernel_long_t + +#include <asm/posix_types_64.h> + +#endif /* _ASM_X86_POSIX_TYPES_X32_H */
arch/x86/include/asm/processor.h +8 -2
@@ -924,9 +924,9 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ 0xc0000000 : 0xFFFFe000) -#define TASK_SIZE (test_thread_flag(TIF_IA32) ? \ +#define TASK_SIZE (test_thread_flag(TIF_ADDR32) ? \ IA32_PAGE_OFFSET : TASK_SIZE_MAX) -#define TASK_SIZE_OF (child) ((test_tsk_thread_flag(child, TIF_IA32)) ? \ +#define TASK_SIZE_OF (child) ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \ IA32_PAGE_OFFSET : TASK_SIZE_MAX)#define STACK_TOP TASK_SIZE
@@ -948,6 +948,12 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);#define task_pt_regs (tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)extern unsigned long KSTK_ESP (struct task_struct *task); + +/* +* User space RSP while inside the SYSCALL fast path +*/ +DECLARE_PER_CPU(unsigned long, old_rsp); +#endif /* CONFIG_X86_64 */ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
arch/x86/include/asm/ptrace.h +0 -1
@@ -145,7 +145,6 @@ extern unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);extern void send_sigtrap (struct task_struct *tsk,struct pt_regs *regs,int error_code,int si_code); -void signal_fault (struct pt_regs *regs,void __user *frame,char *where);extern long syscall_trace_enter (struct pt_regs *);extern void syscall_trace_leave (struct pt_regs *);
arch/x86/include/asm/sigcontext.h +30 -27
64 lines not on this page · raw message
arch/x86/include/asm/sigframe.h +13 -0
@@ -59,12 +59,25 @@ struct rt_sigframe_ia32 {#endif /* defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) */ #ifdef CONFIG_X86_64 +struct rt_sigframe {char __user *pretcode;struct ucontext uc;struct siginfo info;/* fp state follows here */ }; + +#ifdef CONFIG_X86_X32_ABI + +struct rt_sigframe_x32 { +u64 pretcode; +struct ucontext_x32 uc; +compat_siginfo_t info; +/* fp state follows here */ +}; + +#endif /* CONFIG_X86_X32_ABI */ +#endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_SIGFRAME_H */
arch/x86/include/asm/sighandling.h new file +24 -0
@@ -0,0 +1,24 @@ +#ifndef _ASM_X86_SIGHANDLING_H +#define _ASM_X86_SIGHANDLING_H + +#include <linux/compiler.h> +#include <linux/ptrace.h> +#include <linux/signal.h> + +#include <asm/processor-flags.h> + +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) + +#define __FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \ + X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \ + X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \ + X86_EFLAGS_CF) + +void signal_fault (struct pt_regs *regs,void __user *frame,char *where); + +int restore_sigcontext (struct pt_regs *regs,struct sigcontext __user *sc, +unsigned long *pax); +int setup_sigcontext (struct sigcontext __user *sc,void __user *fpstate, +struct pt_regs *regs,unsigned long mask); + +#endif /* _ASM_X86_SIGHANDLING_H */
arch/x86/include/asm/sys_ia32.h +5 -2
@@ -10,6 +10,8 @@#ifndef _ASM_X86_SYS_IA32_H#define _ASM_X86_SYS_IA32_H +#ifdef CONFIG_COMPAT +#include <linux/compiler.h> #include <linux/linkage.h> #include <linux/types.h>
@@ -36,8 +38,6 @@ asmlinkage long sys32_rt_sigaction(int, struct sigaction32 __user *, struct sigaction32 __user *, unsigned int);asmlinkage long sys32_sigaction (int ,struct old_sigaction32 __user *,struct old_sigaction32 __user *); -asmlinkage long sys32_rt_sigprocmask (int ,compat_sigset_t __user *, -compat_sigset_t __user *,unsigned int );asmlinkage long sys32_alarm (unsigned int );asmlinkage long sys32_waitpid (compat_pid_t ,unsigned int *,int );
@@ -83,4 +83,7 @@ asmlinkage long sys32_ipc(u32, int, int, int, compat_uptr_t, u32);asmlinkage long sys32_fanotify_mark (int ,unsigned int ,u32 ,u32 ,int ,const char __user *); + +#endif /* CONFIG_COMPAT */ +#endif /* _ASM_X86_SYS_IA32_H */
arch/x86/include/asm/syscall.h +3 -2
@@ -16,6 +16,7 @@#include <linux/sched.h> #include <linux/err.h> #include <asm/asm-offsets.h> /* For NR_syscalls */ +#include <asm/unistd.h> extern const unsigned long sys_call_table[];
@@ -26,13 +27,13 @@ extern const unsigned long sys_call_table[];*/ static inline int syscall_get_nr (struct task_struct *task,struct pt_regs *regs) { -return regs->orig_ax; +return regs->orig_ax & __SYSCALL_MASK; }static inline void syscall_rollback (struct task_struct *task,struct pt_regs *regs) { - regs->ax = regs->orig_ax; + regs->ax = regs->orig_ax & __SYSCALL_MASK; } static inline long syscall_get_error(struct task_struct *task,
arch/x86/include/asm/thread_info.h +5 -1
@@ -86,7 +86,7 @@ struct thread_info {#define TIF_MCE_NOTIFY 10/* notify userspace of an MCE */ #define TIF_USER_RETURN_NOTIFY 11/* notify kernel of userspace return */ #define TIF_NOTSC 16/* TSC is not accessible in userland */ -#define TIF_IA32 17/* 32bit process */ +#define TIF_IA32 17/* IA32 compatibility process */ #define TIF_FORK 18/* ret_from_fork */ #define TIF_MEMDIE 20/* is terminating due to OOM killer */ #define TIF_DEBUG 21/* uses debug registers */
@@ -95,6 +95,8 @@ struct thread_info {#define TIF_BLOCKSTEP 25/* set when we want DEBUGCTLMSR_BTF */ #define TIF_LAZY_MMU_UPDATES 27/* task is updating the mmu lazily */ #define TIF_SYSCALL_TRACEPOINT 28/* syscall tracepoint instrumentation */ +#define TIF_ADDR32 29/* 32-bit address space on 64 bits */ +#define TIF_X32 30/* 32-bit native x86-64 binary */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
@@ -116,6 +118,8 @@ struct thread_info {#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) +#define _TIF_ADDR32 (1 << TIF_ADDR32) +#define _TIF_X32 (1 << TIF_X32)/* work to do in syscall_trace_enter() */ #define _TIF_WORK_SYSCALL_ENTRY \
arch/x86/include/asm/unistd.h +14 -1
@@ -1,7 +1,17 @@#ifndef _ASM_X86_UNISTD_H#define _ASM_X86_UNISTD_H 1 +/* x32 syscall flag bit */ +#define __X32_SYSCALL_BIT 0x40000000 +#ifdef __KERNEL__ + +# ifdef CONFIG_X86_X32_ABI +# define __SYSCALL_MASK (~(__X32_SYSCALL_BIT)) +# else +# define __SYSCALL_MASK (~0) +# endif +# ifdef CONFIG_X86_32 # include <asm/unistd_32.h>
@@ -14,6 +24,7 @@# else # include <asm/unistd_64.h> +# include <asm/unistd_64_x32.h> # define __ARCH_WANT_COMPAT_SYS_TIME# endif
@@ -52,8 +63,10 @@#else # ifdef __i386__# include <asm/unistd_32.h> -# else +# elif defined(__LP64__)# include <asm/unistd_64.h> +# else +# include <asm/unistd_x32.h> # endif #endif
arch/x86/kernel/asm-offsets_64.c +6 -0
@@ -1,6 +1,12 @@#include <asm/ia32.h> #define __SYSCALL_64 (nr, sym, compat) [nr] = 1, +#define __SYSCALL_COMMON (nr, sym, compat) [nr] = 1, +#ifdef CONFIG_X86_X32_ABI +# define __SYSCALL_X32 (nr, sym, compat) [nr] = 1, +#else +# define __SYSCALL_X32 (nr, sym, compat)/* nothing */ +#endif static char syscalls_64[] = {#include <asm/syscalls_64.h> };
arch/x86/kernel/cpu/mtrr/if.c +6 -4
@@ -167,6 +167,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) {int err =0 ;mtrr_type type; +unsigned long base;unsigned long size;struct mtrr_sentry sentry;struct mtrr_gentry gentry;
@@ -267,14 +268,14 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)#endif if (gentry.regnum >= num_var_ranges)return -EINVAL ; - mtrr_if->get (gentry.regnum, &gentry.base, &size, &type); + mtrr_if->get (gentry.regnum, &base, &size, &type);/* Hide entries that go above 4GB */ -if (gentry.base + size -1 >= (1UL << (8 *sizeof (gentry.size) -PAGE_SHIFT )) +if (base + size -1 >= (1UL << (8 *sizeof (gentry.size) -PAGE_SHIFT )) || size >= (1UL << (8 *sizeof (gentry.size) -PAGE_SHIFT ))) gentry.base = gentry.size = gentry.type =0 ;else { - gentry.base <<=PAGE_SHIFT ; + gentry.base = base <<PAGE_SHIFT ; gentry.size = size <<PAGE_SHIFT ; gentry.type = type; }
@@ -321,11 +322,12 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)#endif if (gentry.regnum >= num_var_ranges)return -EINVAL ; - mtrr_if->get (gentry.regnum, &gentry.base, &size, &type); + mtrr_if->get (gentry.regnum, &base, &size, &type);/* Hide entries that would overflow */ if (size != (__typeof__(gentry.size))size) gentry.base = gentry.size = gentry.type =0 ;else { + gentry.base = base; gentry.size = size; gentry.type = type; }
arch/x86/kernel/cpu/perf_event.c +3 -1
@@ -28,7 +28,6 @@#include <asm/apic.h> #include <asm/stacktrace.h> #include <asm/nmi.h> -#include <asm/compat.h> #include <asm/smp.h> #include <asm/alternative.h>
@@ -1595,6 +1594,9 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs) }#ifdef CONFIG_COMPAT + +#include <asm/compat.h> +static inline int perf_callchain_user32 (struct pt_regs *regs,struct perf_callchain_entry *entry) {
arch/x86/kernel/entry_64.S +44 -0
64 lines not on this page · raw message
arch/x86/kernel/process_64.c +21 -6
@@ -364,7 +364,9 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)void start_thread_ia32 (struct pt_regs *regs,u32 new_ip,u32 new_sp) {start_thread_common (regs, new_ip, new_sp, - __USER32_CS, __USER32_DS, __USER32_DS); +test_thread_flag (TIF_X32 ) + ? __USER_CS : __USER32_CS, + __USER_DS, __USER_DS); }#endif
@@ -508,6 +510,8 @@ void set_personality_64bit(void)/* Make sure to be in 64bit mode */ clear_thread_flag (TIF_IA32 ); +clear_thread_flag (TIF_ADDR32 ); +clear_thread_flag (TIF_X32 );/* Ensure the corresponding mm is not marked. */ if (current->mm)
@@ -520,20 +524,31 @@ void set_personality_64bit(void) current->personality &= ~READ_IMPLIES_EXEC ; } -void set_personality_ia32 (void ) +void set_personality_ia32 (bool x32) {/* inherit personality from parent */ /* Make sure to be in 32bit mode */ -set_thread_flag (TIF_IA32 ); - current->personality |= force_personality32; +set_thread_flag (TIF_ADDR32 );/* Mark the associated mm as containing 32-bit tasks. */ if (current->mm) current->mm->context.ia32_compat =1 ; -/* Prepare the first "return" to user space */ -current_thread_info ()->status |=TS_COMPAT ; +if (x32) { +clear_thread_flag (TIF_IA32 ); +set_thread_flag (TIF_X32 ); + current->personality &= ~READ_IMPLIES_EXEC ; +/* is_compat_task() uses the presence of the x32 +syscall bit flag to determine compat status */ +current_thread_info ()->status &= ~TS_COMPAT ; + }else { +set_thread_flag (TIF_IA32 ); +clear_thread_flag (TIF_X32 ); + current->personality |= force_personality32; +/* Prepare the first "return" to user space */ +current_thread_info ()->status |=TS_COMPAT ; + } }unsigned long get_wchan (struct task_struct *p)
arch/x86/kernel/ptrace.c +99 -0
111 lines not on this page · raw message
arch/x86/kernel/signal.c +122 -16
189 lines not on this page · raw message
arch/x86/syscalls/syscall_64.tbl +306 -273
579 lines not on this page · raw message
arch/x86/vdso/Makefile +45 -1
46 lines not on this page · raw message
arch/x86/vdso/vma.c +70 -8
78 lines not on this page · raw message
arch/xtensa/include/asm/posix_types.h +7 -90
97 lines not on this page · raw message
fs/file.c +25 -27
52 lines not on this page · raw message
include/asm-generic/posix_types.h +22 -87
109 lines not on this page · raw message
include/linux/fdtable.h +34 -12
46 lines not on this page · raw message
kernel/compat.c +60 -8
68 lines not on this page · raw message
net/compat.c +40 -25
65 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.
H. Peter Anvin
reviewerQuoted 8 lines · Ingo Molnar
Linus,
Please pull the latest x86-x32-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.gitx86-x32-for-linusHEAD:
31796ac4e8f0e88f5c10f1ad6dab8f19bebe44a4x32: Fix alignment fail in structcompat_siginfo
Quoted 9 lines
This tree introduces the X32 binary format and execution mode for x86: 32-bit data space binaries using 64-bit instructions and 64-bit kernel syscalls.
This allows applications whose working set fits into a 32 bits address space to make use of 64-bit instructions while using a 32-bit address space with shorter pointers, more compressed data structures, etc.
Hi Linus,
Any problem either with this tree and/or the pull request? The posix_types.h revamp ended up being part of this request (because x32 depends on it) but is technically standalone.
-hpa