void *info = call_data->info;
 
        clear_softint(1 << irq);
+
+       irq_enter();
+
+       if (!call_data->wait) {
+               /* let initiator proceed after getting data */
+               atomic_inc(&call_data->finished);
+       }
+
+       func(info);
+
+       irq_exit();
+
        if (call_data->wait) {
                /* let initiator proceed only after completion */
-               func(info);
                atomic_inc(&call_data->finished);
-       } else {
-               /* let initiator proceed after getting data */
-               atomic_inc(&call_data->finished);
-               func(info);
        }
 }
 
 
 void smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
+       irq_enter();
        clear_softint(1 << irq);
+       irq_exit();
 }
 
 void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
        struct mm_struct *mm;
        unsigned long flags;
 
+       irq_enter();
+
        clear_softint(1 << irq);
 
        /* See if we need to allocate a new TLB context because
        load_secondary_context(mm);
        __flush_tlb_mm(CTX_HWBITS(mm->context),
                       SECONDARY_CONTEXT);
+
+       irq_exit();
 }
 
 void smp_new_mmu_context_version(void)
 {
        clear_softint(1 << irq);
 
+       irq_enter();
+
        preempt_disable();
 
        __asm__ __volatile__("flushw");
        prom_world(0);
 
        preempt_enable();
+
+       irq_exit();
 }
 
 /* /proc/profile writes can call this, don't __init it please. */