Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull pile 2 of execve and kernel_thread unification work from Al Viro: "Stuff in there: kernel_thread/kernel_execve/sys_execve conversions for several more architectures plus assorted signal fixes and cleanups. There'll be more (in particular, real fixes for the alpha do_notify_resume() irq mess)..." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (43 commits) alpha: don't open-code trace_report_syscall_{enter,exit} Uninclude linux/freezer.h m32r: trim masks avr32: trim masks tile: don't bother with SIGTRAP in setup_frame microblaze: don't bother with SIGTRAP in setup_rt_frame() mn10300: don't bother with SIGTRAP in setup_frame() frv: no need to raise SIGTRAP in setup_frame() x86: get rid of duplicate code in case of CONFIG_VM86 unicore32: remove pointless test h8300: trim _TIF_WORK_MASK parisc: decide whether to go to slow path (tracesys) based on thread flags parisc: don't bother looping in do_signal() parisc: fix double restarts bury the rest of TIF_IRET sanitize tsk_is_polling() bury _TIF_RESTORE_SIGMASK unicore32: unobfuscate _TIF_WORK_MASK mips: NOTIFY_RESUME is not needed in TIF masks mips: merge the identical "return from syscall" per-ABI code ... Conflicts: arch/arm/include/asm/thread_info.h
This commit is contained in:
@@ -435,6 +435,22 @@ ret_from_fork:
|
||||
li r3,0
|
||||
b ret_from_syscall
|
||||
|
||||
.globl ret_from_kernel_thread
|
||||
ret_from_kernel_thread:
|
||||
REST_NVGPRS(r1)
|
||||
bl schedule_tail
|
||||
mtlr r14
|
||||
mr r3,r15
|
||||
PPC440EP_ERR42
|
||||
blrl
|
||||
li r3,0
|
||||
b do_exit # no return
|
||||
|
||||
.globl __ret_from_kernel_execve
|
||||
__ret_from_kernel_execve:
|
||||
addi r1,r3,-STACK_FRAME_OVERHEAD
|
||||
b ret_from_syscall
|
||||
|
||||
/* Traced system call support */
|
||||
syscall_dotrace:
|
||||
SAVE_NVGPRS(r1)
|
||||
|
@@ -370,6 +370,22 @@ _GLOBAL(ret_from_fork)
|
||||
li r3,0
|
||||
b syscall_exit
|
||||
|
||||
_GLOBAL(ret_from_kernel_thread)
|
||||
bl .schedule_tail
|
||||
REST_NVGPRS(r1)
|
||||
REST_GPR(2,r1)
|
||||
mtlr r14
|
||||
mr r3,r15
|
||||
blrl
|
||||
li r3,0
|
||||
b .do_exit # no return
|
||||
|
||||
_GLOBAL(__ret_from_kernel_execve)
|
||||
addi r1,r3,-STACK_FRAME_OVERHEAD
|
||||
li r10,1
|
||||
std r10,SOFTE(r1)
|
||||
b syscall_exit
|
||||
|
||||
.section ".toc","aw"
|
||||
DSCR_DEFAULT:
|
||||
.tc dscr_default[TC],dscr_default
|
||||
|
@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset)
|
||||
.align 3
|
||||
2: PPC_LONG 1b
|
||||
|
||||
_GLOBAL(kernel_execve)
|
||||
li r0,__NR_execve
|
||||
sc
|
||||
bnslr
|
||||
neg r3,r3
|
||||
blr
|
||||
|
||||
_GLOBAL(setjmp)
|
||||
mflr r0
|
||||
PPC_STL r0,0(r3)
|
||||
|
@@ -663,39 +663,6 @@ _GLOBAL(abs)
|
||||
sub r3,r3,r4
|
||||
blr
|
||||
|
||||
/*
|
||||
* Create a kernel thread
|
||||
* kernel_thread(fn, arg, flags)
|
||||
*/
|
||||
_GLOBAL(kernel_thread)
|
||||
stwu r1,-16(r1)
|
||||
stw r30,8(r1)
|
||||
stw r31,12(r1)
|
||||
mr r30,r3 /* function */
|
||||
mr r31,r4 /* argument */
|
||||
ori r3,r5,CLONE_VM /* flags */
|
||||
oris r3,r3,CLONE_UNTRACED>>16
|
||||
li r4,0 /* new sp (unused) */
|
||||
li r0,__NR_clone
|
||||
sc
|
||||
bns+ 1f /* did system call indicate error? */
|
||||
neg r3,r3 /* if so, make return code negative */
|
||||
1: cmpwi 0,r3,0 /* parent or child? */
|
||||
bne 2f /* return if parent */
|
||||
li r0,0 /* make top-level stack frame */
|
||||
stwu r0,-16(r1)
|
||||
mtlr r30 /* fn addr in lr */
|
||||
mr r3,r31 /* load arg and call fn */
|
||||
PPC440EP_ERR42
|
||||
blrl
|
||||
li r0,__NR_exit /* exit if function returns */
|
||||
li r3,0
|
||||
sc
|
||||
2: lwz r30,8(r1)
|
||||
lwz r31,12(r1)
|
||||
addi r1,r1,16
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
_GLOBAL(start_secondary_resume)
|
||||
/* Reset stack */
|
||||
|
@@ -406,40 +406,6 @@ _GLOBAL(scom970_write)
|
||||
#endif /* CONFIG_CPU_FREQ_PMAC64 || CONFIG_CPU_FREQ_MAPLE */
|
||||
|
||||
|
||||
/*
|
||||
* Create a kernel thread
|
||||
* kernel_thread(fn, arg, flags)
|
||||
*/
|
||||
_GLOBAL(kernel_thread)
|
||||
std r29,-24(r1)
|
||||
std r30,-16(r1)
|
||||
stdu r1,-STACK_FRAME_OVERHEAD(r1)
|
||||
mr r29,r3
|
||||
mr r30,r4
|
||||
ori r3,r5,CLONE_VM /* flags */
|
||||
oris r3,r3,(CLONE_UNTRACED>>16)
|
||||
li r4,0 /* new sp (unused) */
|
||||
li r0,__NR_clone
|
||||
sc
|
||||
bns+ 1f /* did system call indicate error? */
|
||||
neg r3,r3 /* if so, make return code negative */
|
||||
1: cmpdi 0,r3,0 /* parent or child? */
|
||||
bne 2f /* return if parent */
|
||||
li r0,0
|
||||
stdu r0,-STACK_FRAME_OVERHEAD(r1)
|
||||
ld r2,8(r29)
|
||||
ld r29,0(r29)
|
||||
mtlr r29 /* fn addr in lr */
|
||||
mr r3,r30 /* load arg and call fn */
|
||||
blrl
|
||||
li r0,__NR_exit /* exit after child exits */
|
||||
li r3,0
|
||||
sc
|
||||
2: addi r1,r1,STACK_FRAME_OVERHEAD
|
||||
ld r29,-24(r1)
|
||||
ld r30,-16(r1)
|
||||
blr
|
||||
|
||||
/*
|
||||
* disable_kernel_fp()
|
||||
* Disable the FPU.
|
||||
|
@@ -94,7 +94,6 @@ EXPORT_SYMBOL(pci_dram_offset);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
EXPORT_SYMBOL(start_thread);
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
EXPORT_SYMBOL(giveup_fpu);
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
|
@@ -733,30 +733,39 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
||||
extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
|
||||
|
||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
unsigned long unused, struct task_struct *p,
|
||||
unsigned long arg, struct task_struct *p,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *childregs, *kregs;
|
||||
extern void ret_from_fork(void);
|
||||
extern void ret_from_kernel_thread(void);
|
||||
void (*f)(void);
|
||||
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
|
||||
|
||||
CHECK_FULL_REGS(regs);
|
||||
/* Copy registers */
|
||||
sp -= sizeof(struct pt_regs);
|
||||
childregs = (struct pt_regs *) sp;
|
||||
*childregs = *regs;
|
||||
if ((childregs->msr & MSR_PR) == 0) {
|
||||
if (!regs) {
|
||||
/* for kernel thread, set `current' and stackptr in new task */
|
||||
memset(childregs, 0, sizeof(struct pt_regs));
|
||||
childregs->gpr[1] = sp + sizeof(struct pt_regs);
|
||||
#ifdef CONFIG_PPC32
|
||||
childregs->gpr[2] = (unsigned long) p;
|
||||
#else
|
||||
#ifdef CONFIG_PPC64
|
||||
childregs->gpr[14] = *(unsigned long *)usp;
|
||||
childregs->gpr[2] = ((unsigned long *)usp)[1],
|
||||
clear_tsk_thread_flag(p, TIF_32BIT);
|
||||
#else
|
||||
childregs->gpr[14] = usp; /* function */
|
||||
childregs->gpr[2] = (unsigned long) p;
|
||||
#endif
|
||||
childregs->gpr[15] = arg;
|
||||
p->thread.regs = NULL; /* no user register state */
|
||||
f = ret_from_kernel_thread;
|
||||
} else {
|
||||
CHECK_FULL_REGS(regs);
|
||||
*childregs = *regs;
|
||||
childregs->gpr[1] = usp;
|
||||
p->thread.regs = childregs;
|
||||
childregs->gpr[3] = 0; /* Result from fork() */
|
||||
if (clone_flags & CLONE_SETTLS) {
|
||||
#ifdef CONFIG_PPC64
|
||||
if (!is_32bit_task())
|
||||
@@ -765,8 +774,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
#endif
|
||||
childregs->gpr[2] = childregs->gpr[6];
|
||||
}
|
||||
|
||||
f = ret_from_fork;
|
||||
}
|
||||
childregs->gpr[3] = 0; /* Result from fork() */
|
||||
sp -= STACK_FRAME_OVERHEAD;
|
||||
|
||||
/*
|
||||
@@ -805,19 +815,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
p->thread.dscr = current->thread.dscr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The PPC64 ABI makes use of a TOC to contain function
|
||||
* pointers. The function (ret_from_except) is actually a pointer
|
||||
* to the TOC entry. The first entry is a pointer to the actual
|
||||
* function.
|
||||
*/
|
||||
*/
|
||||
#ifdef CONFIG_PPC64
|
||||
kregs->nip = *((unsigned long *)ret_from_fork);
|
||||
kregs->nip = *((unsigned long *)f);
|
||||
#else
|
||||
kregs->nip = (unsigned long)ret_from_fork;
|
||||
kregs->nip = (unsigned long)f;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1055,26 +1063,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
|
||||
regs, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
void __ret_from_kernel_execve(struct pt_regs *normal)
|
||||
__noreturn;
|
||||
|
||||
filename = getname((const char __user *) a0);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
flush_fp_to_thread(current);
|
||||
flush_altivec_to_thread(current);
|
||||
flush_spe_to_thread(current);
|
||||
error = do_execve(filename,
|
||||
(const char __user *const __user *) a1,
|
||||
(const char __user *const __user *) a2, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
void ret_from_kernel_execve(struct pt_regs *normal)
|
||||
{
|
||||
set_thread_flag(TIF_RESTOREALL);
|
||||
__ret_from_kernel_execve(normal);
|
||||
}
|
||||
|
||||
static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/freezer.h>
|
||||
#endif
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
@@ -156,28 +156,6 @@ asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
|
||||
(off_t __user *)offset, count);
|
||||
}
|
||||
|
||||
long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
|
||||
filename = getname((char __user *) a0);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
flush_fp_to_thread(current);
|
||||
flush_altivec_to_thread(current);
|
||||
|
||||
error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
|
||||
|
||||
putname(filename);
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Note: it is necessary to treat option as an unsigned int,
|
||||
* with the corresponding cast to a signed int to insure that the
|
||||
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
|
||||
|
Reference in New Issue
Block a user