selftests/bpf: Fix test_core_autosize on big-endian machines
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 12 Aug 2021 22:48:14 +0000 (00:48 +0200)
committerAndrii Nakryiko <andrii@kernel.org>
Fri, 13 Aug 2021 23:40:40 +0000 (16:40 -0700)
The "probed" part of test_core_autosize copies an integer using
bpf_core_read() into an integer of a potentially different size.
On big-endian machines a destination offset is required for this to
produce a sensible result.

Fixes: 888d83b961f6 ("selftests/bpf: Validate libbpf's auto-sizing of LD/ST/STX instructions")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210812224814.187460-1-iii@linux.ibm.com
tools/testing/selftests/bpf/progs/test_core_autosize.c

index 44f5aa2..9a7829c 100644 (file)
@@ -125,6 +125,16 @@ int handle_downsize(void *ctx)
        return 0;
 }
 
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define bpf_core_read_int bpf_core_read
+#else
+#define bpf_core_read_int(dst, sz, src) ({ \
+       /* Prevent "subtraction from stack pointer prohibited" */ \
+       volatile long __off = sizeof(*dst) - (sz); \
+       bpf_core_read((char *)(dst) + __off, sz, src); \
+})
+#endif
+
 SEC("raw_tp/sys_enter")
 int handle_probed(void *ctx)
 {
@@ -132,23 +142,23 @@ int handle_probed(void *ctx)
        __u64 tmp;
 
        tmp = 0;
-       bpf_core_read(&tmp, bpf_core_field_size(in->ptr), &in->ptr);
+       bpf_core_read_int(&tmp, bpf_core_field_size(in->ptr), &in->ptr);
        ptr_probed = tmp;
 
        tmp = 0;
-       bpf_core_read(&tmp, bpf_core_field_size(in->val1), &in->val1);
+       bpf_core_read_int(&tmp, bpf_core_field_size(in->val1), &in->val1);
        val1_probed = tmp;
 
        tmp = 0;
-       bpf_core_read(&tmp, bpf_core_field_size(in->val2), &in->val2);
+       bpf_core_read_int(&tmp, bpf_core_field_size(in->val2), &in->val2);
        val2_probed = tmp;
 
        tmp = 0;
-       bpf_core_read(&tmp, bpf_core_field_size(in->val3), &in->val3);
+       bpf_core_read_int(&tmp, bpf_core_field_size(in->val3), &in->val3);
        val3_probed = tmp;
 
        tmp = 0;
-       bpf_core_read(&tmp, bpf_core_field_size(in->val4), &in->val4);
+       bpf_core_read_int(&tmp, bpf_core_field_size(in->val4), &in->val4);
        val4_probed = tmp;
 
        return 0;