Skip to content

Commit 4a26c23

Browse files
committed
arm64/sysreg: Fix GIC CDEOI instruction encoding
JIRA: https://issues.redhat.com/browse/RHEL-101059 commit e9ad390 Author: Lorenzo Pieralisi <lpieralisi@kernel.org> Date: Tue, 7 Oct 2025 12:26:00 +0200 The GIC CDEOI system instruction requires the Rt field to be set to 0b11111 otherwise the instruction behaviour becomes CONSTRAINED UNPREDICTABLE. Currenly, its usage is encoded as a system register write, with a constant 0 value: write_sysreg_s(0, GICV5_OP_GIC_CDEOI) While compiling with GCC, the 0 constant value, through these asm constraints and modifiers ('x' modifier and 'Z' constraint combo): asm volatile(__msr_s(r, "%x0") : : "rZ" (__val)); forces the compiler to issue the XZR register for the MSR operation (ie that corresponds to Rt == 0b11111) issuing the right instruction encoding. Unfortunately LLVM does not yet understand that modifier/constraint combo so it ends up issuing a different register from XZR for the MSR source, which in turns means that it encodes the GIC CDEOI instruction wrongly and the instruction behaviour becomes CONSTRAINED UNPREDICTABLE that we must prevent. Add a conditional to write_sysreg_s() macro that detects whether it is passed a constant 0 value and issues an MSR write with XZR as source register - explicitly doing what the asm modifier/constraint is meant to achieve through constraints/modifiers, fixing the LLVM compilation issue. Fixes: 7ec80fb ("irqchip/gic-v5: Add GICv5 PPI support") Suggested-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Acked-by: Marc Zyngier <maz@kernel.org> Cc: stable@vger.kernel.org Cc: Sascha Bischoff <sascha.bischoff@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Marc Zyngier <maz@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Mark Salter <msalter@redhat.com>
1 parent c46de5d commit 4a26c23

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

arch/arm64/include/asm/sysreg.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,10 +1171,19 @@
11711171
__val; \
11721172
})
11731173

1174+
/*
1175+
* The "Z" constraint combined with the "%x0" template should be enough
1176+
* to force XZR generation if (v) is a constant 0 value but LLVM does not
1177+
* yet understand that modifier/constraint combo so a conditional is required
1178+
* to nudge the compiler into using XZR as a source for a 0 constant value.
1179+
*/
11741180
#define write_sysreg_s(v, r) do { \
11751181
u64 __val = (u64)(v); \
11761182
u32 __maybe_unused __check_r = (u32)(r); \
1177-
asm volatile(__msr_s(r, "%x0") : : "rZ" (__val)); \
1183+
if (__builtin_constant_p(__val) && __val == 0) \
1184+
asm volatile(__msr_s(r, "xzr")); \
1185+
else \
1186+
asm volatile(__msr_s(r, "%x0") : : "r" (__val)); \
11781187
} while (0)
11791188

11801189
/*

0 commit comments

Comments
 (0)