Skip to content

Commit 42859ee

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull generic execve() changes from Al Viro: "This introduces the generic kernel_thread() and kernel_execve() functions, and switches x86, arm, alpha, um and s390 over to them." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (26 commits) s390: convert to generic kernel_execve() s390: switch to generic kernel_thread() s390: fold kernel_thread_helper() into ret_from_fork() s390: fold execve_tail() into start_thread(), convert to generic sys_execve() um: switch to generic kernel_thread() x86, um/x86: switch to generic sys_execve and kernel_execve x86: split ret_from_fork alpha: introduce ret_from_kernel_execve(), switch to generic kernel_execve() alpha: switch to generic kernel_thread() alpha: switch to generic sys_execve() arm: get rid of execve wrapper, switch to generic execve() implementation arm: optimized current_pt_regs() arm: introduce ret_from_kernel_execve(), switch to generic kernel_execve() arm: split ret_from_fork, simplify kernel_thread() [based on patch by rmk] generic sys_execve() generic kernel_execve() new helper: current_pt_regs() preparation for generic kernel_thread() um: kill thread->forking um: let signal_delivered() do SIGTRAP on singlestepping into handler ...
2 parents f59b51f + f322220 commit 42859ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+390
-899
lines changed

arch/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ config ARCH_WANT_OLD_COMPAT_IPC
271271
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
272272
bool
273273

274+
config GENERIC_KERNEL_THREAD
275+
bool
276+
274277
config HAVE_ARCH_SECCOMP_FILTER
275278
bool
276279
help

arch/alpha/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ config ALPHA
2020
select GENERIC_CMOS_UPDATE
2121
select GENERIC_STRNCPY_FROM_USER
2222
select GENERIC_STRNLEN_USER
23+
select GENERIC_KERNEL_THREAD
2324
help
2425
The Alpha is a 64-bit general-purpose processor designed and
2526
marketed by the Digital Equipment Corporation of blessed memory,

arch/alpha/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ header-y += pal.h
1010
header-y += reg.h
1111
header-y += regdef.h
1212
header-y += sysinfo.h
13+
generic-y += exec.h

arch/alpha/include/asm/exec.h

Lines changed: 0 additions & 6 deletions
This file was deleted.

arch/alpha/include/asm/processor.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
4949
/* Free all resources held by a thread. */
5050
extern void release_thread(struct task_struct *);
5151

52-
/* Create a kernel thread without removing it from tasklists. */
53-
extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
54-
5552
unsigned long get_wchan(struct task_struct *p);
5653

5754
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)

arch/alpha/include/asm/unistd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@
481481
#define __ARCH_WANT_SYS_OLDUMOUNT
482482
#define __ARCH_WANT_SYS_SIGPENDING
483483
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
484+
#define __ARCH_WANT_SYS_EXECVE
485+
#define __ARCH_WANT_KERNEL_EXECVE
484486

485487
/* "Conditional" syscalls. What we want is
486488

arch/alpha/kernel/alpha_ksyms.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ EXPORT_SYMBOL(alpha_read_fp_reg_s);
5050
EXPORT_SYMBOL(alpha_write_fp_reg);
5151
EXPORT_SYMBOL(alpha_write_fp_reg_s);
5252

53-
/* entry.S */
54-
EXPORT_SYMBOL(kernel_thread);
55-
5653
/* Networking helper routines. */
5754
EXPORT_SYMBOL(csum_tcpudp_magic);
5855
EXPORT_SYMBOL(ip_compute_csum);

arch/alpha/kernel/entry.S

Lines changed: 18 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -609,59 +609,35 @@ ret_from_fork:
609609
.end ret_from_fork
610610

611611
/*
612-
* kernel_thread(fn, arg, clone_flags)
612+
* ... and new kernel threads - here
613613
*/
614614
.align 4
615-
.globl kernel_thread
616-
.ent kernel_thread
617-
kernel_thread:
618-
/* We can be called from a module. */
619-
ldgp $gp, 0($27)
620-
.prologue 1
621-
subq $sp, SP_OFF+6*8, $sp
622-
br $1, 2f /* load start address */
623-
624-
/* We've now "returned" from a fake system call. */
625-
unop
626-
blt $0, 1f /* error? */
627-
ldi $1, 0x3fff
628-
beq $20, 1f /* parent or child? */
629-
630-
bic $sp, $1, $8 /* in child. */
631-
jsr $26, ($27)
615+
.globl ret_from_kernel_thread
616+
.ent ret_from_kernel_thread
617+
ret_from_kernel_thread:
618+
mov $17, $16
619+
jsr $26, schedule_tail
620+
mov $9, $27
621+
mov $10, $16
622+
jsr $26, ($9)
632623
ldgp $gp, 0($26)
633624
mov $0, $16
634625
mov $31, $26
635626
jmp $31, sys_exit
627+
.end ret_from_kernel_thread
636628

637-
1: ret /* in parent. */
638-
639-
.align 4
640-
2: /* Fake a system call stack frame, as we can't do system calls
641-
from kernel space. Note that we store FN and ARG as they
642-
need to be set up in the child for the call. Also store $8
643-
and $26 for use in the parent. */
644-
stq $31, SP_OFF($sp) /* ps */
645-
stq $1, SP_OFF+8($sp) /* pc */
646-
stq $gp, SP_OFF+16($sp) /* gp */
647-
stq $16, 136($sp) /* $27; FN for child */
648-
stq $17, SP_OFF+24($sp) /* $16; ARG for child */
649-
stq $8, 64($sp) /* $8 */
650-
stq $26, 128($sp) /* $26 */
629+
.globl ret_from_kernel_execve
630+
.align 4
631+
.ent ret_from_kernel_execve
632+
ret_from_kernel_execve:
633+
mov $16, $sp
651634
/* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
652635
ldq $2, alpha_mv+HAE_CACHE
653636
stq $2, 152($sp) /* HAE */
637+
mov $31, $19 /* to disable syscall restarts */
638+
br $31, ret_to_user
654639

655-
/* Shuffle FLAGS to the front; add CLONE_VM. */
656-
ldi $1, CLONE_VM|CLONE_UNTRACED
657-
or $18, $1, $16
658-
bsr $26, sys_clone
659-
660-
/* We don't actually care for a3 success widgetry in the kernel.
661-
Not for positive errno values. */
662-
stq $0, 0($sp) /* $0 */
663-
br ret_to_kernel
664-
.end kernel_thread
640+
.end ret_from_kernel_execve
665641

666642

667643
/*
@@ -744,15 +720,6 @@ sys_rt_sigreturn:
744720
br ret_from_sys_call
745721
.end sys_rt_sigreturn
746722

747-
.align 4
748-
.globl sys_execve
749-
.ent sys_execve
750-
sys_execve:
751-
.prologue 0
752-
mov $sp, $19
753-
jmp $31, do_sys_execve
754-
.end sys_execve
755-
756723
.align 4
757724
.globl alpha_ni_syscall
758725
.ent alpha_ni_syscall

arch/alpha/kernel/process.c

Lines changed: 20 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -263,41 +263,42 @@ alpha_vfork(struct pt_regs *regs)
263263

264264
/*
265265
* Copy an alpha thread..
266-
*
267-
* Note the "stack_offset" stuff: when returning to kernel mode, we need
268-
* to have some extra stack-space for the kernel stack that still exists
269-
* after the "ret_from_fork". When returning to user mode, we only want
270-
* the space needed by the syscall stack frame (ie "struct pt_regs").
271-
* Use the passed "regs" pointer to determine how much space we need
272-
* for a kernel fork().
273266
*/
274267

275268
int
276269
copy_thread(unsigned long clone_flags, unsigned long usp,
277-
unsigned long unused,
270+
unsigned long arg,
278271
struct task_struct * p, struct pt_regs * regs)
279272
{
280273
extern void ret_from_fork(void);
274+
extern void ret_from_kernel_thread(void);
281275

282276
struct thread_info *childti = task_thread_info(p);
283-
struct pt_regs * childregs;
284-
struct switch_stack * childstack, *stack;
285-
unsigned long stack_offset, settls;
286-
287-
stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
288-
if (!(regs->ps & 8))
289-
stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
290-
childregs = (struct pt_regs *)
291-
(stack_offset + PAGE_SIZE + task_stack_page(p));
292-
277+
struct pt_regs *childregs = task_pt_regs(p);
278+
struct switch_stack *childstack, *stack;
279+
unsigned long settls;
280+
281+
childstack = ((struct switch_stack *) childregs) - 1;
282+
if (unlikely(!regs)) {
283+
/* kernel thread */
284+
memset(childstack, 0,
285+
sizeof(struct switch_stack) + sizeof(struct pt_regs));
286+
childstack->r26 = (unsigned long) ret_from_kernel_thread;
287+
childstack->r9 = usp; /* function */
288+
childstack->r10 = arg;
289+
childregs->hae = alpha_mv.hae_cache,
290+
childti->pcb.usp = 0;
291+
childti->pcb.ksp = (unsigned long) childstack;
292+
childti->pcb.flags = 1; /* set FEN, clear everything else */
293+
return 0;
294+
}
293295
*childregs = *regs;
294296
settls = regs->r20;
295297
childregs->r0 = 0;
296298
childregs->r19 = 0;
297299
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
298300
regs->r20 = 0;
299301
stack = ((struct switch_stack *) regs) - 1;
300-
childstack = ((struct switch_stack *) childregs) - 1;
301302
*childstack = *stack;
302303
childstack->r26 = (unsigned long) ret_from_fork;
303304
childti->pcb.usp = usp;
@@ -385,27 +386,6 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
385386
}
386387
EXPORT_SYMBOL(dump_elf_task_fp);
387388

388-
/*
389-
* sys_execve() executes a new program.
390-
*/
391-
asmlinkage int
392-
do_sys_execve(const char __user *ufilename,
393-
const char __user *const __user *argv,
394-
const char __user *const __user *envp, struct pt_regs *regs)
395-
{
396-
int error;
397-
char *filename;
398-
399-
filename = getname(ufilename);
400-
error = PTR_ERR(filename);
401-
if (IS_ERR(filename))
402-
goto out;
403-
error = do_execve(filename, argv, envp, regs);
404-
putname(filename);
405-
out:
406-
return error;
407-
}
408-
409389
/*
410390
* Return saved PC of a blocked thread. This assumes the frame
411391
* pointer is the 6th saved long on the kernel stack and that the
@@ -459,22 +439,3 @@ get_wchan(struct task_struct *p)
459439
}
460440
return pc;
461441
}
462-
463-
int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
464-
{
465-
/* Avoid the HAE being gratuitously wrong, which would cause us
466-
to do the whole turn off interrupts thing and restore it. */
467-
struct pt_regs regs = {.hae = alpha_mv.hae_cache};
468-
int err = do_execve(path, argv, envp, &regs);
469-
if (!err) {
470-
struct pt_regs *p = current_pt_regs();
471-
/* copy regs to normal position and off to userland we go... */
472-
*p = regs;
473-
__asm__ __volatile__ (
474-
"mov %0, $sp;"
475-
"br $31, ret_from_sys_call"
476-
: : "r"(p));
477-
}
478-
return err;
479-
}
480-
EXPORT_SYMBOL(kernel_execve);

arch/arm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ config ARM
5252
select GENERIC_STRNCPY_FROM_USER
5353
select GENERIC_STRNLEN_USER
5454
select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
55+
select GENERIC_KERNEL_THREAD
5556
help
5657
The ARM series is a line of low-power-consumption RISC chip designs
5758
licensed by ARM Ltd and targeted at embedded applications and

0 commit comments

Comments
 (0)