All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mukesh Kumar Chaurasiya <mkchauras@linux.ibm.com>
To: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com,
	christophe.leroy@csgroup.eu, oleg@redhat.com, kees@kernel.org,
	luto@amacapital.net, wad@chromium.org, mchauras@linux.ibm.com,
	thuth@redhat.com, sshegde@linux.ibm.com, charlie@rivosinc.com,
	macro@orcam.me.uk, akpm@linux-foundation.org, ldv@strace.io,
	deller@gmx.de, ankur.a.arora@oracle.com,
	segher@kernel.crashing.org, tglx@linutronix.de,
	thomas.weissschuh@linutronix.de, peterz@infradead.org,
	menglong8.dong@gmail.com, bigeasy@linutronix.de,
	namcao@linutronix.de, kan.liang@linux.intel.com,
	mingo@kernel.org, atrajeev@linux.vnet.ibm.com,
	mark.barnett@arm.com, linuxppc-dev@lists.ozlabs.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v2 3/8] powerpc: introduce arch_enter_from_user_mode
Date: Sun, 14 Dec 2025 18:32:39 +0530	[thread overview]
Message-ID: <20251214130245.43664-4-mkchauras@linux.ibm.com> (raw)
In-Reply-To: <20251214130245.43664-1-mkchauras@linux.ibm.com>

From: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>

Implement the arch_enter_from_user_mode() hook required by the generic
entry/exit framework. This helper prepares the CPU state when entering
the kernel from userspace, ensuring correct handling of KUAP/KUEP,
transactional memory, and debug register state.

As part of this change, move booke_load_dbcr0() from interrupt.c to
interrupt.h so it can be used by the new helper without introducing
cross-file dependencies.

This patch contains no functional changes, it is purely preparatory for
enabling the generic syscall and interrupt entry path on PowerPC.

Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
---
 arch/powerpc/include/asm/entry-common.h | 97 +++++++++++++++++++++++++
 arch/powerpc/include/asm/interrupt.h    | 22 ++++++
 arch/powerpc/kernel/interrupt.c         | 22 ------
 3 files changed, 119 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h
index 3af16d821d07..093ece06ef79 100644
--- a/arch/powerpc/include/asm/entry-common.h
+++ b/arch/powerpc/include/asm/entry-common.h
@@ -5,7 +5,104 @@
 
 #ifdef CONFIG_GENERIC_IRQ_ENTRY
 
+#include <asm/cputime.h>
+#include <asm/interrupt.h>
 #include <asm/stacktrace.h>
+#include <asm/tm.h>
+
+static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs)
+{
+	if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+		BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
+
+	BUG_ON(regs_is_unrecoverable(regs));
+	BUG_ON(!user_mode(regs));
+	BUG_ON(regs_irqs_disabled(regs));
+
+#ifdef CONFIG_PPC_PKEY
+	if (mmu_has_feature(MMU_FTR_PKEY) && trap_is_syscall(regs)) {
+		unsigned long amr, iamr;
+		bool flush_needed = false;
+		/*
+		 * When entering from userspace we mostly have the AMR/IAMR
+		 * different from kernel default values. Hence don't compare.
+		 */
+		amr = mfspr(SPRN_AMR);
+		iamr = mfspr(SPRN_IAMR);
+		regs->amr  = amr;
+		regs->iamr = iamr;
+		if (mmu_has_feature(MMU_FTR_KUAP)) {
+			mtspr(SPRN_AMR, AMR_KUAP_BLOCKED);
+			flush_needed = true;
+		}
+		if (mmu_has_feature(MMU_FTR_BOOK3S_KUEP)) {
+			mtspr(SPRN_IAMR, AMR_KUEP_BLOCKED);
+			flush_needed = true;
+		}
+		if (flush_needed)
+			isync();
+	} else
+#endif
+		kuap_assert_locked();
+
+	booke_restore_dbcr0();
+
+	account_cpu_user_entry();
+
+	account_stolen_time();
+
+	/*
+	 * This is not required for the syscall exit path, but makes the
+	 * stack frame look nicer. If this was initialised in the first stack
+	 * frame, or if the unwinder was taught the first stack frame always
+	 * returns to user with IRQS_ENABLED, this store could be avoided!
+	 */
+	irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
+
+	/*
+	 * If system call is called with TM active, set _TIF_RESTOREALL to
+	 * prevent RFSCV being used to return to userspace, because POWER9
+	 * TM implementation has problems with this instruction returning to
+	 * transactional state. Final register values are not relevant because
+	 * the transaction will be aborted upon return anyway. Or in the case
+	 * of unsupported_scv SIGILL fault, the return state does not much
+	 * matter because it's an edge case.
+	 */
+	if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) &&
+	    unlikely(MSR_TM_TRANSACTIONAL(regs->msr)))
+		set_bits(_TIF_RESTOREALL, &current_thread_info()->flags);
+
+	/*
+	 * If the system call was made with a transaction active, doom it and
+	 * return without performing the system call. Unless it was an
+	 * unsupported scv vector, in which case it's treated like an illegal
+	 * instruction.
+	 */
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+	if (unlikely(MSR_TM_TRANSACTIONAL(regs->msr)) &&
+	    !trap_is_unsupported_scv(regs)) {
+		/* Enable TM in the kernel, and disable EE (for scv) */
+		hard_irq_disable();
+		mtmsr(mfmsr() | MSR_TM);
+
+		/* tabort, this dooms the transaction, nothing else */
+		asm volatile(".long 0x7c00071d | ((%0) << 16)"
+			     :: "r"(TM_CAUSE_SYSCALL | TM_CAUSE_PERSISTENT));
+
+		/*
+		 * Userspace will never see the return value. Execution will
+		 * resume after the tbegin. of the aborted transaction with the
+		 * checkpointed register state. A context switch could occur
+		 * or signal delivered to the process before resuming the
+		 * doomed transaction context, but that should all be handled
+		 * as expected.
+		 */
+		return;
+	}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+}
+
+#define arch_enter_from_user_mode arch_enter_from_user_mode
 
 #endif /* CONFIG_GENERIC_IRQ_ENTRY */
 #endif /* _ASM_PPC_ENTRY_COMMON_H */
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index 0e2cddf8bd21..ca8a2cda9400 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -138,6 +138,28 @@ static inline void nap_adjust_return(struct pt_regs *regs)
 #endif
 }
 
+static inline void booke_load_dbcr0(void)
+{
+#ifdef CONFIG_PPC_ADV_DEBUG_REGS
+	unsigned long dbcr0 = current->thread.debug.dbcr0;
+
+	if (likely(!(dbcr0 & DBCR0_IDM)))
+		return;
+
+	/*
+	 * Check to see if the dbcr0 register is set up to debug.
+	 * Use the internal debug mode bit to do this.
+	 */
+	mtmsr(mfmsr() & ~MSR_DE);
+	if (IS_ENABLED(CONFIG_PPC32)) {
+		isync();
+		global_dbcr0[smp_processor_id()] = mfspr(SPRN_DBCR0);
+	}
+	mtspr(SPRN_DBCR0, dbcr0);
+	mtspr(SPRN_DBSR, -1);
+#endif
+}
+
 static inline void booke_restore_dbcr0(void)
 {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 0d8fd47049a1..2a09ac5dabd6 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -78,28 +78,6 @@ static notrace __always_inline bool prep_irq_for_enabled_exit(bool restartable)
 	return true;
 }
 
-static notrace void booke_load_dbcr0(void)
-{
-#ifdef CONFIG_PPC_ADV_DEBUG_REGS
-	unsigned long dbcr0 = current->thread.debug.dbcr0;
-
-	if (likely(!(dbcr0 & DBCR0_IDM)))
-		return;
-
-	/*
-	 * Check to see if the dbcr0 register is set up to debug.
-	 * Use the internal debug mode bit to do this.
-	 */
-	mtmsr(mfmsr() & ~MSR_DE);
-	if (IS_ENABLED(CONFIG_PPC32)) {
-		isync();
-		global_dbcr0[smp_processor_id()] = mfspr(SPRN_DBCR0);
-	}
-	mtspr(SPRN_DBCR0, dbcr0);
-	mtspr(SPRN_DBSR, -1);
-#endif
-}
-
 static notrace void check_return_regs_valid(struct pt_regs *regs)
 {
 #ifdef CONFIG_PPC_BOOK3S_64
-- 
2.52.0



  parent reply	other threads:[~2025-12-14 13:05 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-14 13:02 [PATCH v2 0/8] Generic IRQ entry/exit support for powerpc Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` [PATCH v2 1/8] powerpc: rename arch_irq_disabled_regs Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` [PATCH v2 2/8] powerpc: Prepare to build with generic entry/exit framework Mukesh Kumar Chaurasiya
2025-12-16  9:27   ` Christophe Leroy (CS GROUP)
2025-12-16 14:42     ` Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` Mukesh Kumar Chaurasiya [this message]
2025-12-16  9:38   ` [PATCH v2 3/8] powerpc: introduce arch_enter_from_user_mode Christophe Leroy (CS GROUP)
2025-12-16 14:47     ` Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` [PATCH v2 4/8] powerpc: Introduce syscall exit arch functions Mukesh Kumar Chaurasiya
2025-12-16  9:46   ` Christophe Leroy (CS GROUP)
2025-12-16 14:51     ` Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` [PATCH v2 5/8] powerpc: add exit_flags field in pt_regs Mukesh Kumar Chaurasiya
2025-12-16  9:52   ` Christophe Leroy (CS GROUP)
2025-12-16 14:56     ` Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` [PATCH v2 6/8] powerpc: Prepare for IRQ entry exit Mukesh Kumar Chaurasiya
2025-12-16  9:58   ` Christophe Leroy (CS GROUP)
2025-12-16 15:00     ` Mukesh Kumar Chaurasiya
2025-12-16 22:40       ` Christophe Leroy (CS GROUP)
2025-12-17  4:43         ` Mukesh Kumar Chaurasiya
2025-12-19  4:56           ` Mukesh Kumar Chaurasiya
2025-12-14 13:02 ` [PATCH v2 7/8] powerpc: Enable IRQ generic entry/exit path Mukesh Kumar Chaurasiya
2025-12-16  6:29   ` kernel test robot
2025-12-16 15:02     ` Mukesh Kumar Chaurasiya
2025-12-16 10:43   ` Christophe Leroy (CS GROUP)
2025-12-16 15:06     ` Mukesh Kumar Chaurasiya
2025-12-17  2:10   ` kernel test robot
2025-12-17 21:32   ` kernel test robot
2025-12-14 13:02 ` [PATCH v2 8/8] powerpc: Enable Generic Entry/Exit for syscalls Mukesh Kumar Chaurasiya
2025-12-14 16:20   ` Segher Boessenkool
2025-12-15 18:32     ` Mukesh Kumar Chaurasiya
2025-12-15 20:27   ` kernel test robot
2025-12-16 15:08     ` Mukesh Kumar Chaurasiya
2025-12-16 22:57       ` Christophe Leroy (CS GROUP)
2025-12-16  6:41   ` Christophe Leroy (CS GROUP)
2025-12-16 15:09     ` Mukesh Kumar Chaurasiya
2025-12-16 11:01   ` Christophe Leroy (CS GROUP)
2025-12-16 15:13     ` Mukesh Kumar Chaurasiya
2026-01-04 12:36 ` [PATCH v2 0/8] Generic IRQ entry/exit support for powerpc Samir M

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251214130245.43664-4-mkchauras@linux.ibm.com \
    --to=mkchauras@linux.ibm.com \
    --cc=akpm@linux-foundation.org \
    --cc=ankur.a.arora@oracle.com \
    --cc=atrajeev@linux.vnet.ibm.com \
    --cc=bigeasy@linutronix.de \
    --cc=charlie@rivosinc.com \
    --cc=christophe.leroy@csgroup.eu \
    --cc=deller@gmx.de \
    --cc=kan.liang@linux.intel.com \
    --cc=kees@kernel.org \
    --cc=ldv@strace.io \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=luto@amacapital.net \
    --cc=macro@orcam.me.uk \
    --cc=maddy@linux.ibm.com \
    --cc=mark.barnett@arm.com \
    --cc=mchauras@linux.ibm.com \
    --cc=menglong8.dong@gmail.com \
    --cc=mingo@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=namcao@linutronix.de \
    --cc=npiggin@gmail.com \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=segher@kernel.crashing.org \
    --cc=sshegde@linux.ibm.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.weissschuh@linutronix.de \
    --cc=thuth@redhat.com \
    --cc=wad@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.