Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,6 @@
*.mod
*.mod.c
*.o
.ko
/Module.symvers
/modules.order
@@ -0,0 +1,45 @@
TEST_KMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
SRCTREE_KDIR := $(abspath $(TEST_KMOD_DIR)/../../../../..)
# Honor O=/KBUILD_OUTPUT only if they point at a prepared kernel build
# directory (one containing Module.symvers); otherwise treat the value as a
# selftests-only output directory and fall back to in-tree or distro headers.
# The parent bpf/Makefile resolves O=/KBUILD_OUTPUT to absolute paths before
# invoking this sub-make so relative paths still anchor to the user's
# invocation directory.
KMOD_O := $(or $(O),$(KBUILD_OUTPUT))
KMOD_O_VALID := $(if $(KMOD_O),$(if $(wildcard $(KMOD_O)/Module.symvers),$(KMOD_O)))
KDIR ?= $(if $(KMOD_O_VALID),$(SRCTREE_KDIR), \
$(if $(wildcard $(SRCTREE_KDIR)/Module.symvers),$(SRCTREE_KDIR), \
/lib/modules/$(shell uname -r)/build))
ifeq ($(V),1)
Q =
else
Q = @
endif
MODULES = bpf_testmod.ko bpf_test_no_cfi.ko bpf_test_modorder_x.ko \
bpf_test_modorder_y.ko bpf_test_rqspinlock.ko
$(foreach m,$(MODULES),$(eval obj-m += $(m:.ko=.o)))
CFLAGS_bpf_testmod.o = -I$(src)
# When BPF_STRICT_BUILD != 0, a missing KDIR is fatal (the default).
# When permissive, skip silently.
PERMISSIVE := $(filter 0,$(BPF_STRICT_BUILD))
all:
ifeq ($(PERMISSIVE),)
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
M=$(TEST_KMOD_DIR) modules
else ifneq ("$(wildcard $(KDIR))", "")
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
M=$(TEST_KMOD_DIR) modules
endif
clean:
ifneq ("$(wildcard $(KDIR))", "")
$(Q)$(MAKE) -C $(KDIR) $(if $(KMOD_O_VALID),O=$(KMOD_O_VALID) KBUILD_OUTPUT=$(KMOD_O_VALID),KBUILD_OUTPUT=) \
M=$(TEST_KMOD_DIR) clean
endif
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include <linux/btf.h>
#include <linux/module.h>
#include <linux/init.h>
__bpf_kfunc_start_defs();
__bpf_kfunc int bpf_test_modorder_retx(void)
{
return 'x';
}
__bpf_kfunc_end_defs();
BTF_KFUNCS_START(bpf_test_modorder_kfunc_x_ids)
BTF_ID_FLAGS(func, bpf_test_modorder_retx);
BTF_KFUNCS_END(bpf_test_modorder_kfunc_x_ids)
static const struct btf_kfunc_id_set bpf_test_modorder_x_set = {
.owner = THIS_MODULE,
.set = &bpf_test_modorder_kfunc_x_ids,
};
static int __init bpf_test_modorder_x_init(void)
{
return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
&bpf_test_modorder_x_set);
}
static void __exit bpf_test_modorder_x_exit(void)
{
}
module_init(bpf_test_modorder_x_init);
module_exit(bpf_test_modorder_x_exit);
MODULE_DESCRIPTION("BPF selftest ordertest module X");
MODULE_LICENSE("GPL");
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/bpf.h>
#include <linux/btf.h>
#include <linux/module.h>
#include <linux/init.h>
__bpf_kfunc_start_defs();
__bpf_kfunc int bpf_test_modorder_rety(void)
{
return 'y';
}
__bpf_kfunc_end_defs();
BTF_KFUNCS_START(bpf_test_modorder_kfunc_y_ids)
BTF_ID_FLAGS(func, bpf_test_modorder_rety);
BTF_KFUNCS_END(bpf_test_modorder_kfunc_y_ids)
static const struct btf_kfunc_id_set bpf_test_modorder_y_set = {
.owner = THIS_MODULE,
.set = &bpf_test_modorder_kfunc_y_ids,
};
static int __init bpf_test_modorder_y_init(void)
{
return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS,
&bpf_test_modorder_y_set);
}
static void __exit bpf_test_modorder_y_exit(void)
{
}
module_init(bpf_test_modorder_y_init);
module_exit(bpf_test_modorder_y_exit);
MODULE_DESCRIPTION("BPF selftest ordertest module Y");
MODULE_LICENSE("GPL");
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
#include <linux/bpf.h>
#include <linux/btf.h>
#include <linux/init.h>
#include <linux/module.h>
struct bpf_test_no_cfi_ops {
void (*fn_1)(void);
void (*fn_2)(void);
};
static int dummy_init(struct btf *btf)
{
return 0;
}
static int dummy_init_member(const struct btf_type *t,
const struct btf_member *member,
void *kdata, const void *udata)
{
return 0;
}
static int dummy_reg(void *kdata, struct bpf_link *link)
{
return 0;
}
static void dummy_unreg(void *kdata, struct bpf_link *link)
{
}
static const struct bpf_verifier_ops dummy_verifier_ops;
static void bpf_test_no_cfi_ops__fn_1(void)
{
}
static void bpf_test_no_cfi_ops__fn_2(void)
{
}
static struct bpf_test_no_cfi_ops __test_no_cif_ops = {
.fn_1 = bpf_test_no_cfi_ops__fn_1,
.fn_2 = bpf_test_no_cfi_ops__fn_2,
};
static struct bpf_struct_ops test_no_cif_ops = {
.verifier_ops = &dummy_verifier_ops,
.init = dummy_init,
.init_member = dummy_init_member,
.reg = dummy_reg,
.unreg = dummy_unreg,
.name = "bpf_test_no_cfi_ops",
.owner = THIS_MODULE,
};
static int bpf_test_no_cfi_init(void)
{
int ret;
ret = register_bpf_struct_ops(&test_no_cif_ops,
bpf_test_no_cfi_ops);
if (!ret)
return -EINVAL;
test_no_cif_ops.cfi_stubs = &__test_no_cif_ops;
ret = register_bpf_struct_ops(&test_no_cif_ops,
bpf_test_no_cfi_ops);
return ret;
}
static void bpf_test_no_cfi_exit(void)
{
}
module_init(bpf_test_no_cfi_init);
module_exit(bpf_test_no_cfi_exit);
MODULE_AUTHOR("Kuifeng Lee");
MODULE_DESCRIPTION("BPF no cfi_stubs test module");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,393 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/prandom.h>
#include <linux/ktime.h>
#include <asm/rqspinlock.h>
#include <linux/perf_event.h>
#include <linux/kthread.h>
#include <linux/atomic.h>
#include <linux/slab.h>
static struct perf_event_attr hw_attr = {
.type = PERF_TYPE_HARDWARE,
.config = PERF_COUNT_HW_CPU_CYCLES,
.size = sizeof(struct perf_event_attr),
.pinned = 1,
.disabled = 1,
.sample_period = 100000,
};
static rqspinlock_t lock_a;
static rqspinlock_t lock_b;
static rqspinlock_t lock_c;
#define RQSL_SLOW_THRESHOLD_MS 10
static const unsigned int rqsl_hist_ms[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
12, 14, 16, 18, 20, 25, 30, 40, 50, 75,
100, 150, 200, 250, 1000,
};
#define RQSL_NR_HIST_BUCKETS ARRAY_SIZE(rqsl_hist_ms)
enum rqsl_context {
RQSL_CTX_NORMAL = 0,
RQSL_CTX_NMI,
RQSL_CTX_MAX,
};
struct rqsl_cpu_hist {
atomic64_t hist[RQSL_CTX_MAX][RQSL_NR_HIST_BUCKETS];
atomic64_t success[RQSL_CTX_MAX];
atomic64_t failure[RQSL_CTX_MAX];
};
static DEFINE_PER_CPU(struct rqsl_cpu_hist, rqsl_cpu_hists);
enum rqsl_mode {
RQSL_MODE_AA = 0,
RQSL_MODE_ABBA,
RQSL_MODE_ABBCCA,
};
static int test_mode = RQSL_MODE_AA;
module_param(test_mode, int, 0644);
MODULE_PARM_DESC(test_mode,
"rqspinlock test mode: 0 = AA, 1 = ABBA, 2 = ABBCCA");
static int normal_delay = 20;
module_param(normal_delay, int, 0644);
MODULE_PARM_DESC(normal_delay,
"rqspinlock critical section length for normal context (20ms default)");
static int nmi_delay = 10;
module_param(nmi_delay, int, 0644);
MODULE_PARM_DESC(nmi_delay,
"rqspinlock critical section length for NMI context (10ms default)");
static struct perf_event **rqsl_evts;
static int rqsl_nevts;
static struct task_struct **rqsl_threads;
static int rqsl_nthreads;
static atomic_t rqsl_ready_cpus = ATOMIC_INIT(0);
static int pause = 0;
static const char *rqsl_mode_names[] = {
[RQSL_MODE_AA] = "AA",
[RQSL_MODE_ABBA] = "ABBA",
[RQSL_MODE_ABBCCA] = "ABBCCA",
};
struct rqsl_lock_pair {
rqspinlock_t *worker_lock;
rqspinlock_t *nmi_lock;
};
static struct rqsl_lock_pair rqsl_get_lock_pair(int cpu)
{
int mode = READ_ONCE(test_mode);
switch (mode) {
default:
case RQSL_MODE_AA:
return (struct rqsl_lock_pair){ &lock_a, &lock_a };
case RQSL_MODE_ABBA:
if (cpu & 1)
return (struct rqsl_lock_pair){ &lock_b, &lock_a };
return (struct rqsl_lock_pair){ &lock_a, &lock_b };
case RQSL_MODE_ABBCCA:
switch (cpu % 3) {
case 0:
return (struct rqsl_lock_pair){ &lock_a, &lock_b };
case 1:
return (struct rqsl_lock_pair){ &lock_b, &lock_c };
default:
return (struct rqsl_lock_pair){ &lock_c, &lock_a };
}
}
}
static u32 rqsl_hist_bucket_idx(u32 delta_ms)
{
int i;
for (i = 0; i < RQSL_NR_HIST_BUCKETS; i++) {
if (delta_ms <= rqsl_hist_ms[i])
return i;
}
return RQSL_NR_HIST_BUCKETS - 1;
}
static void rqsl_record_lock_result(u64 delta_ns, enum rqsl_context ctx, int ret)
{
struct rqsl_cpu_hist *hist = this_cpu_ptr(&rqsl_cpu_hists);
u32 delta_ms = DIV_ROUND_UP_ULL(delta_ns, NSEC_PER_MSEC);
u32 bucket = rqsl_hist_bucket_idx(delta_ms);
atomic64_t *buckets = hist->hist[ctx];
atomic64_inc(&buckets[bucket]);
if (!ret)
atomic64_inc(&hist->success[ctx]);
else
atomic64_inc(&hist->failure[ctx]);
}
static int rqspinlock_worker_fn(void *arg)
{
int cpu = smp_processor_id();
unsigned long flags;
u64 start_ns;
int ret;
if (cpu) {
atomic_inc(&rqsl_ready_cpus);
while (!kthread_should_stop()) {
struct rqsl_lock_pair locks = rqsl_get_lock_pair(cpu);
rqspinlock_t *worker_lock = locks.worker_lock;
if (READ_ONCE(pause)) {
msleep(1000);
continue;
}
start_ns = ktime_get_mono_fast_ns();
ret = raw_res_spin_lock_irqsave(worker_lock, flags);
rqsl_record_lock_result(ktime_get_mono_fast_ns() - start_ns,
RQSL_CTX_NORMAL, ret);
mdelay(normal_delay);
if (!ret)
raw_res_spin_unlock_irqrestore(worker_lock, flags);
cpu_relax();
}
return 0;
}
while (!kthread_should_stop()) {
int expected = rqsl_nthreads > 0 ? rqsl_nthreads - 1 : 0;
int ready = atomic_read(&rqsl_ready_cpus);
if (ready == expected && !READ_ONCE(pause)) {
for (int i = 0; i < rqsl_nevts; i++)
perf_event_enable(rqsl_evts[i]);
pr_err("Waiting 5 secs to pause the test\n");
msleep(1000 * 5);
WRITE_ONCE(pause, 1);
pr_err("Paused the test\n");
} else {
msleep(1000);
cpu_relax();
}
}
return 0;
}
static void nmi_cb(struct perf_event *event, struct perf_sample_data *data,
struct pt_regs *regs)
{
struct rqsl_lock_pair locks;
int cpu = smp_processor_id();
unsigned long flags;
u64 start_ns;
int ret;
if (!cpu || READ_ONCE(pause))
return;
locks = rqsl_get_lock_pair(cpu);
start_ns = ktime_get_mono_fast_ns();
ret = raw_res_spin_lock_irqsave(locks.nmi_lock, flags);
rqsl_record_lock_result(ktime_get_mono_fast_ns() - start_ns,
RQSL_CTX_NMI, ret);
mdelay(nmi_delay);
if (!ret)
raw_res_spin_unlock_irqrestore(locks.nmi_lock, flags);
}
static void free_rqsl_threads(void)
{
int i;
if (rqsl_threads) {
for_each_online_cpu(i) {
if (rqsl_threads[i])
kthread_stop(rqsl_threads[i]);
}
kfree(rqsl_threads);
}
}
static void free_rqsl_evts(void)
{
int i;
if (rqsl_evts) {
for (i = 0; i < rqsl_nevts; i++) {
if (rqsl_evts[i])
perf_event_release_kernel(rqsl_evts[i]);
}
kfree(rqsl_evts);
}
}
static int bpf_test_rqspinlock_init(void)
{
int i, ret;
int ncpus = num_online_cpus();
if (test_mode < RQSL_MODE_AA || test_mode > RQSL_MODE_ABBCCA) {
pr_err("Invalid mode %d\n", test_mode);
return -EINVAL;
}
pr_err("Mode = %s\n", rqsl_mode_names[test_mode]);
if (ncpus < test_mode + 2)
return -ENOTSUPP;
raw_res_spin_lock_init(&lock_a);
raw_res_spin_lock_init(&lock_b);
raw_res_spin_lock_init(&lock_c);
rqsl_evts = kcalloc(ncpus - 1, sizeof(*rqsl_evts), GFP_KERNEL);
if (!rqsl_evts)
return -ENOMEM;
rqsl_nevts = ncpus - 1;
for (i = 1; i < ncpus; i++) {
struct perf_event *e;
e = perf_event_create_kernel_counter(&hw_attr, i, NULL, nmi_cb, NULL);
if (IS_ERR(e)) {
ret = PTR_ERR(e);
goto err_perf_events;
}
rqsl_evts[i - 1] = e;
}
rqsl_threads = kcalloc(ncpus, sizeof(*rqsl_threads), GFP_KERNEL);
if (!rqsl_threads) {
ret = -ENOMEM;
goto err_perf_events;
}
rqsl_nthreads = ncpus;
for_each_online_cpu(i) {
struct task_struct *t;
t = kthread_create(rqspinlock_worker_fn, NULL, "rqsl_w/%d", i);
if (IS_ERR(t)) {
ret = PTR_ERR(t);
goto err_threads_create;
}
kthread_bind(t, i);
rqsl_threads[i] = t;
wake_up_process(t);
}
return 0;
err_threads_create:
free_rqsl_threads();
err_perf_events:
free_rqsl_evts();
return ret;
}
module_init(bpf_test_rqspinlock_init);
static void rqsl_print_histograms(void)
{
int cpu, i;
pr_err("rqspinlock acquisition latency histogram (ms):\n");
for_each_online_cpu(cpu) {
struct rqsl_cpu_hist *hist = per_cpu_ptr(&rqsl_cpu_hists, cpu);
u64 norm_counts[RQSL_NR_HIST_BUCKETS];
u64 nmi_counts[RQSL_NR_HIST_BUCKETS];
u64 total_counts[RQSL_NR_HIST_BUCKETS];
u64 norm_success, nmi_success, success_total;
u64 norm_failure, nmi_failure, failure_total;
u64 norm_total = 0, nmi_total = 0, total = 0;
bool has_slow = false;
for (i = 0; i < RQSL_NR_HIST_BUCKETS; i++) {
norm_counts[i] = atomic64_read(&hist->hist[RQSL_CTX_NORMAL][i]);
nmi_counts[i] = atomic64_read(&hist->hist[RQSL_CTX_NMI][i]);
total_counts[i] = norm_counts[i] + nmi_counts[i];
norm_total += norm_counts[i];
nmi_total += nmi_counts[i];
total += total_counts[i];
if (rqsl_hist_ms[i] > RQSL_SLOW_THRESHOLD_MS &&
total_counts[i])
has_slow = true;
}
norm_success = atomic64_read(&hist->success[RQSL_CTX_NORMAL]);
nmi_success = atomic64_read(&hist->success[RQSL_CTX_NMI]);
norm_failure = atomic64_read(&hist->failure[RQSL_CTX_NORMAL]);
nmi_failure = atomic64_read(&hist->failure[RQSL_CTX_NMI]);
success_total = norm_success + nmi_success;
failure_total = norm_failure + nmi_failure;
if (!total)
continue;
if (!has_slow) {
pr_err(" cpu%d: total %llu (normal %llu, nmi %llu) | "
"success %llu (normal %llu, nmi %llu) | "
"failure %llu (normal %llu, nmi %llu), all within 0-%ums\n",
cpu, total, norm_total, nmi_total,
success_total, norm_success, nmi_success,
failure_total, norm_failure, nmi_failure,
RQSL_SLOW_THRESHOLD_MS);
continue;
}
pr_err(" cpu%d: total %llu (normal %llu, nmi %llu) | "
"success %llu (normal %llu, nmi %llu) | "
"failure %llu (normal %llu, nmi %llu)\n",
cpu, total, norm_total, nmi_total,
success_total, norm_success, nmi_success,
failure_total, norm_failure, nmi_failure);
for (i = 0; i < RQSL_NR_HIST_BUCKETS; i++) {
unsigned int start_ms;
if (!total_counts[i])
continue;
start_ms = i == 0 ? 0 : rqsl_hist_ms[i - 1] + 1;
if (i == RQSL_NR_HIST_BUCKETS - 1) {
pr_err(" >= %ums: total %llu (normal %llu, nmi %llu)\n",
start_ms, total_counts[i],
norm_counts[i], nmi_counts[i]);
} else {
pr_err(" %u-%ums: total %llu (normal %llu, nmi %llu)\n",
start_ms, rqsl_hist_ms[i],
total_counts[i],
norm_counts[i], nmi_counts[i]);
}
}
}
}
static void bpf_test_rqspinlock_exit(void)
{
WRITE_ONCE(pause, 1);
free_rqsl_threads();
free_rqsl_evts();
rqsl_print_histograms();
}
module_exit(bpf_test_rqspinlock_exit);
MODULE_AUTHOR("Kumar Kartikeya Dwivedi");
MODULE_DESCRIPTION("BPF rqspinlock stress test module");
MODULE_LICENSE("GPL");
@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2020 Facebook */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM bpf_testmod
#if !defined(_BPF_TESTMOD_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ)
#define _BPF_TESTMOD_EVENTS_H
#include <linux/tracepoint.h>
#include "bpf_testmod.h"
TRACE_EVENT(bpf_testmod_test_read,
TP_PROTO(struct task_struct *task, struct bpf_testmod_test_read_ctx *ctx),
TP_ARGS(task, ctx),
TP_STRUCT__entry(
__field(pid_t, pid)
__array(char, comm, TASK_COMM_LEN)
__field(loff_t, off)
__field(size_t, len)
),
TP_fast_assign(
__entry->pid = task->pid;
memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
__entry->off = ctx->off;
__entry->len = ctx->len;
),
TP_printk("pid=%d comm=%s off=%llu len=%zu",
__entry->pid, __entry->comm, __entry->off, __entry->len)
);
/* A bare tracepoint with no event associated with it */
DECLARE_TRACE(bpf_testmod_test_write_bare,
TP_PROTO(struct task_struct *task, struct bpf_testmod_test_write_ctx *ctx),
TP_ARGS(task, ctx)
);
/* Used in bpf_testmod_test_read() to test __nullable suffix */
DECLARE_TRACE(bpf_testmod_test_nullable_bare,
TP_PROTO(struct bpf_testmod_test_read_ctx *ctx__nullable),
TP_ARGS(ctx__nullable)
);
struct sk_buff;
DECLARE_TRACE(bpf_testmod_test_raw_tp_null,
TP_PROTO(struct sk_buff *skb),
TP_ARGS(skb)
);
#undef BPF_TESTMOD_DECLARE_TRACE
#ifdef DECLARE_TRACE_WRITABLE
#define BPF_TESTMOD_DECLARE_TRACE(call, proto, args, size) \
DECLARE_TRACE_WRITABLE(call, PARAMS(proto), PARAMS(args), size)
#else
#define BPF_TESTMOD_DECLARE_TRACE(call, proto, args, size) \
DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))
#endif
BPF_TESTMOD_DECLARE_TRACE(bpf_testmod_test_writable_bare,
TP_PROTO(struct bpf_testmod_test_writable_ctx *ctx),
TP_ARGS(ctx),
sizeof(struct bpf_testmod_test_writable_ctx)
);
DECLARE_TRACE(bpf_testmod_fentry_test1,
TP_PROTO(int a),
TP_ARGS(a)
);
DECLARE_TRACE(bpf_testmod_fentry_test2,
TP_PROTO(int a, u64 b),
TP_ARGS(a, b)
);
#endif /* _BPF_TESTMOD_EVENTS_H */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE bpf_testmod-events
#include <trace/define_trace.h>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,128 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2020 Facebook */
#ifndef _BPF_TESTMOD_H
#define _BPF_TESTMOD_H
#include <linux/types.h>
struct task_struct;
struct cgroup;
struct bpf_testmod_test_read_ctx {
char *buf;
loff_t off;
size_t len;
};
struct bpf_testmod_test_write_ctx {
char *buf;
loff_t off;
size_t len;
};
struct bpf_testmod_test_writable_ctx {
bool early_ret;
int val;
};
/* BPF iter that returns *value* *n* times in a row */
struct bpf_iter_testmod_seq {
s64 value;
int cnt;
};
struct bpf_testmod_ops {
int (*test_1)(void);
void (*test_2)(int a, int b);
/* Used to test nullable arguments. */
int (*test_maybe_null)(int dummy, struct task_struct *task);
int (*unsupported_ops)(void);
/* Used to test ref_acquired arguments. */
int (*test_refcounted)(int dummy, struct task_struct *task);
/* Used to test checking of __ref arguments when it not the first argument. */
int (*test_refcounted_multi)(int dummy, struct task_struct *task,
struct task_struct *task2);
/* Used to test returning referenced kptr. */
struct task_struct *(*test_return_ref_kptr)(int dummy, struct task_struct *task,
struct cgroup *cgrp);
/* The following fields are used to test shadow copies. */
char onebyte;
struct {
int a;
int b;
} unsupported;
int data;
/* The following pointers are used to test the maps having multiple
* pages of trampolines.
*/
int (*tramp_1)(int value);
int (*tramp_2)(int value);
int (*tramp_3)(int value);
int (*tramp_4)(int value);
int (*tramp_5)(int value);
int (*tramp_6)(int value);
int (*tramp_7)(int value);
int (*tramp_8)(int value);
int (*tramp_9)(int value);
int (*tramp_10)(int value);
int (*tramp_11)(int value);
int (*tramp_12)(int value);
int (*tramp_13)(int value);
int (*tramp_14)(int value);
int (*tramp_15)(int value);
int (*tramp_16)(int value);
int (*tramp_17)(int value);
int (*tramp_18)(int value);
int (*tramp_19)(int value);
int (*tramp_20)(int value);
int (*tramp_21)(int value);
int (*tramp_22)(int value);
int (*tramp_23)(int value);
int (*tramp_24)(int value);
int (*tramp_25)(int value);
int (*tramp_26)(int value);
int (*tramp_27)(int value);
int (*tramp_28)(int value);
int (*tramp_29)(int value);
int (*tramp_30)(int value);
int (*tramp_31)(int value);
int (*tramp_32)(int value);
int (*tramp_33)(int value);
int (*tramp_34)(int value);
int (*tramp_35)(int value);
int (*tramp_36)(int value);
int (*tramp_37)(int value);
int (*tramp_38)(int value);
int (*tramp_39)(int value);
int (*tramp_40)(int value);
};
struct bpf_testmod_ops2 {
int (*test_1)(void);
};
struct bpf_testmod_ops3 {
int (*test_1)(void);
int (*test_2)(void);
};
struct st_ops_args {
u64 a;
};
struct bpf_testmod_st_ops {
int (*test_prologue)(struct st_ops_args *args);
int (*test_epilogue)(struct st_ops_args *args);
int (*test_pro_epilogue)(struct st_ops_args *args);
struct module *owner;
};
struct bpf_testmod_multi_st_ops {
int (*test_1)(struct st_ops_args *args);
struct hlist_node node;
int id;
};
#endif /* _BPF_TESTMOD_H */
@@ -0,0 +1,211 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BPF_TESTMOD_KFUNC_H
#define _BPF_TESTMOD_KFUNC_H
#ifndef __KERNEL__
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#else
#define __ksym
struct prog_test_member1 {
int a;
};
struct prog_test_member {
struct prog_test_member1 m;
int c;
};
struct prog_test_ref_kfunc {
int a;
int b;
struct prog_test_member memb;
struct prog_test_ref_kfunc *next;
refcount_t cnt;
};
#endif
struct bpf_iter_testmod_seq;
struct prog_test_pass1 {
int x0;
struct {
int x1;
struct {
int x2;
struct {
int x3;
};
};
};
};
struct prog_test_pass2 {
int len;
short arr1[4];
struct {
char arr2[4];
unsigned long arr3[8];
} x;
};
struct prog_test_big_arg {
__u64 a;
__u64 b;
};
struct prog_test_fail1 {
void *p;
int x;
};
struct prog_test_fail2 {
int x8;
struct prog_test_pass1 x;
};
struct prog_test_fail3 {
int len;
char arr1[2];
char arr2[];
};
struct init_sock_args {
int af;
int type;
};
struct addr_args {
char addr[sizeof(struct __kernel_sockaddr_storage)];
int addrlen;
};
struct sendmsg_args {
struct addr_args addr;
char msg[10];
int msglen;
};
struct bpf_testmod_ctx {
struct callback_head rcu;
refcount_t usage;
};
struct prog_test_ref_kfunc *
bpf_kfunc_call_test_acquire(unsigned long *scalar_ptr) __ksym;
void bpf_kfunc_call_test_release(struct prog_test_ref_kfunc *p) __ksym;
void bpf_kfunc_call_test_ref(struct prog_test_ref_kfunc *p) __ksym;
void bpf_kfunc_call_test_mem_len_pass1(void *mem, int len) __ksym;
int *bpf_kfunc_call_test_get_rdwr_mem(struct prog_test_ref_kfunc *p, const int rdwr_buf_size) __ksym;
int *bpf_kfunc_call_test_get_rdonly_mem(struct prog_test_ref_kfunc *p, const int rdonly_buf_size) __ksym;
int *bpf_kfunc_call_test_acq_rdonly_mem(struct prog_test_ref_kfunc *p, const int rdonly_buf_size) __ksym;
void bpf_kfunc_call_int_mem_release(int *p) __ksym;
/* The bpf_kfunc_call_test_static_unused_arg is defined as static,
* but bpf program compilation needs to see it as global symbol.
*/
#ifndef __KERNEL__
u32 bpf_kfunc_call_test_static_unused_arg(u32 arg, u32 unused) __ksym;
#endif
void bpf_testmod_test_mod_kfunc(int i) __ksym;
__u64 bpf_kfunc_call_test1(struct sock *sk, __u32 a, __u64 b,
__u32 c, __u64 d) __ksym;
int bpf_kfunc_call_test2(struct sock *sk, __u32 a, __u32 b) __ksym;
struct sock *bpf_kfunc_call_test3(struct sock *sk) __ksym;
long bpf_kfunc_call_test4(signed char a, short b, int c, long d) __ksym;
int bpf_kfunc_call_test5(__u8 a, __u16 b, __u32 c) __ksym;
__u64 bpf_kfunc_call_stack_arg(__u64 a, __u64 b, __u64 c, __u64 d,
__u64 e, __u64 f, __u64 g, __u64 h,
__u64 i, __u64 j) __ksym;
__u64 bpf_kfunc_call_stack_arg_ptr(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
__u64 f, __u64 g, __u64 h, __u64 i,
struct prog_test_pass1 *p) __ksym;
__u64 bpf_kfunc_call_stack_arg_mix(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
__u64 f, __u64 g,
struct prog_test_pass1 *p, __u64 h,
struct prog_test_pass1 *q) __ksym;
__u64 bpf_kfunc_call_stack_arg_dynptr(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
__u64 f, __u64 g, __u64 h, __u64 i,
struct bpf_dynptr *ptr) __ksym;
__u64 bpf_kfunc_call_stack_arg_mem(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
void *mem, int mem__sz) __ksym;
__u64 bpf_kfunc_call_stack_arg_iter(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
__u64 f, __u64 g, __u64 h, __u64 i,
struct bpf_iter_testmod_seq *it__iter) __ksym;
__u64 bpf_kfunc_call_stack_arg_const_str(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
__u64 f, __u64 g, __u64 h, __u64 i,
const char *str__str) __ksym;
__u64 bpf_kfunc_call_stack_arg_timer(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
__u64 f, __u64 g, __u64 h, __u64 i,
struct bpf_timer *timer) __ksym;
__u64 bpf_kfunc_call_stack_arg_big(__u64 a, __u64 b, __u64 c, __u64 d, __u64 e,
struct prog_test_big_arg s) __ksym;
void bpf_kfunc_call_test_pass_ctx(struct __sk_buff *skb) __ksym;
void bpf_kfunc_call_test_pass1(struct prog_test_pass1 *p) __ksym;
void bpf_kfunc_call_test_pass2(struct prog_test_pass2 *p) __ksym;
void bpf_kfunc_call_test_mem_len_fail2(__u64 *mem, int len) __ksym;
void bpf_kfunc_call_test_destructive(void) __ksym;
void bpf_kfunc_call_test_sleepable(void) __ksym;
int bpf_kfunc_call_test_call_rcu_tasks_trace(int *done) __ksym;
void bpf_kfunc_call_test_offset(struct prog_test_ref_kfunc *p);
struct prog_test_member *bpf_kfunc_call_memb_acquire(void);
void bpf_kfunc_call_memb1_release(struct prog_test_member1 *p);
void bpf_kfunc_call_test_fail1(struct prog_test_fail1 *p);
void bpf_kfunc_call_test_fail2(struct prog_test_fail2 *p);
void bpf_kfunc_call_test_fail3(struct prog_test_fail3 *p);
void bpf_kfunc_call_test_mem_len_fail1(void *mem, int len);
void bpf_kfunc_common_test(void) __ksym;
int bpf_kfunc_init_sock(struct init_sock_args *args) __ksym;
void bpf_kfunc_close_sock(void) __ksym;
int bpf_kfunc_call_kernel_connect(struct addr_args *args) __ksym;
int bpf_kfunc_call_kernel_bind(struct addr_args *args) __ksym;
int bpf_kfunc_call_kernel_listen(void) __ksym;
int bpf_kfunc_call_kernel_sendmsg(struct sendmsg_args *args) __ksym;
int bpf_kfunc_call_sock_sendmsg(struct sendmsg_args *args) __ksym;
int bpf_kfunc_call_kernel_getsockname(struct addr_args *args) __ksym;
int bpf_kfunc_call_kernel_getpeername(struct addr_args *args) __ksym;
void bpf_kfunc_dynptr_test(struct bpf_dynptr *ptr, struct bpf_dynptr *ptr__nullable) __ksym;
struct bpf_testmod_ctx *bpf_testmod_ctx_create(int *err) __ksym;
void bpf_testmod_ctx_release(struct bpf_testmod_ctx *ctx) __ksym;
struct sk_buff *bpf_kfunc_nested_acquire_nonzero_offset_test(struct sk_buff_head *ptr) __ksym;
struct sk_buff *bpf_kfunc_nested_acquire_zero_offset_test(struct sock_common *ptr) __ksym;
void bpf_kfunc_nested_release_test(struct sk_buff *ptr) __ksym;
struct st_ops_args;
int bpf_kfunc_st_ops_test_prologue(struct st_ops_args *args) __ksym;
int bpf_kfunc_st_ops_test_epilogue(struct st_ops_args *args) __ksym;
int bpf_kfunc_st_ops_test_pro_epilogue(struct st_ops_args *args) __ksym;
int bpf_kfunc_st_ops_inc10(struct st_ops_args *args) __ksym;
void bpf_kfunc_trusted_vma_test(struct vm_area_struct *ptr) __ksym;
void bpf_kfunc_trusted_task_test(struct task_struct *ptr) __ksym;
void bpf_kfunc_trusted_num_test(int *ptr) __ksym;
void bpf_kfunc_rcu_task_test(struct task_struct *ptr) __ksym;
struct task_struct *bpf_kfunc_ret_rcu_test(void) __ksym;
int *bpf_kfunc_ret_rcu_test_nostruct(int rdonly_buf_size) __ksym;
#ifndef __KERNEL__
extern int bpf_kfunc_multi_st_ops_test_1(struct st_ops_args *args, u32 id) __weak __ksym;
extern int bpf_kfunc_multi_st_ops_test_1_assoc(struct st_ops_args *args) __weak __ksym;
#endif
struct prog_test_member *bpf_kfunc_get_default_trusted_ptr_test(void) __ksym;
void bpf_kfunc_put_default_trusted_ptr_test(struct prog_test_member *trusted_ptr) __ksym;
void bpf_testmod_test_hardirq_fn(void);
void bpf_testmod_test_softirq_fn(void);
void bpf_kfunc_trigger_ctx_check(void) __ksym;
#endif /* _BPF_TESTMOD_KFUNC_H */