[PATCH 2/2] arm64: tools: Fix GIC CDEOI instruction encoding
From: Sascha Bischoff
Date: Fri Sep 04 2026 - 14:27:37 EST
The tools copy of write_sysreg_s() relies on the "rZ" constraint with
the "%x0" modifier to select XZR for a constant zero. LLVM does not
understand this combination and can select another general-purpose
register instead.
The GICv5 PPI selftest emits CDEOI through the tools copy. Its Rt field
must select XZR, so using another register results in unpredictable
behaviour.
Mirror the kernel implementation so that a constant zero selects XZR
regardless of the optimisation level.
Fixes: 0a9f38bf612b ("KVM: arm64: selftests: Introduce a minimal GICv5 PPI selftest")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Link: https://lore.kernel.org/r/20260807173928.3F6731F000E9@xxxxxxxxxxxxxxx
Signed-off-by: Sascha Bischoff <sascha.bischoff@xxxxxxx>
---
tools/arch/arm64/include/asm/sysreg.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index f75efe98e9df3..342790d13f788 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -1152,10 +1152,19 @@
__val; \
})
+/*
+ * The "Z" constraint combined with the "%x0" template should be enough
+ * to force XZR generation if (v) is a constant 0 value but LLVM does not
+ * yet understand that modifier/constraint combo so a conditional is required
+ * to nudge the compiler into using XZR as a source for a 0 constant value.
+ */
#define write_sysreg_s(v, r) do { \
u64 __val = (u64)(v); \
u32 __maybe_unused __check_r = (u32)(r); \
- asm volatile(__msr_s(r, "%x0") : : "rZ" (__val)); \
+ if (__builtin_constant_p(v) && (u64)(v) == 0) \
+ asm volatile(__msr_s(r, "xzr")); \
+ else \
+ asm volatile(__msr_s(r, "%x0") : : "r" (__val)); \
} while (0)
/*
--
2.34.1