• Brendan Jackman's avatar
    bpf: Add instructions for atomic_[cmp]xchg · 5ffa2550
    Brendan Jackman authored
    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: default avatarBrendan Jackman <jackmanb@google.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Acked-by: default avatarYonghong Song <yhs@fb.com>
    Link: https://lore.kernel.org/bpf/20210114181751.768687-8-jackmanb@google.com
    5ffa2550
disasm.c 8.43 KB