patch-2.3.26 linux/arch/ppc/kernel/process.c
Next file: linux/arch/ppc/kernel/setup.c
Previous file: linux/arch/ppc/kernel/ppc_ksyms.c
Back to the patch index
Back to the overall index
- Lines: 157
- Date:
Fri Nov 5 15:53:26 1999
- Orig file:
v2.3.25/linux/arch/ppc/kernel/process.c
- Orig date:
Sat Oct 9 11:47:50 1999
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
@@ -45,6 +45,7 @@
extern unsigned long _get_SP(void);
struct task_struct *last_task_used_math = NULL;
+struct task_struct *last_task_used_altivec = NULL;
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
@@ -60,6 +61,7 @@
#undef SHOW_TASK_SWITCHES 1
#undef CHECK_STACK 1
+#if defined(CHECK_STACK)
unsigned long
kernel_stack_top(struct task_struct *tsk)
{
@@ -72,28 +74,6 @@
return ((unsigned long)tsk) + sizeof(struct task_struct);
}
-int
-dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
-{
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
- memcpy(fpregs, ¤t->thread.fpr[0], sizeof(*fpregs));
- return 1;
-}
-
-void
-enable_kernel_fp(void)
-{
-#ifdef __SMP__
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu(last_task_used_math);
-#endif /* __SMP__ */
-}
-
/* check to make sure the kernel stack is healthy */
int check_stack(struct task_struct *tsk)
{
@@ -156,6 +136,29 @@
}
return(ret);
}
+#endif /* defined(CHECK_STACK) */
+
+int
+dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+{
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
+ memcpy(fpregs, ¤t->thread.fpr[0], sizeof(*fpregs));
+ return 1;
+}
+
+void
+enable_kernel_fp(void)
+{
+#ifdef __SMP__
+ if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+ giveup_fpu(current);
+ else
+ giveup_fpu(NULL); /* just enables FP for kernel */
+#else
+ giveup_fpu(last_task_used_math);
+#endif /* __SMP__ */
+}
void
_switch_to(struct task_struct *prev, struct task_struct *new,
@@ -187,9 +190,23 @@
* every switch, just a save.
* -- Cort
*/
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
+ if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) )
giveup_fpu(prev);
-
+ /*
+ * If the previous thread 1) has some altivec regs it wants saved
+ * (has bits in vrsave set) and 2) used altivec in the last quantum
+ * (thus changing altivec regs) then save them.
+ *
+ * On SMP we always save/restore altivec regs just to avoid the
+ * complexity of changing processors.
+ * -- Cort
+ */
+ if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
+ prev->thread.vrsave )
+ giveup_altivec(prev);
+ if ( (new->last_processor != NO_PROC_ID) &&
+ (new->last_processor != new->processor) && new->mm )
+ flush_tlb_mm(new->mm);
prev->last_processor = prev->processor;
current_set[smp_processor_id()] = new;
#endif /* __SMP__ */
@@ -213,7 +230,8 @@
printk("TASK = %p[%d] '%s' ",
current, current->pid, current->comm);
printk("Last syscall: %ld ", current->thread.last_syscall);
- printk("\nlast math %p", last_task_used_math);
+ printk("\nlast math %p last altivec %p", last_task_used_math,
+ last_task_used_altivec);
#ifdef __SMP__
printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
@@ -243,12 +261,16 @@
{
if (last_task_used_math == current)
last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
}
void flush_thread(void)
{
if (last_task_used_math == current)
last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
}
void
@@ -305,11 +327,18 @@
*/
if (regs->msr & MSR_FP)
giveup_fpu(current);
-
memcpy(&p->thread.fpr, ¤t->thread.fpr, sizeof(p->thread.fpr));
p->thread.fpscr = current->thread.fpscr;
childregs->msr &= ~MSR_FP;
+ if (regs->msr & MSR_VEC)
+ giveup_altivec(current);
+ if ( p->thread.vrsave )
+ memcpy(&p->thread.vrf, ¤t->thread.vrf, sizeof(p->thread.vrf));
+ p->thread.vscr = current->thread.vscr;
+ p->thread.vrsave = current->thread.vrsave;
+ childregs->msr &= ~MSR_VEC;
+
#ifdef __SMP__
p->last_processor = NO_PROC_ID;
#endif /* __SMP__ */
@@ -367,6 +396,8 @@
shove_aux_table(sp);
if (last_task_used_math == current)
last_task_used_math = 0;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = 0;
current->thread.fpscr = 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)