Commit 702f0980 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64s/exception: Remove lite interrupt return



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: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200225173541.1549955-30-npiggin@gmail.com
parent 6cc0c16d
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -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
+14 −10
Original line number Diff line number Diff line
@@ -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