diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-11 21:49:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-11 21:49:08 -0400 |
commit | 8213a2f3eeafdecf06dd718cb4130372263f6067 (patch) | |
tree | 0d02e3201dac64d1429f8552ee1163d4a1ef1646 /arch/powerpc/kernel | |
parent | 40924754f2cabd5d9af4bcd4dcecc362b5e0baa1 (diff) | |
parent | 12f79be93d94698778ff2b3f921073fc5f6780d6 (diff) |
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
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc.S | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_32.S | 33 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_64.S | 34 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 59 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/sys_ppc32.c | 22 |
9 files changed, 59 insertions, 130 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index af37528da49f..9499385676e7 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -435,6 +435,22 @@ ret_from_fork: | |||
435 | li r3,0 | 435 | li r3,0 |
436 | b ret_from_syscall | 436 | b ret_from_syscall |
437 | 437 | ||
438 | .globl ret_from_kernel_thread | ||
439 | ret_from_kernel_thread: | ||
440 | REST_NVGPRS(r1) | ||
441 | bl schedule_tail | ||
442 | mtlr r14 | ||
443 | mr r3,r15 | ||
444 | PPC440EP_ERR42 | ||
445 | blrl | ||
446 | li r3,0 | ||
447 | b do_exit # no return | ||
448 | |||
449 | .globl __ret_from_kernel_execve | ||
450 | __ret_from_kernel_execve: | ||
451 | addi r1,r3,-STACK_FRAME_OVERHEAD | ||
452 | b ret_from_syscall | ||
453 | |||
438 | /* Traced system call support */ | 454 | /* Traced system call support */ |
439 | syscall_dotrace: | 455 | syscall_dotrace: |
440 | SAVE_NVGPRS(r1) | 456 | SAVE_NVGPRS(r1) |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 0e931aaffca2..56e0ff0878b5 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -370,6 +370,22 @@ _GLOBAL(ret_from_fork) | |||
370 | li r3,0 | 370 | li r3,0 |
371 | b syscall_exit | 371 | b syscall_exit |
372 | 372 | ||
373 | _GLOBAL(ret_from_kernel_thread) | ||
374 | bl .schedule_tail | ||
375 | REST_NVGPRS(r1) | ||
376 | REST_GPR(2,r1) | ||
377 | mtlr r14 | ||
378 | mr r3,r15 | ||
379 | blrl | ||
380 | li r3,0 | ||
381 | b .do_exit # no return | ||
382 | |||
383 | _GLOBAL(__ret_from_kernel_execve) | ||
384 | addi r1,r3,-STACK_FRAME_OVERHEAD | ||
385 | li r10,1 | ||
386 | std r10,SOFTE(r1) | ||
387 | b syscall_exit | ||
388 | |||
373 | .section ".toc","aw" | 389 | .section ".toc","aw" |
374 | DSCR_DEFAULT: | 390 | DSCR_DEFAULT: |
375 | .tc dscr_default[TC],dscr_default | 391 | .tc dscr_default[TC],dscr_default |
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S index ba16874fe294..7ce26d45777e 100644 --- a/arch/powerpc/kernel/misc.S +++ b/arch/powerpc/kernel/misc.S | |||
@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset) | |||
54 | .align 3 | 54 | .align 3 |
55 | 2: PPC_LONG 1b | 55 | 2: PPC_LONG 1b |
56 | 56 | ||
57 | _GLOBAL(kernel_execve) | ||
58 | li r0,__NR_execve | ||
59 | sc | ||
60 | bnslr | ||
61 | neg r3,r3 | ||
62 | blr | ||
63 | |||
64 | _GLOBAL(setjmp) | 57 | _GLOBAL(setjmp) |
65 | mflr r0 | 58 | mflr r0 |
66 | PPC_STL r0,0(r3) | 59 | PPC_STL r0,0(r3) |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 407e293aad2f..19e096bd0e73 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -663,39 +663,6 @@ _GLOBAL(abs) | |||
663 | sub r3,r3,r4 | 663 | sub r3,r3,r4 |
664 | blr | 664 | blr |
665 | 665 | ||
666 | /* | ||
667 | * Create a kernel thread | ||
668 | * kernel_thread(fn, arg, flags) | ||
669 | */ | ||
670 | _GLOBAL(kernel_thread) | ||
671 | stwu r1,-16(r1) | ||
672 | stw r30,8(r1) | ||
673 | stw r31,12(r1) | ||
674 | mr r30,r3 /* function */ | ||
675 | mr r31,r4 /* argument */ | ||
676 | ori r3,r5,CLONE_VM /* flags */ | ||
677 | oris r3,r3,CLONE_UNTRACED>>16 | ||
678 | li r4,0 /* new sp (unused) */ | ||
679 | li r0,__NR_clone | ||
680 | sc | ||
681 | bns+ 1f /* did system call indicate error? */ | ||
682 | neg r3,r3 /* if so, make return code negative */ | ||
683 | 1: cmpwi 0,r3,0 /* parent or child? */ | ||
684 | bne 2f /* return if parent */ | ||
685 | li r0,0 /* make top-level stack frame */ | ||
686 | stwu r0,-16(r1) | ||
687 | mtlr r30 /* fn addr in lr */ | ||
688 | mr r3,r31 /* load arg and call fn */ | ||
689 | PPC440EP_ERR42 | ||
690 | blrl | ||
691 | li r0,__NR_exit /* exit if function returns */ | ||
692 | li r3,0 | ||
693 | sc | ||
694 | 2: lwz r30,8(r1) | ||
695 | lwz r31,12(r1) | ||
696 | addi r1,r1,16 | ||
697 | blr | ||
698 | |||
699 | #ifdef CONFIG_SMP | 666 | #ifdef CONFIG_SMP |
700 | _GLOBAL(start_secondary_resume) | 667 | _GLOBAL(start_secondary_resume) |
701 | /* Reset stack */ | 668 | /* Reset stack */ |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 565b78625a32..5cfa8008693b 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
@@ -407,40 +407,6 @@ _GLOBAL(scom970_write) | |||
407 | 407 | ||
408 | 408 | ||
409 | /* | 409 | /* |
410 | * Create a kernel thread | ||
411 | * kernel_thread(fn, arg, flags) | ||
412 | */ | ||
413 | _GLOBAL(kernel_thread) | ||
414 | std r29,-24(r1) | ||
415 | std r30,-16(r1) | ||
416 | stdu r1,-STACK_FRAME_OVERHEAD(r1) | ||
417 | mr r29,r3 | ||
418 | mr r30,r4 | ||
419 | ori r3,r5,CLONE_VM /* flags */ | ||
420 | oris r3,r3,(CLONE_UNTRACED>>16) | ||
421 | li r4,0 /* new sp (unused) */ | ||
422 | li r0,__NR_clone | ||
423 | sc | ||
424 | bns+ 1f /* did system call indicate error? */ | ||
425 | neg r3,r3 /* if so, make return code negative */ | ||
426 | 1: cmpdi 0,r3,0 /* parent or child? */ | ||
427 | bne 2f /* return if parent */ | ||
428 | li r0,0 | ||
429 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | ||
430 | ld r2,8(r29) | ||
431 | ld r29,0(r29) | ||
432 | mtlr r29 /* fn addr in lr */ | ||
433 | mr r3,r30 /* load arg and call fn */ | ||
434 | blrl | ||
435 | li r0,__NR_exit /* exit after child exits */ | ||
436 | li r3,0 | ||
437 | sc | ||
438 | 2: addi r1,r1,STACK_FRAME_OVERHEAD | ||
439 | ld r29,-24(r1) | ||
440 | ld r30,-16(r1) | ||
441 | blr | ||
442 | |||
443 | /* | ||
444 | * disable_kernel_fp() | 410 | * disable_kernel_fp() |
445 | * Disable the FPU. | 411 | * Disable the FPU. |
446 | */ | 412 | */ |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 3e4031581c65..19e4288d8486 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -94,7 +94,6 @@ EXPORT_SYMBOL(pci_dram_offset); | |||
94 | #endif /* CONFIG_PCI */ | 94 | #endif /* CONFIG_PCI */ |
95 | 95 | ||
96 | EXPORT_SYMBOL(start_thread); | 96 | EXPORT_SYMBOL(start_thread); |
97 | EXPORT_SYMBOL(kernel_thread); | ||
98 | 97 | ||
99 | EXPORT_SYMBOL(giveup_fpu); | 98 | EXPORT_SYMBOL(giveup_fpu); |
100 | #ifdef CONFIG_ALTIVEC | 99 | #ifdef CONFIG_ALTIVEC |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d5ad666efd8b..ba48233500f6 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -733,30 +733,39 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
733 | extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */ | 733 | extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */ |
734 | 734 | ||
735 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 735 | int copy_thread(unsigned long clone_flags, unsigned long usp, |
736 | unsigned long unused, struct task_struct *p, | 736 | unsigned long arg, struct task_struct *p, |
737 | struct pt_regs *regs) | 737 | struct pt_regs *regs) |
738 | { | 738 | { |
739 | struct pt_regs *childregs, *kregs; | 739 | struct pt_regs *childregs, *kregs; |
740 | extern void ret_from_fork(void); | 740 | extern void ret_from_fork(void); |
741 | extern void ret_from_kernel_thread(void); | ||
742 | void (*f)(void); | ||
741 | unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; | 743 | unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; |
742 | 744 | ||
743 | CHECK_FULL_REGS(regs); | ||
744 | /* Copy registers */ | 745 | /* Copy registers */ |
745 | sp -= sizeof(struct pt_regs); | 746 | sp -= sizeof(struct pt_regs); |
746 | childregs = (struct pt_regs *) sp; | 747 | childregs = (struct pt_regs *) sp; |
747 | *childregs = *regs; | 748 | if (!regs) { |
748 | if ((childregs->msr & MSR_PR) == 0) { | ||
749 | /* for kernel thread, set `current' and stackptr in new task */ | 749 | /* for kernel thread, set `current' and stackptr in new task */ |
750 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
750 | childregs->gpr[1] = sp + sizeof(struct pt_regs); | 751 | childregs->gpr[1] = sp + sizeof(struct pt_regs); |
751 | #ifdef CONFIG_PPC32 | 752 | #ifdef CONFIG_PPC64 |
752 | childregs->gpr[2] = (unsigned long) p; | 753 | childregs->gpr[14] = *(unsigned long *)usp; |
753 | #else | 754 | childregs->gpr[2] = ((unsigned long *)usp)[1], |
754 | clear_tsk_thread_flag(p, TIF_32BIT); | 755 | clear_tsk_thread_flag(p, TIF_32BIT); |
756 | #else | ||
757 | childregs->gpr[14] = usp; /* function */ | ||
758 | childregs->gpr[2] = (unsigned long) p; | ||
755 | #endif | 759 | #endif |
760 | childregs->gpr[15] = arg; | ||
756 | p->thread.regs = NULL; /* no user register state */ | 761 | p->thread.regs = NULL; /* no user register state */ |
762 | f = ret_from_kernel_thread; | ||
757 | } else { | 763 | } else { |
764 | CHECK_FULL_REGS(regs); | ||
765 | *childregs = *regs; | ||
758 | childregs->gpr[1] = usp; | 766 | childregs->gpr[1] = usp; |
759 | p->thread.regs = childregs; | 767 | p->thread.regs = childregs; |
768 | childregs->gpr[3] = 0; /* Result from fork() */ | ||
760 | if (clone_flags & CLONE_SETTLS) { | 769 | if (clone_flags & CLONE_SETTLS) { |
761 | #ifdef CONFIG_PPC64 | 770 | #ifdef CONFIG_PPC64 |
762 | if (!is_32bit_task()) | 771 | if (!is_32bit_task()) |
@@ -765,8 +774,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
765 | #endif | 774 | #endif |
766 | childregs->gpr[2] = childregs->gpr[6]; | 775 | childregs->gpr[2] = childregs->gpr[6]; |
767 | } | 776 | } |
777 | |||
778 | f = ret_from_fork; | ||
768 | } | 779 | } |
769 | childregs->gpr[3] = 0; /* Result from fork() */ | ||
770 | sp -= STACK_FRAME_OVERHEAD; | 780 | sp -= STACK_FRAME_OVERHEAD; |
771 | 781 | ||
772 | /* | 782 | /* |
@@ -805,19 +815,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
805 | p->thread.dscr = current->thread.dscr; | 815 | p->thread.dscr = current->thread.dscr; |
806 | } | 816 | } |
807 | #endif | 817 | #endif |
808 | |||
809 | /* | 818 | /* |
810 | * The PPC64 ABI makes use of a TOC to contain function | 819 | * The PPC64 ABI makes use of a TOC to contain function |
811 | * pointers. The function (ret_from_except) is actually a pointer | 820 | * pointers. The function (ret_from_except) is actually a pointer |
812 | * to the TOC entry. The first entry is a pointer to the actual | 821 | * to the TOC entry. The first entry is a pointer to the actual |
813 | * function. | 822 | * function. |
814 | */ | 823 | */ |
815 | #ifdef CONFIG_PPC64 | 824 | #ifdef CONFIG_PPC64 |
816 | kregs->nip = *((unsigned long *)ret_from_fork); | 825 | kregs->nip = *((unsigned long *)f); |
817 | #else | 826 | #else |
818 | kregs->nip = (unsigned long)ret_from_fork; | 827 | kregs->nip = (unsigned long)f; |
819 | #endif | 828 | #endif |
820 | |||
821 | return 0; | 829 | return 0; |
822 | } | 830 | } |
823 | 831 | ||
@@ -1055,26 +1063,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, | |||
1055 | regs, 0, NULL, NULL); | 1063 | regs, 0, NULL, NULL); |
1056 | } | 1064 | } |
1057 | 1065 | ||
1058 | int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, | 1066 | void __ret_from_kernel_execve(struct pt_regs *normal) |
1059 | unsigned long a3, unsigned long a4, unsigned long a5, | 1067 | __noreturn; |
1060 | struct pt_regs *regs) | 1068 | |
1069 | void ret_from_kernel_execve(struct pt_regs *normal) | ||
1061 | { | 1070 | { |
1062 | int error; | 1071 | set_thread_flag(TIF_RESTOREALL); |
1063 | char *filename; | 1072 | __ret_from_kernel_execve(normal); |
1064 | |||
1065 | filename = getname((const char __user *) a0); | ||
1066 | error = PTR_ERR(filename); | ||
1067 | if (IS_ERR(filename)) | ||
1068 | goto out; | ||
1069 | flush_fp_to_thread(current); | ||
1070 | flush_altivec_to_thread(current); | ||
1071 | flush_spe_to_thread(current); | ||
1072 | error = do_execve(filename, | ||
1073 | (const char __user *const __user *) a1, | ||
1074 | (const char __user *const __user *) a2, regs); | ||
1075 | putname(filename); | ||
1076 | out: | ||
1077 | return error; | ||
1078 | } | 1073 | } |
1079 | 1074 | ||
1080 | static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, | 1075 | static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 8b4c049aee20..804e323c139d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/stddef.h> | 35 | #include <linux/stddef.h> |
36 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
37 | #include <linux/binfmts.h> | 37 | #include <linux/binfmts.h> |
38 | #include <linux/freezer.h> | ||
39 | #endif | 38 | #endif |
40 | 39 | ||
41 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index abd1112da54f..9c2ed90ece8f 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -156,28 +156,6 @@ asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd, | |||
156 | (off_t __user *)offset, count); | 156 | (off_t __user *)offset, count); |
157 | } | 157 | } |
158 | 158 | ||
159 | long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, | ||
160 | unsigned long a3, unsigned long a4, unsigned long a5, | ||
161 | struct pt_regs *regs) | ||
162 | { | ||
163 | int error; | ||
164 | char * filename; | ||
165 | |||
166 | filename = getname((char __user *) a0); | ||
167 | error = PTR_ERR(filename); | ||
168 | if (IS_ERR(filename)) | ||
169 | goto out; | ||
170 | flush_fp_to_thread(current); | ||
171 | flush_altivec_to_thread(current); | ||
172 | |||
173 | error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs); | ||
174 | |||
175 | putname(filename); | ||
176 | |||
177 | out: | ||
178 | return error; | ||
179 | } | ||
180 | |||
181 | /* Note: it is necessary to treat option as an unsigned int, | 159 | /* Note: it is necessary to treat option as an unsigned int, |
182 | * with the corresponding cast to a signed int to insure that the | 160 | * with the corresponding cast to a signed int to insure that the |
183 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | 161 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |