Commit a214ee88 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/interrupt: Refactor interrupt_exit_user_prepare()



interrupt_exit_user_prepare() is a superset of
interrupt_exit_user_prepare_main().

Refactor to avoid code duplication.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
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/20210617155116.2167984-15-npiggin@gmail.com
parent f84aa284
Loading
Loading
Loading
Loading
+3 −54
Original line number Diff line number Diff line
@@ -404,9 +404,7 @@ notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *reg

notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs)
{
	unsigned long ti_flags;
	unsigned long flags;
	unsigned long ret = 0;
	unsigned long ret;

	if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x))
		BUG_ON(!(regs->msr & MSR_RI));
@@ -420,63 +418,14 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs)
	 */
	kuap_assert_locked();

	local_irq_save(flags);

again:
	ti_flags = READ_ONCE(current_thread_info()->flags);
	while (unlikely(ti_flags & (_TIF_USER_WORK_MASK & ~_TIF_RESTORE_TM))) {
		local_irq_enable(); /* returning to user: may enable */
		if (ti_flags & _TIF_NEED_RESCHED) {
			schedule();
		} else {
			if (ti_flags & _TIF_SIGPENDING)
				ret |= _TIF_RESTOREALL;
			do_notify_resume(regs, ti_flags);
		}
	local_irq_disable();
		ti_flags = READ_ONCE(current_thread_info()->flags);
	}

	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && IS_ENABLED(CONFIG_PPC_FPU)) {
		if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
				unlikely((ti_flags & _TIF_RESTORE_TM))) {
			restore_tm_state(regs);
		} else {
			unsigned long mathflags = MSR_FP;

			if (cpu_has_feature(CPU_FTR_VSX))
				mathflags |= MSR_VEC | MSR_VSX;
			else if (cpu_has_feature(CPU_FTR_ALTIVEC))
				mathflags |= MSR_VEC;

			/* See above restore_math comment */
			if ((regs->msr & mathflags) != mathflags)
				restore_math(regs);
		}
	}

	if (!prep_irq_for_user_exit()) {
		local_irq_enable();
		local_irq_disable();
		goto again;
	}

	booke_load_dbcr0();

#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
	local_paca->tm_scratch = regs->msr;
#endif

	account_cpu_user_exit();
	ret = interrupt_exit_user_prepare_main(0, regs);

#ifdef CONFIG_PPC64
	regs->exit_result = ret;
#endif

	/* Restore user access locks last */
	kuap_user_restore(regs);
	kuep_unlock();

	return ret;
}