The difference between lite and regular returns is that the lite case
restores all NVGPRs, whereas lite skips that. This is quite clumsy
though, most interrupts want the NVGPRs saved for debugging, not to
modify in the caller, so the NVGPRs restore is not necessary most of
the time. Restore NVGPRs explicitly for one case that requires it,
and move everything else over to avoiding the restore unless the
interrupt return demands it (e.g., handling a signal).

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/kernel/entry_64.S       |  4 ----
 arch/powerpc/kernel/exceptions-64s.S | 21 +++++++++++----------
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index b2e68f5ca8f7..00173cc904ef 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -452,10 +452,6 @@ _GLOBAL(fast_interrupt_return)
 
        .balign IFETCH_ALIGN_BYTES
 _GLOBAL(interrupt_return)
-       REST_NVGPRS(r1)
-
-       .balign IFETCH_ALIGN_BYTES
-_GLOBAL(interrupt_return_lite)
        ld      r4,_MSR(r1)
        andi.   r0,r4,MSR_PR
        beq     kernel_interrupt_return
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 269edd1460be..1bccc869ebd3 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1507,7 +1507,7 @@ EXC_COMMON_BEGIN(hardware_interrupt_common)
        RUNLATCH_ON
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_IRQ
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM hardware_interrupt
 
@@ -1694,7 +1694,7 @@ EXC_COMMON_BEGIN(decrementer_common)
        RUNLATCH_ON
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      timer_interrupt
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM decrementer
 
@@ -1785,7 +1785,7 @@ EXC_COMMON_BEGIN(doorbell_super_common)
 #else
        bl      unknown_exception
 #endif
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM doorbell_super
 
@@ -2183,7 +2183,7 @@ EXC_COMMON_BEGIN(h_doorbell_common)
 #else
        bl      unknown_exception
 #endif
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM h_doorbell
 
@@ -2213,7 +2213,7 @@ EXC_COMMON_BEGIN(h_virt_irq_common)
        RUNLATCH_ON
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_IRQ
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM h_virt_irq
 
@@ -2260,7 +2260,7 @@ EXC_COMMON_BEGIN(performance_monitor_common)
        RUNLATCH_ON
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      performance_monitor_exception
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM performance_monitor
 
@@ -3013,7 +3013,7 @@ do_hash_page:
         cmpdi  r3,0                    /* see if __hash_page succeeded */
 
        /* Success */
-       beq     interrupt_return_lite   /* Return from exception on success */
+       beq     interrupt_return        /* Return from exception on success */
 
        /* Error */
        blt-    13f
@@ -3027,10 +3027,11 @@ do_hash_page:
 handle_page_fault:
 11:    andis.  r0,r5,DSISR_DABRMATCH@h
        bne-    handle_dabr_fault
+       bl      save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      do_page_fault
        cmpdi   r3,0
-       beq+    interrupt_return_lite
+       beq+    interrupt_return
        mr      r5,r3
        addi    r3,r1,STACK_FRAME_OVERHEAD
        ld      r4,_DAR(r1)
@@ -3045,9 +3046,9 @@ handle_dabr_fault:
        bl      do_break
        /*
         * do_break() may have changed the NV GPRS while handling a breakpoint.
-        * If so, we need to restore them with their updated values. Don't use
-        * interrupt_return_lite here.
+        * If so, we need to restore them with their updated values.
         */
+       REST_NVGPRS(r1)
        b       interrupt_return
 
 
-- 
2.23.0

Reply via email to