Commit 097157e1 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64e/interrupt: reconcile irq soft-mask state in C



Use existing 64s interrupt entry wrapper code to reconcile irqs in C.

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/20210316104206.407354-7-npiggin@gmail.com
parent 3db8aa10
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -51,14 +51,14 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
		kuap_save_and_lock(regs);
	}
#endif
	/*
	 * Book3E reconciles irq soft mask in asm
	 */
#ifdef CONFIG_PPC_BOOK3S_64

#ifdef CONFIG_PPC64
	if (irq_soft_mask_set_return(IRQS_ALL_DISABLED) == IRQS_ENABLED)
		trace_hardirqs_off();
	local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
#endif

#ifdef CONFIG_PPC_BOOK3S_64
	if (user_mode(regs)) {
		CT_WARN_ON(ct_state() != CONTEXT_USER);
		user_exit_irqoff();
+8 −10
Original line number Diff line number Diff line
@@ -117,13 +117,12 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)

	/*
	 * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
	 * would clobber syscall parameters. Also we always enter with IRQs
	 * enabled and nothing pending. system_call_exception() will call
	 * trace_hardirqs_off().
	 *
	 * scv enters with MSR[EE]=1, so don't set PACA_IRQ_HARD_DIS. The
	 * entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED.
	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
	 * and interrupts may be masked and pending already.
	 * system_call_exception() will call trace_hardirqs_off() which means
	 * interrupts could already have been blocked before trace_hardirqs_off,
	 * but this is the best we can do.
	 */

	/* Calling convention has r9 = orig r0, r10 = regs */
@@ -288,9 +287,8 @@ END_BTB_FLUSH_SECTION
	std	r11,-16(r10)		/* "regshere" marker */

	/*
	 * RECONCILE_IRQ_STATE without calling trace_hardirqs_off(), which
	 * would clobber syscall parameters. Also we always enter with IRQs
	 * enabled and nothing pending. system_call_exception() will call
	 * We always enter kernel from userspace with irq soft-mask enabled and
	 * nothing pending. system_call_exception() will call
	 * trace_hardirqs_off().
	 */
	li	r11,IRQS_ALL_DISABLED
+1 −38
Original line number Diff line number Diff line
@@ -409,28 +409,6 @@ exc_##n##_common: \
#define EXCEPTION_COMMON_DBG(n) \
	EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)

/*
 * This is meant for exceptions that don't immediately hard-enable.  We
 * set a bit in paca->irq_happened to ensure that a subsequent call to
 * arch_local_irq_restore() will properly hard-enable and avoid the
 * fast-path, and then reconcile irq state.
 */
#define INTS_DISABLE	RECONCILE_IRQ_STATE(r3,r4)

/*
 * This is called by exceptions that don't use INTS_DISABLE (that did not
 * touch irq indicators in the PACA).  This will restore MSR:EE to it's
 * previous value
 *
 * XXX In the long run, we may want to open-code it in order to separate the
 *     load from the wrtee, thus limiting the latency caused by the dependency
 *     but at this point, I'll favor code clarity until we have a near to final
 *     implementation
 */
#define INTS_RESTORE_HARD						    \
	ld	r11,_MSR(r1);						    \
	wrtee	r11;

/* XXX FIXME: Restore r14/r15 when necessary */
#define BAD_STACK_TRAMPOLINE(n)						    \
exc_##n##_bad_stack:							    \
@@ -479,7 +457,6 @@ exc_##n##_bad_stack: \
	START_EXCEPTION(label);						\
	NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
	EXCEPTION_COMMON(trapnum)					\
	INTS_DISABLE;							\
	ack(r8);							\
	CHECK_NAPPING();						\
	addi	r3,r1,STACK_FRAME_OVERHEAD;				\
@@ -559,7 +536,6 @@ __end_interrupts:
	mfspr	r14,SPRN_DEAR
	mfspr	r15,SPRN_ESR
	EXCEPTION_COMMON(0x300)
	INTS_DISABLE
	b	storage_fault_common

/* Instruction Storage Interrupt */
@@ -569,7 +545,6 @@ __end_interrupts:
	li	r15,0
	mr	r14,r10
	EXCEPTION_COMMON(0x400)
	INTS_DISABLE
	b	storage_fault_common

/* External Input Interrupt */
@@ -591,7 +566,6 @@ __end_interrupts:
				PROLOG_ADDITION_1REG)
	mfspr	r14,SPRN_ESR
	EXCEPTION_COMMON(0x700)
	INTS_DISABLE
	std	r14,_DSISR(r1)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	ld	r14,PACA_EXGEN+EX_R14(r13)
@@ -610,8 +584,7 @@ __end_interrupts:
	beq-	1f
	bl	load_up_fpu
	b	fast_interrupt_return
1:	INTS_DISABLE
	addi	r3,r1,STACK_FRAME_OVERHEAD
1:	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	kernel_fp_unavailable_exception
	b	interrupt_return

@@ -631,7 +604,6 @@ BEGIN_FTR_SECTION
1:
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif
	INTS_DISABLE
	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	altivec_unavailable_exception
	b	interrupt_return
@@ -642,7 +614,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
				BOOKE_INTERRUPT_ALTIVEC_ASSIST,
				PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0x220)
	INTS_DISABLE
	addi	r3,r1,STACK_FRAME_OVERHEAD
#ifdef CONFIG_ALTIVEC
BEGIN_FTR_SECTION
@@ -691,7 +662,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
	NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
				PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0xf20)
	INTS_DISABLE
	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	unknown_exception
	b	interrupt_return
@@ -827,7 +797,6 @@ kernel_dbg_exc:
	 */
	mfspr	r14,SPRN_DBSR
	EXCEPTION_COMMON_DBG(0xd08)
	INTS_DISABLE
	std	r14,_DSISR(r1)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	ld	r14,PACA_EXDBG+EX_R14(r13)
@@ -840,7 +809,6 @@ kernel_dbg_exc:
	NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
				PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0x260)
	INTS_DISABLE
	CHECK_NAPPING()
	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	performance_monitor_exception
@@ -870,7 +838,6 @@ kernel_dbg_exc:
			        PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0x2c0)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	INTS_RESTORE_HARD
	bl	unknown_exception
	b	interrupt_return

@@ -891,7 +858,6 @@ kernel_dbg_exc:
			        PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0x310)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	INTS_RESTORE_HARD
	bl	unknown_exception
	b	interrupt_return

@@ -901,7 +867,6 @@ kernel_dbg_exc:
			        PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0x320)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	INTS_RESTORE_HARD
	bl	unknown_exception
	b	interrupt_return

@@ -911,7 +876,6 @@ kernel_dbg_exc:
			        PROLOG_ADDITION_NONE)
	EXCEPTION_COMMON(0x340)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	INTS_RESTORE_HARD
	bl	unknown_exception
	b	interrupt_return

@@ -991,7 +955,6 @@ alignment_more:
	addi	r3,r1,STACK_FRAME_OVERHEAD
	ld	r14,PACA_EXGEN+EX_R14(r13)
	ld	r15,PACA_EXGEN+EX_R15(r13)
	INTS_RESTORE_HARD
	bl	alignment_exception
	REST_NVGPRS(r1)
	b	interrupt_return