Skip to contentSkip to conversation

Patch "arm64: ensure extension of smp_store_release value" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message May 23, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

arm64: ensure extension of smp_store_release value

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
arm64-ensure-extension-of-smp_store_release-value.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 994870bead4ab19087a79492400a5478e2906196 Mon Sep 17 00:00:00 2001

From: Mark Rutland <[email protected]>
Date: Wed, 3 May 2017 16:09:34 +0100
Subject: arm64: ensure extension of smp_store_release value

From: Mark Rutland <[email protected]>

commit 994870bead4ab19087a79492400a5478e2906196 upstream.

When an inline assembly operand's type is narrower than the register it is allocated to, the least significant bits of the register (up to the operand type's width) are valid, and any other bits are permitted to contain any arbitrary value. This aligns with the AAPCS64 parameter passing rules.

Our __smp_store_release() implementation does not account for this, and implicitly assumes that operands have been zero-extended to the width of the type being stored to. Thus, we may store unknown values to memory when the value type is narrower than the pointer type (e.g. when storing a char to a long).

This patch fixes the issue by casting the value operand to the same width as the pointer operand in all cases, which ensures that the value is zero-extended as we expect. We use the same union trickery as __smp_load_acquire and {READ,WRITE}_ONCE() to avoid GCC complaining that pointers are potentially cast to narrower width integers in unreachable paths.

A whitespace issue at the top of __smp_store_release() is also corrected.

No changes are necessary for __smp_load_acquire(). Load instructions implicitly clear any upper bits of the register, and the compiler will only consider the least significant bits of the register as valid regardless.

Fixes 47933ad41a86 ("arch: Introduce smp_load_acquire(), smp_store_release()")
Fixes 878a84d5a8a1 ("arm64: add missing data types in smp_load_acquire/smp_store_release")
Cc Matthias Kaehlcke <[email protected]>
---
 arch/arm64/include/asm/barrier.h |   20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
arch/arm64/include/asm/barrier.h +15 -5
@@ -42,25 +42,35 @@
 #define __smp_rmb()	dmb(ishld)
 #define __smp_wmb()	dmb(ishst)
 
-#define __smp_store_release(p, v)						\
+#define __smp_store_release(p, v)					\
 do {									\
+	union { typeof(*p) __val; char __c[1]; } __u =			\
+		{ .__val = (__force typeof(*p)) (v) }; 			\
 	compiletime_assert_atomic_type(*p);				\
 	switch (sizeof(*p)) {						\
 	case 1:								\
 		asm volatile ("stlrb %w1, %0"				\
-				: "=Q" (*p) : "r" (v) : "memory");	\
+				: "=Q" (*p)				\
+				: "r" (*(__u8 *)__u.__c)		\
+				: "memory");				\
 		break;							\
 	case 2:								\
 		asm volatile ("stlrh %w1, %0"				\
-				: "=Q" (*p) : "r" (v) : "memory");	\
+				: "=Q" (*p)				\
+				: "r" (*(__u16 *)__u.__c)		\
+				: "memory");				\
 		break;							\
 	case 4:								\
 		asm volatile ("stlr %w1, %0"				\
-				: "=Q" (*p) : "r" (v) : "memory");	\
+				: "=Q" (*p)				\
+				: "r" (*(__u32 *)__u.__c)		\
+				: "memory");				\
 		break;							\
 	case 8:								\
 		asm volatile ("stlr %1, %0"				\
-				: "=Q" (*p) : "r" (v) : "memory");	\
+				: "=Q" (*p)				\
+				: "r" (*(__u64 *)__u.__c)		\
+				: "memory");				\
 		break;							\
 	}								\
 } while (0)

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/arm64-armv8_deprecated-ensure-extension-of-addr.patch queue-4.9/arm64-uaccess-ensure-extension-of-access_ok-addr.patch queue-4.9/arm64-xchg-hazard-against-entire-exchange-variable.patch queue-4.9/arm64-ensure-extension-of-smp_store_release-value.patch