Commit 0c8bbf99 authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by Andrii Nakryiko
Browse files

selftests/bpf: Test may_goto

parent 06375801
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@
exceptions				 # JIT does not support calling kfunc bpf_throw				       (exceptions)
get_stack_raw_tp                         # user_stack corrupted user stack                                             (no backchain userspace)
stacktrace_build_id                      # compare_map_keys stackid_hmap vs. stackmap err -2 errno 2                   (?)
verifier_iterating_callbacks
+100 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "bpf_experimental.h"

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
@@ -239,4 +237,103 @@ int bpf_loop_iter_limit_nested(void *unused)
	return 1000 * a + b + c;
}

#define ARR_SZ 1000000
int zero;
char arr[ARR_SZ];

SEC("socket")
__success __retval(0xd495cdc0)
int cond_break1(const void *ctx)
{
	unsigned long i;
	unsigned int sum = 0;

	for (i = zero; i < ARR_SZ; cond_break, i++)
		sum += i;
	for (i = zero; i < ARR_SZ; i++) {
		barrier_var(i);
		sum += i + arr[i];
		cond_break;
	}

	return sum;
}

SEC("socket")
__success __retval(999000000)
int cond_break2(const void *ctx)
{
	int i, j;
	int sum = 0;

	for (i = zero; i < 1000; cond_break, i++)
		for (j = zero; j < 1000; j++) {
			sum += i + j;
			cond_break;
		}

	return sum;
}

static __noinline int loop(void)
{
	int i, sum = 0;

	for (i = zero; i <= 1000000; i++, cond_break)
		sum += i;

	return sum;
}

SEC("socket")
__success __retval(0x6a5a2920)
int cond_break3(const void *ctx)
{
	return loop();
}

SEC("socket")
__success __retval(1)
int cond_break4(const void *ctx)
{
	int cnt = zero;

	for (;;) {
		/* should eventually break out of the loop */
		cond_break;
		cnt++;
	}
	/* if we looped a bit, it's a success */
	return cnt > 1 ? 1 : 0;
}

static __noinline int static_subprog(void)
{
	int cnt = zero;

	for (;;) {
		cond_break;
		cnt++;
	}

	return cnt;
}

SEC("socket")
__success __retval(1)
int cond_break5(const void *ctx)
{
	int cnt1 = zero, cnt2;

	for (;;) {
		cond_break;
		cnt1++;
	}

	cnt2 = static_subprog();

	/* main and subprog have to loop a bit */
	return cnt1 > 1 && cnt2 > 1 ? 1 : 0;
}

char _license[] SEC("license") = "GPL";