parisc: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
ddffeb8c4d
commit
a44e060fc5
|
@ -22,6 +22,7 @@ config PARISC
|
||||||
select GENERIC_STRNCPY_FROM_USER
|
select GENERIC_STRNCPY_FROM_USER
|
||||||
select HAVE_MOD_ARCH_SPECIFIC
|
select HAVE_MOD_ARCH_SPECIFIC
|
||||||
select MODULES_USE_ELF_RELA
|
select MODULES_USE_ELF_RELA
|
||||||
|
select GENERIC_KERNEL_THREAD
|
||||||
|
|
||||||
help
|
help
|
||||||
The PA-RISC microprocessor is designed by Hewlett-Packard and used
|
The PA-RISC microprocessor is designed by Hewlett-Packard and used
|
||||||
|
|
|
@ -707,60 +707,10 @@ ENTRY(end_fault_vector)
|
||||||
.import handle_interruption,code
|
.import handle_interruption,code
|
||||||
.import do_cpu_irq_mask,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
|
* Child Returns here
|
||||||
*
|
*
|
||||||
* copy_thread moved args from temp save area set up above
|
* copy_thread moved args into task save area.
|
||||||
* into task save area.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ENTRY(ret_from_kernel_thread)
|
ENTRY(ret_from_kernel_thread)
|
||||||
|
@ -773,7 +723,6 @@ ENTRY(ret_from_kernel_thread)
|
||||||
LDREG TASK_PT_GR25(%r1), %r26
|
LDREG TASK_PT_GR25(%r1), %r26
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
LDREG TASK_PT_GR27(%r1), %r27
|
LDREG TASK_PT_GR27(%r1), %r27
|
||||||
LDREG TASK_PT_GR22(%r1), %r22
|
|
||||||
#endif
|
#endif
|
||||||
LDREG TASK_PT_GR26(%r1), %r1
|
LDREG TASK_PT_GR26(%r1), %r1
|
||||||
ble 0(%sr7, %r1)
|
ble 0(%sr7, %r1)
|
||||||
|
|
|
@ -164,23 +164,6 @@ void machine_power_off(void)
|
||||||
void (*pm_power_off)(void) = machine_power_off;
|
void (*pm_power_off)(void) = machine_power_off;
|
||||||
EXPORT_SYMBOL(pm_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..
|
* Free current thread data structures etc..
|
||||||
*/
|
*/
|
||||||
|
@ -256,8 +239,8 @@ sys_vfork(struct pt_regs *regs)
|
||||||
|
|
||||||
int
|
int
|
||||||
copy_thread(unsigned long clone_flags, unsigned long usp,
|
copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
unsigned long unused, /* in ia64 this is "user_stack_size" */
|
unsigned long arg,
|
||||||
struct task_struct * p, struct pt_regs * pregs)
|
struct task_struct *p, struct pt_regs *pregs)
|
||||||
{
|
{
|
||||||
struct pt_regs * cregs = &(p->thread.regs);
|
struct pt_regs * cregs = &(p->thread.regs);
|
||||||
void *stack = task_stack_page(p);
|
void *stack = task_stack_page(p);
|
||||||
|
@ -271,21 +254,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
extern void * const hpux_child_return;
|
extern void * const hpux_child_return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*cregs = *pregs;
|
if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) {
|
||||||
|
memset(cregs, 0, sizeof(struct pt_regs));
|
||||||
/* 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 */
|
/* kernel thread */
|
||||||
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
|
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
|
||||||
/* Must exit via ret_from_kernel_thread in order
|
/* Must exit via ret_from_kernel_thread in order
|
||||||
|
@ -297,10 +267,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
* ret_from_kernel_thread.
|
* ret_from_kernel_thread.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_64BIT
|
#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
|
#endif
|
||||||
cregs->gr[26] = pregs->gr[26];
|
cregs->gr[25] = arg;
|
||||||
cregs->gr[25] = pregs->gr[25];
|
|
||||||
} else {
|
} else {
|
||||||
/* user thread */
|
/* user thread */
|
||||||
/*
|
/*
|
||||||
|
@ -308,6 +280,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||||
* for setting gr[21].
|
* for setting gr[21].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
*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 */
|
||||||
|
|
||||||
/* Use same stack depth as parent */
|
/* Use same stack depth as parent */
|
||||||
cregs->ksp = (unsigned long)stack
|
cregs->ksp = (unsigned long)stack
|
||||||
+ (pregs->gr[21] & (THREAD_SIZE - 1));
|
+ (pregs->gr[21] & (THREAD_SIZE - 1));
|
||||||
|
|
Loading…
Reference in New Issue