[PATCH Dovetail v3 5/6] dovetail: Decouple kernel/irq/pipeline.c from irqstate bit definitions

Florian Bezdeka <[email protected]> Mon, 22 Jun 2026 10:05:29 +0200
Newsgroups dev.linux.lists.xenomai
Message-ID <20260622-wip-flo-v7-1-arm-pipelining-fixes-v3-5-230f03227abb@siemens.com>
This only affects architectures where CONFIG_GENERIC_ENTRY is not set.

Moving the stall bit definitions into the architecture specific
implementations allows re-use of those definition within the arch
specifics.

Moving the defines to include/linux/irq_pipeline.h turned out to
trigger a lot of trouble as re-use will live in asm/ where including
a "general" header is quite hard.

The platform independent implementation will now need the following
arch specific hooks, all operating on the platform specific
struct pt_regs:
  - arch_kentry_irqs_enabled()
  - arch_kentry_lockdep_set()
  - arch_kentry_clear_irq_state()
  - arch_kentry_set_irqs_stalled()
  - arch_kentry_set_lockdep()

Signed-off-by: Florian Bezdeka <[email protected]>
---
 arch/arm/include/asm/irq_pipeline.h   | 41 +++++++++++++++++++++++++++--------
 arch/arm64/include/asm/irq_pipeline.h |  9 ++++----
 kernel/irq/pipeline.c                 | 20 +++++------------
 3 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/arch/arm/include/asm/irq_pipeline.h b/arch/arm/include/asm/irq_pipeline.h
index 5e3a20149246505e8401bc7157d9c9f13673f45e..d1ee5cefd407a117eca5a1907848580e0a5bb622 100644
--- a/arch/arm/include/asm/irq_pipeline.h
+++ b/arch/arm/include/asm/irq_pipeline.h
@@ -98,15 +98,33 @@ static inline void arch_handle_irq_pipelined(struct pt_regs *regs)
 	handle_arch_irq(regs);
 }
 
-#define arch_kentry_get_irqstate(__regs)		\
-	({						\
-		to_svc_pt_regs(__regs)->irqstate;	\
-	})
-
-#define arch_kentry_set_irqstate(__regs, __irqstate)		\
-	do {							\
-		to_svc_pt_regs(__regs)->irqstate = __irqstate;	\
-	} while (0)
+#define KENTRY_STALL_BIT      BIT(0) /* Tracks INBAND_STALL_BIT */
+#define KENTRY_LOCKDEP_BIT    BIT(1) /* Tracks hardirqs_enabled */
+
+#define arch_kentry_irqs_enabled(__regs)			\
+({								\
+	!(to_svc_pt_regs(__regs)->irqstate & KENTRY_STALL_BIT);	\
+})
+
+#define arch_kentry_lockdep_set(__regs)				\
+({								\
+	to_svc_pt_regs(__regs)->irqstate & KENTRY_LOCKDEP_BIT;	\
+})
+
+#define arch_kentry_clear_irq_state(__regs)			\
+({								\
+	to_svc_pt_regs(__regs)->irqstate = 0;			\
+})
+
+#define arch_kentry_set_irqs_stalled(__regs)			\
+({								\
+	to_svc_pt_regs(__regs)->irqstate |= KENTRY_STALL_BIT;	\
+})
+
+#define arch_kentry_set_lockdep(__regs)				\
+({								\
+	to_svc_pt_regs(__regs)->irqstate |= KENTRY_LOCKDEP_BIT;	\
+})
 
 int handle_arch_irq_pipelined(struct pt_regs *regs);
 
@@ -142,6 +160,11 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
 	return native_irqs_disabled_flags(flags);
 }
 
+#define arch_kentry_irqs_enabled(regs)	\
+({					\
+	!interrupts_enabled(regs);	\
+})
+
 #endif /* !CONFIG_IRQ_PIPELINE */
 
 #endif /* _ASM_ARM_IRQ_PIPELINE_H */
diff --git a/arch/arm64/include/asm/irq_pipeline.h b/arch/arm64/include/asm/irq_pipeline.h
index 09cb33b826cb63701678f40b61b65df885923db2..c4f9a39ad323bf4cd5c1ff59e43c64b1a87b49cf 100644
--- a/arch/arm64/include/asm/irq_pipeline.h
+++ b/arch/arm64/include/asm/irq_pipeline.h
@@ -102,10 +102,11 @@ static inline void arch_handle_irq_pipelined(struct pt_regs *regs)
  * the latter for now, until we enventually switch to using whichever
  * of them is available first.
  */
-#define arch_kentry_get_irqstate(__regs)	0
-
-#define arch_kentry_set_irqstate(__regs, __irqstate)	\
-	do { (void)__irqstate; } while (0)
+#define arch_kentry_irqs_enabled(__regs)	0
+#define arch_kentry_lockdep_set(__regs)		0
+#define arch_kentry_clear_irq_state(__regs)
+#define arch_kentry_set_irqs_stalled(__regs)
+#define arch_kentry_set_lockdep(__regs)
 
 #else  /* !CONFIG_IRQ_PIPELINE */
 
diff --git a/kernel/irq/pipeline.c b/kernel/irq/pipeline.c
index ced7003a8444125ff38d71bf867ce34cfa0235f1..34a62805def0e3a5a70893a8ea71d6c200bd8e70 100644
--- a/kernel/irq/pipeline.c
+++ b/kernel/irq/pipeline.c
@@ -1401,33 +1401,26 @@ void sync_current_irq_stage(void) /* hard irqs off */
  * in kernel context, indexed on the current register frame.
  */
 
-#define KENTRY_STALL_BIT      BIT(0) /* Tracks INBAND_STALL_BIT */
-#define KENTRY_LOCKDEP_BIT    BIT(1) /* Tracks hardirqs_enabled */
-
 asmlinkage __visible noinstr void kentry_enter_pipelined(struct pt_regs *regs)
 {
-	long irqstate = 0;
-
 	WARN_ON(irq_pipeline_debug() && !hard_irqs_disabled());
 
 	if (!running_inband())
 		return;
 
+	arch_kentry_clear_irq_state(regs);
+
 	if (lockdep_read_irqs_state())
-		irqstate |= KENTRY_LOCKDEP_BIT;
+		arch_kentry_set_lockdep(regs);
 
 	if (irqs_disabled())
-		irqstate |= KENTRY_STALL_BIT;
+		arch_kentry_set_irqs_stalled(regs);
 	else
 		trace_hardirqs_off();
-
-	arch_kentry_set_irqstate(regs, irqstate);
 }
 
 asmlinkage void __visible noinstr kentry_exit_pipelined(struct pt_regs *regs)
 {
-	long irqstate;
-
 	WARN_ON(irq_pipeline_debug() && !hard_irqs_disabled());
 
 	if (!running_inband())
@@ -1444,13 +1437,12 @@ asmlinkage void __visible noinstr kentry_exit_pipelined(struct pt_regs *regs)
 	 * do flip the stall bit, but are not tracked by lockdep).
 	 */
 
-	irqstate = arch_kentry_get_irqstate(regs);
-	if (!(irqstate & KENTRY_STALL_BIT)) {
+	if (arch_kentry_irqs_enabled(regs)) {
 		stall_inband_nocheck();
 		trace_hardirqs_on();
 		unstall_inband_nocheck();
 	} else {
-		lockdep_write_irqs_state(!!(irqstate & KENTRY_LOCKDEP_BIT));
+		lockdep_write_irqs_state(arch_kentry_lockdep_set(regs));
 	}
 }
 

-- 
2.54.0