[PATCH Dovetail v4 1/8] arm: irq_pipeline: Rename and move fault_entry_{enter,exit}

Florian Bezdeka <[email protected]> Tue, 07 Jul 2026 11:50:17 +0200
Newsgroups dev.linux.lists.xenomai
Message-ID <20260707-wip-flo-v7-1-arm-pipelining-fixes-v4-1-057b8af5a2ca@siemens.com>
Introducing a new header allows us to keep the implementation as
static inline function and make it re-usable for other compile units.
Moving the implementation into existing headers like asm/dovetail.h or
asm/irq_pipeline.h would require us to rewrite those helpers as macros.

Prefixing with dovetail_ to keep the Linux namespace clean.

Signed-off-by: Florian Bezdeka <[email protected]>
---
 arch/arm/include/asm/trap_entry.h | 83 ++++++++++++++++++++++++++++++++++++
 arch/arm/mm/fault.c               | 89 ++++++---------------------------------
 2 files changed, 96 insertions(+), 76 deletions(-)

diff --git a/arch/arm/include/asm/trap_entry.h b/arch/arm/include/asm/trap_entry.h
new file mode 100644
index 0000000000000000000000000000000000000000..abe5f80cd301a8ca5ddb2ca350b80bf5708f0f79
--- /dev/null
+++ b/arch/arm/include/asm/trap_entry.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASMARM_TRAP_ENTRY_H
+#define _ASMARM_TRAP_ENTRY_H
+
+#include <asm/dovetail.h>
+#include <asm/trace/exceptions.h>
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_IRQ_PIPELINE
+/*
+ * We need to synchronize the virtual interrupt state with the hard
+ * interrupt state we received on entry, then turn hardirqs back on to
+ * allow code which does not require strict serialization to be
+ * preempted by an out-of-band activity.
+ */
+static inline unsigned long dovetail_fault_entry(int exception,
+						 struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	trace_ARM_trap_entry(exception, regs);
+
+	flags = hard_local_save_flags();
+
+	/*
+	 * The companion core must demote the current context to
+	 * in-band stage if running oob on entry.
+	 */
+	mark_trap_entry(exception, regs);
+
+	if (raw_irqs_disabled_flags(flags)) {
+		stall_inband();
+		trace_hardirqs_off();
+	}
+
+	hard_local_irq_enable();
+
+	return flags;
+}
+
+static inline void dovetail_fault_exit(int exception, struct pt_regs *regs,
+				       unsigned long flags)
+{
+	WARN_ON_ONCE(irq_pipeline_debug() && hard_irqs_disabled());
+
+	/*
+	 * We expect kentry_exit_pipelined() to clear the stall bit if
+	 * kentry_enter_pipelined() observed it that way.
+	 */
+	mark_trap_exit(exception, regs);
+	trace_ARM_trap_exit(exception, regs);
+	hard_local_irq_restore(flags);
+}
+
+#else /* !CONFIG_IRQ_PIPELINE */
+
+#define dovetail_fault_entry(__exception, __regs)		\
+	do {							\
+		(void)(__exception);				\
+		(void)(__regs);					\
+	} while (0)
+
+#define dovetail_fault_exit(__exception, __regs, __flags)	\
+	do {							\
+		(void)(__exception);				\
+		(void)(__regs);					\
+		(void)(__flags);				\
+	} while (0)
+
+#endif /* !CONFIG_IRQ_PIPELINE */
+
+#else /* CONFIG_MMU */
+unsigned long dovetail_fault_entry(int exception, struct pt_regs *regs)
+{
+	return 0;
+}
+
+static inline void dovetail_fault_exit(int exception, struct pt_regs *regs,
+				       unsigned long combo)
+{ }
+#endif /* !CONFIG_MMU */
+
+#endif
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 49f5d628c4c9a91a3e879af0d541fd76665d78fe..b6b766652b753ef860d16b153685b0d3b582bffa 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -24,6 +24,7 @@
 #include <asm/system_info.h>
 #include <asm/tlbflush.h>
 #include <asm/dovetail.h>
+#include <asm/trap_entry.h>
 #define CREATE_TRACE_POINTS
 #include <asm/trace/exceptions.h>
 
@@ -38,61 +39,6 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
 	return addr >= TASK_SIZE && ULONG_MAX - addr >= size;
 }
 
-#ifdef CONFIG_IRQ_PIPELINE
-/*
- * We need to synchronize the virtual interrupt state with the hard
- * interrupt state we received on entry, then turn hardirqs back on to
- * allow code which does not require strict serialization to be
- * preempted by an out-of-band activity.
- */
-static inline
-unsigned long fault_entry(int exception, struct pt_regs *regs)
-{
-	unsigned long flags;
-
-	trace_ARM_trap_entry(exception, regs);
-
-	flags = hard_local_save_flags();
-
-	/*
-	 * The companion core must demote the current context to
-	 * in-band stage if running oob on entry.
-	 */
-	mark_trap_entry(exception, regs);
-
-	if (raw_irqs_disabled_flags(flags)) {
-		stall_inband();
-		trace_hardirqs_off();
-	}
-
-	hard_local_irq_enable();
-
-	return flags;
-}
-
-static inline
-void fault_exit(int exception, struct pt_regs *regs,
-		unsigned long flags)
-{
-	WARN_ON_ONCE(irq_pipeline_debug() && hard_irqs_disabled());
-
-	/*
-	 * We expect kentry_exit_pipelined() to clear the stall bit if
-	 * kentry_enter_pipelined() observed it that way.
-	 */
-	mark_trap_exit(exception, regs);
-	trace_ARM_trap_exit(exception, regs);
-	hard_local_irq_restore(flags);
-}
-
-#else	/* !CONFIG_IRQ_PIPELINE */
-
-#define fault_entry(__exception, __regs)  ({ 0; })
-#define fault_exit(__exception, __regs, __flags)  \
-	do { (void)(__flags); } while (0)
-
-#endif	/* !CONFIG_IRQ_PIPELINE */
-
 /*
  * This is useful to dump out the page tables associated with
  * 'addr' in mm 'mm'.
@@ -165,15 +111,6 @@ void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
 	pr_cont("\n");
 }
 #else					/* CONFIG_MMU */
-unsigned long fault_entry(int exception, struct pt_regs *regs)
-{
-	return 0;
-}
-
-static inline void fault_exit(int exception, struct pt_regs *regs,
-			unsigned long combo)
-{ }
-
 void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
 { }
 #endif					/* CONFIG_MMU */
@@ -278,9 +215,9 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	 * have no context to handle this fault with.
 	 */
 	  if (user_mode(regs)) {
-		irqflags = fault_entry(ARM_TRAP_ACCESS, regs);
+		irqflags = dovetail_fault_entry(ARM_TRAP_ACCESS, regs);
 		__do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs);
-		fault_exit(ARM_TRAP_ACCESS, regs, irqflags);
+		dovetail_fault_exit(ARM_TRAP_ACCESS, regs, irqflags);
 	  } else
 		/*
 		 * irq_pipeline: kernel faults are either quickly
@@ -391,9 +328,9 @@ do_kernel_address_page_fault(struct mm_struct *mm, unsigned long addr,
 		 * Note that __do_user_fault() will enable interrupts.
 		 */
 		harden_branch_predictor();
-		irqflags = fault_entry(ARM_TRAP_ACCESS, regs);
+		irqflags = dovetail_fault_entry(ARM_TRAP_ACCESS, regs);
 		__do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs);
-		fault_exit(ARM_TRAP_ACCESS, regs, irqflags);
+		dovetail_fault_exit(ARM_TRAP_ACCESS, regs, irqflags);
 	} else {
 		/*
 		 * Fault from kernel mode. Enable interrupts if they were
@@ -433,7 +370,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (addr >= TASK_SIZE)
 		return do_kernel_address_page_fault(mm, addr, fsr, regs);
 
-	irqflags = fault_entry(ARM_TRAP_ACCESS, regs);
+	irqflags = dovetail_fault_entry(ARM_TRAP_ACCESS, regs);
 
 	/* Enable interrupts if they were enabled in the parent context. */
 	if (interrupts_enabled(regs))
@@ -595,7 +532,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 no_context:
 	__do_kernel_fault(mm, addr, fsr, regs);
 out:
-	fault_exit(ARM_TRAP_ACCESS, regs, irqflags);
+	dovetail_fault_exit(ARM_TRAP_ACCESS, regs, irqflags);
 
 	return 0;
 }
@@ -671,9 +608,9 @@ do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (addr >= TASK_SIZE && user_mode(regs))
 		harden_branch_predictor();
 
-	irqflags = fault_entry(ARM_TRAP_SECTION, regs);
+	irqflags = dovetail_fault_entry(ARM_TRAP_SECTION, regs);
 	do_bad_area(addr, fsr, regs);
-	fault_exit(ARM_TRAP_SECTION, regs, irqflags);
+	dovetail_fault_exit(ARM_TRAP_SECTION, regs, irqflags);
 	return 0;
 }
 #endif /* CONFIG_ARM_LPAE */
@@ -726,7 +663,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
 		return;
 
-	irqflags = fault_entry(ARM_TRAP_DABT, regs);
+	irqflags = dovetail_fault_entry(ARM_TRAP_DABT, regs);
 	pr_alert("8<--- cut here ---\n");
 	pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
 		inf->name, fsr, addr);
@@ -734,7 +671,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 
 	arm_notify_die("", regs, inf->sig, inf->code, (void __user *)addr,
 		       fsr, 0);
-	fault_exit(ARM_TRAP_DABT, regs, irqflags);
+	dovetail_fault_exit(ARM_TRAP_DABT, regs, irqflags);
 }
 
 void __init
@@ -759,14 +696,14 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
 	if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
 		return;
 
-	irqflags = fault_entry(ARM_TRAP_PABT, regs);
+	irqflags = dovetail_fault_entry(ARM_TRAP_PABT, regs);
 	pr_alert("8<--- cut here ---\n");
 	pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
 		inf->name, ifsr, addr);
 
 	arm_notify_die("", regs, inf->sig, inf->code, (void __user *)addr,
 		       ifsr, 0);
-	fault_exit(ARM_TRAP_PABT, regs, irqflags);
+	dovetail_fault_exit(ARM_TRAP_PABT, regs, irqflags);
 }
 
 /*

-- 
2.55.0