]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64: fpsimd: Fix type mismatch in sme_{save,load}_state()
authorMark Rutland <mark.rutland@arm.com>
Wed, 3 Jun 2026 11:06:12 +0000 (12:06 +0100)
committerWill Deacon <will@kernel.org>
Wed, 3 Jun 2026 15:50:47 +0000 (16:50 +0100)
The sme_save_state() and sme_load_state() functions take a 32-bit int
argument that describes whether to save/restore ZT0. Their assembly
implementations consume the entire 64-bit register containing this
32-bit value, and will attempt to save/restore ZT0 if any bit of
that 64-bit register is non-zero.

Per the AAPCS64 parameter passing rules, the callee is responsible for
any necessary widening, and the upper 32-bits are permitted to contain
arbitrary values. If the upper 32 bits are non-zero, this could result
in an unexpected attempt to save/restore ZT0, and consequently could
lead to unexpected traps/undefs/faults.

In practice compilers are very unlikely to generate code where the upper
32-bits would be non-zero, but they are permitted to do so.

Fix this by only consuming the low 32 bits of the register, and update
comments accordingly.

Fixes: 95fcec713259 ("arm64/sme: Implement context switching for ZT0")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/entry-fpsimd.S

index cb08d879cb4de6ab282ec04f83cd61c8bcefccce..28af4bcd97a50acbc7c1f41c99cacccad7a6effe 100644 (file)
@@ -103,13 +103,13 @@ SYM_FUNC_END(sme_set_vq)
  * Save the ZA and ZT state
  *
  * x0 - pointer to buffer for state
- * x1 - number of ZT registers to save
+ * w1 - number of ZT registers to save
  */
 SYM_FUNC_START(sme_save_state)
        _sme_rdsvl      2, 1            // x2 = VL/8
        sme_save_za 0, x2, 12           // Leaves x0 pointing to the end of ZA
 
-       cbz     x1, 1f
+       cbz     w1, 1f
        _str_zt 0
 1:
        ret
@@ -119,13 +119,13 @@ SYM_FUNC_END(sme_save_state)
  * Load the ZA and ZT state
  *
  * x0 - pointer to buffer for state
- * x1 - number of ZT registers to save
+ * w1 - number of ZT registers to save
  */
 SYM_FUNC_START(sme_load_state)
        _sme_rdsvl      2, 1            // x2 = VL/8
        sme_load_za 0, x2, 12           // Leaves x0 pointing to the end of ZA
 
-       cbz     x1, 1f
+       cbz     w1, 1f
        _ldr_zt 0
 1:
        ret