]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] ppc32: Even more preempt fixes
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 30 Mar 2004 02:50:51 +0000 (18:50 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 30 Mar 2004 02:50:51 +0000 (18:50 -0800)
Add a warning if enable_kernel_{fp,altivec} is called with preempt
enabled since this is always an error, and make sure the alignement
exception handler properly disables preempt when doing FP operations.

arch/ppc/kernel/align.c
arch/ppc/kernel/process.c

index 3d0b2650b9d7ae5eee12feb2415f641f0dd71161..59a20f38809b2ddb14645d0eda0d77f37c485fe2 100644 (file)
@@ -325,14 +325,18 @@ fix_alignment(struct pt_regs *regs)
         * the kernel with -msoft-float so it doesn't use the
         * fp regs for copying 8-byte objects. */
        case LD+F+S:
+               preempt_disable();
                enable_kernel_fp();
                cvt_fd(&data.f, &current->thread.fpr[reg], &current->thread.fpscr);
                /* current->thread.fpr[reg] = data.f; */
+               preempt_enable();
                break;
        case ST+F+S:
+               preempt_disable();
                enable_kernel_fp();
                cvt_df(&current->thread.fpr[reg], &data.f, &current->thread.fpscr);
                /* data.f = current->thread.fpr[reg]; */
+               preempt_enable();
                break;
        default:
                printk("align: can't handle flags=%x\n", flags);
index e94ead3eac9b76061f0f1a62b87e093784afccc3..ada32baeda19b5617664d35ed48ff245c0d84dec 100644 (file)
@@ -163,7 +163,8 @@ dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
 void
 enable_kernel_altivec(void)
 {
-       preempt_disable();
+       WARN_ON(current_thread_info()->preempt_count == 0 && !irqs_disabled());
+
 #ifdef CONFIG_SMP
        if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
                giveup_altivec(current);
@@ -172,14 +173,15 @@ enable_kernel_altivec(void)
 #else
        giveup_altivec(last_task_used_altivec);
 #endif /* __SMP __ */
-       preempt_enable();
 }
+EXPORT_SYMBOL(enable_kernel_altivec);
 #endif /* CONFIG_ALTIVEC */
 
 void
 enable_kernel_fp(void)
 {
-       preempt_disable();
+       WARN_ON(current_thread_info()->preempt_count == 0 && !irqs_disabled());
+
 #ifdef CONFIG_SMP
        if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
                giveup_fpu(current);
@@ -188,8 +190,8 @@ enable_kernel_fp(void)
 #else
        giveup_fpu(last_task_used_math);
 #endif /* CONFIG_SMP */
-       preempt_enable();
 }
+EXPORT_SYMBOL(enable_kernel_fp);
 
 int
 dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)