Commit 8f6ff5bd authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/32: Only restore non volatile registers when required



Until now, non volatile registers were restored everytime they
were saved, ie using EXC_XFER_STD meant saving and restoring
them while EXC_XFER_LITE meant neither saving not restoring them.

Now that they are always saved, EXC_XFER_STD means to restore
them and EXC_XFER_LITE means to not restore them.

Most of the users of EXC_XFER_STD only need to retrieve the
non volatile registers. For them there is no need to restore
the non volatile registers as they have not been modified.

Only very few exceptions require non volatile registers restore.

Opencode the few places which require saving of non volatile
registers.

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/d1cb12d8023cc6afc1f07150565571373c04945c.1615552867.git.christophe.leroy@csgroup.eu
parent bce4c26a
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -358,7 +358,6 @@ _ASM_NOKPROBE_SYMBOL(fast_exception_return)

	.globl	ret_from_except_full
ret_from_except_full:
	REST_NVGPRS(r1)
	/* fall through */

	.globl	ret_from_except
+8 −2
Original line number Diff line number Diff line
@@ -228,12 +228,18 @@ _ASM_NOKPROBE_SYMBOL(\name\()_virt)
/* 0x0600 - Alignment Exception */
	START_EXCEPTION(0x0600, Alignment)
	EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1
	EXC_XFER_STD(0x600, alignment_exception)
	prepare_transfer_to_handler
	bl	alignment_exception
	REST_NVGPRS(r1)
	b	interrupt_return

/* 0x0700 - Program Exception */
	START_EXCEPTION(0x0700, ProgramCheck)
	EXCEPTION_PROLOG 0x700 ProgramCheck handle_dar_dsisr=1
	EXC_XFER_STD(0x700, program_check_exception)
	prepare_transfer_to_handler
	bl	program_check_exception
	REST_NVGPRS(r1)
	b	interrupt_return

	EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_STD)
	EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_STD)
+20 −4
Original line number Diff line number Diff line
@@ -131,10 +131,18 @@ instruction_counter:
/* Alignment exception */
	START_EXCEPTION(0x600, Alignment)
	EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1
	EXC_XFER_STD(0x600, alignment_exception)
	prepare_transfer_to_handler
	bl	alignment_exception
	REST_NVGPRS(r1)
	b	interrupt_return

/* Program check exception */
	EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
	START_EXCEPTION(0x700, ProgramCheck)
	EXCEPTION_PROLOG 0x700 ProgramCheck
	prepare_transfer_to_handler
	bl	program_check_exception
	REST_NVGPRS(r1)
	b	interrupt_return

/* Decrementer */
	EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
@@ -149,7 +157,12 @@ instruction_counter:
/* On the MPC8xx, this is a software emulation interrupt.  It occurs
 * for all unimplemented and illegal instructions.
 */
	EXCEPTION(0x1000, SoftEmu, emulation_assist_interrupt, EXC_XFER_STD)
	START_EXCEPTION(0x1000, SoftEmu)
	EXCEPTION_PROLOG 0x1000 SoftEmu
	prepare_transfer_to_handler
	bl	emulation_assist_interrupt
	REST_NVGPRS(r1)
	b	interrupt_return

/*
 * For the MPC8xx, this is a software tablewalk to load the instruction
@@ -348,7 +361,10 @@ DARFixed:/* Return from dcbx instruction bug workaround */
	EXCEPTION_PROLOG_2 0x1c00 DataBreakpoint handle_dar_dsisr=1
	mfspr	r4,SPRN_BAR
	stw	r4,_DAR(r11)
	EXC_XFER_STD(0x1c00, do_break)
	prepare_transfer_to_handler
	bl	do_break
	REST_NVGPRS(r1)
	b	interrupt_return

#ifdef CONFIG_PERF_EVENTS
	START_EXCEPTION(0x1d00, InstructionBreakpoint)
+14 −3
Original line number Diff line number Diff line
@@ -300,7 +300,10 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
	andis.	r0, r5, DSISR_DABRMATCH@h
	bne-	1f
	EXC_XFER_LITE(0x300, do_page_fault)
1:	EXC_XFER_STD(0x300, do_break)
1:	prepare_transfer_to_handler
	bl	do_break
	REST_NVGPRS(r1)
	b	interrupt_return


/* Instruction access exception. */
@@ -336,10 +339,18 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
/* Alignment exception */
	START_EXCEPTION(0x600, Alignment)
	EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1
	EXC_XFER_STD(0x600, alignment_exception)
	prepare_transfer_to_handler
	bl	alignment_exception
	REST_NVGPRS(r1)
	b	interrupt_return

/* Program check exception */
	EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
	START_EXCEPTION(0x700, ProgramCheck)
	EXCEPTION_PROLOG 0x700 ProgramCheck
	prepare_transfer_to_handler
	bl	program_check_exception
	REST_NVGPRS(r1)
	b	interrupt_return

/* Floating-point unavailable */
	START_EXCEPTION(0x800, FPUnavailable)
+8 −2
Original line number Diff line number Diff line
@@ -483,14 +483,20 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
	NORMAL_EXCEPTION_PROLOG(0x600, ALIGNMENT);		      \
	mfspr   r4,SPRN_DEAR;           /* Grab the DEAR and save it */	      \
	stw     r4,_DEAR(r11);						      \
	EXC_XFER_STD(0x0600, alignment_exception)
	prepare_transfer_to_handler;					      \
	bl	alignment_exception;					      \
	REST_NVGPRS(r1);						      \
	b	interrupt_return

#define PROGRAM_EXCEPTION						      \
	START_EXCEPTION(Program)					      \
	NORMAL_EXCEPTION_PROLOG(0x700, PROGRAM);		      \
	mfspr	r4,SPRN_ESR;		/* Grab the ESR and save it */	      \
	stw	r4,_ESR(r11);						      \
	EXC_XFER_STD(0x0700, program_check_exception)
	prepare_transfer_to_handler;					      \
	bl	program_check_exception;				      \
	REST_NVGPRS(r1);						      \
	b	interrupt_return

#define DECREMENTER_EXCEPTION						      \
	START_EXCEPTION(Decrementer)					      \
Loading