Commit 8213a2f3 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 40924754 12f79be9
...@@ -84,7 +84,6 @@ register struct thread_info *__current_thread_info __asm__("$8"); ...@@ -84,7 +84,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
/* Work to do on interrupt/exception return. */ /* Work to do on interrupt/exception return. */
...@@ -117,5 +116,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); ...@@ -117,5 +116,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
(int __user *)(value)); \ (int __user *)(value)); \
}) })
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ALPHA_THREAD_INFO_H */ #endif /* _ALPHA_THREAD_INFO_H */
...@@ -418,11 +418,10 @@ $work_notifysig: ...@@ -418,11 +418,10 @@ $work_notifysig:
strace: strace:
/* set up signal stack, call syscall_trace */ /* set up signal stack, call syscall_trace */
bsr $1, do_switch_stack bsr $1, do_switch_stack
jsr $26, syscall_trace jsr $26, syscall_trace_enter /* returns the syscall number */
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
/* get the system call number and the arguments back.. */ /* get the arguments back.. */
ldq $0, 0($sp)
ldq $16, SP_OFF+24($sp) ldq $16, SP_OFF+24($sp)
ldq $17, SP_OFF+32($sp) ldq $17, SP_OFF+32($sp)
ldq $18, SP_OFF+40($sp) ldq $18, SP_OFF+40($sp)
...@@ -449,7 +448,7 @@ $strace_success: ...@@ -449,7 +448,7 @@ $strace_success:
stq $0, 0($sp) /* save return value */ stq $0, 0($sp) /* save return value */
bsr $1, do_switch_stack bsr $1, do_switch_stack
jsr $26, syscall_trace jsr $26, syscall_trace_leave
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
br $31, ret_from_sys_call br $31, ret_from_sys_call
...@@ -467,7 +466,7 @@ $strace_error: ...@@ -467,7 +466,7 @@ $strace_error:
bsr $1, do_switch_stack bsr $1, do_switch_stack
mov $19, $9 /* save old syscall number */ mov $19, $9 /* save old syscall number */
mov $20, $10 /* save old a3 */ mov $20, $10 /* save old a3 */
jsr $26, syscall_trace jsr $26, syscall_trace_leave
mov $9, $19 mov $9, $19
mov $10, $20 mov $10, $20
bsr $1, undo_switch_stack bsr $1, undo_switch_stack
...@@ -698,7 +697,7 @@ sys_sigreturn: ...@@ -698,7 +697,7 @@ sys_sigreturn:
lda $sp, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp)
jsr $26, do_sigreturn jsr $26, do_sigreturn
bne $9, 1f bne $9, 1f
jsr $26, syscall_trace jsr $26, syscall_trace_leave
1: br $1, undo_switch_stack 1: br $1, undo_switch_stack
br ret_from_sys_call br ret_from_sys_call
.end sys_sigreturn .end sys_sigreturn
...@@ -715,7 +714,7 @@ sys_rt_sigreturn: ...@@ -715,7 +714,7 @@ sys_rt_sigreturn:
lda $sp, -SWITCH_STACK_SIZE($sp) lda $sp, -SWITCH_STACK_SIZE($sp)
jsr $26, do_rt_sigreturn jsr $26, do_rt_sigreturn
bne $9, 1f bne $9, 1f
jsr $26, syscall_trace jsr $26, syscall_trace_leave
1: br $1, undo_switch_stack 1: br $1, undo_switch_stack
br ret_from_sys_call br ret_from_sys_call
.end sys_rt_sigreturn .end sys_rt_sigreturn
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/user.h> #include <linux/user.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/tracehook.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -312,25 +313,18 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -312,25 +313,18 @@ long arch_ptrace(struct task_struct *child, long request,
return ret; return ret;
} }
asmlinkage void asmlinkage unsigned long syscall_trace_enter(void)
syscall_trace(void)
{ {
if (!test_thread_flag(TIF_SYSCALL_TRACE)) unsigned long ret = 0;
return; if (test_thread_flag(TIF_SYSCALL_TRACE) &&
if (!(current->ptrace & PT_PTRACED)) tracehook_report_syscall_entry(current_pt_regs()))
return; ret = -1UL;
/* The 0x80 provides a way for the tracing parent to distinguish return ret ?: current_pt_regs()->r0;
between a syscall stop and SIGTRAP delivery */ }
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/* asmlinkage void
* This isn't the same as continuing with a signal, but it will do syscall_trace_leave(void)
* for normal use. strace only continues with a signal if the {
* stopping signal is not SIGTRAP. -brl if (test_thread_flag(TIF_SYSCALL_TRACE))
*/ tracehook_report_syscall_exit(current_pt_regs(), 0);
if (current->exit_code) {
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
} }
...@@ -151,7 +151,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, ...@@ -151,7 +151,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9 #define TIF_SYSCALL_AUDIT 9
#define TIF_SYSCALL_TRACEPOINT 10 #define TIF_SYSCALL_TRACEPOINT 10
#define TIF_POLLING_NRFLAG 16
#define TIF_USING_IWMMXT 17 #define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 20 #define TIF_RESTORE_SIGMASK 20
...@@ -164,7 +163,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, ...@@ -164,7 +163,6 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
......
...@@ -77,8 +77,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -77,8 +77,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_BREAKPOINT 4 /* enter monitor mode on return */ #define TIF_BREAKPOINT 4 /* enter monitor mode on return */
#define TIF_SINGLE_STEP 5 /* single step in progress */ #define TIF_SINGLE_STEP 5 /* single step in progress */
#define TIF_MEMDIE 6 /* is terminating due to OOM killer */ #define TIF_MEMDIE 6 /* is terminating due to OOM killer */
...@@ -91,10 +89,9 @@ static inline struct thread_info *current_thread_info(void) ...@@ -91,10 +89,9 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_BREAKPOINT (1 << TIF_BREAKPOINT)
#define _TIF_SINGLE_STEP (1 << TIF_SINGLE_STEP) #define _TIF_SINGLE_STEP (1 << TIF_SINGLE_STEP)
#define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
...@@ -102,17 +99,14 @@ static inline struct thread_info *current_thread_info(void) ...@@ -102,17 +99,14 @@ static inline struct thread_info *current_thread_info(void)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \ #define _TIF_WORK_MASK \
((1 << TIF_SIGPENDING) \ (_TIF_SIGPENDING \
| _TIF_NOTIFY_RESUME \ | _TIF_NOTIFY_RESUME \
| (1 << TIF_NEED_RESCHED) \ | _TIF_NEED_RESCHED \
| (1 << TIF_POLLING_NRFLAG) \ | _TIF_BREAKPOINT)
| (1 << TIF_BREAKPOINT) \
| (1 << TIF_RESTORE_SIGMASK))
/* work to do on any return to userspace */ /* work to do on any return to userspace */
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \ #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
_TIF_NOTIFY_RESUME)
/* work to do on return from debug mode */ /* work to do on return from debug mode */
#define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT)) #define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~_TIF_BREAKPOINT)
#endif /* __ASM_AVR32_THREAD_INFO_H */ #endif /* __ASM_AVR32_THREAD_INFO_H */
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/freezer.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
......
...@@ -96,8 +96,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -96,8 +96,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_MEMDIE 4 /* is terminating due to OOM killer */ #define TIF_MEMDIE 4 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
#define TIF_IRQ_SYNC 7 /* sync pipeline stage */ #define TIF_IRQ_SYNC 7 /* sync pipeline stage */
...@@ -108,8 +106,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -108,8 +106,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC) #define _TIF_IRQ_SYNC (1<<TIF_IRQ_SYNC)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/freezer.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
......
...@@ -17,6 +17,7 @@ config C6X ...@@ -17,6 +17,7 @@ config C6X
select OF select OF
select OF_EARLY_FLATTREE select OF_EARLY_FLATTREE
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_KERNEL_THREAD
config MMU config MMU
def_bool n def_bool n
......
...@@ -92,8 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) ...@@ -92,8 +92,6 @@ static inline void release_thread(struct task_struct *dead_task)
{ {
} }
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
#define copy_segments(tsk, mm) do { } while (0) #define copy_segments(tsk, mm) do { } while (0)
#define release_segments(mm) do { } while (0) #define release_segments(mm) do { } while (0)
......
...@@ -44,11 +44,6 @@ extern int sys_cache_sync(unsigned long s, unsigned long e); ...@@ -44,11 +44,6 @@ extern int sys_cache_sync(unsigned long s, unsigned long e);
struct pt_regs; struct pt_regs;
extern asmlinkage long sys_c6x_clone(struct pt_regs *regs); extern asmlinkage long sys_c6x_clone(struct pt_regs *regs);
extern asmlinkage long sys_c6x_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp,
struct pt_regs *regs);
#include <asm-generic/syscalls.h> #include <asm-generic/syscalls.h>
......
...@@ -97,7 +97,6 @@ struct thread_info *current_thread_info(void) ...@@ -97,7 +97,6 @@ struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* OOM killer killed process */ #define TIF_MEMDIE 17 /* OOM killer killed process */
#define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */ #define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
* more details. * more details.
*/ */
#define __ARCH_WANT_KERNEL_EXECVE
#define __ARCH_WANT_SYS_EXECVE
/* Use the standard ABI for syscalls. */ /* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h> #include <asm-generic/unistd.h>
......
...@@ -116,7 +116,6 @@ void foo(void) ...@@ -116,7 +116,6 @@ void foo(void)
DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME)); DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING)); DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED)); DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
DEFINE(_TIF_POLLING_NRFLAG, (1<<TIF_POLLING_NRFLAG));
DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK); DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK); DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);
......
...@@ -400,6 +400,32 @@ ret_from_fork_2: ...@@ -400,6 +400,32 @@ ret_from_fork_2:
STW .D2T2 B0,*+SP(REGS_A4+8) STW .D2T2 B0,*+SP(REGS_A4+8)
ENDPROC(ret_from_fork) ENDPROC(ret_from_fork)
ENTRY(ret_from_kernel_thread)
#ifdef CONFIG_C6X_BIG_KERNEL
MVKL .S1 schedule_tail,A0
MVKH .S1 schedule_tail,A0
B .S2X A0
#else
B .S2 schedule_tail
#endif
LDW .D2T2 *+SP(REGS_A0+8),B10 /* get fn */
ADDKPC .S2 0f,B3,3
0:
B .S2 B10 /* call fn */
LDW .D2T1 *+SP(REGS_A1+8),A4 /* get arg */
MVKL .S2 sys_exit,B11
MVKH .S2 sys_exit,B11
ADDKPC .S2 0f,B3,1
0:
BNOP .S2 B11,5 /* jump to sys_exit */
ENDPROC(ret_from_kernel_thread)
ENTRY(ret_from_kernel_execve)
GET_THREAD_INFO A12
BNOP .S2 syscall_exit,4
ADD .D2X A4,-8,SP
ENDPROC(ret_from_kernel_execve)
;; ;;
;; These are the interrupt handlers, responsible for calling __do_IRQ() ;; These are the interrupt handlers, responsible for calling __do_IRQ()
;; int6 is used for syscalls (see _system_call entry) ;; int6 is used for syscalls (see _system_call entry)
...@@ -593,13 +619,6 @@ ENTRY(sys_sigaltstack) ...@@ -593,13 +619,6 @@ ENTRY(sys_sigaltstack)
NOP 4 NOP 4
ENDPROC(sys_sigaltstack) ENDPROC(sys_sigaltstack)
;; kernel_execve
ENTRY(kernel_execve)
MVK .S2 __NR_execve,B0
SWE
BNOP .S2 B3,5
ENDPROC(kernel_execve)
;; ;;
;; Special system calls ;; Special system calls
;; return address is in B3 ;; return address is in B3
...@@ -628,29 +647,6 @@ ENTRY(sys_rt_sigreturn) ...@@ -628,29 +647,6 @@ ENTRY(sys_rt_sigreturn)
#endif #endif
ENDPROC(sys_rt_sigreturn) ENDPROC(sys_rt_sigreturn)
ENTRY(sys_execve)
ADDAW .D2 SP,2,B6 ; put regs addr in 4th parameter
; & adjust regs stack addr
LDW .D2T2 *+SP(REGS_B4+8),B4
;; c6x_execve(char *name, char **argv,
;; char **envp, struct pt_regs *regs)
#ifdef CONFIG_C6X_BIG_KERNEL
|| MVKL .S1 sys_c6x_execve,A0
MVKH .S1 sys_c6x_execve,A0
B .S2X A0
#else
|| B .S2 sys_c6x_execve
#endif
STW .D2T2 B3,*SP--[2]
ADDKPC .S2 ret_from_c6x_execve,B3,3
ret_from_c6x_execve:
LDW .D2T2 *++SP[2],B3
NOP 4
BNOP .S2 B3,5
ENDPROC(sys_execve)
ENTRY(sys_pread_c6x) ENTRY(sys_pread_c6x)
MV .D2X A8,B7 MV .D2X A8,B7
#ifdef CONFIG_C6X_BIG_KERNEL #ifdef CONFIG_C6X_BIG_KERNEL
......
...@@ -25,6 +25,7 @@ void (*c6x_restart)(void); ...@@ -25,6 +25,7 @@ void (*c6x_restart)(void);
void (*c6x_halt)(void); void (*c6x_halt)(void);
extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_fork(void);
extern asmlinkage void ret_from_kernel_thread(void);
/* /*
* power off function, if any * power off function, if any
...@@ -103,37 +104,6 @@ void machine_power_off(void) ...@@ -103,37 +104,6 @@ void machine_power_off(void)
halt_loop(); halt_loop();
} }
static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
{
do_exit(fn(arg));
}
/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;
/*
* copy_thread sets a4 to zero (child return from fork)
* so we can't just set things up to directly return to
* fn.
*/
memset(&regs, 0, sizeof(regs));
regs.b4 = (unsigned long) arg;
regs.a6 = (unsigned long) fn;
regs.pc = (unsigned long) kernel_thread_helper;
local_save_flags(regs.csr);
regs.csr |= 1;
regs.tsr = 5; /* Set GEE and GIE in TSR */
/* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, &regs,
0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);
void flush_thread(void) void flush_thread(void)
{ {
} }
...@@ -191,22 +161,24 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -191,22 +161,24 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childregs = task_pt_regs(p); childregs = task_pt_regs(p);
*childregs = *regs; if (!regs) {
childregs->a4 = 0;
if (usp == -1)
/* case of __kernel_thread: we return to supervisor space */ /* case of __kernel_thread: we return to supervisor space */
memset(childregs, 0, sizeof(struct pt_regs));
childregs->sp = (unsigned long)(childregs + 1); childregs->sp = (unsigned long)(childregs + 1);
else p->thread.pc = (unsigned long) ret_from_kernel_thread;
childregs->a0 = usp; /* function */
childregs->a1 = ustk_size; /* argument */
} else {
/* Otherwise use the given stack */ /* Otherwise use the given stack */
*childregs = *regs;
childregs->sp = usp; childregs->sp = usp;
p->thread.pc = (unsigned long) ret_from_fork;
}
/* Set usp/ksp */ /* Set usp/ksp */
p->thread.usp = childregs->sp; p->thread.usp = childregs->sp;
/* switch_to uses stack to save/restore 14 callee-saved regs */
thread_saved_ksp(p) = (unsigned long)childregs - 8; thread_saved_ksp(p) = (unsigned long)childregs - 8;
p->thread.pc = (unsigned int) ret_from_fork; p->thread.wchan = p->thread.pc;
p->thread.wchan = (unsigned long) ret_from_fork;
#ifdef __DSBT__ #ifdef __DSBT__
{ {
unsigned long dp; unsigned long dp;
...@@ -221,28 +193,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -221,28 +193,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
return 0; return 0;
} }
/*
* c6x_execve() executes a new program.
*/
SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
const char __user *const __user *, argv,
const char __user *const __user *, envp,
struct pt_regs *, regs)
{
int error;
char *filename;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, argv, envp, regs);
putname(filename);
out:
return error;
}
unsigned long get_wchan(struct task_struct *p) unsigned long get_wchan(struct task_struct *p)
{ {
return p->thread.wchan; return p->thread.wchan;
......
...@@ -78,15 +78,12 @@ struct thread_info { ...@@ -78,15 +78,12 @@ struct thread_info {
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ #define TIF_MEMDIE 17 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
......
...@@ -12,6 +12,7 @@ config FRV ...@@ -12,6 +12,7 @@ config FRV
select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CPU_DEVICES select GENERIC_CPU_DEVICES
select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_KERNEL_THREAD
config ZONE_DMA config ZONE_DMA
bool bool
......
...@@ -92,14 +92,12 @@ extern struct task_struct *__kernel_current_task; ...@@ -92,14 +92,12 @@ extern struct task_struct *__kernel_current_task;
/* /*
* do necessary setup to start up a newly executed thread. * do necessary setup to start up a newly executed thread.
* - need to discard the frame stacked by init() invoking the execve syscall
*/ */
#define start_thread(_regs, _pc, _usp) \ #define start_thread(_regs, _pc, _usp) \
do { \ do { \
__frame = __kernel_frame0_ptr; \ _regs->pc = (_pc); \
__frame->pc = (_pc); \ _regs->psr &= ~PSR_S; \
__frame->psr &= ~PSR_S; \ _regs->sp = (_usp); \
__frame->sp = (_usp); \
} while(0) } while(0)
/* Free all resources held by a thread. */ /* Free all resources held by a thread. */
...@@ -107,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task) ...@@ -107,7 +105,6 @@ static inline void release_thread(struct task_struct *dead_task)
{ {
} }
extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern asmlinkage void save_user_regs(struct user_context *target); extern asmlinkage void save_user_regs(struct user_context *target);
extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
......
...@@ -76,6 +76,7 @@ register struct pt_regs *__frame asm("gr28"); ...@@ -76,6 +76,7 @@ register struct pt_regs *__frame asm("gr28");
#define user_mode(regs) (!((regs)->psr & PSR_S)) #define user_mode(regs) (!((regs)->psr & PSR_S))
#define instruction_pointer(regs) ((regs)->pc) #define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->sp) #define user_stack_pointer(regs) ((regs)->sp)
#define current_pt_regs() (__frame)
extern unsigned long user_stack(const struct pt_regs *); extern unsigned long user_stack(const struct pt_regs *);
#define profile_pc(regs) ((regs)->pc) #define profile_pc(regs) ((regs)->pc)
......
...@@ -94,7 +94,6 @@ register struct thread_info *__current_thread_info asm("gr15"); ...@@ -94,7 +94,6 @@ register struct thread_info *__current_thread_info asm("gr15");
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 6 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 7 /* is terminating due to OOM killer */ #define TIF_MEMDIE 7 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
...@@ -102,8 +101,6 @@ register struct thread_info *__current_thread_info asm("gr15"); ...@@ -102,8 +101,6 @@ register struct thread_info *__current_thread_info asm("gr15");
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
/* work to do on interrupt/exception return */ /* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \ #define _TIF_WORK_MASK \
......
...@@ -372,6 +372,8 @@ ...@@ -372,6 +372,8 @@
#define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_KERNEL_EXECVE
/* /*
* "Conditional" syscalls * "Conditional" syscalls
......
...@@ -7,8 +7,8 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o ...@@ -7,8 +7,8 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o
extra-y:= head.o vmlinux.lds extra-y:= head.o vmlinux.lds
obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \
kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ process.o traps.o ptrace.o signal.o dma.o \
sys_frv.o time.o setup.o frv_ksyms.o \ sys_frv.o time.o setup.o frv_ksyms.o \
debug-stub.o irq.o sleep.o uaccess.o debug-stub.o irq.o sleep.o uaccess.o
......
...@@ -863,6 +863,19 @@ ret_from_fork: ...@@ -863,6 +863,19 @@ ret_from_fork:
setlos.p #0,gr8 setlos.p #0,gr8
bra __syscall_exit bra __syscall_exit
.globl ret_from_kernel_thread
ret_from_kernel_thread:
lddi.p @(gr28,#REG_GR(8)),gr20
call schedule_tail
or.p gr20,gr20,gr8
calll @(gr21,gr0)
bra sys_exit
.globl ret_from_kernel_execve
ret_from_kernel_execve:
ori gr28,0,sp
bra __syscall_exit
################################################################################################### ###################################################################################################
# #
# Return to user mode is not as complex as all this looks, # Return to user mode is not as complex as all this looks,
......
...@@ -30,7 +30,6 @@ EXPORT_SYMBOL(ip_fast_csum); ...@@ -30,7 +30,6 @@ EXPORT_SYMBOL(ip_fast_csum);
EXPORT_SYMBOL(local_irq_count); EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(local_bh_count); EXPORT_SYMBOL(local_bh_count);
#endif #endif
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(__res_bus_clock_speed_HZ); EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
EXPORT_SYMBOL(__page_offset); EXPORT_SYMBOL(__page_offset);
......
/* in-kernel program execution
*
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/linkage.h>
#include <asm/unistd.h>
###############################################################################
#
# Do a system call from kernel instead of calling sys_execve so we end up with
# proper pt_regs.
#
# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
#
# On entry: GR8/GR9/GR10: arguments to function
# On return: GR8: syscall return.
#
###############################################################################
.globl kernel_execve
.type kernel_execve,@function
kernel_execve:
setlos __NR_execve,gr7
tira gr0,#0
bralr
.size kernel_execve,.-kernel_execve
/* kernel_thread.S: kernel thread creation
*
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/linkage.h>
#include <linux/kern_levels.h>
#include <asm/unistd.h>
#define CLONE_VM 0x00000100 /* set if VM shared between processes */
.section .rodata
kernel_thread_emsg:
.asciz KERN_ERR "failed to create kernel thread: error=%d\n"
.text
.balign 4
###############################################################################
#
# Create a kernel thread
#
# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
#
###############################################################################
.globl kernel_thread
.type kernel_thread,@function
kernel_thread:
or.p gr8,gr0,gr4
or gr9,gr0,gr5
# start by forking the current process, but with shared VM
setlos.p #__NR_clone,gr7 ; syscall number
ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags]
sethi.p #0xe4e4,gr9 ; second syscall arg [newsp]
setlo #0xe4e4,gr9
setlos.p #0,gr10 ; third syscall arg [parent_tidptr]
setlos #0,gr11 ; fourth syscall arg [child_tidptr]
tira gr0,#0
setlos.p #4095,gr7
andcc gr8,gr8,gr0,icc0
addcc.p gr8,gr7,gr0,icc1
bnelr icc0,#2
bc icc1,#0,kernel_thread_error
# now invoke the work function
or gr5,gr0,gr8
calll @(gr4,gr0)
# and finally exit the thread
setlos #__NR_exit,gr7 ; syscall number
tira gr0,#0
kernel_thread_error:
subi sp,#8,sp
movsg lr,gr4
sti gr8,@(sp,#0)
sti.p gr4,@(sp,#4)
or gr8,gr0,gr9
sethi.p %hi(kernel_thread_emsg),gr8
setlo %lo(kernel_thread_emsg),gr8
call printk
ldi @(sp,#4),gr4
ldi @(sp,#0),gr8
subi sp,#8,sp
jmpl @(gr4,gr0)
.size kernel_thread,.-kernel_thread
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "local.h" #include "local.h"
asmlinkage void ret_from_fork(void); asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
...@@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, ...@@ -172,32 +173,13 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
* set up the kernel stack and exception frames for a new process * set up the kernel stack and exception frames for a new process
*/ */
int copy_thread(unsigned long clone_flags, int copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long topstk, unsigned long usp, unsigned long arg,
struct task_struct *p, struct pt_regs *regs) struct task_struct *p, struct pt_regs *regs)
{ {
struct pt_regs *childregs0, *childregs, *regs0; struct pt_regs *childregs;
regs0 = __kernel_frame0_ptr; childregs = (struct pt_regs *)
childregs0 = (struct pt_regs *)
(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
childregs = childregs0;
/* set up the userspace frame (the only place that the USP is stored) */
*childregs0 = *regs0;
childregs0->gr8 = 0;
childregs0->sp = usp;
childregs0->next_frame = NULL;
/* set up the return kernel frame if called from kernel_thread() */
if (regs != regs0) {
childregs--;
*childregs = *regs;
childregs->sp = (unsigned long) childregs0;
childregs->next_frame = childregs0;
childregs->gr15 = (unsigned long) task_thread_info(p);
childregs->gr29 = (unsigned long) p;
}
p->set_child_tid = p->clear_child_tid = NULL; p->set_child_tid = p->clear_child_tid = NULL;
...@@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags, ...@@ -206,8 +188,25 @@ int copy_thread(unsigned long clone_flags,
p->thread.sp = (unsigned long) childregs; p->thread.sp = (unsigned long) childregs;
p->thread.fp = 0; p->thread.fp = 0;
p->thread.lr = 0; p->thread.lr = 0;
p->thread.frame0 = childregs;
if (unlikely(!regs)) {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->gr9 = usp; /* function */
childregs->gr8 = arg;
chilregs->psr = PSR_S;
p->thread.pc = (unsigned long) ret_from_kernel_thread;
save_user_regs(p->thread.user);
return 0;
}
/* set up the userspace frame (the only place that the USP is stored) */
*childregs = *regs;
childregs->sp = usp;
childregs->next_frame = NULL;
p->thread.pc = (unsigned long) ret_from_fork; p->thread.pc = (unsigned long) ret_from_fork;
p->thread.frame0 = childregs0;
/* the new TLS pointer is passed in as arg #5 to sys_clone() */ /* the new TLS pointer is passed in as arg #5 to sys_clone() */
if (clone_flags & CLONE_SETTLS) if (clone_flags & CLONE_SETTLS)
...@@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags, ...@@ -218,25 +217,6 @@ int copy_thread(unsigned long clone_flags,
return 0; return 0;
} /* end copy_thread() */ } /* end copy_thread() */
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char * filename;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
error = do_execve(filename, argv, envp, __frame);
putname(filename);
return error;
}
unsigned long get_wchan(struct task_struct *p) unsigned long get_wchan(struct task_struct *p)
{ {
struct pt_regs *regs0; struct pt_regs *regs0;
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -298,10 +297,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) ...@@ -298,10 +297,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
__frame->lr = (unsigned long) &frame->retcode; __frame->lr = (unsigned long) &frame->retcode;
__frame->gr8 = sig; __frame->gr8 = sig;
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
#if DEBUG_SIG #if DEBUG_SIG
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, __frame->pc, sig, current->comm, current->pid, frame, __frame->pc,
...@@ -400,10 +395,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -400,10 +395,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
__frame->gr8 = sig; __frame->gr8 = sig;
__frame->gr9 = (unsigned long) &frame->info; __frame->gr9 = (unsigned long) &frame->info;
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
#if DEBUG_SIG #if DEBUG_SIG
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, __frame->pc, sig, current->comm, current->pid, frame, __frame->pc,
......
...@@ -85,8 +85,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -85,8 +85,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_MEMDIE 4 /* is terminating due to OOM killer */ #define TIF_MEMDIE 4 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_RESUME 6 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 6 /* callback before returning to user */
...@@ -95,11 +93,10 @@ static inline struct thread_info *current_thread_info(void) ...@@ -95,11 +93,10 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
_TIF_NOTIFY_RESUME)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/freezer.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/setup.h> #include <asm/setup.h>
......
...@@ -120,10 +120,8 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG); ...@@ -120,10 +120,8 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore ss @ return to usr mode */ #define TIF_SINGLESTEP 4 /* restore ss @ return to usr mode */
#define TIF_IRET 5 /* return with iret */
#define TIF_RESTORE_SIGMASK 6 /* restore sig mask in do_signal() */ #define TIF_RESTORE_SIGMASK 6 /* restore sig mask in do_signal() */
/* true if poll_idle() is polling TIF_NEED_RESCHED */ /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_POLLING_NRFLAG 16
#define TIF_MEMDIE 17 /* OOM killer killed process */ #define TIF_MEMDIE 17 /* OOM killer killed process */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
...@@ -131,9 +129,6 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG); ...@@ -131,9 +129,6 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG);
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
/* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */ /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
#define _TIF_WORK_MASK (0x0000FFFF & ~_TIF_SYSCALL_TRACE) #define _TIF_WORK_MASK (0x0000FFFF & ~_TIF_SYSCALL_TRACE)
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/freezer.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/registers.h> #include <asm/registers.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
......
...@@ -106,7 +106,6 @@ struct thread_info { ...@@ -106,7 +106,6 @@ struct thread_info {
#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_NOTIFY_RESUME 6 /* resumption notification requested */ #define TIF_NOTIFY_RESUME 6 /* resumption notification requested */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17 /* is terminating due to OOM killer */ #define TIF_MEMDIE 17 /* is terminating due to OOM killer */
#define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */ #define TIF_MCA_INIT 18 /* this task is processing MCA or INIT */
#define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */ #define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
...@@ -119,7 +118,6 @@ struct thread_info { ...@@ -119,7 +118,6 @@ struct thread_info {
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MCA_INIT (1 << TIF_MCA_INIT) #define _TIF_MCA_INIT (1 << TIF_MCA_INIT)
#define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED) #define _TIF_DB_DISABLED (1 << TIF_DB_DISABLED)
#define _TIF_RESTORE_RSE (1 << TIF_RESTORE_RSE) #define _TIF_RESTORE_RSE (1 << TIF_RESTORE_RSE)
......
...@@ -437,14 +437,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) ...@@ -437,14 +437,6 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
long restart = in_syscall; long restart = in_syscall;
long errno = scr->pt.r8; long errno = scr->pt.r8;
/*
* In the ia64_leave_kernel code path, we want the common case to go fast, which
* is why we may in certain cases get here from kernel mode. Just return without
* doing anything if so.
*/
if (!user_mode(&scr->pt))
return;
/* /*
* This only loops in the rare cases of handle_signal() failing, in which case we * This only loops in the rare cases of handle_signal() failing, in which case we
* need to push through a forced SIGSEGV. * need to push through a forced SIGSEGV.
......
...@@ -119,25 +119,20 @@ static inline unsigned int get_thread_fault_code(void) ...@@ -119,25 +119,20 @@ static inline unsigned int get_thread_fault_code(void)
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
#define TIF_IRET 4 /* return with iret */
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_IRET (1<<TIF_IRET)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
/* /*
* Thread-synchronous status. * Thread-synchronous status.
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
...@@ -366,6 +365,4 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags) ...@@ -366,6 +365,4 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
clear_thread_flag(TIF_NOTIFY_RESUME); clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs); tracehook_notify_resume(regs);
} }
clear_thread_flag(TIF_IRET);
} }
...@@ -15,6 +15,7 @@ config M68K ...@@ -15,6 +15,7 @@ config M68K
select FPU if MMU select FPU if MMU
select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
select GENERIC_KERNEL_THREAD
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
bool bool
......
...@@ -100,6 +100,16 @@ struct thread_struct { ...@@ -100,6 +100,16 @@ struct thread_struct {
.fs = __KERNEL_DS, \ .fs = __KERNEL_DS, \
} }
/*
* ColdFire stack format sbould be 0x4 for an aligned usp (will always be
* true on thread creation). We need to set this explicitly.
*/
#ifdef CONFIG_COLDFIRE
#define setframeformat(_regs) do { (_regs)->format = 0x4; } while(0)
#else
#define setframeformat(_regs) do { } while (0)
#endif
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
/* /*
* Do necessary setup to start up a newly executed thread. * Do necessary setup to start up a newly executed thread.
...@@ -109,6 +119,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc, ...@@ -109,6 +119,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
{ {
regs->pc = pc; regs->pc = pc;
regs->sr &= ~0x2000; regs->sr &= ~0x2000;
setframeformat(regs);
wrusp(usp); wrusp(usp);
} }
...@@ -116,21 +127,11 @@ extern int handle_kernel_fault(struct pt_regs *regs); ...@@ -116,21 +127,11 @@ extern int handle_kernel_fault(struct pt_regs *regs);
#else #else
/*
* Coldfire stacks need to be re-aligned on trap exit, conventional
* 68k can handle this case cleanly.
*/
#ifdef CONFIG_COLDFIRE
#define reformat(_regs) do { (_regs)->format = 0x4; } while(0)
#else
#define reformat(_regs) do { } while (0)
#endif
#define start_thread(_regs, _pc, _usp) \ #define start_thread(_regs, _pc, _usp) \
do { \ do { \
(_regs)->pc = (_pc); \ (_regs)->pc = (_pc); \
((struct switch_stack *)(_regs))[-1].a6 = 0; \ ((struct switch_stack *)(_regs))[-1].a6 = 0; \
reformat(_regs); \ setframeformat(_regs); \
if (current->mm) \ if (current->mm) \
(_regs)->d5 = current->mm->start_data; \ (_regs)->d5 = current->mm->start_data; \
(_regs)->sr &= ~0x2000; \ (_regs)->sr &= ~0x2000; \
...@@ -153,8 +154,6 @@ static inline void release_thread(struct task_struct *dead_task) ...@@ -153,8 +154,6 @@ static inline void release_thread(struct task_struct *dead_task)
{ {
} }
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* /*
* Free current thread data structures etc.. * Free current thread data structures etc..
*/ */
......
...@@ -85,6 +85,8 @@ struct switch_stack { ...@@ -85,6 +85,8 @@ struct switch_stack {
#define user_mode(regs) (!((regs)->sr & PS_S)) #define user_mode(regs) (!((regs)->sr & PS_S))
#define instruction_pointer(regs) ((regs)->pc) #define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs) #define profile_pc(regs) instruction_pointer(regs)
#define current_pt_regs() \
(struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1
#define arch_has_single_step() (1) #define arch_has_single_step() (1)
......
...@@ -382,6 +382,8 @@ ...@@ -382,6 +382,8 @@
#define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_KERNEL_EXECVE
/* /*
* "Conditional" syscalls * "Conditional" syscalls
......
...@@ -111,6 +111,22 @@ ENTRY(ret_from_fork) ...@@ -111,6 +111,22 @@ ENTRY(ret_from_fork)
addql #4,%sp addql #4,%sp
jra ret_from_exception jra ret_from_exception
ENTRY(ret_from_kernel_thread)
| a3 contains the kernel thread payload, d7 - its argument
movel %d1,%sp@-
jsr schedule_tail
GET_CURRENT(%d0)
movel %d7,(%sp)
jsr %a3@
addql #4,%sp
movel %d0,(%sp)
jra sys_exit
ENTRY(ret_from_kernel_execve)
movel 4(%sp), %sp
GET_CURRENT(%d0)
jra ret_from_exception
#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
#ifdef TRAP_DBG_INTERRUPT #ifdef TRAP_DBG_INTERRUPT
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
asmlinkage void ret_from_fork(void); asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);
/* /*
...@@ -123,51 +124,6 @@ void show_regs(struct pt_regs * regs) ...@@ -123,51 +124,6 @@ void show_regs(struct pt_regs * regs)
printk("USP: %08lx\n", rdusp()); printk("USP: %08lx\n", rdusp());
} }
/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
int pid;
mm_segment_t fs;
fs = get_fs();
set_fs (KERNEL_DS);
{
register long retval __asm__ ("d0");
register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
retval = __NR_clone;
__asm__ __volatile__
("clrl %%d2\n\t"
"trap #0\n\t" /* Linux/m68k system call */
"tstl %0\n\t" /* child or parent */
"jne 1f\n\t" /* parent - jump */
#ifdef CONFIG_MMU
"lea %%sp@(%c7),%6\n\t" /* reload current */
"movel %6@,%6\n\t"
#endif
"movel %3,%%sp@-\n\t" /* push argument */
"jsr %4@\n\t" /* call fn */
"movel %0,%%d1\n\t" /* pass exit value */
"movel %2,%%d0\n\t" /* exit */
"trap #0\n"
"1:"
: "+d" (retval)
: "i" (__NR_clone), "i" (__NR_exit),
"r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
"i" (-THREAD_SIZE)
: "d2");
pid = retval;
}
set_fs (fs);
return pid;
}
EXPORT_SYMBOL(kernel_thread);
void flush_thread(void) void flush_thread(void)
{ {
current->thread.fs = __USER_DS; current->thread.fs = __USER_DS;
...@@ -219,30 +175,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs) ...@@ -219,30 +175,18 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
} }
int copy_thread(unsigned long clone_flags, unsigned long usp, int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, unsigned long arg,
struct task_struct * p, struct pt_regs * regs) struct task_struct * p, struct pt_regs * regs)
{ {
struct pt_regs * childregs; struct pt_regs * childregs;
struct switch_stack * childstack, *stack; struct switch_stack *childstack;
unsigned long *retp;
childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
*childregs = *regs;
childregs->d0 = 0;
retp = ((unsigned long *) regs);
stack = ((struct switch_stack *) retp) - 1;
childstack = ((struct switch_stack *) childregs) - 1; childstack = ((struct switch_stack *) childregs) - 1;
*childstack = *stack;
childstack->retpc = (unsigned long)ret_from_fork;
p->thread.usp = usp; p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack; p->thread.ksp = (unsigned long)childstack;
p->thread.esp0 = (unsigned long)childregs;
if (clone_flags & CLONE_SETTLS)
task_thread_info(p)->tp_value = regs->d5;
/* /*
* Must save the current SFC/DFC value, NOT the value when * Must save the current SFC/DFC value, NOT the value when
...@@ -250,6 +194,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -250,6 +194,26 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
*/ */
p->thread.fs = get_fs().seg; p->thread.fs = get_fs().seg;
if (unlikely(!regs)) {
/* kernel thread */
memset(childstack, 0,
sizeof(struct switch_stack) + sizeof(struct pt_regs));
childregs->sr = PS_S;
childstack->a3 = usp; /* function */
childstack->d7 = arg;
childstack->retpc = (unsigned long)ret_from_kernel_thread;
p->thread.usp = 0;
return 0;
}
*childregs = *regs;
childregs->d0 = 0;
*childstack = ((struct switch_stack *) regs)[-1];
childstack->retpc = (unsigned long)ret_from_fork;
if (clone_flags & CLONE_SETTLS)
task_thread_info(p)->tp_value = regs->d5;
#ifdef CONFIG_FPU #ifdef CONFIG_FPU
if (!FPU_IS_EMU) { if (!FPU_IS_EMU) {
/* Copy the current fpu state */ /* Copy the current fpu state */
...@@ -337,26 +301,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) ...@@ -337,26 +301,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(dump_fpu);
#endif /* CONFIG_FPU */ #endif /* CONFIG_FPU */
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
int error;
char * filename;
struct pt_regs *regs = (struct pt_regs *) &name;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
error = do_execve(filename, argv, envp, regs);
putname(filename);
return error;
}
unsigned long get_wchan(struct task_struct *p) unsigned long get_wchan(struct task_struct *p)
{ {
unsigned long fp, pc; unsigned long fp, pc;
......
...@@ -549,23 +549,6 @@ asmlinkage int sys_getpagesize(void) ...@@ -549,23 +549,6 @@ asmlinkage int sys_getpagesize(void)
return PAGE_SIZE; return PAGE_SIZE;
} }
/*
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long __res asm ("%d0") = __NR_execve;
register long __a asm ("%d1") = (long)(filename);
register long __b asm ("%d2") = (long)(argv);
register long __c asm ("%d3") = (long)(envp);
asm volatile ("trap #0" : "+d" (__res)
: "d" (__a), "d" (__b), "d" (__c));
return __res;
}
asmlinkage unsigned long sys_get_thread_area(void) asmlinkage unsigned long sys_get_thread_area(void)
{ {
return current_thread_info()->tp_value; return current_thread_info()->tp_value;
......
...@@ -121,7 +121,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -121,7 +121,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
/* restore singlestep on return to user mode */ /* restore singlestep on return to user mode */
#define TIF_SINGLESTEP 4 #define TIF_SINGLESTEP 4
#define TIF_IRET 5 /* return with iret */
#define TIF_MEMDIE 6 /* is terminating due to OOM killer */ #define TIF_MEMDIE 6 /* is terminating due to OOM killer */
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
#define TIF_SECCOMP 10 /* secure computing */ #define TIF_SECCOMP 10 /* secure computing */
...@@ -134,7 +133,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -134,7 +133,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_IRET (1 << TIF_IRET)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_SECCOMP (1 << TIF_SECCOMP)
...@@ -184,6 +182,7 @@ static inline bool test_and_clear_restore_sigmask(void) ...@@ -184,6 +182,7 @@ static inline bool test_and_clear_restore_sigmask(void)
ti->status &= ~TS_RESTORE_SIGMASK; ti->status &= ~TS_RESTORE_SIGMASK;
return true; return true;
} }
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif #endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -254,10 +254,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -254,10 +254,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
set_fs(USER_DS); set_fs(USER_DS);
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
#ifdef DEBUG_SIG #ifdef DEBUG_SIG
printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n", printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
current->comm, current->pid, frame, regs->pc); current->comm, current->pid, frame, regs->pc);
...@@ -315,7 +311,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, ...@@ -315,7 +311,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
if (ret) if (ret)
return; return;
signal_delivered(sig, info, ka, regs, 0); signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
} }
/* /*
......
...@@ -103,7 +103,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); ...@@ -103,7 +103,6 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FIXADE 20 /* Fix address errors in software */ #define TIF_FIXADE 20 /* Fix address errors in software */
#define TIF_LOGADE 21 /* Log address errors to syslog */ #define TIF_LOGADE 21 /* Log address errors to syslog */
...@@ -125,9 +124,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); ...@@ -125,9 +124,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_FIXADE (1<<TIF_FIXADE) #define _TIF_FIXADE (1<<TIF_FIXADE)
#define _TIF_LOGADE (1<<TIF_LOGADE) #define _TIF_LOGADE (1<<TIF_LOGADE)
#define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS) #define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS)
......
...@@ -8,6 +8,7 @@ config MN10300 ...@@ -8,6 +8,7 @@ config MN10300
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_KERNEL_THREAD
config AM33_2 config AM33_2
def_bool n def_bool n
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
############################################################################### ###############################################################################
.macro RESTORE_ALL .macro RESTORE_ALL
# peel back the stack to the calling frame # peel back the stack to the calling frame
# - this permits execve() to discard extra frames due to kernel syscalls # - we need that when returning from interrupts to kernel mode
GET_THREAD_INFO a0 GET_THREAD_INFO a0
mov (TI_frame,a0),fp mov (TI_frame,a0),fp
mov fp,sp mov fp,sp
......
...@@ -119,31 +119,19 @@ struct thread_struct { ...@@ -119,31 +119,19 @@ struct thread_struct {
/* /*
* do necessary setup to start up a newly executed thread * do necessary setup to start up a newly executed thread
* - need to discard the frame stacked by the kernel thread invoking the execve
* syscall (see RESTORE_ALL macro)
*/ */
static inline void start_thread(struct pt_regs *regs, static inline void start_thread(struct pt_regs *regs,
unsigned long new_pc, unsigned long new_sp) unsigned long new_pc, unsigned long new_sp)
{ {
struct thread_info *ti = current_thread_info(); regs->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
struct pt_regs *frame0; regs->pc = new_pc;
regs->sp = new_sp;
frame0 = thread_info_to_uregs(ti);
frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
frame0->pc = new_pc;
frame0->sp = new_sp;
ti->frame = frame0;
} }
/* Free all resources held by a thread. */ /* Free all resources held by a thread. */
extern void release_thread(struct task_struct *); extern void release_thread(struct task_struct *);
/*
* create a kernel thread without removing it from tasklists
*/
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
/* /*
* Return saved PC of a blocked thread. * Return saved PC of a blocked thread.
*/ */
......
...@@ -86,6 +86,7 @@ struct pt_regs { ...@@ -86,6 +86,7 @@ struct pt_regs {
#define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL) #define user_mode(regs) (((regs)->epsw & EPSW_nSL) == EPSW_nSL)
#define instruction_pointer(regs) ((regs)->pc) #define instruction_pointer(regs) ((regs)->pc)
#define user_stack_pointer(regs) ((regs)->sp) #define user_stack_pointer(regs) ((regs)->sp)
#define current_pt_regs() current_frame()
#define arch_has_single_step() (1) #define arch_has_single_step() (1)
......
...@@ -160,12 +160,13 @@ void arch_release_thread_info(struct thread_info *ti); ...@@ -160,12 +160,13 @@ void arch_release_thread_info(struct thread_info *ti);
#define _TIF_SIGPENDING +(1 << TIF_SIGPENDING) #define _TIF_SIGPENDING +(1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED +(1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED +(1 << TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP +(1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP +(1 << TIF_SINGLESTEP)
#define _TIF_RESTORE_SIGMASK +(1 << TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG +(1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG +(1 << TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
...@@ -382,6 +382,8 @@ ...@@ -382,6 +382,8 @@
#define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION #define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_KERNEL_EXECVE
/* /*
* "Conditional" syscalls * "Conditional" syscalls
......
...@@ -7,8 +7,8 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o ...@@ -7,8 +7,8 @@ fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o
fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
obj-y := process.o signal.o entry.o traps.o irq.o \ obj-y := process.o signal.o entry.o traps.o irq.o \
ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \ ptrace.o setup.o time.o sys_mn10300.o io.o \
switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \ switch_to.o mn10300_ksyms.o $(fpu-obj-y) \
csrc-mn10300.o cevt-mn10300.o csrc-mn10300.o cevt-mn10300.o
obj-$(CONFIG_SMP) += smp.o smp-low.o obj-$(CONFIG_SMP) += smp.o smp-low.o
......
...@@ -55,6 +55,20 @@ ENTRY(ret_from_fork) ...@@ -55,6 +55,20 @@ ENTRY(ret_from_fork)
mov d0,(REG_D0,fp) mov d0,(REG_D0,fp)
jmp syscall_exit jmp syscall_exit
ENTRY(ret_from_kernel_thread)
call schedule_tail[],0
mov (REG_D0,fp),d0
mov (REG_A0,fp),a0
calls (a0)
jmp sys_exit
ENTRY(ret_from_kernel_execve)
add -12,d0 /* pt_regs -> frame */
mov d0,sp
GET_THREAD_INFO a2
clr d0
jmp syscall_exit
############################################################################### ###############################################################################
# #
# system call handler # system call handler
...@@ -94,6 +108,10 @@ restore_all: ...@@ -94,6 +108,10 @@ restore_all:
############################################################################### ###############################################################################
ALIGN ALIGN
syscall_exit_work: syscall_exit_work:
mov (REG_EPSW,fp),d0
and EPSW_nSL,d0
beq resume_kernel # returning to supervisor mode
btst _TIF_SYSCALL_TRACE,d2 btst _TIF_SYSCALL_TRACE,d2
beq work_pending beq work_pending
LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call
......
...@@ -14,15 +14,11 @@ ...@@ -14,15 +14,11 @@
struct clocksource; struct clocksource;
struct clock_event_device; struct clock_event_device;
/*
* kthread.S
*/
extern int kernel_thread_helper(int);
/* /*
* entry.S * entry.S
*/ */
extern void ret_from_fork(struct task_struct *) __attribute__((noreturn)); extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn));
/* /*
* smp-low.S * smp-low.S
......
/* MN10300 In-kernel program execution
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#include <linux/linkage.h>
#include <asm/unistd.h>
###############################################################################
#
# Do a system call from kernel instead of calling sys_execve so we end up with
# proper pt_regs.
#
# int kernel_execve(const char *filename, char *const argv[],
# char *const envp[])
#
# On entry: D0/D1/8(SP): arguments to function
# On return: D0: syscall return.
#
###############################################################################
.globl kernel_execve
.type kernel_execve,@function
kernel_execve:
mov a3,a1
mov d0,a0
mov (12,sp),a3
mov +__NR_execve,d0
syscall 0
mov a1,a3
rets
.size kernel_execve,.-kernel_execve
/* MN10300 Kernel thread trampoline function
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by Mark Salter (msalter@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
.text
###############################################################################
#
# kernel_thread_helper - trampoline for kernel_thread()
#
# On entry:
# A2 = address of function to call
# D2 = function argument
#
###############################################################################
.globl kernel_thread_helper
.type kernel_thread_helper,@function
kernel_thread_helper:
mov do_exit,d1
mov d1,(sp)
mov d1,mdr
mov d2,d0
jmp (a2)
.size kernel_thread_helper,.-kernel_thread_helper
...@@ -164,27 +164,6 @@ void show_regs(struct pt_regs *regs) ...@@ -164,27 +164,6 @@ void show_regs(struct pt_regs *regs)
{ {
} }
/*
* create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));
regs.a2 = (unsigned long) fn;
regs.d2 = (unsigned long) arg;
regs.pc = (unsigned long) kernel_thread_helper;
local_save_flags(regs.epsw);
regs.epsw |= EPSW_IE | EPSW_IM_7;
/* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);
/* /*
* free current thread data structures etc.. * free current thread data structures etc..
*/ */
...@@ -230,50 +209,42 @@ int copy_thread(unsigned long clone_flags, ...@@ -230,50 +209,42 @@ int copy_thread(unsigned long clone_flags,
struct task_struct *p, struct pt_regs *kregs) struct task_struct *p, struct pt_regs *kregs)
{ {
struct thread_info *ti = task_thread_info(p); struct thread_info *ti = task_thread_info(p);
struct pt_regs *c_uregs, *c_kregs, *uregs; struct pt_regs *c_regs;
unsigned long c_ksp; unsigned long c_ksp;
uregs = current->thread.uregs;
c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE; c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
/* allocate the userspace exception frame and set it up */ /* allocate the userspace exception frame and set it up */
c_ksp -= sizeof(struct pt_regs); c_ksp -= sizeof(struct pt_regs);
c_uregs = (struct pt_regs *) c_ksp; c_regs = (struct pt_regs *) c_ksp;
c_ksp -= 12; /* allocate function call ABI slack */
p->thread.uregs = c_uregs; /* set up things up so the scheduler can start the new task */
*c_uregs = *uregs; p->thread.uregs = c_regs;
c_uregs->sp = c_usp; ti->frame = c_regs;
c_uregs->epsw &= ~EPSW_FE; /* my FPU */ p->thread.a3 = (unsigned long) c_regs;
p->thread.sp = c_ksp;
p->thread.wchan = p->thread.pc;
p->thread.usp = c_usp;
c_ksp -= 12; /* allocate function call ABI slack */ if (unlikely(!kregs)) {
memset(c_regs, 0, sizeof(struct pt_regs));
c_regs->a0 = c_usp; /* function */
c_regs->d0 = ustk_size; /* argument */
local_save_flags(c_regs->epsw);
c_regs->epsw |= EPSW_IE | EPSW_IM_7;
p->thread.pc = (unsigned long) ret_from_kernel_thread;
return 0;
}
*c_regs = *kregs;
c_regs->sp = c_usp;
c_regs->epsw &= ~EPSW_FE; /* my FPU */
/* the new TLS pointer is passed in as arg #5 to sys_clone() */ /* the new TLS pointer is passed in as arg #5 to sys_clone() */
if (clone_flags & CLONE_SETTLS) if (clone_flags & CLONE_SETTLS)
c_uregs->e2 = current_frame()->d3; c_regs->e2 = current_frame()->d3;
/* set up the return kernel frame if called from kernel_thread() */
c_kregs = c_uregs;
if (kregs != uregs) {
c_ksp -= sizeof(struct pt_regs);
c_kregs = (struct pt_regs *) c_ksp;
*c_kregs = *kregs;
c_kregs->sp = c_usp;
c_kregs->next = c_uregs;
#ifdef CONFIG_MN10300_CURRENT_IN_E2
c_kregs->e2 = (unsigned long) p; /* current */
#endif
c_ksp -= 12; /* allocate function call ABI slack */
}
/* set up things up so the scheduler can start the new task */
ti->frame = c_kregs;
p->thread.a3 = (unsigned long) c_kregs;
p->thread.sp = c_ksp;
p->thread.pc = (unsigned long) ret_from_fork; p->thread.pc = (unsigned long) ret_from_fork;
p->thread.wchan = (unsigned long) ret_from_fork;
p->thread.usp = c_usp;
return 0; return 0;
} }
...@@ -302,22 +273,6 @@ asmlinkage long sys_vfork(void) ...@@ -302,22 +273,6 @@ asmlinkage long sys_vfork(void)
current_frame(), 0, NULL, NULL); current_frame(), 0, NULL, NULL);
} }
asmlinkage long sys_execve(const char __user *name,
const char __user *const __user *argv,
const char __user *const __user *envp)
{
char *filename;
int error;
filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
error = do_execve(filename, argv, envp, current_frame());
putname(filename);
return error;
}
unsigned long get_wchan(struct task_struct *p) unsigned long get_wchan(struct task_struct *p)
{ {
return p->thread.wchan; return p->thread.wchan;
......
...@@ -317,10 +317,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, ...@@ -317,10 +317,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
regs->d0 = sig; regs->d0 = sig;
regs->d1 = (unsigned long) &frame->sc; regs->d1 = (unsigned long) &frame->sc;
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
#if DEBUG_SIG #if DEBUG_SIG
printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, regs->pc, sig, current->comm, current->pid, frame, regs->pc,
...@@ -398,10 +394,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -398,10 +394,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->d0 = sig; regs->d0 = sig;
regs->d1 = (long) &frame->info; regs->d1 = (long) &frame->info;
/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
#if DEBUG_SIG #if DEBUG_SIG
printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n", printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
sig, current->comm, current->pid, frame, regs->pc, sig, current->comm, current->pid, frame, regs->pc,
...@@ -475,11 +467,6 @@ static void do_signal(struct pt_regs *regs) ...@@ -475,11 +467,6 @@ static void do_signal(struct pt_regs *regs)
siginfo_t info; siginfo_t info;
int signr; int signr;
/* we want the common case to go fast, which is why we may in certain
* cases get here from kernel mode */
if (!user_mode(regs))
return;
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) { if (signr > 0) {
if (handle_signal(signr, &info, &ka, regs) == 0) { if (handle_signal(signr, &info, &ka, regs) == 0) {
......
...@@ -121,7 +121,6 @@ register struct thread_info *current_thread_info_reg asm("r10"); ...@@ -121,7 +121,6 @@ register struct thread_info *current_thread_info_reg asm("r10");
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
...@@ -129,6 +128,8 @@ register struct thread_info *current_thread_info_reg asm("r10"); ...@@ -129,6 +128,8 @@ register struct thread_info *current_thread_info_reg asm("r10");
/* For OpenRISC, this is anything in the LSW other than syscall trace */ /* For OpenRISC, this is anything in the LSW other than syscall trace */
#define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP)) #define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
...@@ -71,7 +71,7 @@ ENTRY(hpux_gateway_page) ...@@ -71,7 +71,7 @@ ENTRY(hpux_gateway_page)
STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
STREG %r27, TASK_PT_GR27(%r1) /* user dp */ STREG %r27, TASK_PT_GR27(%r1) /* user dp */
STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */
STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */ STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */
STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
......
...@@ -68,13 +68,16 @@ struct thread_info { ...@@ -68,13 +68,16 @@ struct thread_info {
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_32BIT (1 << TIF_32BIT)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP) #define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
_TIF_NEED_RESCHED) _TIF_NEED_RESCHED)
#define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
_TIF_BLOCKSTEP)
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -113,6 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) ...@@ -113,6 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
(usp - sigframe_size); (usp - sigframe_size);
DBG(2,"sys_rt_sigreturn: frame is %p\n", frame); DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
regs->orig_r28 = 1; /* no restarts for sigreturn */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
compat_frame = (struct compat_rt_sigframe __user *)frame; compat_frame = (struct compat_rt_sigframe __user *)frame;
...@@ -437,7 +439,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -437,7 +439,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* OK, we're invoking a handler. * OK, we're invoking a handler.
*/ */
static long static void
handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
struct pt_regs *regs, int in_syscall) struct pt_regs *regs, int in_syscall)
{ {
...@@ -447,7 +449,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, ...@@ -447,7 +449,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
/* Set up the stack frame */ /* Set up the stack frame */
if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
return 0; return;
signal_delivered(sig, info, ka, regs, signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP) || test_thread_flag(TIF_SINGLESTEP) ||
...@@ -455,13 +457,14 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, ...@@ -455,13 +457,14 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n", DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
regs->gr[28]); regs->gr[28]);
return 1;
} }
static inline void static inline void
syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{ {
if (regs->orig_r28)
return;
regs->orig_r28 = 1; /* no more restarts */
/* Check the return code */ /* Check the return code */
switch (regs->gr[28]) { switch (regs->gr[28]) {
case -ERESTART_RESTARTBLOCK: case -ERESTART_RESTARTBLOCK:
...@@ -482,8 +485,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) ...@@ -482,8 +485,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
* we have to do is fiddle the return pointer. * we have to do is fiddle the return pointer.
*/ */
regs->gr[31] -= 8; /* delayed branching */ regs->gr[31] -= 8; /* delayed branching */
/* Preserve original r28. */
regs->gr[28] = regs->orig_r28;
break; break;
} }
} }
...@@ -491,6 +492,9 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) ...@@ -491,6 +492,9 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
static inline void static inline void
insert_restart_trampoline(struct pt_regs *regs) insert_restart_trampoline(struct pt_regs *regs)
{ {
if (regs->orig_r28)
return;
regs->orig_r28 = 1; /* no more restarts */
switch(regs->gr[28]) { switch(regs->gr[28]) {
case -ERESTART_RESTARTBLOCK: { case -ERESTART_RESTARTBLOCK: {
/* Restart the system call - no handlers present */ /* Restart the system call - no handlers present */
...@@ -525,9 +529,6 @@ insert_restart_trampoline(struct pt_regs *regs) ...@@ -525,9 +529,6 @@ insert_restart_trampoline(struct pt_regs *regs)
flush_user_icache_range(regs->gr[30], regs->gr[30] + 4); flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
regs->gr[31] = regs->gr[30] + 8; regs->gr[31] = regs->gr[30] + 8;
/* Preserve original r28. */
regs->gr[28] = regs->orig_r28;
return; return;
} }
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
...@@ -539,9 +540,6 @@ insert_restart_trampoline(struct pt_regs *regs) ...@@ -539,9 +540,6 @@ insert_restart_trampoline(struct pt_regs *regs)
* slot of the branch external instruction. * slot of the branch external instruction.
*/ */
regs->gr[31] -= 8; regs->gr[31] -= 8;
/* Preserve original r28. */
regs->gr[28] = regs->orig_r28;
return; return;
} }
default: default:
...@@ -570,30 +568,17 @@ do_signal(struct pt_regs *regs, long in_syscall) ...@@ -570,30 +568,17 @@ do_signal(struct pt_regs *regs, long in_syscall)
DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n", DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
regs, regs->sr[7], in_syscall); regs, regs->sr[7], in_syscall);
/* Everyone else checks to see if they are in kernel mode at
this point and exits if that's the case. I'm not sure why
we would be called in that case, but for some reason we
are. */
/* May need to force signal if handle_signal failed to deliver */
while (1) {
signr = get_signal_to_deliver(&info, &ka, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
if (signr <= 0) if (signr > 0) {
break;
/* Restart a system call if necessary. */ /* Restart a system call if necessary. */
if (in_syscall) if (in_syscall)
syscall_restart(regs, &ka); syscall_restart(regs, &ka);
/* Whee! Actually deliver the signal. If the handle_signal(signr, &info, &ka, regs, in_syscall);
delivery failed, we need to continue to iterate in
this loop so we can deliver the SIGSEGV... */
if (handle_signal(signr, &info, &ka, regs, in_syscall))
return; return;
} }
/* end of while(1) looping forever if we can't force a signal */
/* Did we come from a system call? */ /* Did we come from a system call? */
if (in_syscall) if (in_syscall)
......
...@@ -156,7 +156,7 @@ linux_gateway_entry: ...@@ -156,7 +156,7 @@ linux_gateway_entry:
STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */ STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
STREG %r27, TASK_PT_GR27(%r1) /* user dp */ STREG %r27, TASK_PT_GR27(%r1) /* user dp */
STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */ STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */ STREG %r0, TASK_PT_ORIG_R28(%r1) /* don't prohibit restarts */
STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */ STREG %r29, TASK_PT_GR29(%r1) /* return value 1 */
STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */ STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
...@@ -180,9 +180,10 @@ linux_gateway_entry: ...@@ -180,9 +180,10 @@ linux_gateway_entry:
/* Are we being ptraced? */ /* Are we being ptraced? */
mfctl %cr30, %r1 mfctl %cr30, %r1
LDREG TI_TASK(%r1),%r1 LDREG TI_FLAGS(%r1),%r1
ldw TASK_PTRACE(%r1), %r1 ldi _TIF_SYSCALL_TRACE_MASK, %r19
bb,<,n %r1,31,.Ltracesys and,COND(=) %r1, %r19, %r0
b,n .Ltracesys
/* Note! We cannot use the syscall table that is mapped /* Note! We cannot use the syscall table that is mapped
nearby since the gateway page is mapped execute-only. */ nearby since the gateway page is mapped execute-only. */
......
...@@ -141,6 +141,7 @@ config PPC ...@@ -141,6 +141,7 @@ config PPC
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER select GENERIC_STRNLEN_USER
select GENERIC_KERNEL_THREAD
config EARLY_PRINTK config EARLY_PRINTK
bool bool
......
...@@ -74,9 +74,6 @@ struct task_struct; ...@@ -74,9 +74,6 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *); void release_thread(struct task_struct *);
/* Create a new kernel thread. */
extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
/* Lazy FPU handling on uni-processor */ /* Lazy FPU handling on uni-processor */
extern struct task_struct *last_task_used_math; extern struct task_struct *last_task_used_math;
extern struct task_struct *last_task_used_altivec; extern struct task_struct *last_task_used_altivec;
......
...@@ -125,6 +125,8 @@ extern unsigned long ptrace_get_reg(struct task_struct *task, int regno); ...@@ -125,6 +125,8 @@ extern unsigned long ptrace_get_reg(struct task_struct *task, int regno);
extern int ptrace_put_reg(struct task_struct *task, int regno, extern int ptrace_put_reg(struct task_struct *task, int regno,
unsigned long data); unsigned long data);
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
/* /*
* We use the least-significant bit of the trap field to indicate * We use the least-significant bit of the trap field to indicate
* whether we have saved the full set of registers, or only a * whether we have saved the full set of registers, or only a
......
...@@ -17,9 +17,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, ...@@ -17,9 +17,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags, unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff); unsigned long fd, unsigned long pgoff);
asmlinkage int sys_execve(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs *regs);
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp,
int __user *parent_tidp, void __user *child_threadptr, int __user *parent_tidp, void __user *child_threadptr,
int __user *child_tidp, int p6, struct pt_regs *regs); int __user *child_tidp, int p6, struct pt_regs *regs);
......
...@@ -182,6 +182,8 @@ static inline bool test_thread_local_flags(unsigned int flags) ...@@ -182,6 +182,8 @@ static inline bool test_thread_local_flags(unsigned int flags)
#define is_32bit_task() (1) #define is_32bit_task() (1)
#endif #endif
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -421,6 +421,8 @@ ...@@ -421,6 +421,8 @@
#define __ARCH_WANT_SYS_NEWFSTATAT #define __ARCH_WANT_SYS_NEWFSTATAT
#define __ARCH_WANT_COMPAT_SYS_SENDFILE #define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif #endif
#define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_KERNEL_EXECVE
/* /*
* "Conditional" syscalls * "Conditional" syscalls
......
...@@ -435,6 +435,22 @@ ret_from_fork: ...@@ -435,6 +435,22 @@ ret_from_fork:
li r3,0 li r3,0
b ret_from_syscall b ret_from_syscall
.globl ret_from_kernel_thread
ret_from_kernel_thread:
REST_NVGPRS(r1)
bl schedule_tail
mtlr r14
mr r3,r15
PPC440EP_ERR42
blrl
li r3,0
b do_exit # no return
.globl __ret_from_kernel_execve
__ret_from_kernel_execve:
addi r1,r3,-STACK_FRAME_OVERHEAD
b ret_from_syscall
/* Traced system call support */ /* Traced system call support */
syscall_dotrace: syscall_dotrace:
SAVE_NVGPRS(r1) SAVE_NVGPRS(r1)
......
...@@ -370,6 +370,22 @@ _GLOBAL(ret_from_fork) ...@@ -370,6 +370,22 @@ _GLOBAL(ret_from_fork)
li r3,0 li r3,0
b syscall_exit b syscall_exit
_GLOBAL(ret_from_kernel_thread)
bl .schedule_tail
REST_NVGPRS(r1)
REST_GPR(2,r1)
mtlr r14
mr r3,r15
blrl
li r3,0
b .do_exit # no return
_GLOBAL(__ret_from_kernel_execve)
addi r1,r3,-STACK_FRAME_OVERHEAD
li r10,1
std r10,SOFTE(r1)
b syscall_exit
.section ".toc","aw" .section ".toc","aw"
DSCR_DEFAULT: DSCR_DEFAULT:
.tc dscr_default[TC],dscr_default .tc dscr_default[TC],dscr_default
......
...@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset) ...@@ -54,13 +54,6 @@ _GLOBAL(add_reloc_offset)
.align 3 .align 3
2: PPC_LONG 1b 2: PPC_LONG 1b
_GLOBAL(kernel_execve)
li r0,__NR_execve
sc
bnslr
neg r3,r3
blr
_GLOBAL(setjmp) _GLOBAL(setjmp)
mflr r0 mflr r0
PPC_STL r0,0(r3) PPC_STL r0,0(r3)
......
...@@ -663,39 +663,6 @@ _GLOBAL(abs) ...@@ -663,39 +663,6 @@ _GLOBAL(abs)
sub r3,r3,r4 sub r3,r3,r4
blr blr
/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
_GLOBAL(kernel_thread)
stwu r1,-16(r1)
stw r30,8(r1)
stw r31,12(r1)
mr r30,r3 /* function */
mr r31,r4 /* argument */
ori r3,r5,CLONE_VM /* flags */
oris r3,r3,CLONE_UNTRACED>>16
li r4,0 /* new sp (unused) */
li r0,__NR_clone
sc
bns+ 1f /* did system call indicate error? */
neg r3,r3 /* if so, make return code negative */
1: cmpwi 0,r3,0 /* parent or child? */
bne 2f /* return if parent */
li r0,0 /* make top-level stack frame */
stwu r0,-16(r1)
mtlr r30 /* fn addr in lr */
mr r3,r31 /* load arg and call fn */
PPC440EP_ERR42
blrl
li r0,__NR_exit /* exit if function returns */
li r3,0
sc
2: lwz r30,8(r1)
lwz r31,12(r1)
addi r1,r1,16
blr
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
_GLOBAL(start_secondary_resume) _GLOBAL(start_secondary_resume)
/* Reset stack */ /* Reset stack */
......
...@@ -406,40 +406,6 @@ _GLOBAL(scom970_write) ...@@ -406,40 +406,6 @@ _GLOBAL(scom970_write)
#endif /* CONFIG_CPU_FREQ_PMAC64 || CONFIG_CPU_FREQ_MAPLE */ #endif /* CONFIG_CPU_FREQ_PMAC64 || CONFIG_CPU_FREQ_MAPLE */
/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
_GLOBAL(kernel_thread)
std r29,-24(r1)
std r30,-16(r1)
stdu r1,-STACK_FRAME_OVERHEAD(r1)
mr r29,r3
mr r30,r4
ori r3,r5,CLONE_VM /* flags */
oris r3,r3,(CLONE_UNTRACED>>16)
li r4,0 /* new sp (unused) */
li r0,__NR_clone
sc
bns+ 1f /* did system call indicate error? */
neg r3,r3 /* if so, make return code negative */
1: cmpdi 0,r3,0 /* parent or child? */
bne 2f /* return if parent */
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
ld r2,8(r29)
ld r29,0(r29)
mtlr r29 /* fn addr in lr */
mr r3,r30 /* load arg and call fn */
blrl
li r0,__NR_exit /* exit after child exits */
li r3,0
sc
2: addi r1,r1,STACK_FRAME_OVERHEAD
ld r29,-24(r1)
ld r30,-16(r1)
blr
/* /*
* disable_kernel_fp() * disable_kernel_fp()
* Disable the FPU. * Disable the FPU.
......
...@@ -94,7 +94,6 @@ EXPORT_SYMBOL(pci_dram_offset); ...@@ -94,7 +94,6 @@ EXPORT_SYMBOL(pci_dram_offset);
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(giveup_fpu);
#ifdef CONFIG_ALTIVEC #ifdef CONFIG_ALTIVEC
......
...@@ -733,30 +733,39 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) ...@@ -733,30 +733,39 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */ extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
int copy_thread(unsigned long clone_flags, unsigned long usp, int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, struct task_struct *p, unsigned long arg, struct task_struct *p,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct pt_regs *childregs, *kregs; struct pt_regs *childregs, *kregs;
extern void ret_from_fork(void); extern void ret_from_fork(void);
extern void ret_from_kernel_thread(void);
void (*f)(void);
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE; unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
CHECK_FULL_REGS(regs);
/* Copy registers */ /* Copy registers */
sp -= sizeof(struct pt_regs); sp -= sizeof(struct pt_regs);
childregs = (struct pt_regs *) sp; childregs = (struct pt_regs *) sp;
*childregs = *regs; if (!regs) {
if ((childregs->msr & MSR_PR) == 0) {
/* for kernel thread, set `current' and stackptr in new task */ /* for kernel thread, set `current' and stackptr in new task */
memset(childregs, 0, sizeof(struct pt_regs));
childregs->gpr[1] = sp + sizeof(struct pt_regs); childregs->gpr[1] = sp + sizeof(struct pt_regs);
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC64
childregs->gpr[2] = (unsigned long) p; childregs->gpr[14] = *(unsigned long *)usp;
#else childregs->gpr[2] = ((unsigned long *)usp)[1],
clear_tsk_thread_flag(p, TIF_32BIT); clear_tsk_thread_flag(p, TIF_32BIT);
#else
childregs->gpr[14] = usp; /* function */
childregs->gpr[2] = (unsigned long) p;
#endif #endif
childregs->gpr[15] = arg;
p->thread.regs = NULL; /* no user register state */ p->thread.regs = NULL; /* no user register state */
f = ret_from_kernel_thread;
} else { } else {
CHECK_FULL_REGS(regs);
*childregs = *regs;
childregs->gpr[1] = usp; childregs->gpr[1] = usp;
p->thread.regs = childregs; p->thread.regs = childregs;
childregs->gpr[3] = 0; /* Result from fork() */
if (clone_flags & CLONE_SETTLS) { if (clone_flags & CLONE_SETTLS) {
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
if (!is_32bit_task()) if (!is_32bit_task())
...@@ -765,8 +774,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -765,8 +774,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
#endif #endif
childregs->gpr[2] = childregs->gpr[6]; childregs->gpr[2] = childregs->gpr[6];
} }
f = ret_from_fork;
} }
childregs->gpr[3] = 0; /* Result from fork() */
sp -= STACK_FRAME_OVERHEAD; sp -= STACK_FRAME_OVERHEAD;
/* /*
...@@ -805,7 +815,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -805,7 +815,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.dscr = current->thread.dscr; p->thread.dscr = current->thread.dscr;
} }
#endif #endif
/* /*
* The PPC64 ABI makes use of a TOC to contain function * The PPC64 ABI makes use of a TOC to contain function
* pointers. The function (ret_from_except) is actually a pointer * pointers. The function (ret_from_except) is actually a pointer
...@@ -813,11 +822,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -813,11 +822,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
* function. * function.
*/ */
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
kregs->nip = *((unsigned long *)ret_from_fork); kregs->nip = *((unsigned long *)f);
#else #else
kregs->nip = (unsigned long)ret_from_fork; kregs->nip = (unsigned long)f;
#endif #endif
return 0; return 0;
} }
...@@ -1055,26 +1063,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3, ...@@ -1055,26 +1063,13 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
regs, 0, NULL, NULL); regs, 0, NULL, NULL);
} }
int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, void __ret_from_kernel_execve(struct pt_regs *normal)
unsigned long a3, unsigned long a4, unsigned long a5, __noreturn;
struct pt_regs *regs)
void ret_from_kernel_execve(struct pt_regs *normal)
{ {
int error; set_thread_flag(TIF_RESTOREALL);
char *filename; __ret_from_kernel_execve(normal);
filename = getname((const char __user *) a0);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
flush_spe_to_thread(current);
error = do_execve(filename,
(const char __user *const __user *) a1,
(const char __user *const __user *) a2, regs);
putname(filename);
out:
return error;
} }
static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/freezer.h>
#endif #endif
#include <asm/uaccess.h> #include <asm/uaccess.h>
......
...@@ -156,28 +156,6 @@ asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd, ...@@ -156,28 +156,6 @@ asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
(off_t __user *)offset, count); (off_t __user *)offset, count);
} }
long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs *regs)
{
int error;
char * filename;
filename = getname((char __user *) a0);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
flush_fp_to_thread(current);
flush_altivec_to_thread(current);
error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
putname(filename);
out:
return error;
}
/* Note: it is necessary to treat option as an unsigned int, /* Note: it is necessary to treat option as an unsigned int,
* with the corresponding cast to a signed int to insure that the * with the corresponding cast to a signed int to insure that the
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
......
...@@ -91,8 +91,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -91,8 +91,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */
#define TIF_SECCOMP 10 /* secure computing */ #define TIF_SECCOMP 10 /* secure computing */
#define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_31BIT 17 /* 32bit process */ #define TIF_31BIT 17 /* 32bit process */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */
...@@ -100,7 +98,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -100,7 +98,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL (1<<TIF_SYSCALL) #define _TIF_SYSCALL (1<<TIF_SYSCALL)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_PER_TRAP (1<<TIF_PER_TRAP) #define _TIF_PER_TRAP (1<<TIF_PER_TRAP)
...@@ -109,7 +106,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -109,7 +106,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SECCOMP (1<<TIF_SECCOMP)
#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT) #define _TIF_31BIT (1<<TIF_31BIT)
#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
......
...@@ -86,16 +86,12 @@ register struct thread_info *__current_thread_info __asm__("r28"); ...@@ -86,16 +86,12 @@ register struct thread_info *__current_thread_info __asm__("r28");
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK (0x0000ffff) #define _TIF_WORK_MASK (0x0000ffff)
......
...@@ -174,6 +174,7 @@ score_rt_sigreturn(struct pt_regs *regs) ...@@ -174,6 +174,7 @@ score_rt_sigreturn(struct pt_regs *regs)
/* It is more difficult to avoid calling this function than to /* It is more difficult to avoid calling this function than to
call it and ignore errors. */ call it and ignore errors. */
do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
regs->is_syscall = 0;
__asm__ __volatile__( __asm__ __volatile__(
"mv\tr0, %0\n\t" "mv\tr0, %0\n\t"
......
...@@ -206,6 +206,9 @@ static inline bool test_and_clear_restore_sigmask(void) ...@@ -206,6 +206,9 @@ static inline bool test_and_clear_restore_sigmask(void)
ti->status &= ~TS_RESTORE_SIGMASK; ti->status &= ~TS_RESTORE_SIGMASK;
return true; return true;
} }
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/freezer.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/stddef.h> #include <linux/stddef.h>
......
...@@ -126,13 +126,14 @@ register struct thread_info *current_thread_info_reg asm("g6"); ...@@ -126,13 +126,14 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \ #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
_TIF_SIGPENDING) _TIF_SIGPENDING)
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
...@@ -256,6 +256,9 @@ static inline bool test_and_clear_restore_sigmask(void) ...@@ -256,6 +256,9 @@ static inline bool test_and_clear_restore_sigmask(void)
ti->status &= ~TS_RESTORE_SIGMASK; ti->status &= ~TS_RESTORE_SIGMASK;
return true; return true;
} }
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -354,15 +354,6 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -354,15 +354,6 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[1] = ptr_to_compat_reg(&frame->info); regs->regs[1] = ptr_to_compat_reg(&frame->info);
regs->regs[2] = ptr_to_compat_reg(&frame->uc); regs->regs[2] = ptr_to_compat_reg(&frame->uc);
regs->flags |= PT_FLAGS_CALLER_SAVES; regs->flags |= PT_FLAGS_CALLER_SAVES;
/*
* Notify any tracer that was single-stepping it.
* The tracer may want to single-step inside the
* handler too.
*/
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
return 0; return 0;
give_sigsegv: give_sigsegv:
......
...@@ -219,15 +219,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -219,15 +219,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->regs[1] = (unsigned long) &frame->info; regs->regs[1] = (unsigned long) &frame->info;
regs->regs[2] = (unsigned long) &frame->uc; regs->regs[2] = (unsigned long) &frame->uc;
regs->flags |= PT_FLAGS_CALLER_SAVES; regs->flags |= PT_FLAGS_CALLER_SAVES;
/*
* Notify any tracer that was single-stepping it.
* The tracer may want to single-step inside the
* handler too.
*/
if (test_thread_flag(TIF_SINGLESTEP))
ptrace_notify(SIGTRAP);
return 0; return 0;
give_sigsegv: give_sigsegv:
...@@ -278,7 +269,8 @@ static void handle_signal(unsigned long sig, siginfo_t *info, ...@@ -278,7 +269,8 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
ret = setup_rt_frame(sig, ka, info, oldset, regs); ret = setup_rt_frame(sig, ka, info, oldset, regs);
if (ret) if (ret)
return; return;
signal_delivered(sig, info, ka, regs, 0); signal_delivered(sig, info, ka, regs,
test_thread_flag(TIF_SINGLESTEP));
} }
/* /*
......
...@@ -65,8 +65,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -65,8 +65,6 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
* TIF_NEED_RESCHED */
#define TIF_RESTART_BLOCK 4 #define TIF_RESTART_BLOCK 4
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_SYSCALL_AUDIT 6 #define TIF_SYSCALL_AUDIT 6
...@@ -76,7 +74,6 @@ static inline struct thread_info *current_thread_info(void) ...@@ -76,7 +74,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
......
...@@ -141,12 +141,12 @@ static inline struct thread_info *current_thread_info(void) ...@@ -141,12 +141,12 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
/* /*
* Change these and you break ASM code in entry-common.S * Change these and you break ASM code in entry-common.S
*/ */
#define _TIF_WORK_MASK 0x000000ff #define _TIF_WORK_MASK \
(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* __UNICORE_THREAD_INFO_H__ */ #endif /* __UNICORE_THREAD_INFO_H__ */
...@@ -544,8 +544,6 @@ fast_work_pending: ...@@ -544,8 +544,6 @@ fast_work_pending:
work_pending: work_pending:
cand.a r1, #_TIF_NEED_RESCHED cand.a r1, #_TIF_NEED_RESCHED
bne work_resched bne work_resched
cand.a r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
beq no_work_pending
mov r0, sp @ 'regs' mov r0, sp @ 'regs'
mov r2, why @ 'syscall' mov r2, why @ 'syscall'
cand.a r1, #_TIF_SIGPENDING @ delivering a signal? cand.a r1, #_TIF_SIGPENDING @ delivering a signal?
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <linux/elf.h> #include <linux/elf.h>
......
...@@ -622,6 +622,10 @@ work_notifysig: # deal with pending signals and ...@@ -622,6 +622,10 @@ work_notifysig: # deal with pending signals and
movl %esp, %eax movl %esp, %eax
jne work_notifysig_v86 # returning to kernel-space or jne work_notifysig_v86 # returning to kernel-space or
# vm86-space # vm86-space
1:
#else
movl %esp, %eax
#endif
TRACE_IRQS_ON TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE) ENABLE_INTERRUPTS(CLBR_NONE)
movb PT_CS(%esp), %bl movb PT_CS(%esp), %bl
...@@ -632,24 +636,15 @@ work_notifysig: # deal with pending signals and ...@@ -632,24 +636,15 @@ work_notifysig: # deal with pending signals and
call do_notify_resume call do_notify_resume
jmp resume_userspace jmp resume_userspace
#ifdef CONFIG_VM86
ALIGN ALIGN
work_notifysig_v86: work_notifysig_v86:
pushl_cfi %ecx # save ti_flags for do_notify_resume pushl_cfi %ecx # save ti_flags for do_notify_resume
call save_v86_state # %eax contains pt_regs pointer call save_v86_state # %eax contains pt_regs pointer
popl_cfi %ecx popl_cfi %ecx
movl %eax, %esp movl %eax, %esp
#else jmp 1b
movl %esp, %eax
#endif #endif
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
movb PT_CS(%esp), %bl
andb $SEGMENT_RPL_MASK, %bl
cmpb $USER_RPL, %bl
jb resume_kernel
xorl %edx, %edx
call do_notify_resume
jmp resume_userspace
END(work_pending) END(work_pending)
# perform syscall exit tracing # perform syscall exit tracing
......
...@@ -128,19 +128,14 @@ static inline struct thread_info *current_thread_info(void) ...@@ -128,19 +128,14 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SIGPENDING 1 /* signal pending */ #define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */
#define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */
#define TIF_IRET 4 /* return with iret */
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_IRET (1<<TIF_IRET)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/freezer.h>
#include <linux/tracehook.h> #include <linux/tracehook.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
...@@ -527,9 +526,6 @@ static void do_signal(struct pt_regs *regs) ...@@ -527,9 +526,6 @@ static void do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs)
{ {
if (!user_mode(regs))
return;
if (test_thread_flag(TIF_SIGPENDING)) if (test_thread_flag(TIF_SIGPENDING))
do_signal(regs); do_signal(regs);
......
...@@ -505,7 +505,7 @@ static inline void init_hrtick(void) ...@@ -505,7 +505,7 @@ static inline void init_hrtick(void)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#ifndef tsk_is_polling #ifndef tsk_is_polling
#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) #define tsk_is_polling(t) 0
#endif #endif
void resched_task(struct task_struct *p) void resched_task(struct task_struct *p)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment