[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH for-4.14 2/3] xen/arm: atomic: Rewrite write_atomic()
From: Julien Grall <jgrall@xxxxxxxxxx> The current implementation of write_atomic has two issues: 1) It cannot be used to write pointer value because the switch contains cast to other size than the size of the pointer. 2) It will happily allow to write to a pointer to const. Additionally, the Arm implementation is returning a value when the x86 implementation does not anymore. This was introduced in commit 2934148a0773 "x86: simplify a few macros / inline functions". There are no users of the return value, so it is fine to drop it. The switch is now moved in a static inline helper allowing the compiler to prevent use of const pointer and also allow to write pointer value. Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> --- xen/include/asm-arm/atomic.h | 40 ++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/xen/include/asm-arm/atomic.h b/xen/include/asm-arm/atomic.h index 3c3d6bb04ee8..ac2798d095eb 100644 --- a/xen/include/asm-arm/atomic.h +++ b/xen/include/asm-arm/atomic.h @@ -98,23 +98,41 @@ static always_inline void read_atomic_size(const volatile void *p, } } +static always_inline void write_atomic_size(volatile void *p, + void *val, + unsigned int size) +{ + switch ( size ) + { + case 1: + write_u8_atomic(p, *(uint8_t *)val); + break; + case 2: + write_u16_atomic(p, *(uint16_t *)val); + break; + case 4: + write_u32_atomic(p, *(uint32_t *)val); + break; + case 8: + write_u64_atomic(p, *(uint64_t *)val); + break; + default: + __bad_atomic_size(); + break; + } +} + #define read_atomic(p) ({ \ union { typeof(*p) val; char c[0]; } x_; \ read_atomic_size(p, x_.c, sizeof(*p)); \ x_.val; \ }) -#define write_atomic(p, x) ({ \ - typeof(*p) __x = (x); \ - switch ( sizeof(*p) ) { \ - case 1: write_u8_atomic((uint8_t *)p, (uint8_t)__x); break; \ - case 2: write_u16_atomic((uint16_t *)p, (uint16_t)__x); break; \ - case 4: write_u32_atomic((uint32_t *)p, (uint32_t)__x); break; \ - case 8: write_u64_atomic((uint64_t *)p, (uint64_t)__x); break; \ - default: __bad_atomic_size(); break; \ - } \ - __x; \ -}) +#define write_atomic(p, x) \ + do { \ + typeof(*p) x_ = (x); \ + write_atomic_size(p, &x_, sizeof(*p)); \ + } while ( false ) #define add_sized(p, x) ({ \ typeof(*(p)) __x = (x); \ -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |