[PATCH 04/38] arm64: process: Lift check for exception state to generic infrastructure
Vladimir Murzin
vladimir.murzin at arm.com
Mon Sep 14 03:20:28 PDT 2026
debug_switch_state() explicitly checks the hardware exception state
for both the pseudo-NMI and non-NMI paths. The expected state matches
the NOIRQ_CONTEXT exception context introduced alongside the exception
masking helpers and state checkers. Such checks are handy outside of
task switch, so turn them into generic helpers available for wider
use. Make debug_switch_state() the first user of newly introduced
helpers.
Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie at huawei.com>
---
.../include/asm/interrupts/common_flags.h | 30 +++++++++++++++++++
arch/arm64/kernel/process.c | 21 ++-----------
2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/include/asm/interrupts/common_flags.h b/arch/arm64/include/asm/interrupts/common_flags.h
index 0de5ba1ae155..03cfde24a530 100644
--- a/arch/arm64/include/asm/interrupts/common_flags.h
+++ b/arch/arm64/include/asm/interrupts/common_flags.h
@@ -118,6 +118,36 @@ arm64_exc_hwstate_t arm64_inherit_exc_hwstate(struct pt_regs *regs)
return state;
}
+static __always_inline
+void arm64_debug_exc_hwstate(arm64_exc_hwstate_t expected)
+{
+ arm64_exc_hwstate_t actual;
+
+ if (!IS_ENABLED(CONFIG_DEBUG_IRQFLAGS))
+ return;
+
+ actual.flags = arch_local_save_flags();
+
+ if (expected.flags == actual.flags)
+ return;
+
+ if (system_uses_irq_prio_masking()) {
+ WARN_ONCE(1, "Unexpected DAIF+PMR: 0x%x + 0x%x (expected 0x%x + 0x%x)\n",
+ actual.daif, actual.pmr, expected.daif, expected.pmr);
+ } else {
+ WARN_ONCE(1, "Unexpected DAIF: 0x%x (expected 0x%x)\n",
+ actual.daif, expected.daif);
+ }
+}
+
+static __always_inline
+void arm64_debug_exc_context(arm64_exc_context_t context)
+{
+ arm64_exc_hwstate_t expected = arm64_exc_hwstate_of_context(context);
+
+ arm64_debug_exc_hwstate(expected);
+}
+
static __always_inline
void __arm64_update_exc_hwstate(arm64_exc_hwstate_t hwstate, bool force)
{
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 581f80e9b9b7..0fd09136d398 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -51,6 +51,7 @@
#include <asm/exec.h>
#include <asm/fpsimd.h>
#include <asm/gcs.h>
+#include <asm/interrupts/common_flags.h>
#include <asm/mmu_context.h>
#include <asm/mpam.h>
#include <asm/mte.h>
@@ -703,25 +704,7 @@ void update_sctlr_el1(u64 sctlr)
static inline void debug_switch_state(void)
{
- if (system_uses_irq_prio_masking()) {
- unsigned long daif_expected = 0;
- unsigned long daif_actual = read_sysreg(daif);
- unsigned long pmr_expected = GIC_PRIO_IRQOFF;
- unsigned long pmr_actual = read_sysreg_s(SYS_ICC_PMR_EL1);
-
- WARN_ONCE(daif_actual != daif_expected ||
- pmr_actual != pmr_expected,
- "Unexpected DAIF + PMR: 0x%lx + 0x%lx (expected 0x%lx + 0x%lx)\n",
- daif_actual, pmr_actual,
- daif_expected, pmr_expected);
- } else {
- unsigned long daif_expected = DAIF_PROCCTX_NOIRQ;
- unsigned long daif_actual = read_sysreg(daif);
-
- WARN_ONCE(daif_actual != daif_expected,
- "Unexpected DAIF value: 0x%lx (expected 0x%lx)\n",
- daif_actual, daif_expected);
- }
+ arm64_debug_exc_context(NOIRQ_CONTEXT);
}
/*
--
2.34.1
More information about the linux-arm-kernel
mailing list