• Johan Almbladh's avatar
    bpf, x86: Fix bpf mapping of atomic fetch implementation · ced18582
    Johan Almbladh authored
    Fix the case where the dst register maps to %rax as otherwise this produces
    an incorrect mapping with the implementation in 981f94c3 ("bpf: Add
    bitwise atomic instructions") as %rax is clobbered given it's part of the
    cmpxchg as operand.
    
    The issue is similar to b29dd96b ("bpf, x86: Fix BPF_FETCH atomic and/or/
    xor with r0 as src") just that the case of dst register was missed.
    
    Before, dst=r0 (%rax) src=r2 (%rsi):
    
      [...]
      c5:   mov    %rax,%r10
      c8:   mov    0x0(%rax),%rax       <---+ (broken)
      cc:   mov    %rax,%r11                |
      cf:   and    %rsi,%r11                |
      d2:   lock cmpxchg %r11,0x0(%rax) <---+
      d8:   jne    0x00000000000000c8       |
      da:   mov    %rax,%rsi                |
      dd:   mov    %r10,%rax                |
      [...]                                 |
                                            |
    After, dst=r0 (%rax) src=r2 (%rsi):     |
                                            |
      [...]                                 |
      da:	mov    %rax,%r10                |
      dd:	mov    0x0(%r10),%rax       <---+ (fixed)
      e1:	mov    %rax,%r11                |
      e4:	and    %rsi,%r11                |
      e7:	lock cmpxchg %r11,0x0(%r10) <---+
      ed:	jne    0x00000000000000dd
      ef:	mov    %rax,%rsi
      f2:	mov    %r10,%rax
      [...]
    
    The remaining combinations were fine as-is though:
    
    After, dst=r9 (%r15) src=r0 (%rax):
    
      [...]
      dc:	mov    %rax,%r10
      df:	mov    0x0(%r15),%rax
      e3:	mov    %rax,%r11
      e6:	and    %r10,%r11
      e9:	lock cmpxchg %r11,0x0(%r15)
      ef:	jne    0x00000000000000df      _
      f1:	mov    %rax,%r10                | (unneeded, but
      f4:	mov    %r10,%rax               _|  not a problem)
      [...]
    
    After, dst=r9 (%r15) src=r4 (%rcx):
    
      [...]
      de:	mov    %rax,%r10
      e1:	mov    0x0(%r15),%rax
      e5:	mov    %rax,%r11
      e8:	and    %rcx,%r11
      eb:	lock cmpxchg %r11,0x0(%r15)
      f1:	jne    0x00000000000000e1
      f3:	mov    %rax,%rcx
      f6:	mov    %r10,%rax
      [...]
    
    The case of dst == src register is rejected by the verifier and
    therefore not supported, but x86 JIT also handles this case just
    fine.
    
    After, dst=r0 (%rax) src=r0 (%rax):
    
      [...]
      eb:	mov    %rax,%r10
      ee:	mov    0x0(%r10),%rax
      f2:	mov    %rax,%r11
      f5:	and    %r10,%r11
      f8:	lock cmpxchg %r11,0x0(%r10)
      fe:	jne    0x00000000000000ee
     100:	mov    %rax,%r10
     103:	mov    %r10,%rax
      [...]
    
    Fixes: 981f94c3 ("bpf: Add bitwise atomic instructions")
    Reported-by: default avatarJohan Almbladh <johan.almbladh@anyfinetworks.com>
    Signed-off-by: default avatarJohan Almbladh <johan.almbladh@anyfinetworks.com>
    Co-developed-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Reviewed-by: default avatarBrendan Jackman <jackmanb@google.com>
    Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
    ced18582
bpf_jit_comp.c 63.6 KB