xen/arm: atomic: Rewrite write_atomic()

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
2934148a07 "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@amazon.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Julien Grall committed 2020-05-11 10:48:30 +01:00
1 parent 9efda0281b
commit 52ffcfb739
1 file changed
+29 -11
+29 -11
View File
@@ -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); \
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.