diff options
author | Christophe Leroy <christophe.leroy@csgroup.eu> | 2021-03-12 13:50:41 +0100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2021-03-29 04:22:09 +0200 |
commit | 4c0104a83fc3990a76a01a2f4e504251fa9814c4 (patch) | |
tree | 5e98d03e8e6148c3e75828a511eb13f158f693f9 /arch/powerpc/kernel | |
parent | powerpc/32: Only restore non volatile registers when required (diff) | |
download | linux-4c0104a83fc3990a76a01a2f4e504251fa9814c4.tar.xz linux-4c0104a83fc3990a76a01a2f4e504251fa9814c4.zip |
powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
In order to get more control in exception prolog, dismantle
all non standard exception macros, finishing with EXC_XFER_STD
and EXC_XFER_LITE and EXC_XFER_TEMPLATE.
Also remove transfer_to_handler_full and ret_from_except and
ret_from_except_full as they are not used anymore.
Last parameter of EXCEPTION() is now ignored, will be removed
in a later patch to avoid too much churn.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/ca5795d04a220586b7037dbbbe6951dfa9e768eb.1615552867.git.christophe.leroy@csgroup.eu
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 42 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_32.h | 21 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_40x.S | 33 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_8xx.S | 12 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_book3s_32.S | 27 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_booke.h | 49 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 14 |
7 files changed, 92 insertions, 106 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index e6adb6882bde..bcf8452ebb58 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -48,30 +48,6 @@ */ .align 12 -#ifdef CONFIG_BOOKE - .globl mcheck_transfer_to_handler -mcheck_transfer_to_handler: - /* fall through */ -_ASM_NOKPROBE_SYMBOL(mcheck_transfer_to_handler) - - .globl debug_transfer_to_handler -debug_transfer_to_handler: - /* fall through */ -_ASM_NOKPROBE_SYMBOL(debug_transfer_to_handler) - - .globl crit_transfer_to_handler -crit_transfer_to_handler: - /* fall through */ -_ASM_NOKPROBE_SYMBOL(crit_transfer_to_handler) -#endif - -#ifdef CONFIG_40x - .globl crit_transfer_to_handler -crit_transfer_to_handler: - /* fall through */ -_ASM_NOKPROBE_SYMBOL(crit_transfer_to_handler) -#endif - /* * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception, turning @@ -79,13 +55,6 @@ _ASM_NOKPROBE_SYMBOL(crit_transfer_to_handler) * Note that we rely on the caller having set cr0.eq iff the exception * occurred in kernel mode (i.e. MSR:PR = 0). */ - .globl transfer_to_handler_full -transfer_to_handler_full: -_ASM_NOKPROBE_SYMBOL(transfer_to_handler_full) - /* fall through */ - - .globl transfer_to_handler -transfer_to_handler: .globl prepare_transfer_to_handler prepare_transfer_to_handler: SAVE_NVGPRS(r11) @@ -136,7 +105,6 @@ transfer_to_handler_cont: b fast_exception_return #endif _ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler) -_ASM_NOKPROBE_SYMBOL(transfer_to_handler) _ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont) .globl transfer_to_syscall @@ -352,18 +320,10 @@ _ASM_NOKPROBE_SYMBOL(fast_exception_return) 3: li r10,-1 stw r10,_TRAP(r11) - bl transfer_to_handler_full + prepare_transfer_to_handler bl unrecoverable_exception trap /* should not get here */ - .globl ret_from_except_full -ret_from_except_full: - /* fall through */ - - .globl ret_from_except -ret_from_except: -_ASM_NOKPROBE_SYMBOL(ret_from_except) - .globl interrupt_return interrupt_return: lwz r4,_MSR(r1) diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h index 3ab0f3ad9a6a..412ede8610f7 100644 --- a/arch/powerpc/kernel/head_32.h +++ b/arch/powerpc/kernel/head_32.h @@ -189,20 +189,9 @@ label: #define EXCEPTION(n, label, hdlr, xfer) \ START_EXCEPTION(n, label) \ EXCEPTION_PROLOG n label; \ - xfer(n, hdlr) - -#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \ - bl tfer; \ - bl hdlr; \ - b ret - -#define EXC_XFER_STD(n, hdlr) \ - EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \ - ret_from_except_full) - -#define EXC_XFER_LITE(n, hdlr) \ - EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler, \ - ret_from_except) + prepare_transfer_to_handler; \ + bl hdlr; \ + b interrupt_return .macro vmap_stack_overflow_exception __HEAD @@ -218,7 +207,9 @@ vmap_stack_overflow: lwz r1, emergency_ctx@l(r1) addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE EXCEPTION_PROLOG_2 0 vmap_stack_overflow - EXC_XFER_STD(0, stack_overflow_exception) + prepare_transfer_to_handler + bl stack_overflow_exception + b interrupt_return .endm #endif /* __HEAD_32_H__ */ diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S index f3e5b462113f..7eb49ebd6000 100644 --- a/arch/powerpc/kernel/head_40x.S +++ b/arch/powerpc/kernel/head_40x.S @@ -187,8 +187,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt) #define CRITICAL_EXCEPTION(n, label, hdlr) \ START_EXCEPTION(n, label); \ CRITICAL_EXCEPTION_PROLOG n label; \ - EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ - crit_transfer_to_handler, ret_from_crit_exc) + prepare_transfer_to_handler; \ + bl hdlr; \ + b ret_from_crit_exc /* * 0x0100 - Critical Interrupt Exception @@ -209,7 +210,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt) */ START_EXCEPTION(0x0300, DataStorage) EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1 - EXC_XFER_LITE(0x300, do_page_fault) + prepare_transfer_to_handler + bl do_page_fault + b interrupt_return /* * 0x0400 - Instruction Storage Exception @@ -220,7 +223,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt) li r5,0 stw r5, _ESR(r11) /* Zero ESR */ stw r12, _DEAR(r11) /* SRR0 as DEAR */ - EXC_XFER_LITE(0x400, do_page_fault) + prepare_transfer_to_handler + bl do_page_fault + b interrupt_return /* 0x0500 - External Interrupt Exception */ EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -499,9 +504,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt) /* continue normal handling for a critical exception... */ 2: mfspr r4,SPRN_DBSR stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */ - EXC_XFER_TEMPLATE(DebugException, 0x2002, \ - (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ - crit_transfer_to_handler, ret_from_crit_exc) + prepare_transfer_to_handler + bl DebugException + b ret_from_crit_exc /* Programmable Interval Timer (PIT) Exception. (from 0x1000) */ __HEAD @@ -509,21 +514,25 @@ Decrementer: EXCEPTION_PROLOG 0x1000 Decrementer lis r0,TSR_PIS@h mtspr SPRN_TSR,r0 /* Clear the PIT exception */ - EXC_XFER_LITE(0x1000, timer_interrupt) + prepare_transfer_to_handler + bl timer_interrupt + b interrupt_return /* Fixed Interval Timer (FIT) Exception. (from 0x1010) */ __HEAD FITException: EXCEPTION_PROLOG 0x1010 FITException - EXC_XFER_STD(0x1010, unknown_exception) + prepare_transfer_to_handler + bl unknown_exception + b interrupt_return /* Watchdog Timer (WDT) Exception. (from 0x1020) */ __HEAD WDTException: CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException - EXC_XFER_TEMPLATE(WatchdogException, 0x1020+2, - (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), - crit_transfer_to_handler, ret_from_crit_exc) + prepare_transfer_to_handler + bl WatchdogException + b ret_from_crit_exc /* Other PowerPC processors, namely those derived from the 6xx-series * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 86f844eb0e5a..4d73549722a1 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -123,7 +123,9 @@ instruction_counter: /* Machine check */ START_EXCEPTION(0x200, MachineCheck) EXCEPTION_PROLOG 0x200 MachineCheck handle_dar_dsisr=1 - EXC_XFER_STD(0x200, machine_check_exception) + prepare_transfer_to_handler + bl machine_check_exception + b interrupt_return /* External interrupt */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -314,7 +316,9 @@ instruction_counter: .Litlbie: stw r12, _DAR(r11) stw r5, _DSISR(r11) - EXC_XFER_LITE(0x400, do_page_fault) + prepare_transfer_to_handler + bl do_page_fault + b interrupt_return /* This is the data TLB error on the MPC8xx. This could be due to * many reasons, including a dirty update to a pte. We bail out to @@ -335,7 +339,9 @@ DARFixed:/* Return from dcbx instruction bug workaround */ beq+ .Ldtlbie tlbie r4 .Ldtlbie: - EXC_XFER_LITE(0x300, do_page_fault) + prepare_transfer_to_handler + bl do_page_fault + b interrupt_return #ifdef CONFIG_VMAP_STACK vmap_stack_overflow_exception diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S index 425a4f20ceac..0a3d7d4a9ec4 100644 --- a/arch/powerpc/kernel/head_book3s_32.S +++ b/arch/powerpc/kernel/head_book3s_32.S @@ -271,7 +271,9 @@ __secondary_hold_acknowledge: beq cr1, 1f twi 31, 0, 0 #endif -1: EXC_XFER_STD(0x200, machine_check_exception) +1: prepare_transfer_to_handler + bl machine_check_exception + b interrupt_return /* Data access exception. */ START_EXCEPTION(0x300, DataAccess) @@ -296,12 +298,13 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) 1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1 EXCEPTION_PROLOG_1 EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1 + prepare_transfer_to_handler lwz r5, _DSISR(r11) andis. r0, r5, DSISR_DABRMATCH@h bne- 1f - EXC_XFER_LITE(0x300, do_page_fault) -1: prepare_transfer_to_handler - bl do_break + bl do_page_fault + b interrupt_return +1: bl do_break REST_NVGPRS(r1) b interrupt_return @@ -331,7 +334,9 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ stw r5, _DSISR(r11) stw r12, _DAR(r11) - EXC_XFER_LITE(0x400, do_page_fault) + prepare_transfer_to_handler + bl do_page_fault + b interrupt_return /* External interrupt */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -366,7 +371,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) beq 1f bl load_up_fpu /* if from user, just load it up */ b fast_exception_return -1: EXC_XFER_LITE(0x800, kernel_fp_unavailable_exception) +1: prepare_transfer_to_handler + bl kernel_fp_unavailable_exception + b interrupt_return #else b ProgramCheck #endif @@ -730,12 +737,16 @@ AltiVecUnavailable: bl load_up_altivec /* if from user, just load it up */ b fast_exception_return #endif /* CONFIG_ALTIVEC */ -1: EXC_XFER_LITE(0xf20, altivec_unavailable_exception) +1: prepare_transfer_to_handler + bl altivec_unavailable_exception + b interrupt_return __HEAD PerformanceMonitor: EXCEPTION_PROLOG 0xf00 PerformanceMonitor - EXC_XFER_STD(0xf00, performance_monitor_exception) + prepare_transfer_to_handler + bl performance_monitor_exception + b interrupt_return __HEAD diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index baf10556c587..bc69b9bf61a4 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -302,15 +302,18 @@ label: #define EXCEPTION(n, intno, label, hdlr, xfer) \ START_EXCEPTION(label); \ NORMAL_EXCEPTION_PROLOG(n, intno); \ - xfer(n, hdlr) + prepare_transfer_to_handler; \ + bl hdlr; \ + b interrupt_return #define CRITICAL_EXCEPTION(n, intno, label, hdlr) \ START_EXCEPTION(label); \ CRITICAL_EXCEPTION_PROLOG(n, intno); \ SAVE_MMU_REGS; \ SAVE_xSRR(SRR); \ - EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ - crit_transfer_to_handler, ret_from_crit_exc) + prepare_transfer_to_handler; \ + bl hdlr; \ + b ret_from_crit_exc #define MCHECK_EXCEPTION(n, label, hdlr) \ START_EXCEPTION(label); \ @@ -321,21 +324,9 @@ label: SAVE_xSRR(CSRR); \ SAVE_MMU_REGS; \ SAVE_xSRR(SRR); \ - EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ - mcheck_transfer_to_handler, ret_from_mcheck_exc) - -#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret) \ - bl tfer; \ + prepare_transfer_to_handler; \ bl hdlr; \ - b ret; \ - -#define EXC_XFER_STD(n, hdlr) \ - EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler_full, \ - ret_from_except_full) - -#define EXC_XFER_LITE(n, hdlr) \ - EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, transfer_to_handler, \ - ret_from_except) + b ret_from_mcheck_exc /* Check for a single step debug exception while in an exception * handler before state has been saved. This is to catch the case @@ -404,7 +395,9 @@ label: SAVE_xSRR(CSRR); \ SAVE_MMU_REGS; \ SAVE_xSRR(SRR); \ - EXC_XFER_TEMPLATE(DebugException, 0x2008, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), debug_transfer_to_handler, ret_from_debug_exc) + prepare_transfer_to_handler; \ + bl DebugException; \ + b ret_from_debug_exc #define DEBUG_CRIT_EXCEPTION \ START_EXCEPTION(DebugCrit); \ @@ -459,7 +452,9 @@ label: stw r4,_ESR(r11); /* DebugException takes DBSR in _ESR */\ SAVE_MMU_REGS; \ SAVE_xSRR(SRR); \ - EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), crit_transfer_to_handler, ret_from_crit_exc) + prepare_transfer_to_handler; \ + bl DebugException; \ + b ret_from_crit_exc #define DATA_STORAGE_EXCEPTION \ START_EXCEPTION(DataStorage) \ @@ -468,7 +463,9 @@ label: stw r5,_ESR(r11); \ mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ stw r4, _DEAR(r11); \ - EXC_XFER_LITE(0x0300, do_page_fault) + prepare_transfer_to_handler; \ + bl do_page_fault; \ + b interrupt_return #define INSTRUCTION_STORAGE_EXCEPTION \ START_EXCEPTION(InstructionStorage) \ @@ -476,7 +473,9 @@ label: mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ stw r5,_ESR(r11); \ stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \ - EXC_XFER_LITE(0x0400, do_page_fault) + prepare_transfer_to_handler; \ + bl do_page_fault; \ + b interrupt_return #define ALIGNMENT_EXCEPTION \ START_EXCEPTION(Alignment) \ @@ -503,7 +502,9 @@ label: NORMAL_EXCEPTION_PROLOG(0x900, DECREMENTER); \ lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \ mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \ - EXC_XFER_LITE(0x0900, timer_interrupt) + prepare_transfer_to_handler; \ + bl timer_interrupt; \ + b interrupt_return #define FP_UNAVAILABLE_EXCEPTION \ START_EXCEPTION(FloatingPointUnavailable) \ @@ -511,7 +512,9 @@ label: beq 1f; \ bl load_up_fpu; /* if from user, just load it up */ \ b fast_exception_return; \ -1: EXC_XFER_STD(0x800, kernel_fp_unavailable_exception) +1: prepare_transfer_to_handler; \ + bl kernel_fp_unavailable_exception; \ + b interrupt_return #else /* __ASSEMBLY__ */ struct exception_regs { diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 210871b2eb41..48d022b1f508 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -370,9 +370,13 @@ interrupt_base: stw r4, _DEAR(r11) andis. r10,r5,(ESR_ILK|ESR_DLK)@h bne 1f - EXC_XFER_LITE(0x0300, do_page_fault) + prepare_transfer_to_handler + bl do_page_fault + b interrupt_return 1: - EXC_XFER_LITE(0x0300, CacheLockingException) + prepare_transfer_to_handler + bl CacheLockingException + b interrupt_return /* Instruction Storage Interrupt */ INSTRUCTION_STORAGE_EXCEPTION @@ -617,7 +621,9 @@ END_BTB_FLUSH_SECTION beq 1f bl load_up_spe b fast_exception_return -1: EXC_XFER_LITE(0x2010, KernelSPE) +1: prepare_transfer_to_handler + bl KernelSPE + b interrupt_return #elif defined(CONFIG_SPE_POSSIBLE) EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \ unknown_exception, EXC_XFER_STD) @@ -860,7 +866,7 @@ KernelSPE: lwz r5,_NIP(r1) bl printk #endif - b ret_from_except + b interrupt_return #ifdef CONFIG_PRINTK 87: .string "SPE used in kernel (task=%p, pc=%x) \n" #endif |