summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/bpf/progs/exceptions_fail.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/bpf/progs/exceptions_fail.c')
-rw-r--r--tools/testing/selftests/bpf/progs/exceptions_fail.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/tools/testing/selftests/bpf/progs/exceptions_fail.c b/tools/testing/selftests/bpf/progs/exceptions_fail.c
index 8a0fdff89927..9ea1353488d7 100644
--- a/tools/testing/selftests/bpf/progs/exceptions_fail.c
+++ b/tools/testing/selftests/bpf/progs/exceptions_fail.c
@@ -8,6 +8,11 @@
#include "bpf_experimental.h"
extern void bpf_rcu_read_lock(void) __ksym;
+extern void bpf_rcu_read_unlock(void) __ksym;
+extern void bpf_preempt_disable(void) __ksym;
+extern void bpf_preempt_enable(void) __ksym;
+extern void bpf_local_irq_save(unsigned long *) __ksym;
+extern void bpf_local_irq_restore(unsigned long *) __ksym;
#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
@@ -131,7 +136,7 @@ int reject_subprog_with_lock(void *ctx)
}
SEC("?tc")
-__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region")
+__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region")
int reject_with_rcu_read_lock(void *ctx)
{
bpf_rcu_read_lock();
@@ -147,11 +152,13 @@ __noinline static int throwing_subprog(struct __sk_buff *ctx)
}
SEC("?tc")
-__failure __msg("BPF_EXIT instruction in main prog cannot be used inside bpf_rcu_read_lock-ed region")
+__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region")
int reject_subprog_with_rcu_read_lock(void *ctx)
{
bpf_rcu_read_lock();
- return throwing_subprog(ctx);
+ throwing_subprog(ctx);
+ bpf_rcu_read_unlock();
+ return 0;
}
static bool rbless(struct bpf_rb_node *n1, const struct bpf_rb_node *n2)
@@ -346,4 +353,47 @@ int reject_exception_throw_cb_diff(struct __sk_buff *ctx)
return 0;
}
+__noinline static int always_throws(void)
+{
+ bpf_throw(0);
+ return 0;
+}
+
+__noinline static int rcu_lock_then_throw(void)
+{
+ bpf_rcu_read_lock();
+ bpf_throw(0);
+ return 0;
+}
+
+SEC("?tc")
+__failure __msg("bpf_throw cannot be used inside bpf_rcu_read_lock-ed region")
+int reject_subprog_rcu_lock_throw(void *ctx)
+{
+ rcu_lock_then_throw();
+ return 0;
+}
+
+SEC("?tc")
+__failure __msg("bpf_throw cannot be used inside bpf_preempt_disable-ed region")
+int reject_subprog_throw_preempt_lock(void *ctx)
+{
+ bpf_preempt_disable();
+ always_throws();
+ bpf_preempt_enable();
+ return 0;
+}
+
+SEC("?tc")
+__failure __msg("bpf_throw cannot be used inside bpf_local_irq_save-ed region")
+int reject_subprog_throw_irq_lock(void *ctx)
+{
+ unsigned long flags;
+
+ bpf_local_irq_save(&flags);
+ always_throws();
+ bpf_local_irq_restore(&flags);
+ return 0;
+}
+
char _license[] SEC("license") = "GPL";