]> www.infradead.org Git - linux-platform-drivers-x86.git/commitdiff
powerpc/32: Only restore non volatile registers when required
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Fri, 12 Mar 2021 12:50:40 +0000 (12:50 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 29 Mar 2021 02:22:09 +0000 (13:22 +1100)
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
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/head_40x.S
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/head_book3s_32.S
arch/powerpc/kernel/head_booke.h
arch/powerpc/kernel/head_fsl_booke.S

index 237b753720db4310d9fb1121f59f13efdd95388d..e6adb6882bde55c8ed88c41448a62078d442fbe2 100644 (file)
@@ -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
index 7270caff665c52e2d3ace8906b2c76098db11eba..f3e5b462113f0484d3c85a78f5773929895bbed0 100644 (file)
@@ -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)
index c48de97f42fc1353a0da884a10610ff10303afb5..86f844eb0e5aa035d340f4a140836ca82999d8ce 100644 (file)
@@ -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)
index 2b4875ceaea43eacc98d43565303a41d2198e7f5..425a4f20ceacd62cba2669015c3049c70ac71518 100644 (file)
@@ -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)
index 0f02b970e797b88fa8576f5d774184c02079301d..baf10556c5871ef1127305120d331e2c622f49f2 100644 (file)
@@ -483,14 +483,20 @@ label:
        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)                                          \
index bf2730b4e43ba650492b3b6b12d011eb5f6f8378..210871b2eb41cdb56b6cade9435f9125ade50c4d 100644 (file)
@@ -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)