selftests/bpf: Add a sign-extension test for kfuncs
authorIlya Leoshkevich <iii@linux.ibm.com>
Sat, 28 Jan 2023 00:06:33 +0000 (01:06 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 28 Jan 2023 20:30:09 +0000 (12:30 -0800)
s390x ABI requires the caller to zero- or sign-extend the arguments.
eBPF already deals with zero-extension (by definition of its ABI), but
not with sign-extension.

Add a test to cover that potentially problematic area.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20230128000650.1516334-15-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
net/bpf/test_run.c
tools/testing/selftests/bpf/prog_tests/kfunc_call.c
tools/testing/selftests/bpf/progs/kfunc_call_test.c

index 8da0d73b368e1d8efa3e9803347d03728c093f2d..7dbefa4fd2ebe970a79b4abc9aac590a953aec30 100644 (file)
@@ -550,6 +550,14 @@ struct sock * noinline bpf_kfunc_call_test3(struct sock *sk)
        return sk;
 }
 
+long noinline bpf_kfunc_call_test4(signed char a, short b, int c, long d)
+{
+       /* Provoke the compiler to assume that the caller has sign-extended a,
+        * b and c on platforms where this is required (e.g. s390x).
+        */
+       return (long)a + (long)b + (long)c + d;
+}
+
 struct prog_test_member1 {
        int a;
 };
@@ -746,6 +754,7 @@ BTF_SET8_START(test_sk_check_kfunc_ids)
 BTF_ID_FLAGS(func, bpf_kfunc_call_test1)
 BTF_ID_FLAGS(func, bpf_kfunc_call_test2)
 BTF_ID_FLAGS(func, bpf_kfunc_call_test3)
+BTF_ID_FLAGS(func, bpf_kfunc_call_test4)
 BTF_ID_FLAGS(func, bpf_kfunc_call_test_acquire, KF_ACQUIRE | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_kfunc_call_memb_acquire, KF_ACQUIRE | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_kfunc_call_test_release, KF_RELEASE)
index 5af1ee8f0e6ee2589e72e7f4bed15f4ea9f2857c..bb4cd82a788adb16363ef98368720aecbace99db 100644 (file)
@@ -72,6 +72,7 @@ static struct kfunc_test_params kfunc_tests[] = {
        /* success cases */
        TC_TEST(kfunc_call_test1, 12),
        TC_TEST(kfunc_call_test2, 3),
+       TC_TEST(kfunc_call_test4, -1234),
        TC_TEST(kfunc_call_test_ref_btf_id, 0),
        TC_TEST(kfunc_call_test_get_mem, 42),
        SYSCALL_TEST(kfunc_syscall_test, 0),
index f636e50be2599d52326844d21ff51064db9394f5..d91c58d06d3813dfcab482f15b9019cc23740a9e 100644 (file)
@@ -3,6 +3,7 @@
 #include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 
+extern long bpf_kfunc_call_test4(signed char a, short b, int c, long d) __ksym;
 extern int bpf_kfunc_call_test2(struct sock *sk, __u32 a, __u32 b) __ksym;
 extern __u64 bpf_kfunc_call_test1(struct sock *sk, __u32 a, __u64 b,
                                  __u32 c, __u64 d) __ksym;
@@ -17,6 +18,23 @@ extern void bpf_kfunc_call_test_mem_len_fail2(__u64 *mem, int len) __ksym;
 extern int *bpf_kfunc_call_test_get_rdwr_mem(struct prog_test_ref_kfunc *p, const int rdwr_buf_size) __ksym;
 extern int *bpf_kfunc_call_test_get_rdonly_mem(struct prog_test_ref_kfunc *p, const int rdonly_buf_size) __ksym;
 
+SEC("tc")
+int kfunc_call_test4(struct __sk_buff *skb)
+{
+       struct bpf_sock *sk = skb->sk;
+       long tmp;
+
+       if (!sk)
+               return -1;
+
+       sk = bpf_sk_fullsock(sk);
+       if (!sk)
+               return -1;
+
+       tmp = bpf_kfunc_call_test4(-3, -30, -200, -1000);
+       return (tmp >> 32) + tmp;
+}
+
 SEC("tc")
 int kfunc_call_test2(struct __sk_buff *skb)
 {