Re: [PATCH bpf-next 24/24] s390/bpf: Implement bpf_jit_supports_kfunc_call()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2023-01-25 at 17:28 -0800, Alexei Starovoitov wrote:
> On Wed, Jan 25, 2023 at 10:38:17PM +0100, Ilya Leoshkevich wrote:
> > +
> > +               /* Sign-extend the kfunc arguments. */
> > +               if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
> > +                       m = bpf_jit_find_kfunc_model(fp, insn);
> > +                       if (!m)
> > +                               return -1;
> > +
> > +                       for (j = 0; j < m->nr_args; j++) {
> > +                               if (sign_extend(jit, BPF_REG_1 + j,
> > +                                               m->arg_size[j],
> > +                                               m->arg_flags[j]))
> > +                                       return -1;
> > +                       }
> > +               }
> 
> Is this because s390 doesn't have subregisters?
> Could you give an example where it's necessary?
> I'm guessing a bpf prog compiled with alu32 and operates on signed
> int
> that is passed into a kfunc that expects 'int' in 64-bit reg?

Precisely. The test added in 13/24 fails without this:

verify_success:PASS:skel 0 nsec                                       
verify_success:PASS:bpf_object__find_program_by_name 0 nsec           
verify_success:PASS:kfunc_call_test4 0 nsec                           
verify_success:FAIL:retval unexpected retval: actual 4294966065 !=
expected -1234                                                        
#94/10   kfunc_call/kfunc_call_test4:FAIL                    

Looking at the assembly:

; long noinline bpf_kfunc_call_test4(signed char a, short b, int c,
long d)
0000000000936a78 <bpf_kfunc_call_test4>:
  936a78:       c0 04 00 00 00 00       jgnop   936a78
<bpf_kfunc_call_test4>
; 	return (long)a + (long)b + (long)c + d;
  936a7e:       b9 08 00 45             agr     %r4,%r5
  936a82:       b9 08 00 43             agr     %r4,%r3
  936a86:       b9 08 00 24             agr     %r2,%r4
  936a8a:       c0 f4 00 1e 3b 27       jg      cfe0d8
<__s390_indirect_jump_r14>

As per the s390x ABI, bpf_kfunc_call_test4() has the right to assume
that a, b and c are sign-extended by the caller, which results in using
64-bit additions (agr) without any additional conversions.

On the JITed code side (without this hunk) we have:

; tmp = bpf_kfunc_call_test4(-3, -30, -200, -1000);
;        5:       b4 10 00 00 ff ff ff fd w1 = -3
   0x3ff7fdcdad4:       llilf   %r2,0xfffffffd
;        6:       b4 20 00 00 ff ff ff e2 w2 = -30
   0x3ff7fdcdada:       llilf   %r3,0xffffffe2
;        7:       b4 30 00 00 ff ff ff 38 w3 = -200
   0x3ff7fdcdae0:       llilf   %r4,0xffffff38
;       8:       b7 40 00 00 ff ff fc 18 r4 = -1000
   0x3ff7fdcdae6:       lgfi    %r5,-1000
   0x3ff7fdcdaec:       mvc     64(4,%r15),160(%r15)
   0x3ff7fdcdaf2:       lgrl    %r1,bpf_kfunc_call_test4@GOT
   0x3ff7fdcdaf8:       brasl   %r14,__s390_indirect_jump_r1

This first 3 llilfs are 32-bit loads, that need to be sign-extended
to 64 bits.

> > +bool bpf_jit_supports_kfunc_call(void)
> > +{
> > +       return true;
> > +}
> 
> Timely :) Thanks for working it.





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux