Commit 5f0b6ac3 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64/syscall: Reconcile interrupts



This reconciles interrupts in the system call case like all other
interrupts. This allows system_call_common to be shared with the scv
system call implementation in a subsequent patch.

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-31-npiggin@gmail.com
parent 702f0980
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -119,6 +119,17 @@ END_BTB_FLUSH_SECTION
	ld	r11,exception_marker@toc(r2)
	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
	 * trace_hardirqs_off().
	 */
	li	r11,IRQS_ALL_DISABLED
	li	r12,PACA_IRQ_HARD_DIS
	stb	r11,PACAIRQSOFTMASK(r13)
	stb	r12,PACAIRQHAPPENED(r13)

	/* Calling convention has r9 = orig r0, r10 = regs */
	mr	r9,r0
	bl	system_call_exception
+10 −14
Original line number Diff line number Diff line
@@ -17,13 +17,19 @@

typedef long (*syscall_fn)(long, long, long, long, long, long);

/* Has to run notrace because it is entered "unreconciled" */
notrace long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8,
/* Has to run notrace because it is entered not completely "reconciled" */
notrace long system_call_exception(long r3, long r4, long r5,
				   long r6, long r7, long r8,
				   unsigned long r0, struct pt_regs *regs)
{
	unsigned long ti_flags;
	syscall_fn f;

	if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
		BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);

	trace_hardirqs_off(); /* finish reconciling */

	if (IS_ENABLED(CONFIG_PPC_BOOK3S))
		BUG_ON(!(regs->msr & MSR_RI));
	BUG_ON(!(regs->msr & MSR_PR));
@@ -44,16 +50,6 @@ notrace long system_call_exception(long r3, long r4, long r5, long r6, long r7,

	kuap_check_amr();

	/*
	 * A syscall should always be called with interrupts enabled
	 * so we just unconditionally hard-enable here. When some kind
	 * of irq tracing is used, we additionally check that condition
	 * is correct
	 */
	if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) {
		WARN_ON(irq_soft_mask_return() != IRQS_ENABLED);
		WARN_ON(local_paca->irq_happened);
	}
	/*
	 * This is not required for the syscall exit path, but makes the
	 * stack frame look nicer. If this was initialised in the first stack
@@ -62,7 +58,7 @@ notrace long system_call_exception(long r3, long r4, long r5, long r6, long r7,
	 */
	regs->softe = IRQS_ENABLED;

	__hard_irq_enable();
	local_irq_enable();

	ti_flags = current_thread_info()->flags;
	if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {