powerpc/64s/exception: Remove lite interrupt return
authorNicholas Piggin <npiggin@gmail.com>
Tue, 25 Feb 2020 17:35:38 +0000 (03:35 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 1 Apr 2020 02:42:14 +0000 (13:42 +1100)
Regular interrupt return restores NVGPRS whereas lite returns do not.
This is clumsy: most interrupts can return without restoring NVGPRS in
most of the time, but there are special cases that require it (when
registers have been modified by the kernel). So change interrupt
return to not restore NVGPRS, and have interrupt handlers restore them
explicitly in the cases that requires it.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200225173541.1549955-30-npiggin@gmail.com
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S

index 5d782ac..95905ed 100644 (file)
@@ -479,12 +479,6 @@ _ASM_NOKPROBE_SYMBOL(fast_interrupt_return)
        .globl interrupt_return
 interrupt_return:
 _ASM_NOKPROBE_SYMBOL(interrupt_return)
-       REST_NVGPRS(r1)
-
-       .balign IFETCH_ALIGN_BYTES
-       .globl interrupt_return_lite
-interrupt_return_lite:
-_ASM_NOKPROBE_SYMBOL(interrupt_return_lite)
        ld      r4,_MSR(r1)
        andi.   r0,r4,MSR_PR
        beq     .Lkernel_interrupt_return
index 1124403..18bbce1 100644 (file)
@@ -1529,7 +1529,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
 
@@ -1557,6 +1557,7 @@ EXC_COMMON_BEGIN(alignment_common)
        GEN_COMMON alignment
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      alignment_exception
+       REST_NVGPRS(r1) /* instruction emulation may change GPRs */
        b       interrupt_return
 
        GEN_KVM alignment
@@ -1620,6 +1621,7 @@ EXC_COMMON_BEGIN(program_check_common)
 3:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      program_check_exception
+       REST_NVGPRS(r1) /* instruction emulation may change GPRs */
        b       interrupt_return
 
        GEN_KVM program_check
@@ -1716,7 +1718,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
 
@@ -1807,7 +1809,7 @@ EXC_COMMON_BEGIN(doorbell_super_common)
 #else
        bl      unknown_exception
 #endif
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM doorbell_super
 
@@ -2076,6 +2078,7 @@ EXC_COMMON_BEGIN(emulation_assist_common)
        GEN_COMMON emulation_assist
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      emulation_assist_interrupt
+       REST_NVGPRS(r1) /* instruction emulation may change GPRs */
        b       interrupt_return
 
        GEN_KVM emulation_assist
@@ -2194,7 +2197,7 @@ EXC_COMMON_BEGIN(h_doorbell_common)
 #else
        bl      unknown_exception
 #endif
-       b       interrupt_return_lite
+       b       interrupt_return
 
        GEN_KVM h_doorbell
 
@@ -2224,7 +2227,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
 
@@ -2271,7 +2274,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
 
@@ -2668,6 +2671,7 @@ EXC_COMMON_BEGIN(altivec_assist_common)
        addi    r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_ALTIVEC
        bl      altivec_assist_exception
+       REST_NVGPRS(r1) /* instruction emulation may change GPRs */
 #else
        bl      unknown_exception
 #endif
@@ -3057,7 +3061,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
@@ -3074,7 +3078,7 @@ handle_page_fault:
        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)
@@ -3089,9 +3093,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