diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 4846bf543a8c5cf9dd2f95a611c4deae04cd9863..59311ec0d422d3eca2f94b358808bde287765fbc 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -353,6 +353,12 @@ struct task_struct *__switch_to(struct task_struct *prev, account_process_vtime(current); calculate_steal_time(); + /* + * We can't take a PMU exception inside _switch() since there is a + * window where the kernel stack SLB and the kernel stack are out + * of sync. Hard disable here. + */ + hard_irq_disable(); last = _switch(old_thread, new_thread); local_irq_restore(flags); diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 47b06bad24adbb8e4c857f782df2fdc30ac779fb..906daeda59a8ff431d6bee026af51f55e4318512 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -124,6 +124,12 @@ void slb_flush_and_rebolt(void) ksp_vsid_data = get_slb_shadow()->save_area[2].vsid; } + /* + * We can't take a PMU exception in the following code, so hard + * disable interrupts. + */ + hard_irq_disable(); + /* We need to do this all in asm, so we're sure we don't touch * the stack between the slbia and rebolting it. */ asm volatile("isync\n"