mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

The selftests build four kernel modules which use copy-pasted Makefile targets. This is a bit messy, and doesn't scale so well when we add more modules, so let's consolidate these rules into a single rule generated for each module name, and move the module sources into a single directory. To avoid parallel builds of the different modules stepping on each other's toes during the 'modpost' phase of the Kbuild 'make modules', the module files should really be a grouped target. However, make only added explicit support for grouped targets in version 4.3, which is newer than the minimum version supported by the kernel. However, make implicitly treats pattern matching rules with multiple targets as a grouped target, so we can work around this by turning the rule into a pattern matching target. We do this by replacing '.ko' with '%ko' in the targets with subst(). Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Viktor Malik <vmalik@redhat.com> Link: https://lore.kernel.org/bpf/20241204-bpf-selftests-mod-compile-v5-1-b96231134a49@redhat.com
144 lines
2.8 KiB
C
144 lines
2.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) 2024 Benjamin Tissoires
|
|
*/
|
|
|
|
#include "bpf_experimental.h"
|
|
#include <bpf/bpf_helpers.h>
|
|
#include "bpf_misc.h"
|
|
#include "../test_kmods/bpf_testmod_kfunc.h"
|
|
|
|
char _license[] SEC("license") = "GPL";
|
|
|
|
struct elem {
|
|
struct bpf_wq w;
|
|
};
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_ARRAY);
|
|
__uint(max_entries, 2);
|
|
__type(key, int);
|
|
__type(value, struct elem);
|
|
} array SEC(".maps");
|
|
|
|
struct {
|
|
__uint(type, BPF_MAP_TYPE_LRU_HASH);
|
|
__uint(max_entries, 4);
|
|
__type(key, int);
|
|
__type(value, struct elem);
|
|
} lru SEC(".maps");
|
|
|
|
/* callback for non sleepable workqueue */
|
|
static int wq_callback(void *map, int *key, void *value)
|
|
{
|
|
bpf_kfunc_common_test();
|
|
return 0;
|
|
}
|
|
|
|
/* callback for sleepable workqueue */
|
|
static int wq_cb_sleepable(void *map, int *key, void *value)
|
|
{
|
|
bpf_kfunc_call_test_sleepable();
|
|
return 0;
|
|
}
|
|
|
|
SEC("tc")
|
|
/* test that bpf_wq_init takes a map as a second argument
|
|
*/
|
|
__log_level(2)
|
|
__flag(BPF_F_TEST_STATE_FREQ)
|
|
__failure
|
|
__msg(": (85) call bpf_wq_init#") /* anchor message */
|
|
__msg("pointer in R2 isn't map pointer")
|
|
long test_wq_init_nomap(void *ctx)
|
|
{
|
|
struct bpf_wq *wq;
|
|
struct elem *val;
|
|
int key = 0;
|
|
|
|
val = bpf_map_lookup_elem(&array, &key);
|
|
if (!val)
|
|
return -1;
|
|
|
|
wq = &val->w;
|
|
if (bpf_wq_init(wq, &key, 0) != 0)
|
|
return -3;
|
|
|
|
return 0;
|
|
}
|
|
|
|
SEC("tc")
|
|
/* test that the workqueue is part of the map in bpf_wq_init
|
|
*/
|
|
__log_level(2)
|
|
__flag(BPF_F_TEST_STATE_FREQ)
|
|
__failure
|
|
__msg(": (85) call bpf_wq_init#") /* anchor message */
|
|
__msg("workqueue pointer in R1 map_uid=0 doesn't match map pointer in R2 map_uid=0")
|
|
long test_wq_init_wrong_map(void *ctx)
|
|
{
|
|
struct bpf_wq *wq;
|
|
struct elem *val;
|
|
int key = 0;
|
|
|
|
val = bpf_map_lookup_elem(&array, &key);
|
|
if (!val)
|
|
return -1;
|
|
|
|
wq = &val->w;
|
|
if (bpf_wq_init(wq, &lru, 0) != 0)
|
|
return -3;
|
|
|
|
return 0;
|
|
}
|
|
|
|
SEC("?tc")
|
|
__log_level(2)
|
|
__failure
|
|
/* check that the first argument of bpf_wq_set_callback()
|
|
* is a correct bpf_wq pointer.
|
|
*/
|
|
__msg(": (85) call bpf_wq_set_callback_impl#") /* anchor message */
|
|
__msg("arg#0 doesn't point to a map value")
|
|
long test_wrong_wq_pointer(void *ctx)
|
|
{
|
|
int key = 0;
|
|
struct bpf_wq *wq;
|
|
|
|
wq = bpf_map_lookup_elem(&array, &key);
|
|
if (!wq)
|
|
return 1;
|
|
|
|
if (bpf_wq_init(wq, &array, 0))
|
|
return 2;
|
|
|
|
if (bpf_wq_set_callback((void *)&wq, wq_callback, 0))
|
|
return 3;
|
|
|
|
return -22;
|
|
}
|
|
|
|
SEC("?tc")
|
|
__log_level(2)
|
|
__failure
|
|
/* check that the first argument of bpf_wq_set_callback()
|
|
* is a correct bpf_wq pointer.
|
|
*/
|
|
__msg(": (85) call bpf_wq_set_callback_impl#") /* anchor message */
|
|
__msg("off 1 doesn't point to 'struct bpf_wq' that is at 0")
|
|
long test_wrong_wq_pointer_offset(void *ctx)
|
|
{
|
|
int key = 0;
|
|
struct bpf_wq *wq;
|
|
|
|
wq = bpf_map_lookup_elem(&array, &key);
|
|
if (!wq)
|
|
return 1;
|
|
|
|
if (bpf_wq_init(wq, &array, 0))
|
|
return 2;
|
|
|
|
if (bpf_wq_set_callback((void *)wq + 1, wq_cb_sleepable, 0))
|
|
return 3;
|
|
|
|
return -22;
|
|
}
|