Skip to content

Commit

Permalink
powerpc/32: Only restore non volatile registers when required
Browse files Browse the repository at this point in the history
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: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/d1cb12d8023cc6afc1f07150565571373c04945c.1615552867.git.christophe.leroy@csgroup.eu
  • Loading branch information
Christophe Leroy authored and Michael Ellerman committed Mar 29, 2021
1 parent bce4c26 commit 8f6ff5b
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 16 deletions.
1 change: 0 additions & 1 deletion arch/powerpc/kernel/entry_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions arch/powerpc/kernel/head_40x.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
24 changes: 20 additions & 4 deletions arch/powerpc/kernel/head_8xx.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 14 additions & 3 deletions arch/powerpc/kernel/head_book3s_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 8 additions & 2 deletions arch/powerpc/kernel/head_booke.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
16 changes: 12 additions & 4 deletions arch/powerpc/kernel/head_fsl_booke.S
Original file line number Diff line number Diff line change
Expand Up @@ -625,12 +625,20 @@ END_BTB_FLUSH_SECTION

/* SPE Floating Point Data */
#ifdef CONFIG_SPE
EXCEPTION(0x2030, SPE_FP_DATA, SPEFloatingPointData,
SPEFloatingPointException, EXC_XFER_STD)
START_EXCEPTION(SPEFloatingPointData)
NORMAL_EXCEPTION_PROLOG(0x2030, SPE_FP_DATA)
prepare_transfer_to_handler
bl SPEFloatingPointException
REST_NVGPRS(r1)
b interrupt_return

/* SPE Floating Point Round */
EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
SPEFloatingPointRoundException, EXC_XFER_STD)
START_EXCEPTION(SPEFloatingPointRound)
NORMAL_EXCEPTION_PROLOG(0x2050, SPE_FP_ROUND)
prepare_transfer_to_handler
bl SPEFloatingPointRoundException
REST_NVGPRS(r1)
b interrupt_return
#elif defined(CONFIG_SPE_POSSIBLE)
EXCEPTION(0x2040, SPE_FP_DATA, SPEFloatingPointData,
unknown_exception, EXC_XFER_STD)
Expand Down

0 comments on commit 8f6ff5b

Please sign in to comment.