mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-19 08:05:27 +08:00
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
This commit is contained in:
commit
8213a2f3ee
@ -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");
|
|||||||
(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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
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 @@
|
|||||||
#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,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage void
|
asmlinkage unsigned long syscall_trace_enter(void)
|
||||||
syscall_trace(void)
|
|
||||||
{
|
{
|
||||||
if (!test_thread_flag(TIF_SYSCALL_TRACE))
|
unsigned long ret = 0;
|
||||||
return;
|
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||||
if (!(current->ptrace & PT_PTRACED))
|
tracehook_report_syscall_entry(current_pt_regs()))
|
||||||
return;
|
ret = -1UL;
|
||||||
/* The 0x80 provides a way for the tracing parent to distinguish
|
return ret ?: current_pt_regs()->r0;
|
||||||
between a syscall stop and SIGTRAP delivery */
|
}
|
||||||
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
|
|
||||||
? 0x80 : 0));
|
asmlinkage void
|
||||||
|
syscall_trace_leave(void)
|
||||||
/*
|
{
|
||||||
* This isn't the same as continuing with a signal, but it will do
|
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
* for normal use. strace only continues with a signal if the
|
tracehook_report_syscall_exit(current_pt_regs(), 0);
|
||||||
* 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 *,
|
|||||||
#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 *,
|
|||||||
#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 @@
|
|||||||
#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)
|
|||||||
#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)
|
|||||||
#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)
|
|||||||
|
|
||||||
/* 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 @@
|
|||||||
#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)
|
|||||||
#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)
|
|||||||
#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 @@
|
|||||||
#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
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|||||||
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)
|
|||||||
#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 @@
|
|||||||
* 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)
|
|||||||
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:
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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);
|
|||||||
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)
|
|||||||
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(®s, 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, ®s,
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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 {
|
|||||||
#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
|
|||||||
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;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
|||||||
#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");
|
|||||||
#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");
|
|||||||
#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 @@
|
|||||||
#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
|
|||||||
|
|
||||||
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:
|
|||||||
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);
|
|||||||
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);
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/* 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
|
|
@ -1,77 +0,0 @@
|
|||||||
/* 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 @@
|
|||||||
#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,
|
|||||||
* 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,
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
#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)
|
|||||||
__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,
|
|||||||
__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)
|
|||||||
#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)
|
|||||||
#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 @@
|
|||||||
#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);
|
|||||||
#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);
|
|||||||
#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 @@
|
|||||||
|
|
||||||
#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 {
|
|||||||
#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 {
|
|||||||
#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)
|
|||||||
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)
|
|||||||
#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 @@
|
|||||||
#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)
|
|||||||
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
|
|||||||
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 {
|
|||||||
.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,
|
|||||||
{
|
{
|
||||||
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);
|
|||||||
|
|
||||||
#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)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
#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 @@
|
|||||||
#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)
|
|||||||
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 @@
|
|||||||
|
|
||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
#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)
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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");
|
|||||||
#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");
|
|||||||
#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
|
|||||||
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 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
.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 {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 {
|
|||||||
#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);
|
|||||||
#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 @@
|
|||||||
#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
|
|||||||
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)
|
|||||||
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:
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
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 @@
|
|||||||
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
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
/* 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
|
|
@ -1,31 +0,0 @@
|
|||||||
/* 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)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* create a kernel thread
|
|
||||||
*/
|
|
||||||
int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
|
|
||||||
{
|
|
||||||
struct pt_regs regs;
|
|
||||||
|
|
||||||
memset(®s, 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, ®s, 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,
|
|||||||
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;
|
||||||
|
|
||||||
p->thread.uregs = c_uregs;
|
|
||||||
*c_uregs = *uregs;
|
|
||||||
c_uregs->sp = c_usp;
|
|
||||||
c_uregs->epsw &= ~EPSW_FE; /* my FPU */
|
|
||||||
|
|
||||||
c_ksp -= 12; /* allocate function call ABI slack */
|
c_ksp -= 12; /* allocate function call ABI slack */
|
||||||
|
|
||||||
|
/* set up things up so the scheduler can start the new task */
|
||||||
|
p->thread.uregs = c_regs;
|
||||||
|
ti->frame = c_regs;
|
||||||
|
p->thread.a3 = (unsigned long) c_regs;
|
||||||
|
p->thread.sp = c_ksp;
|
||||||
|
p->thread.wchan = p->thread.pc;
|
||||||
|
p->thread.usp = c_usp;
|
||||||
|
|
||||||
|
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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");
|
|||||||
#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");
|
|||||||
/* 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)
|
|||||||
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 {
|
|||||||
#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)
|
|||||||
(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 @@ give_sigsegv:
|
|||||||
* 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,
|
|||||||
|
|
||||||
/* 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,
|
|||||||
|
|
||||||
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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
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:
|
|||||||
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:
|
|||||||
|
|
||||||
/* 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
|
|||||||
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;
|
|||||||
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);
|
|||||||
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,
|
|||||||
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)
|
|||||||
#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 @@
|
|||||||
#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:
|
|||||||
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)
|
|||||||
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)
|
|||||||
.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)
|
|||||||
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)
|
|||||||
#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);
|
|||||||
#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)
|
|||||||
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,
|
|||||||
#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,
|
|||||||
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,
|
|||||||
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)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
char *filename;
|
|
||||||
|
|
||||||
filename = getname((const char __user *) a0);
|
void ret_from_kernel_execve(struct pt_regs *normal)
|
||||||
error = PTR_ERR(filename);
|
{
|
||||||
if (IS_ERR(filename))
|
set_thread_flag(TIF_RESTOREALL);
|
||||||
goto out;
|
__ret_from_kernel_execve(normal);
|
||||||
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 @@
|
|||||||
#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,
|
|||||||
(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)
|
|||||||
#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)
|
|||||||
|
|
||||||
#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)
|
|||||||
#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");
|
|||||||
#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)
|
|||||||
/* 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)
|
|||||||
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 @@
|
|||||||
#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 @@
|
|||||||
#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");
|
|||||||
#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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
#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)
|
|||||||
#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)
|
|||||||
#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:
|
|||||||
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 @@
|
|||||||
#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,22 +622,7 @@ 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
|
||||||
TRACE_IRQS_ON
|
1:
|
||||||
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
|
|
||||||
|
|
||||||
ALIGN
|
|
||||||
work_notifysig_v86:
|
|
||||||
pushl_cfi %ecx # save ti_flags for do_notify_resume
|
|
||||||
call save_v86_state # %eax contains pt_regs pointer
|
|
||||||
popl_cfi %ecx
|
|
||||||
movl %eax, %esp
|
|
||||||
#else
|
#else
|
||||||
movl %esp, %eax
|
movl %esp, %eax
|
||||||
#endif
|
#endif
|
||||||
@ -650,6 +635,16 @@ work_notifysig_v86:
|
|||||||
xorl %edx, %edx
|
xorl %edx, %edx
|
||||||
call do_notify_resume
|
call do_notify_resume
|
||||||
jmp resume_userspace
|
jmp resume_userspace
|
||||||
|
|
||||||
|
#ifdef CONFIG_VM86
|
||||||
|
ALIGN
|
||||||
|
work_notifysig_v86:
|
||||||
|
pushl_cfi %ecx # save ti_flags for do_notify_resume
|
||||||
|
call save_v86_state # %eax contains pt_regs pointer
|
||||||
|
popl_cfi %ecx
|
||||||
|
movl %eax, %esp
|
||||||
|
jmp 1b
|
||||||
|
#endif
|
||||||
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)
|
|||||||
#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 @@
|
|||||||
#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)
|
|||||||
|
|
||||||
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)
|
|||||||
#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)
|
||||||
|
Loading…
Reference in New Issue
Block a user