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 unsigned long syscall_trace_enter(void)
{
unsigned long ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(current_pt_regs()))
ret = -1UL;
return ret ?: current_pt_regs()->r0;
}
asmlinkage void asmlinkage void
syscall_trace(void) syscall_trace_leave(void)
{ {
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
return; tracehook_report_syscall_exit(current_pt_regs(), 0);
if (!(current->ptrace & PT_PTRACED))
return;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
* This isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
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.pc = (unsigned long) ret_from_fork; p->thread.frame0 = childregs;
p->thread.frame0 = childregs0;
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;
/* 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 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
this point and exits if that's the case. I'm not sure why DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
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);
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 return;
this loop so we can deliver the SIGSEGV... */
if (handle_signal(signr, &info, &ka, regs, in_syscall))
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,19 +815,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -805,19 +815,17 @@ 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
* to the TOC entry. The first entry is a pointer to the actual * to the TOC entry. The first entry is a pointer to the actual
* 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