|
@@ -237,61 +237,6 @@ void show_regs(struct pt_regs *regs)
|
|
|
show_trace(NULL, regs, (void *)(regs + 1), regs->bp);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Free current thread data structures etc..
|
|
|
- */
|
|
|
-void exit_thread(void)
|
|
|
-{
|
|
|
- struct task_struct *me = current;
|
|
|
- struct thread_struct *t = &me->thread;
|
|
|
-
|
|
|
- if (me->thread.io_bitmap_ptr) {
|
|
|
- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
|
|
|
-
|
|
|
- kfree(t->io_bitmap_ptr);
|
|
|
- t->io_bitmap_ptr = NULL;
|
|
|
- clear_thread_flag(TIF_IO_BITMAP);
|
|
|
- /*
|
|
|
- * Careful, clear this in the TSS too:
|
|
|
- */
|
|
|
- memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
|
|
|
- t->io_bitmap_max = 0;
|
|
|
- put_cpu();
|
|
|
- }
|
|
|
-
|
|
|
- ds_exit_thread(current);
|
|
|
-}
|
|
|
-
|
|
|
-void flush_thread(void)
|
|
|
-{
|
|
|
- struct task_struct *tsk = current;
|
|
|
-
|
|
|
- if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) {
|
|
|
- clear_tsk_thread_flag(tsk, TIF_ABI_PENDING);
|
|
|
- if (test_tsk_thread_flag(tsk, TIF_IA32)) {
|
|
|
- clear_tsk_thread_flag(tsk, TIF_IA32);
|
|
|
- } else {
|
|
|
- set_tsk_thread_flag(tsk, TIF_IA32);
|
|
|
- current_thread_info()->status |= TS_COMPAT;
|
|
|
- }
|
|
|
- }
|
|
|
- clear_tsk_thread_flag(tsk, TIF_DEBUG);
|
|
|
-
|
|
|
- tsk->thread.debugreg0 = 0;
|
|
|
- tsk->thread.debugreg1 = 0;
|
|
|
- tsk->thread.debugreg2 = 0;
|
|
|
- tsk->thread.debugreg3 = 0;
|
|
|
- tsk->thread.debugreg6 = 0;
|
|
|
- tsk->thread.debugreg7 = 0;
|
|
|
- memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
|
|
|
- /*
|
|
|
- * Forget coprocessor state..
|
|
|
- */
|
|
|
- tsk->fpu_counter = 0;
|
|
|
- clear_fpu(tsk);
|
|
|
- clear_used_math();
|
|
|
-}
|
|
|
-
|
|
|
void release_thread(struct task_struct *dead_task)
|
|
|
{
|
|
|
if (dead_task->mm) {
|
|
@@ -425,118 +370,6 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(start_thread);
|
|
|
|
|
|
-static void hard_disable_TSC(void)
|
|
|
-{
|
|
|
- write_cr4(read_cr4() | X86_CR4_TSD);
|
|
|
-}
|
|
|
-
|
|
|
-void disable_TSC(void)
|
|
|
-{
|
|
|
- preempt_disable();
|
|
|
- if (!test_and_set_thread_flag(TIF_NOTSC))
|
|
|
- /*
|
|
|
- * Must flip the CPU state synchronously with
|
|
|
- * TIF_NOTSC in the current running context.
|
|
|
- */
|
|
|
- hard_disable_TSC();
|
|
|
- preempt_enable();
|
|
|
-}
|
|
|
-
|
|
|
-static void hard_enable_TSC(void)
|
|
|
-{
|
|
|
- write_cr4(read_cr4() & ~X86_CR4_TSD);
|
|
|
-}
|
|
|
-
|
|
|
-static void enable_TSC(void)
|
|
|
-{
|
|
|
- preempt_disable();
|
|
|
- if (test_and_clear_thread_flag(TIF_NOTSC))
|
|
|
- /*
|
|
|
- * Must flip the CPU state synchronously with
|
|
|
- * TIF_NOTSC in the current running context.
|
|
|
- */
|
|
|
- hard_enable_TSC();
|
|
|
- preempt_enable();
|
|
|
-}
|
|
|
-
|
|
|
-int get_tsc_mode(unsigned long adr)
|
|
|
-{
|
|
|
- unsigned int val;
|
|
|
-
|
|
|
- if (test_thread_flag(TIF_NOTSC))
|
|
|
- val = PR_TSC_SIGSEGV;
|
|
|
- else
|
|
|
- val = PR_TSC_ENABLE;
|
|
|
-
|
|
|
- return put_user(val, (unsigned int __user *)adr);
|
|
|
-}
|
|
|
-
|
|
|
-int set_tsc_mode(unsigned int val)
|
|
|
-{
|
|
|
- if (val == PR_TSC_SIGSEGV)
|
|
|
- disable_TSC();
|
|
|
- else if (val == PR_TSC_ENABLE)
|
|
|
- enable_TSC();
|
|
|
- else
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * This special macro can be used to load a debugging register
|
|
|
- */
|
|
|
-#define loaddebug(thread, r) set_debugreg(thread->debugreg ## r, r)
|
|
|
-
|
|
|
-static inline void __switch_to_xtra(struct task_struct *prev_p,
|
|
|
- struct task_struct *next_p,
|
|
|
- struct tss_struct *tss)
|
|
|
-{
|
|
|
- struct thread_struct *prev, *next;
|
|
|
-
|
|
|
- prev = &prev_p->thread,
|
|
|
- next = &next_p->thread;
|
|
|
-
|
|
|
- if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
|
|
|
- test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
|
|
|
- ds_switch_to(prev_p, next_p);
|
|
|
- else if (next->debugctlmsr != prev->debugctlmsr)
|
|
|
- update_debugctlmsr(next->debugctlmsr);
|
|
|
-
|
|
|
- if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
|
|
|
- loaddebug(next, 0);
|
|
|
- loaddebug(next, 1);
|
|
|
- loaddebug(next, 2);
|
|
|
- loaddebug(next, 3);
|
|
|
- /* no 4 and 5 */
|
|
|
- loaddebug(next, 6);
|
|
|
- loaddebug(next, 7);
|
|
|
- }
|
|
|
-
|
|
|
- if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
|
|
|
- test_tsk_thread_flag(next_p, TIF_NOTSC)) {
|
|
|
- /* prev and next are different */
|
|
|
- if (test_tsk_thread_flag(next_p, TIF_NOTSC))
|
|
|
- hard_disable_TSC();
|
|
|
- else
|
|
|
- hard_enable_TSC();
|
|
|
- }
|
|
|
-
|
|
|
- if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
|
|
|
- /*
|
|
|
- * Copy the relevant range of the IO bitmap.
|
|
|
- * Normally this is 128 bytes or less:
|
|
|
- */
|
|
|
- memcpy(tss->io_bitmap, next->io_bitmap_ptr,
|
|
|
- max(prev->io_bitmap_max, next->io_bitmap_max));
|
|
|
- } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
|
|
|
- /*
|
|
|
- * Clear any possible leftover bits:
|
|
|
- */
|
|
|
- memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* switch_to(x,y) should switch tasks from x to y.
|
|
|
*
|
|
@@ -694,11 +527,6 @@ void set_personality_64bit(void)
|
|
|
current->personality &= ~READ_IMPLIES_EXEC;
|
|
|
}
|
|
|
|
|
|
-asmlinkage long sys_fork(struct pt_regs *regs)
|
|
|
-{
|
|
|
- return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
|
|
|
-}
|
|
|
-
|
|
|
asmlinkage long
|
|
|
sys_clone(unsigned long clone_flags, unsigned long newsp,
|
|
|
void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
|
|
@@ -708,22 +536,6 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
|
|
|
return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * This is trivial, and on the face of it looks like it
|
|
|
- * could equally well be done in user mode.
|
|
|
- *
|
|
|
- * Not so, for quite unobvious reasons - register pressure.
|
|
|
- * In user mode vfork() cannot have a stack frame, and if
|
|
|
- * done by calling the "clone()" system call directly, you
|
|
|
- * do not have enough call-clobbered registers to hold all
|
|
|
- * the information you need.
|
|
|
- */
|
|
|
-asmlinkage long sys_vfork(struct pt_regs *regs)
|
|
|
-{
|
|
|
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
|
|
|
- NULL, NULL);
|
|
|
-}
|
|
|
-
|
|
|
unsigned long get_wchan(struct task_struct *p)
|
|
|
{
|
|
|
unsigned long stack;
|