diff options
author | Brendan Jackman <jackmanb@google.com> | 2021-01-14 21:17:47 +0300 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2021-01-15 05:34:29 +0300 |
commit | 5ffa25502b5ab3d639829a2d1e316cff7f59a41e (patch) | |
tree | b3ae91f0bdbcbad21f09cd5ed54b39ee7942c79f /kernel/extable.c | |
parent | 5ca419f2864a2c60940dcf4bbaeb69546200e36f (diff) | |
download | linux-5ffa25502b5ab3d639829a2d1e316cff7f59a41e.tar.xz |
bpf: Add instructions for atomic_[cmp]xchg
This adds two atomic opcodes, both of which include the BPF_FETCH
flag. XCHG without the BPF_FETCH flag would naturally encode
atomic_set. This is not supported because it would be of limited
value to userspace (it doesn't imply any barriers). CMPXCHG without
BPF_FETCH woulud be an atomic compare-and-write. We don't have such
an operation in the kernel so it isn't provided to BPF either.
There are two significant design decisions made for the CMPXCHG
instruction:
- To solve the issue that this operation fundamentally has 3
operands, but we only have two register fields. Therefore the
operand we compare against (the kernel's API calls it 'old') is
hard-coded to be R0. x86 has similar design (and A64 doesn't
have this problem).
A potential alternative might be to encode the other operand's
register number in the immediate field.
- The kernel's atomic_cmpxchg returns the old value, while the C11
userspace APIs return a boolean indicating the comparison
result. Which should BPF do? A64 returns the old value. x86 returns
the old value in the hard-coded register (and also sets a
flag). That means return-old-value is easier to JIT, so that's
what we use.
Signed-off-by: Brendan Jackman <jackmanb@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210114181751.768687-8-jackmanb@google.com
Diffstat (limited to 'kernel/extable.c')
0 files changed, 0 insertions, 0 deletions