Merge branch 'arch-parisc' into no-rebases

This commit is contained in:
Al Viro 2012-11-16 22:27:35 -05:00
commit 2482f8449d
6 changed files with 39 additions and 301 deletions

View File

@ -22,6 +22,8 @@ config PARISC
select GENERIC_STRNCPY_FROM_USER
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used

View File

@ -995,6 +995,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE
#endif /* __ASSEMBLY__ */

View File

@ -707,60 +707,10 @@ ENTRY(end_fault_vector)
.import handle_interruption,code
.import do_cpu_irq_mask,code
/*
* r26 = function to be called
* r25 = argument to pass in
* r24 = flags for do_fork()
*
* Kernel threads don't ever return, so they don't need
* a true register context. We just save away the arguments
* for copy_thread/ret_ to properly set up the child.
*/
#define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
#define CLONE_UNTRACED 0x00800000
.import do_fork
ENTRY(__kernel_thread)
STREG %r2, -RP_OFFSET(%r30)
copy %r30, %r1
ldo PT_SZ_ALGN(%r30),%r30
#ifdef CONFIG_64BIT
/* Yo, function pointers in wide mode are little structs... -PB */
ldd 24(%r26), %r2
STREG %r2, PT_GR27(%r1) /* Store childs %dp */
ldd 16(%r26), %r26
STREG %r22, PT_GR22(%r1) /* save r22 (arg5) */
copy %r0, %r22 /* user_tid */
#endif
STREG %r26, PT_GR26(%r1) /* Store function & argument for child */
STREG %r25, PT_GR25(%r1)
ldil L%CLONE_UNTRACED, %r26
ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */
or %r26, %r24, %r26 /* will have kernel mappings. */
ldi 1, %r25 /* stack_start, signals kernel thread */
stw %r0, -52(%r30) /* user_tid */
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
BL do_fork, %r2
copy %r1, %r24 /* pt_regs */
/* Parent Returns here */
LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2
ldo -PT_SZ_ALGN(%r30), %r30
bv %r0(%r2)
nop
ENDPROC(__kernel_thread)
/*
* Child Returns here
*
* copy_thread moved args from temp save area set up above
* into task save area.
* copy_thread moved args into task save area.
*/
ENTRY(ret_from_kernel_thread)
@ -769,51 +719,17 @@ ENTRY(ret_from_kernel_thread)
BL schedule_tail, %r2
nop
LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
LDREG TASK_PT_GR25(%r1), %r26
#ifdef CONFIG_64BIT
LDREG TASK_PT_GR27(%r1), %r27
LDREG TASK_PT_GR22(%r1), %r22
#endif
LDREG TASK_PT_GR26(%r1), %r1
ble 0(%sr7, %r1)
copy %r31, %r2
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
loadgp /* Thread could have been in a module */
#endif
#ifndef CONFIG_64BIT
b sys_exit
#else
load32 sys_exit, %r1
bv %r0(%r1)
#endif
ldi 0, %r26
ENDPROC(ret_from_kernel_thread)
.import sys_execve, code
ENTRY(__execve)
copy %r2, %r15
copy %r30, %r16
ldo PT_SZ_ALGN(%r30), %r30
STREG %r26, PT_GR26(%r16)
STREG %r25, PT_GR25(%r16)
STREG %r24, PT_GR24(%r16)
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
BL sys_execve, %r2
copy %r16, %r26
cmpib,=,n 0,%r28,intr_return /* forward */
/* yes, this will trap and die. */
copy %r15, %r2
copy %r16, %r30
bv %r0(%r2)
b finish_child_return
nop
ENDPROC(__execve)
ENDPROC(ret_from_kernel_thread)
/*
@ -1776,49 +1692,27 @@ ENTRY(sys_fork_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
ldo TASK_REGS(%r1),%r1
reg_save %r1
mfctl %cr27, %r3
STREG %r3, PT_CR27(%r1)
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
/* These are call-clobbered registers and therefore
also syscall-clobbered (we hope). */
STREG %r2,PT_GR19(%r1) /* save for child */
STREG %r30,PT_GR21(%r1)
mfctl %cr27, %r28
STREG %r28, PT_CR27(%r1)
LDREG PT_GR30(%r1),%r25
copy %r1,%r24
BL sys_clone,%r2
b sys_clone
ldi SIGCHLD,%r26
LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
wrapper_exit:
ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
LDREG PT_CR27(%r1), %r3
mtctl %r3, %cr27
reg_restore %r1
/* strace expects syscall # to be preserved in r20 */
ldi __NR_fork,%r20
bv %r0(%r2)
STREG %r20,PT_GR20(%r1)
ENDPROC(sys_fork_wrapper)
/* Set the return value for the child */
ENTRY(child_return)
BL schedule_tail, %r2
nop
finish_child_return:
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
LDREG TASK_PT_GR19(%r1),%r2
b wrapper_exit
LDREG PT_CR27(%r1), %r3
mtctl %r3, %cr27
reg_restore %r1
b syscall_exit
copy %r0,%r28
ENDPROC(child_return)
@ -1827,23 +1721,10 @@ ENTRY(sys_clone_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_save %r1
mfctl %cr27, %r3
STREG %r3, PT_CR27(%r1)
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
/* WARNING - Clobbers r19 and r21, userspace must save these! */
STREG %r2,PT_GR19(%r1) /* save for child */
STREG %r30,PT_GR21(%r1)
BL sys_clone,%r2
mfctl %cr27, %r28
STREG %r28, PT_CR27(%r1)
b sys_clone
copy %r1,%r24
b wrapper_exit
LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
ENDPROC(sys_clone_wrapper)
@ -1851,72 +1732,14 @@ ENTRY(sys_vfork_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_save %r1
mfctl %cr27, %r3
STREG %r3, PT_CR27(%r1)
mfctl %cr27, %r28
STREG %r28, PT_CR27(%r1)
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
STREG %r2,PT_GR19(%r1) /* save for child */
STREG %r30,PT_GR21(%r1)
BL sys_vfork,%r2
b sys_vfork
copy %r1,%r26
b wrapper_exit
LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
ENDPROC(sys_vfork_wrapper)
.macro execve_wrapper execve
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
/*
* Do we need to save/restore r3-r18 here?
* I don't think so. why would new thread need old
* threads registers?
*/
/* %arg0 - %arg3 are already saved for us. */
STREG %r2,-RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30),%r30
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
BL \execve,%r2
copy %r1,%arg0
ldo -FRAME_SIZE(%r30),%r30
LDREG -RP_OFFSET(%r30),%r2
/* If exec succeeded we need to load the args */
ldo -1024(%r0),%r1
cmpb,>>= %r28,%r1,error_\execve
copy %r2,%r19
error_\execve:
bv %r0(%r19)
nop
.endm
.import sys_execve
ENTRY(sys_execve_wrapper)
execve_wrapper sys_execve
ENDPROC(sys_execve_wrapper)
#ifdef CONFIG_64BIT
.import sys32_execve
ENTRY(sys32_execve_wrapper)
execve_wrapper sys32_execve
ENDPROC(sys32_execve_wrapper)
#endif
ENTRY(sys_rt_sigreturn_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
ldo TASK_REGS(%r26),%r26 /* get pt regs */

View File

@ -52,6 +52,7 @@
#include <asm/io.h>
#include <asm/asm-offsets.h>
#include <asm/assembly.h>
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
#include <asm/pgalloc.h>
@ -164,23 +165,6 @@ void machine_power_off(void)
void (*pm_power_off)(void) = machine_power_off;
EXPORT_SYMBOL(pm_power_off);
/*
* Create a kernel thread
*/
extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
/*
* FIXME: Once we are sure we don't need any debug here,
* kernel_thread can become a #define.
*/
return __kernel_thread(fn, arg, flags);
}
EXPORT_SYMBOL(kernel_thread);
/*
* Free current thread data structures etc..
*/
@ -256,8 +240,8 @@ sys_vfork(struct pt_regs *regs)
int
copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, /* in ia64 this is "user_stack_size" */
struct task_struct * p, struct pt_regs * pregs)
unsigned long arg,
struct task_struct *p, struct pt_regs *pregs)
{
struct pt_regs * cregs = &(p->thread.regs);
void *stack = task_stack_page(p);
@ -270,48 +254,32 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
#ifdef CONFIG_HPUX
extern void * const hpux_child_return;
#endif
if (unlikely(p->flags & PF_KTHREAD)) {
memset(cregs, 0, sizeof(struct pt_regs));
if (!usp) /* idle thread */
return 0;
*cregs = *pregs;
/* Set the return value for the child. Note that this is not
actually restored by the syscall exit path, but we put it
here for consistency in case of signals. */
cregs->gr[28] = 0; /* child */
/*
* We need to differentiate between a user fork and a
* kernel fork. We can't use user_mode, because the
* the syscall path doesn't save iaoq. Right now
* We rely on the fact that kernel_thread passes
* in zero for usp.
*/
if (usp == 1) {
/* kernel thread */
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
/* Must exit via ret_from_kernel_thread in order
* to call schedule_tail()
*/
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
cregs->kpc = (unsigned long) &ret_from_kernel_thread;
/*
* Copy function and argument to be called from
* ret_from_kernel_thread.
*/
#ifdef CONFIG_64BIT
cregs->gr[27] = pregs->gr[27];
cregs->gr[27] = ((unsigned long *)usp)[3];
cregs->gr[26] = ((unsigned long *)usp)[2];
#else
cregs->gr[26] = usp;
#endif
cregs->gr[26] = pregs->gr[26];
cregs->gr[25] = pregs->gr[25];
cregs->gr[25] = arg;
} else {
/* user thread */
/*
* Note that the fork wrappers are responsible
* for setting gr[21].
*/
/* Use same stack depth as parent */
cregs->ksp = (unsigned long)stack
+ (pregs->gr[21] & (THREAD_SIZE - 1));
cregs->gr[30] = usp;
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
if (personality(p->personality) == PER_HPUX) {
#ifdef CONFIG_HPUX
cregs->kpc = (unsigned long) &hpux_child_return;
@ -323,8 +291,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
}
/* Setup thread TLS area from the 4th parameter in clone */
if (clone_flags & CLONE_SETTLS)
cregs->cr27 = pregs->gr[23];
cregs->cr27 = pregs->gr[23];
}
return 0;
@ -335,39 +302,6 @@ unsigned long thread_saved_pc(struct task_struct *t)
return t->thread.regs.kpc;
}
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(struct pt_regs *regs)
{
int error;
struct filename *filename;
filename = getname((const char __user *) regs->gr[26]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename->name,
(const char __user *const __user *) regs->gr[25],
(const char __user *const __user *) regs->gr[24],
regs);
putname(filename);
out:
return error;
}
extern int __execve(const char *filename,
const char *const argv[],
const char *const envp[], struct task_struct *task);
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
return __execve(filename, argv, envp, current);
}
unsigned long
get_wchan(struct task_struct *p)
{

View File

@ -53,28 +53,6 @@
#define DBG(x)
#endif
/*
* sys32_execve() executes a new program.
*/
asmlinkage int sys32_execve(struct pt_regs *regs)
{
int error;
struct filename *filename;
DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26]));
filename = getname((const char __user *) regs->gr[26]);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]),
compat_ptr(regs->gr[24]), regs);
putname(filename);
out:
return error;
}
asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
int r22, int r21, int r20)
{

View File

@ -66,7 +66,7 @@
ENTRY_SAME(creat)
ENTRY_SAME(link)
ENTRY_SAME(unlink) /* 10 */
ENTRY_DIFF(execve_wrapper)
ENTRY_COMP(execve)
ENTRY_SAME(chdir)
/* See comments in kernel/time.c!!! Maybe we don't need this? */
ENTRY_COMP(time)