Commit 4c0104a8 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

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: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/ca5795d04a220586b7037dbbbe6951dfa9e768eb.1615552867.git.christophe.leroy@csgroup.eu
parent 8f6ff5bd
Loading
Loading
Loading
Loading
+1 −41
Original line number Original line Diff line number Diff line
@@ -48,30 +48,6 @@
 */
 */
	.align	12
	.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
 * This code finishes saving the registers to the exception frame
 * and jumps to the appropriate handler for the exception, turning
 * 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
 * Note that we rely on the caller having set cr0.eq iff the exception
 * occurred in kernel mode (i.e. MSR:PR = 0).
 * 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
	.globl	prepare_transfer_to_handler
prepare_transfer_to_handler:
prepare_transfer_to_handler:
	SAVE_NVGPRS(r11)
	SAVE_NVGPRS(r11)
@@ -136,7 +105,6 @@ transfer_to_handler_cont:
	b	fast_exception_return
	b	fast_exception_return
#endif
#endif
_ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler)
_ASM_NOKPROBE_SYMBOL(prepare_transfer_to_handler)
_ASM_NOKPROBE_SYMBOL(transfer_to_handler)
_ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont)
_ASM_NOKPROBE_SYMBOL(transfer_to_handler_cont)


	.globl	transfer_to_syscall
	.globl	transfer_to_syscall
@@ -352,18 +320,10 @@ _ASM_NOKPROBE_SYMBOL(fast_exception_return)
3:
3:
	li	r10,-1
	li	r10,-1
	stw	r10,_TRAP(r11)
	stw	r10,_TRAP(r11)
	bl	transfer_to_handler_full
	prepare_transfer_to_handler
	bl	unrecoverable_exception
	bl	unrecoverable_exception
	trap	/* should not get here */
	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
	.globl interrupt_return
interrupt_return:
interrupt_return:
	lwz	r4,_MSR(r1)
	lwz	r4,_MSR(r1)
+6 −15
Original line number Original line Diff line number Diff line
@@ -189,20 +189,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
#define EXCEPTION(n, label, hdlr, xfer)		\
#define EXCEPTION(n, label, hdlr, xfer)		\
	START_EXCEPTION(n, label)		\
	START_EXCEPTION(n, label)		\
	EXCEPTION_PROLOG n label;		\
	EXCEPTION_PROLOG n label;		\
	xfer(n, hdlr)
	prepare_transfer_to_handler;		\

#define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret)		\
	bl	tfer;						\
	bl	hdlr;				\
	bl	hdlr;				\
	b	ret
	b	interrupt_return

#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)


.macro vmap_stack_overflow_exception
.macro vmap_stack_overflow_exception
	__HEAD
	__HEAD
@@ -218,7 +207,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
	lwz	r1, emergency_ctx@l(r1)
	lwz	r1, emergency_ctx@l(r1)
	addi	r1, r1, THREAD_SIZE - INT_FRAME_SIZE
	addi	r1, r1, THREAD_SIZE - INT_FRAME_SIZE
	EXCEPTION_PROLOG_2 0 vmap_stack_overflow
	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
.endm


#endif /* __HEAD_32_H__ */
#endif /* __HEAD_32_H__ */
+21 −12
Original line number Original line Diff line number Diff line
@@ -187,8 +187,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
#define CRITICAL_EXCEPTION(n, label, hdlr)			\
#define CRITICAL_EXCEPTION(n, label, hdlr)			\
	START_EXCEPTION(n, label);				\
	START_EXCEPTION(n, label);				\
	CRITICAL_EXCEPTION_PROLOG n label;				\
	CRITICAL_EXCEPTION_PROLOG n label;				\
	EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
	prepare_transfer_to_handler;				\
			  crit_transfer_to_handler, ret_from_crit_exc)
	bl	hdlr;						\
	b	ret_from_crit_exc


/*
/*
 * 0x0100 - Critical Interrupt Exception
 * 0x0100 - Critical Interrupt Exception
@@ -209,7 +210,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
 */
 */
	START_EXCEPTION(0x0300,	DataStorage)
	START_EXCEPTION(0x0300,	DataStorage)
	EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1
	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
 * 0x0400 - Instruction Storage Exception
@@ -220,7 +223,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
	li	r5,0
	li	r5,0
	stw	r5, _ESR(r11)		/* Zero ESR */
	stw	r5, _ESR(r11)		/* Zero ESR */
	stw	r12, _DEAR(r11)		/* SRR0 as DEAR */
	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 */
/* 0x0500 - External Interrupt Exception */
	EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
	EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
@@ -499,9 +504,9 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
	/* continue normal handling for a critical exception... */
	/* continue normal handling for a critical exception... */
2:	mfspr	r4,SPRN_DBSR
2:	mfspr	r4,SPRN_DBSR
	stw	r4,_ESR(r11)		/* DebugException takes DBSR in _ESR */
	stw	r4,_ESR(r11)		/* DebugException takes DBSR in _ESR */
	EXC_XFER_TEMPLATE(DebugException, 0x2002, \
	prepare_transfer_to_handler
		(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
	bl	DebugException
		crit_transfer_to_handler, ret_from_crit_exc)
	b	ret_from_crit_exc


	/* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
	/* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
	__HEAD
	__HEAD
@@ -509,21 +514,25 @@ Decrementer:
	EXCEPTION_PROLOG 0x1000 Decrementer
	EXCEPTION_PROLOG 0x1000 Decrementer
	lis	r0,TSR_PIS@h
	lis	r0,TSR_PIS@h
	mtspr	SPRN_TSR,r0		/* Clear the PIT exception */
	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) */
	/* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
	__HEAD
	__HEAD
FITException:
FITException:
	EXCEPTION_PROLOG 0x1010 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) */
	/* Watchdog Timer (WDT) Exception. (from 0x1020) */
	__HEAD
	__HEAD
WDTException:
WDTException:
	CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
	CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException
	EXC_XFER_TEMPLATE(WatchdogException, 0x1020+2,
	prepare_transfer_to_handler
	                  (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)),
	bl	WatchdogException
			  crit_transfer_to_handler, ret_from_crit_exc)
	b	ret_from_crit_exc


/* Other PowerPC processors, namely those derived from the 6xx-series
/* Other PowerPC processors, namely those derived from the 6xx-series
 * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
 * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
+9 −3
Original line number Original line Diff line number Diff line
@@ -123,7 +123,9 @@ instruction_counter:
/* Machine check */
/* Machine check */
	START_EXCEPTION(0x200, MachineCheck)
	START_EXCEPTION(0x200, MachineCheck)
	EXCEPTION_PROLOG 0x200 MachineCheck handle_dar_dsisr=1
	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 */
/* External interrupt */
	EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
	EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
@@ -314,7 +316,9 @@ instruction_counter:
.Litlbie:
.Litlbie:
	stw	r12, _DAR(r11)
	stw	r12, _DAR(r11)
	stw	r5, _DSISR(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
/* 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
 * 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
	beq+	.Ldtlbie
	tlbie	r4
	tlbie	r4
.Ldtlbie:
.Ldtlbie:
	EXC_XFER_LITE(0x300, do_page_fault)
	prepare_transfer_to_handler
	bl	do_page_fault
	b	interrupt_return


#ifdef CONFIG_VMAP_STACK
#ifdef CONFIG_VMAP_STACK
	vmap_stack_overflow_exception
	vmap_stack_overflow_exception
+19 −8
Original line number Original line Diff line number Diff line
@@ -271,7 +271,9 @@ __secondary_hold_acknowledge:
	beq	cr1, 1f
	beq	cr1, 1f
	twi	31, 0, 0
	twi	31, 0, 0
#endif
#endif
1:	EXC_XFER_STD(0x200, machine_check_exception)
1:	prepare_transfer_to_handler
	bl	machine_check_exception
	b	interrupt_return


/* Data access exception. */
/* Data access exception. */
	START_EXCEPTION(0x300, DataAccess)
	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
1:	EXCEPTION_PROLOG_0 handle_dar_dsisr=1
	EXCEPTION_PROLOG_1
	EXCEPTION_PROLOG_1
	EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1
	EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1
	prepare_transfer_to_handler
	lwz	r5, _DSISR(r11)
	lwz	r5, _DSISR(r11)
	andis.	r0, r5, DSISR_DABRMATCH@h
	andis.	r0, r5, DSISR_DABRMATCH@h
	bne-	1f
	bne-	1f
	EXC_XFER_LITE(0x300, do_page_fault)
	bl	do_page_fault
1:	prepare_transfer_to_handler
	b	interrupt_return
	bl	do_break
1:	bl	do_break
	REST_NVGPRS(r1)
	REST_NVGPRS(r1)
	b	interrupt_return
	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 */
	andis.	r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
	stw	r5, _DSISR(r11)
	stw	r5, _DSISR(r11)
	stw	r12, _DAR(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 */
/* External interrupt */
	EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
	EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
@@ -366,7 +371,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
	beq	1f
	beq	1f
	bl	load_up_fpu		/* if from user, just load it up */
	bl	load_up_fpu		/* if from user, just load it up */
	b	fast_exception_return
	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
#else
	b 	ProgramCheck
	b 	ProgramCheck
#endif
#endif
@@ -730,12 +737,16 @@ AltiVecUnavailable:
	bl	load_up_altivec		/* if from user, just load it up */
	bl	load_up_altivec		/* if from user, just load it up */
	b	fast_exception_return
	b	fast_exception_return
#endif /* CONFIG_ALTIVEC */
#endif /* CONFIG_ALTIVEC */
1:	EXC_XFER_LITE(0xf20, altivec_unavailable_exception)
1:	prepare_transfer_to_handler
	bl	altivec_unavailable_exception
	b	interrupt_return


	__HEAD
	__HEAD
PerformanceMonitor:
PerformanceMonitor:
	EXCEPTION_PROLOG 0xf00 PerformanceMonitor
	EXCEPTION_PROLOG 0xf00 PerformanceMonitor
	EXC_XFER_STD(0xf00, performance_monitor_exception)
	prepare_transfer_to_handler
	bl	performance_monitor_exception
	b	interrupt_return




	__HEAD
	__HEAD
Loading