On Wed, May 24, 2017 at 10:56:01AM +0100, Mark Rutland wrote: > 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: <stable@xxxxxxxxxxxxxxx> # 3.14.x- > Acked-by: Will Deacon <will.deacon@xxxxxxx> > Signed-off-by: Mark Rutland <mark.rutland@xxxxxxx> > Cc: Matthias Kaehlcke <mka@xxxxxxxxxxxx> > Signed-off-by: Catalin Marinas <catalin.marinas@xxxxxxx> > --- > arch/arm64/include/asm/barrier.h | 18 ++++++++++++++---- > 1 file changed, 14 insertions(+), 4 deletions(-) Applied, thanks. greg k-h