bpf: define READ_ONCE and WRITE_ONCE
These are convenience macros which do (const|volatile) cast for atomic operations. I've run into a case where two 32-bit writes get optimized by the compiler into a single 64-bit write, which then fails verification. WRITE_ONCE() avoids that by virtue of the volatile annotation. Technically I think the same thing could happen on read, so add READ_ONCE too. Test: N/A Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: Iade089aab3522916bd7b431d4064f89a21bc78b0
This commit is contained in:
parent
56d6ad9764
commit
645b2d9755
1 changed files with 16 additions and 0 deletions
|
|
@ -419,6 +419,22 @@ static void (*bpf_ringbuf_submit_unsafe)(const void* data, __u64 flags) = (void*
|
|||
DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
|
||||
DEFAULT_BPF_MAP_UID, gid, 0660)
|
||||
|
||||
// idea from Linux include/linux/compiler_types.h (eBPF is always a 64-bit arch)
|
||||
#define NATIVE_WORD(t) ((sizeof(t) == 1) || (sizeof(t) == 2) || (sizeof(t) == 4) || (sizeof(t) == 8))
|
||||
|
||||
// simplified from Linux include/asm-generic/rwonce.h
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
_Static_assert(NATIVE_WORD(x), "READ_ONCE requires a native word size"); \
|
||||
(*(const volatile typeof(x) *)&(x)) \
|
||||
})
|
||||
|
||||
#define WRITE_ONCE(x, value) \
|
||||
do { \
|
||||
_Static_assert(NATIVE_WORD(x), "WRITE_ONCE requires a native word size"); \
|
||||
*(volatile typeof(x) *)&(x) = (value); \
|
||||
} while (0)
|
||||
|
||||
// LLVM eBPF builtins: they directly generate BPF_LD_ABS/BPF_LD_IND (skb may be ignored?)
|
||||
unsigned long long load_byte(void* skb, unsigned long long off) asm("llvm.bpf.load.byte");
|
||||
unsigned long long load_half(void* skb, unsigned long long off) asm("llvm.bpf.load.half");
|
||||
|
|
|
|||
Loading…
Reference in a new issue