diff options
Diffstat (limited to 'arch/parisc')
-rw-r--r-- | arch/parisc/Kconfig | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/parport.h | 2 | ||||
-rw-r--r-- | arch/parisc/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/signal.h | 2 | ||||
-rw-r--r-- | arch/parisc/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/parisc/include/uapi/asm/ioctls.h | 3 | ||||
-rw-r--r-- | arch/parisc/include/uapi/asm/mman.h | 11 | ||||
-rw-r--r-- | arch/parisc/include/uapi/asm/signal.h | 6 | ||||
-rw-r--r-- | arch/parisc/include/uapi/asm/socket.h | 1 | ||||
-rw-r--r-- | arch/parisc/kernel/entry.S | 241 | ||||
-rw-r--r-- | arch/parisc/kernel/hardware.c | 7 | ||||
-rw-r--r-- | arch/parisc/kernel/module.c | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/pdc_cons.c | 5 | ||||
-rw-r--r-- | arch/parisc/kernel/process.c | 142 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc32.c | 22 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall_table.S | 2 |
17 files changed, 72 insertions, 380 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 11def45b98c5..b77feffbadea 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -22,6 +22,7 @@ config PARISC select GENERIC_STRNCPY_FROM_USER select HAVE_MOD_ARCH_SPECIFIC select MODULES_USE_ELF_RELA + select CLONE_BACKWARDS help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index bac8debecffb..ff4c9faed546 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ poll.h xor.h clkdev.h exec.h +generic-y += trace_clock.h diff --git a/arch/parisc/include/asm/parport.h b/arch/parisc/include/asm/parport.h index 00d9cc3e7b97..c391d7cbc223 100644 --- a/arch/parisc/include/asm/parport.h +++ b/arch/parisc/include/asm/parport.h @@ -8,7 +8,7 @@ #define _ASM_PARPORT_H 1 -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +static int parport_pc_find_nonpci_ports (int autoirq, int autodma) { /* nothing ! */ return 0; diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 0e8b7b8ce8a2..09b54a57a48d 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -326,7 +326,6 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm); diff --git a/arch/parisc/include/asm/signal.h b/arch/parisc/include/asm/signal.h index 21abf4fc169a..0fdb3c835952 100644 --- a/arch/parisc/include/asm/signal.h +++ b/arch/parisc/include/asm/signal.h @@ -34,8 +34,6 @@ struct k_sigaction { struct sigaction sa; }; -#define ptrace_signal_deliver(regs, cookie) do { } while (0) - #include <asm/sigcontext.h> #endif /* !__ASSEMBLY */ diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 541639c3f607..3043194547cd 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -163,6 +163,9 @@ 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_FORK +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_CLONE #endif /* __ASSEMBLY__ */ diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index 054ec06f9e23..66719c38a36b 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -55,6 +55,9 @@ #define TIOCGDEV _IOR('T',0x32, int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h index 12219ebce869..294d251ca7b2 100644 --- a/arch/parisc/include/uapi/asm/mman.h +++ b/arch/parisc/include/uapi/asm/mman.h @@ -70,4 +70,15 @@ #define MAP_FILE 0 #define MAP_VARIABLE 0 +/* + * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. + * This gives us 6 bits, which is enough until someone invents 128 bit address + * spaces. + * + * Assume these are all power of twos. + * When 0 use the default page size. + */ +#define MAP_HUGE_SHIFT 26 +#define MAP_HUGE_MASK 0x3f + #endif /* __PARISC_MMAN_H__ */ diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index b1ddaa243376..a2fa297196bc 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -71,12 +71,6 @@ #define SA_RESTORER 0x04000000 /* obsolete -- ignored */ -/* - * sigaltstack controls - */ -#define SS_ONSTACK 1 -#define SS_DISABLE 2 - #define MINSIGSTKSZ 2048 #define SIGSTKSZ 8192 diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 1b52c2c31a7a..d9ff4731253b 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -48,6 +48,7 @@ /* Socket filtering */ #define SO_ATTACH_FILTER 0x401a #define SO_DETACH_FILTER 0x401b +#define SO_GET_FILTER SO_ATTACH_FILTER #define SO_ACCEPTCONN 0x401c diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 18670a078849..bfb44247d7a7 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -708,59 +708,9 @@ ENTRY(end_fault_vector) .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) /* @@ -1772,151 +1688,36 @@ dtlb_fault: LDREG PT_GR18(\regs),%r18 .endm -ENTRY(sys_fork_wrapper) + .macro fork_like name +ENTRY(sys_\name\()_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) - - LDREG PT_GR30(%r1),%r25 - copy %r1,%r24 - BL sys_clone,%r2 - 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 + mfctl %cr27, %r28 + b sys_\name + STREG %r28, PT_CR27(%r1) +ENDPROC(sys_\name\()_wrapper) + .endm - /* strace expects syscall # to be preserved in r20 */ - ldi __NR_fork,%r20 - bv %r0(%r2) - STREG %r20,PT_GR20(%r1) -ENDPROC(sys_fork_wrapper) +fork_like clone +fork_like fork +fork_like vfork /* 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) - -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 - copy %r1,%r24 - - b wrapper_exit - LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 -ENDPROC(sys_clone_wrapper) - - -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) - - 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 - 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 */ diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index f48a640b55fb..f7752f6af29e 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c @@ -38,7 +38,7 @@ * so don't reference this table after starting the init process */ -static struct hp_hardware hp_hardware_list[] __devinitdata = { +static struct hp_hardware hp_hardware_list[] = { {HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"}, {HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"}, {HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"}, @@ -1230,7 +1230,7 @@ static struct hp_cpu_type_mask { unsigned short model; unsigned short mask; enum cpu_type cpu; -} hp_cpu_type_mask_list[] __devinitdata = { +} hp_cpu_type_mask_list[] = { { 0x0000, 0x0ff0, pcx }, /* 0x0000 - 0x000f */ { 0x0048, 0x0ff0, pcxl }, /* 0x0040 - 0x004f */ @@ -1327,8 +1327,7 @@ const char * const cpu_name_version[][2] = { [mako2] = { "PA8900 (Shortfin)", "2.0" } }; -const char * __devinit -parisc_hardware_description(struct parisc_device_id *id) +const char *parisc_hardware_description(struct parisc_device_id *id) { struct hp_hardware *listptr; diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 5e34ccf39a49..2a625fb063e1 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -214,8 +214,6 @@ static inline int reassemble_22(int as22) void *module_alloc(unsigned long size) { - if (size == 0) - return NULL; /* using RWX means less protection for modules, but it's * easier than trying to map the text, data, init_text and * init_data correctly */ diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 88238638aee6..efc5e7d30530 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -186,13 +186,13 @@ static int __init pdc_console_tty_driver_init(void) printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); pdc_cons.flags &= ~CON_BOOT; - tty_port_init(&tty_port); - pdc_console_tty_driver = alloc_tty_driver(1); if (!pdc_console_tty_driver) return -ENOMEM; + tty_port_init(&tty_port); + pdc_console_tty_driver->driver_name = "pdc_cons"; pdc_console_tty_driver->name = "ttyB"; pdc_console_tty_driver->major = MUX_MAJOR; @@ -207,6 +207,7 @@ static int __init pdc_console_tty_driver_init(void) err = tty_register_driver(pdc_console_tty_driver); if (err) { printk(KERN_ERR "Unable to register the PDC console TTY driver\n"); + tty_port_destroy(&tty_port); return err; } diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index cbc37216bf90..d13507246c5d 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -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> @@ -165,23 +166,6 @@ 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.. */ void exit_thread(void) @@ -218,48 +202,11 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) return 1; } -/* Note that "fork()" is implemented in terms of clone, with - parameters (SIGCHLD, regs->gr[30], regs). */ -int -sys_clone(unsigned long clone_flags, unsigned long usp, - struct pt_regs *regs) -{ - /* Arugments from userspace are: - r26 = Clone flags. - r25 = Child stack. - r24 = parent_tidptr. - r23 = Is the TLS storage descriptor - r22 = child_tidptr - - However, these last 3 args are only examined - if the proper flags are set. */ - int __user *parent_tidptr = (int __user *)regs->gr[24]; - int __user *child_tidptr = (int __user *)regs->gr[22]; - - /* usp must be word aligned. This also prevents users from - * passing in the value 1 (which is the signal for a special - * return for a kernel thread) */ - usp = ALIGN(usp, 4); - - /* A zero value for usp means use the current stack */ - if (usp == 0) - usp = regs->gr[30]; - - return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); -} - -int -sys_vfork(struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); -} - 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 * cregs = &(p->thread.regs); + struct pt_regs *cregs = &(p->thread.regs); void *stack = task_stack_page(p); /* We have to use void * instead of a function pointer, because @@ -270,48 +217,39 @@ 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; + /* usp must be word aligned. This also prevents users from + * passing in the value 1 (which is the signal for a special + * return for a kernel thread) */ + if (usp) { + usp = ALIGN(usp, 4); + if (likely(usp)) + 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 +261,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 = cregs->gr[23]; } return 0; @@ -335,39 +272,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) { diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index bf5b93a885d3..9cfdaa19ab63 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -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) { diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index cbf5d59d5d6a..54d950b067b7 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -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) |