Commit c139aa60 authored by Will Deacon's avatar Will Deacon Committed by Catalin Marinas

arm64: barriers: fix smp_load_acquire to work with const arguments

A newly introduced function in include/net/sock.h passes a const
argument to smp_load_acquire:

  static inline int sk_state_load(const struct sock *sk)
  {
	return smp_load_acquire(&sk->sk_state);
  }

This cause an allmodconfig build failure, since our underlying
load-acquire implementation does not handle const types correctly:

  include/net/sock.h: In function 'sk_state_load':
  ./arch/arm64/include/asm/barrier.h:71:3: error: read-only variable '___p1' used as 'asm' output
     asm volatile ("ldarb %w0, %1"    \

This patch fixes the problem by reusing the trick in READ_ONCE that
loads via a non-const member of an anonymous union. This has the
advantage of allowing us to use smp_load_acquire on packed structures
(e.g. arch_spinlock_t) as well as primitive types.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: David Daney <david.daney@cavium.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Reported-by: default avatarArnd Bergmann <arnd@arndb.de>
Reported-by: default avatarDavid Daney <david.daney@cavium.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 0b2aa5b8
...@@ -64,27 +64,31 @@ do { \ ...@@ -64,27 +64,31 @@ do { \
#define smp_load_acquire(p) \ #define smp_load_acquire(p) \
({ \ ({ \
typeof(*p) ___p1; \ union { typeof(*p) __val; char __c[1]; } __u; \
compiletime_assert_atomic_type(*p); \ compiletime_assert_atomic_type(*p); \
switch (sizeof(*p)) { \ switch (sizeof(*p)) { \
case 1: \ case 1: \
asm volatile ("ldarb %w0, %1" \ asm volatile ("ldarb %w0, %1" \
: "=r" (___p1) : "Q" (*p) : "memory"); \ : "=r" (*(__u8 *)__u.__c) \
: "Q" (*p) : "memory"); \
break; \ break; \
case 2: \ case 2: \
asm volatile ("ldarh %w0, %1" \ asm volatile ("ldarh %w0, %1" \
: "=r" (___p1) : "Q" (*p) : "memory"); \ : "=r" (*(__u16 *)__u.__c) \
: "Q" (*p) : "memory"); \
break; \ break; \
case 4: \ case 4: \
asm volatile ("ldar %w0, %1" \ asm volatile ("ldar %w0, %1" \
: "=r" (___p1) : "Q" (*p) : "memory"); \ : "=r" (*(__u32 *)__u.__c) \
: "Q" (*p) : "memory"); \
break; \ break; \
case 8: \ case 8: \
asm volatile ("ldar %0, %1" \ asm volatile ("ldar %0, %1" \
: "=r" (___p1) : "Q" (*p) : "memory"); \ : "=r" (*(__u64 *)__u.__c) \
: "Q" (*p) : "memory"); \
break; \ break; \
} \ } \
___p1; \ __u.__val; \
}) })
#define read_barrier_depends() do { } while(0) #define read_barrier_depends() do { } while(0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment