test_run.c (ea68a3e9d14e9e0bf017d178fb4bd53b6deb1482) test_run.c (75dcef8d3609d0b1d3497d6ed4809096513e0b83)
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2017 Facebook
3 */
4#include <linux/bpf.h>
5#include <linux/btf.h>
6#include <linux/btf_ids.h>
7#include <linux/slab.h>
8#include <linux/init.h>

--- 83 unchanged lines hidden (view full) ---

92
93/* We put this struct at the head of each page with a context and frame
94 * initialised when the page is allocated, so we don't have to do this on each
95 * repetition of the test run.
96 */
97struct xdp_page_head {
98 struct xdp_buff orig_ctx;
99 struct xdp_buff ctx;
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2017 Facebook
3 */
4#include <linux/bpf.h>
5#include <linux/btf.h>
6#include <linux/btf_ids.h>
7#include <linux/slab.h>
8#include <linux/init.h>

--- 83 unchanged lines hidden (view full) ---

92
93/* We put this struct at the head of each page with a context and frame
94 * initialised when the page is allocated, so we don't have to do this on each
95 * repetition of the test run.
96 */
97struct xdp_page_head {
98 struct xdp_buff orig_ctx;
99 struct xdp_buff ctx;
100 union {
101 /* ::data_hard_start starts here */
102 DECLARE_FLEX_ARRAY(struct xdp_frame, frame);
103 DECLARE_FLEX_ARRAY(u8, data);
104 };
100 struct xdp_frame frm;
101 u8 data[];
105};
106
107struct xdp_test_data {
108 struct xdp_buff *orig_ctx;
109 struct xdp_rxq_info rxq;
110 struct net_device *dev;
111 struct page_pool *pp;
112 struct xdp_frame **frames;
113 struct sk_buff **skbs;
114 struct xdp_mem_info mem;
115 u32 batch_size;
116 u32 frame_cnt;
117};
118
102};
103
104struct xdp_test_data {
105 struct xdp_buff *orig_ctx;
106 struct xdp_rxq_info rxq;
107 struct net_device *dev;
108 struct page_pool *pp;
109 struct xdp_frame **frames;
110 struct sk_buff **skbs;
111 struct xdp_mem_info mem;
112 u32 batch_size;
113 u32 frame_cnt;
114};
115
119/* tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c:%MAX_PKT_SIZE
120 * must be updated accordingly this gets changed, otherwise BPF selftests
121 * will fail.
122 */
123#define TEST_XDP_FRAME_SIZE (PAGE_SIZE - sizeof(struct xdp_page_head))
124#define TEST_XDP_MAX_BATCH 256
125
126static void xdp_test_run_init_page(struct page *page, void *arg)
127{
128 struct xdp_page_head *head = phys_to_virt(page_to_phys(page));
129 struct xdp_buff *new_ctx, *orig_ctx;
130 u32 headroom = XDP_PACKET_HEADROOM;
131 struct xdp_test_data *xdp = arg;
132 size_t frm_len, meta_len;
133 struct xdp_frame *frm;
134 void *data;
135
136 orig_ctx = xdp->orig_ctx;
137 frm_len = orig_ctx->data_end - orig_ctx->data_meta;
138 meta_len = orig_ctx->data - orig_ctx->data_meta;
139 headroom -= meta_len;
140
141 new_ctx = &head->ctx;
116#define TEST_XDP_FRAME_SIZE (PAGE_SIZE - sizeof(struct xdp_page_head))
117#define TEST_XDP_MAX_BATCH 256
118
119static void xdp_test_run_init_page(struct page *page, void *arg)
120{
121 struct xdp_page_head *head = phys_to_virt(page_to_phys(page));
122 struct xdp_buff *new_ctx, *orig_ctx;
123 u32 headroom = XDP_PACKET_HEADROOM;
124 struct xdp_test_data *xdp = arg;
125 size_t frm_len, meta_len;
126 struct xdp_frame *frm;
127 void *data;
128
129 orig_ctx = xdp->orig_ctx;
130 frm_len = orig_ctx->data_end - orig_ctx->data_meta;
131 meta_len = orig_ctx->data - orig_ctx->data_meta;
132 headroom -= meta_len;
133
134 new_ctx = &head->ctx;
142 frm = head->frame;
143 data = head->data;
135 frm = &head->frm;
136 data = &head->data;
144 memcpy(data + headroom, orig_ctx->data_meta, frm_len);
145
146 xdp_init_buff(new_ctx, TEST_XDP_FRAME_SIZE, &xdp->rxq);
147 xdp_prepare_buff(new_ctx, data, headroom, frm_len, true);
148 new_ctx->data = new_ctx->data_meta + meta_len;
149
150 xdp_update_frame_from_buff(new_ctx, frm);
151 frm->mem = new_ctx->rxq->mem;

--- 58 unchanged lines hidden (view full) ---

210static void xdp_test_run_teardown(struct xdp_test_data *xdp)
211{
212 xdp_unreg_mem_model(&xdp->mem);
213 page_pool_destroy(xdp->pp);
214 kfree(xdp->frames);
215 kfree(xdp->skbs);
216}
217
137 memcpy(data + headroom, orig_ctx->data_meta, frm_len);
138
139 xdp_init_buff(new_ctx, TEST_XDP_FRAME_SIZE, &xdp->rxq);
140 xdp_prepare_buff(new_ctx, data, headroom, frm_len, true);
141 new_ctx->data = new_ctx->data_meta + meta_len;
142
143 xdp_update_frame_from_buff(new_ctx, frm);
144 frm->mem = new_ctx->rxq->mem;

--- 58 unchanged lines hidden (view full) ---

203static void xdp_test_run_teardown(struct xdp_test_data *xdp)
204{
205 xdp_unreg_mem_model(&xdp->mem);
206 page_pool_destroy(xdp->pp);
207 kfree(xdp->frames);
208 kfree(xdp->skbs);
209}
210
211static bool frame_was_changed(const struct xdp_page_head *head)
212{
213 /* xdp_scrub_frame() zeroes the data pointer, flags is the last field,
214 * i.e. has the highest chances to be overwritten. If those two are
215 * untouched, it's most likely safe to skip the context reset.
216 */
217 return head->frm.data != head->orig_ctx.data ||
218 head->frm.flags != head->orig_ctx.flags;
219}
220
218static bool ctx_was_changed(struct xdp_page_head *head)
219{
220 return head->orig_ctx.data != head->ctx.data ||
221 head->orig_ctx.data_meta != head->ctx.data_meta ||
222 head->orig_ctx.data_end != head->ctx.data_end;
223}
224
225static void reset_ctx(struct xdp_page_head *head)
226{
221static bool ctx_was_changed(struct xdp_page_head *head)
222{
223 return head->orig_ctx.data != head->ctx.data ||
224 head->orig_ctx.data_meta != head->ctx.data_meta ||
225 head->orig_ctx.data_end != head->ctx.data_end;
226}
227
228static void reset_ctx(struct xdp_page_head *head)
229{
227 if (likely(!ctx_was_changed(head)))
230 if (likely(!frame_was_changed(head) && !ctx_was_changed(head)))
228 return;
229
230 head->ctx.data = head->orig_ctx.data;
231 head->ctx.data_meta = head->orig_ctx.data_meta;
232 head->ctx.data_end = head->orig_ctx.data_end;
231 return;
232
233 head->ctx.data = head->orig_ctx.data;
234 head->ctx.data_meta = head->orig_ctx.data_meta;
235 head->ctx.data_end = head->orig_ctx.data_end;
233 xdp_update_frame_from_buff(&head->ctx, head->frame);
236 xdp_update_frame_from_buff(&head->ctx, &head->frm);
234}
235
236static int xdp_recv_frames(struct xdp_frame **frames, int nframes,
237 struct sk_buff **skbs,
238 struct net_device *dev)
239{
240 gfp_t gfp = __GFP_ZERO | GFP_ATOMIC;
241 int i, n;

--- 45 unchanged lines hidden (view full) ---

287 if (!page) {
288 err = -ENOMEM;
289 goto out;
290 }
291
292 head = phys_to_virt(page_to_phys(page));
293 reset_ctx(head);
294 ctx = &head->ctx;
237}
238
239static int xdp_recv_frames(struct xdp_frame **frames, int nframes,
240 struct sk_buff **skbs,
241 struct net_device *dev)
242{
243 gfp_t gfp = __GFP_ZERO | GFP_ATOMIC;
244 int i, n;

--- 45 unchanged lines hidden (view full) ---

290 if (!page) {
291 err = -ENOMEM;
292 goto out;
293 }
294
295 head = phys_to_virt(page_to_phys(page));
296 reset_ctx(head);
297 ctx = &head->ctx;
295 frm = head->frame;
298 frm = &head->frm;
296 xdp->frame_cnt++;
297
298 act = bpf_prog_run_xdp(prog, ctx);
299
300 /* if program changed pkt bounds we need to update the xdp_frame */
301 if (unlikely(ctx_was_changed(head))) {
302 ret = xdp_update_frame_from_buff(ctx, frm);
303 if (ret) {

--- 229 unchanged lines hidden (view full) ---

533 return (long)arg;
534}
535
536int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg)
537{
538 return (long)arg->a;
539}
540
299 xdp->frame_cnt++;
300
301 act = bpf_prog_run_xdp(prog, ctx);
302
303 /* if program changed pkt bounds we need to update the xdp_frame */
304 if (unlikely(ctx_was_changed(head))) {
305 ret = xdp_update_frame_from_buff(ctx, frm);
306 if (ret) {

--- 229 unchanged lines hidden (view full) ---

536 return (long)arg;
537}
538
539int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg)
540{
541 return (long)arg->a;
542}
543
544__bpf_kfunc u32 bpf_fentry_test9(u32 *a)
545{
546 return *a;
547}
548
541__bpf_kfunc int bpf_modify_return_test(int a, int *b)
542{
543 *b += 1;
544 return a + *b;
545}
546
547__bpf_kfunc u64 bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d)
548{

--- 13 unchanged lines hidden (view full) ---

562long noinline bpf_kfunc_call_test4(signed char a, short b, int c, long d)
563{
564 /* Provoke the compiler to assume that the caller has sign-extended a,
565 * b and c on platforms where this is required (e.g. s390x).
566 */
567 return (long)a + (long)b + (long)c + d;
568}
569
549__bpf_kfunc int bpf_modify_return_test(int a, int *b)
550{
551 *b += 1;
552 return a + *b;
553}
554
555__bpf_kfunc u64 bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d)
556{

--- 13 unchanged lines hidden (view full) ---

570long noinline bpf_kfunc_call_test4(signed char a, short b, int c, long d)
571{
572 /* Provoke the compiler to assume that the caller has sign-extended a,
573 * b and c on platforms where this is required (e.g. s390x).
574 */
575 return (long)a + (long)b + (long)c + d;
576}
577
578int noinline bpf_fentry_shadow_test(int a)
579{
580 return a + 1;
581}
582
570struct prog_test_member1 {
571 int a;
572};
573
574struct prog_test_member {
575 struct prog_test_member1 m;
576 int c;
577};

--- 15 unchanged lines hidden (view full) ---

593
594__bpf_kfunc struct prog_test_ref_kfunc *
595bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr)
596{
597 refcount_inc(&prog_test_struct.cnt);
598 return &prog_test_struct;
599}
600
583struct prog_test_member1 {
584 int a;
585};
586
587struct prog_test_member {
588 struct prog_test_member1 m;
589 int c;
590};

--- 15 unchanged lines hidden (view full) ---

606
607__bpf_kfunc struct prog_test_ref_kfunc *
608bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr)
609{
610 refcount_inc(&prog_test_struct.cnt);
611 return &prog_test_struct;
612}
613
614__bpf_kfunc void bpf_kfunc_call_test_offset(struct prog_test_ref_kfunc *p)
615{
616 WARN_ON_ONCE(1);
617}
618
601__bpf_kfunc struct prog_test_member *
602bpf_kfunc_call_memb_acquire(void)
603{
604 WARN_ON_ONCE(1);
605 return NULL;
606}
607
608__bpf_kfunc void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p)
609{
619__bpf_kfunc struct prog_test_member *
620bpf_kfunc_call_memb_acquire(void)
621{
622 WARN_ON_ONCE(1);
623 return NULL;
624}
625
626__bpf_kfunc void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p)
627{
610 if (!p)
611 return;
612
613 refcount_dec(&p->cnt);
614}
615
616__bpf_kfunc void bpf_kfunc_call_memb_release(struct prog_test_member *p)
617{
618}
619
620__bpf_kfunc void bpf_kfunc_call_memb1_release(struct prog_test_member1 *p)

--- 118 unchanged lines hidden (view full) ---

739}
740
741__bpf_kfunc void bpf_kfunc_call_test_mem_len_fail2(u64 *mem, int len)
742{
743}
744
745__bpf_kfunc void bpf_kfunc_call_test_ref(struct prog_test_ref_kfunc *p)
746{
628 refcount_dec(&p->cnt);
629}
630
631__bpf_kfunc void bpf_kfunc_call_memb_release(struct prog_test_member *p)
632{
633}
634
635__bpf_kfunc void bpf_kfunc_call_memb1_release(struct prog_test_member1 *p)

--- 118 unchanged lines hidden (view full) ---

754}
755
756__bpf_kfunc void bpf_kfunc_call_test_mem_len_fail2(u64 *mem, int len)
757{
758}
759
760__bpf_kfunc void bpf_kfunc_call_test_ref(struct prog_test_ref_kfunc *p)
761{
762 /* p != NULL, but p->cnt could be 0 */
747}
748
749__bpf_kfunc void bpf_kfunc_call_test_destructive(void)
750{
751}
752
753__bpf_kfunc static u32 bpf_kfunc_call_test_static_unused_arg(u32 arg, u32 unused)
754{

--- 31 unchanged lines hidden (view full) ---

786BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass1)
787BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass2)
788BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail1)
789BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail2)
790BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail3)
791BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_pass1)
792BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail1)
793BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail2)
763}
764
765__bpf_kfunc void bpf_kfunc_call_test_destructive(void)
766{
767}
768
769__bpf_kfunc static u32 bpf_kfunc_call_test_static_unused_arg(u32 arg, u32 unused)
770{

--- 31 unchanged lines hidden (view full) ---

802BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass1)
803BTF_ID_FLAGS(func, bpf_kfunc_call_test_pass2)
804BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail1)
805BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail2)
806BTF_ID_FLAGS(func, bpf_kfunc_call_test_fail3)
807BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_pass1)
808BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail1)
809BTF_ID_FLAGS(func, bpf_kfunc_call_test_mem_len_fail2)
794BTF_ID_FLAGS(func, bpf_kfunc_call_test_ref, KF_TRUSTED_ARGS)
810BTF_ID_FLAGS(func, bpf_kfunc_call_test_ref, KF_TRUSTED_ARGS | KF_RCU)
795BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE)
796BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg)
811BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE)
812BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg)
813BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset)
797BTF_SET8_END(test_sk_check_kfunc_ids)
798
799static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
800 u32 size, u32 headroom, u32 tailroom)
801{
802 void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
803 void *data;
804

--- 33 unchanged lines hidden (view full) ---

838 case BPF_TRACE_FEXIT:
839 if (bpf_fentry_test1(1) != 2 ||
840 bpf_fentry_test2(2, 3) != 5 ||
841 bpf_fentry_test3(4, 5, 6) != 15 ||
842 bpf_fentry_test4((void *)7, 8, 9, 10) != 34 ||
843 bpf_fentry_test5(11, (void *)12, 13, 14, 15) != 65 ||
844 bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111 ||
845 bpf_fentry_test7((struct bpf_fentry_test_t *)0) != 0 ||
814BTF_SET8_END(test_sk_check_kfunc_ids)
815
816static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
817 u32 size, u32 headroom, u32 tailroom)
818{
819 void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
820 void *data;
821

--- 33 unchanged lines hidden (view full) ---

855 case BPF_TRACE_FEXIT:
856 if (bpf_fentry_test1(1) != 2 ||
857 bpf_fentry_test2(2, 3) != 5 ||
858 bpf_fentry_test3(4, 5, 6) != 15 ||
859 bpf_fentry_test4((void *)7, 8, 9, 10) != 34 ||
860 bpf_fentry_test5(11, (void *)12, 13, 14, 15) != 65 ||
861 bpf_fentry_test6(16, (void *)17, 18, 19, (void *)20, 21) != 111 ||
862 bpf_fentry_test7((struct bpf_fentry_test_t *)0) != 0 ||
846 bpf_fentry_test8(&arg) != 0)
863 bpf_fentry_test8(&arg) != 0 ||
864 bpf_fentry_test9(&retval) != 0)
847 goto out;
848 break;
849 case BPF_MODIFY_RETURN:
850 ret = bpf_modify_return_test(1, &b);
851 if (b != 2)
852 side_effect = 1;
853 break;
854 default:

--- 860 unchanged lines hidden ---
865 goto out;
866 break;
867 case BPF_MODIFY_RETURN:
868 ret = bpf_modify_return_test(1, &b);
869 if (b != 2)
870 side_effect = 1;
871 break;
872 default:

--- 860 unchanged lines hidden ---