Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 297736
b: refs/heads/master
c: f044db4
h: refs/heads/master
v: v3
  • Loading branch information
Bobby Powers authored and H. Peter Anvin committed Feb 24, 2012
1 parent fff49b0 commit 1676ba3
Show file tree
Hide file tree
Showing 54 changed files with 508 additions and 1,139 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 862ae3132dc393ab6ea750b9ee9e0e1c276b9abb
refs/heads/master: f044db4cb4bf16893812d35b5fbeaaf3e30c9215
21 changes: 4 additions & 17 deletions trunk/arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2165,32 +2165,19 @@ config IA32_EMULATION
depends on X86_64
select COMPAT_BINFMT_ELF
---help---
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.
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.

config IA32_AOUT
tristate "IA32 a.out support"
depends on IA32_EMULATION
---help---
Support old a.out binaries in the 32bit emulation.

config X86_X32_ABI
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 || X86_X32_ABI
depends on IA32_EMULATION

config COMPAT_FOR_U64_ALIGNMENT
def_bool COMPAT
Expand Down
12 changes: 10 additions & 2 deletions trunk/arch/x86/ia32/ia32_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
#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>
Expand All @@ -29,10 +31,16 @@
#include <asm/proto.h>
#include <asm/vdso.h>
#include <asm/sigframe.h>
#include <asm/sighandling.h>
#include <asm/sys_ia32.h>

#define FIX_EFLAGS __FIX_EFLAGS
#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 copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
{
Expand Down
40 changes: 40 additions & 0 deletions trunk/arch/x86/ia32/sys_ia32.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,46 @@ 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);
Expand Down
2 changes: 0 additions & 2 deletions trunk/arch/x86/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ 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
Expand All @@ -25,4 +24,3 @@ header-y += vsyscall.h

genhdr-y += unistd_32.h
genhdr-y += unistd_64.h
genhdr-y += unistd_x32.h
39 changes: 4 additions & 35 deletions trunk/arch/x86/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
*/
#include <linux/types.h>
#include <linux/sched.h>
#include <asm/processor.h>
#include <asm/user32.h>
#include <asm/unistd.h>

#define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "i686\0\0"
Expand Down Expand Up @@ -188,20 +186,7 @@ struct compat_shmid64_ds {
/*
* The type of struct elf_prstatus.pr_reg in compatible core dumps.
*/
#ifdef CONFIG_X86_X32_ABI
typedef struct user_regs_struct compat_elf_gregset_t;

#define PR_REG_SIZE(S) (test_thread_flag(TIF_IA32) ? 68 : 216)
#define PRSTATUS_SIZE(S) (test_thread_flag(TIF_IA32) ? 144 : 296)
#define SET_PR_FPVALID(S,V) \
do { *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE(0)) = (V); } \
while (0)

#define COMPAT_USE_64BIT_TIME \
(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
#else
typedef struct user_regs_struct32 compat_elf_gregset_t;
#endif

/*
* A pointer passed in from user mode. This should not
Expand All @@ -223,29 +208,13 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)

static inline void __user *arch_compat_alloc_user_space(long len)
{
compat_uptr_t sp;

if (test_thread_flag(TIF_IA32)) {
sp = task_pt_regs(current)->sp;
} else {
/* -128 for the x32 ABI redzone */
sp = percpu_read(old_rsp) - 128;
}

return (void __user *)round_down(sp - len, 16);
struct pt_regs *regs = task_pt_regs(current);
return (void __user *)regs->sp - len;
}

static inline bool is_compat_task(void)
static inline int is_compat_task(void)
{
#ifdef CONFIG_IA32_EMULATION
if (current_thread_info()->status & TS_COMPAT)
return true;
#endif
#ifdef CONFIG_X86_X32_ABI
if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
return true;
#endif
return false;
return current_thread_info()->status & TS_COMPAT;
}

#endif /* _ASM_X86_COMPAT_H */
31 changes: 6 additions & 25 deletions trunk/arch/x86/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,7 @@ do { \
#define elf_check_arch(x) \
((x)->e_machine == EM_X86_64)

#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
#define compat_elf_check_arch(x) elf_check_arch_ia32(x)

static inline void elf_common_init(struct thread_struct *t,
struct pt_regs *regs, const u16 ds)
Expand All @@ -184,9 +179,8 @@ 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(bool);
#define COMPAT_SET_PERSONALITY(ex) \
set_personality_ia32((ex).e_machine == EM_X86_64)
void set_personality_ia32(void);
#define COMPAT_SET_PERSONALITY(ex) set_personality_ia32()

#define COMPAT_ELF_PLATFORM ("i686")

Expand Down Expand Up @@ -293,7 +287,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_ADDR32) ? 0x7ff : 0x3fffff)
#define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff)

#define ARCH_DLINFO \
do { \
Expand All @@ -302,20 +296,9 @@ 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 \
if (test_thread_flag(TIF_X32)) \
ARCH_DLINFO_X32; \
else \
ARCH_DLINFO_IA32(sysctl_vsyscall32)
#define COMPAT_ARCH_DLINFO ARCH_DLINFO_IA32(sysctl_vsyscall32)

#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)

Expand All @@ -331,8 +314,6 @@ struct linux_binprm;
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
extern 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
Expand All @@ -349,7 +330,7 @@ static inline int mmap_is_ia32(void)
return 1;
#endif
#ifdef CONFIG_IA32_EMULATION
if (test_thread_flag(TIF_ADDR32))
if (test_thread_flag(TIF_IA32))
return 1;
#endif
return 0;
Expand Down
9 changes: 0 additions & 9 deletions trunk/arch/x86/include/asm/ia32.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,6 @@ 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.
*/
Expand Down
4 changes: 1 addition & 3 deletions trunk/arch/x86/include/asm/posix_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
#else
# ifdef __i386__
# include "posix_types_32.h"
# elif defined(__LP64__)
# include "posix_types_64.h"
# else
# include "posix_types_x32.h"
# include "posix_types_64.h"
# endif
#endif
19 changes: 0 additions & 19 deletions trunk/arch/x86/include/asm/posix_types_x32.h

This file was deleted.

10 changes: 2 additions & 8 deletions trunk/arch/x86/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ADDR32) ? \
#define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
IA32_PAGE_OFFSET : TASK_SIZE_MAX)
#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \
#define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? \
IA32_PAGE_OFFSET : TASK_SIZE_MAX)

#define STACK_TOP TASK_SIZE
Expand All @@ -948,12 +948,6 @@ 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,
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/x86/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ 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 *);
Expand Down
Loading

0 comments on commit 1676ba3

Please sign in to comment.