Signed-off-by: Nicholas Piggin <npig...@gmail.com> --- This moves some of the ifdefs out of line and hopefully makes things slightly more readable. Should be no generated code changes.
arch/powerpc/kernel/entry_64.S | 111 +++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 585b9ca..0a1e33b 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -40,6 +40,54 @@ #include <asm/ppc-opcode.h> /* + * Interrrupt disabling abstraction between BOOK3E and BOOK3S. + * - SET/CLEAR_EE must only be used with RI set. + * - SET/CLEAR_RI must only be used with EE clear. + * - SET/CLEAR_EE_RI must only be used when both bits get modified. + */ +#ifdef CONFIG_PPC_BOOK3E + +/* BOOK3E does not have RI handling, so that gets compiled away. */ +#define SET_EE(reg) wrteei 1 +#define CLEAR_EE(reg) wrteei 0 +#define SET_RI(reg) +#define CLEAR_RI(reg) +#define SET_EE_RI(reg) SET_EE(reg) +#define CLEAR_EE_RI(reg CLEAR_EE(reg) + +#else /* CONFIG_PPC_BOOK3E */ + +/* + * BOOK3S mtmsrd L=1 only modifies EE and RI bits of MSR. A single ori + * instruction could be used to set both bits in the register without changing + * other bits (which do not affect mtmsrd L=1), however it's likely that + * instruction scheduling would consider this a dependency. + */ +#define SET_EE_RI(reg) \ + li reg,MSR_RI; \ + ori reg,reg,MSR_EE; \ + mtmsrd reg,1 + +#define CLEAR_EE_RI(reg) \ + li reg,0; \ + mtmsrd reg,1 + +#define CLEAR_EE(reg) \ + li reg,MSR_RI; \ + mtmsrd reg,1 + +#define SET_EE(reg) SET_EE_RI(reg) + +#define CLEAR_RI(reg) CLEAR_EE_RI(reg) + +#define SET_RI(reg) \ + li reg,MSR_RI; \ + mtmsrd reg,1 + +#endif /* CONFIG_PPC_BOOK3E */ + + +/* * System calls. */ .section ".toc","aw" @@ -136,13 +184,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING #endif -#ifdef CONFIG_PPC_BOOK3E - wrteei 1 -#else - li r11,MSR_RI - ori r11,r11,MSR_EE - mtmsrd r11,1 -#endif /* CONFIG_PPC_BOOK3E */ + SET_EE_RI(r11) /* We do need to set SOFTE in the stack frame or the return * from interrupt will be painful @@ -191,20 +233,15 @@ system_call: /* label this so stack traces look sane */ /* * Disable interrupts so current_thread_info()->flags can't change, * and so that we don't get interrupted after loading SRR0/1. - */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - /* + * + * BOOK3S: * For performance reasons we clear RI the same time that we * clear EE. We only need to clear RI just before we restore r13 * below, but batching it with EE saves us one expensive mtmsrd call. * We have to be careful to restore RI if we branch anywhere from * here (eg syscall_exit_work). */ - li r11,0 - mtmsrd r11,1 -#endif /* CONFIG_PPC_BOOK3E */ + CLEAR_EE_RI(r11) ld r9,TI_FLAGS(r12) li r11,-MAX_ERRNO @@ -218,15 +255,9 @@ system_call: /* label this so stack traces look sane */ bne 3f #endif 2: addi r3,r1,STACK_FRAME_OVERHEAD -#ifdef CONFIG_PPC_BOOK3S - li r10,MSR_RI - mtmsrd r10,1 /* Restore RI */ -#endif + SET_RI(r10) /* See above RI optimisation */ bl restore_math -#ifdef CONFIG_PPC_BOOK3S - li r11,0 - mtmsrd r11,1 -#endif + CLEAR_RI(r11) ld r8,_MSR(r1) ld r3,RESULT(r1) li r11,-MAX_ERRNO @@ -304,13 +335,11 @@ syscall_enosys: b .Lsyscall_exit syscall_exit_work: -#ifdef CONFIG_PPC_BOOK3S - li r10,MSR_RI - mtmsrd r10,1 /* Restore RI */ -#endif - /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr. - If TIF_NOERROR is set, just save r3 as it is. */ - + SET_RI(r10) /* See above RI optimisation */ + /* + * If TIF_RESTOREALL is set, don't scribble on either r3 or ccr. + * If TIF_NOERROR is set, just save r3 as it is. + */ andi. r0,r9,_TIF_RESTOREALL beq+ 0f REST_NVGPRS(r1) @@ -349,13 +378,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) beq ret_from_except_lite /* Re-enable interrupts */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 1 -#else - li r10,MSR_RI - ori r10,r10,MSR_EE - mtmsrd r10,1 -#endif /* CONFIG_PPC_BOOK3E */ + SET_EE_RI(r10) bl save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD @@ -614,12 +637,7 @@ _GLOBAL(ret_from_except_lite) * can't change between when we test it and when we return * from the interrupt. */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - li r10,MSR_RI - mtmsrd r10,1 /* Update machine state */ -#endif /* CONFIG_PPC_BOOK3E */ + CLEAR_EE(r10) CURRENT_THREAD_INFO(r9, r1) ld r3,_MSR(r1) @@ -746,12 +764,7 @@ resume_kernel: * when we return from the interrupt, and so that we don't get * interrupted after loading SRR0/1. */ -#ifdef CONFIG_PPC_BOOK3E - wrteei 0 -#else - li r10,MSR_RI - mtmsrd r10,1 /* Update machine state */ -#endif /* CONFIG_PPC_BOOK3E */ + CLEAR_EE(r10) #endif /* CONFIG_PREEMPT */ .globl fast_exc_return_irq -- 2.9.3