Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions kernel/bpf/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -4252,6 +4252,47 @@ __bpf_kfunc int bpf_task_work_schedule_resume(struct task_struct *task, struct b
return bpf_task_work_schedule(task, tw, map__map, callback, aux__prog, TWA_RESUME);
}

/**
* bpf_in_nmi_context - Check whether we are serving NMI
*
* Return: true if we are serving NMI
*/
__bpf_kfunc bool bpf_in_nmi_context(void)
{
return in_nmi();
}

/**
* bpf_in_hardirq_context - Check whether we are serving hard irq
*
* Return: true if we are serving hard irq
*/
__bpf_kfunc bool bpf_in_hardirq_context(void)
{
return in_hardirq();
}

/**
* bpf_in_softirq_context - Check whether we are serving soft irq
*
* Return: true if we are serving soft irq
*/
__bpf_kfunc bool bpf_in_softirq_context(void)
{
/* in_softirq() has been deprecated */
return in_serving_softirq();
}

/**
* bpf_in_task_context - Check whether we are in task context
*
* Return: true if we are in task context
*/
__bpf_kfunc bool bpf_in_task_context(void)
{
return in_task();
}

__bpf_kfunc_end_defs();

static void bpf_task_work_cancel_scheduled(struct irq_work *irq_work)
Expand Down Expand Up @@ -4429,6 +4470,10 @@ BTF_ID_FLAGS(func, bpf_cgroup_read_xattr, KF_RCU)
BTF_ID_FLAGS(func, bpf_stream_vprintk, KF_TRUSTED_ARGS)
BTF_ID_FLAGS(func, bpf_task_work_schedule_signal, KF_TRUSTED_ARGS)
BTF_ID_FLAGS(func, bpf_task_work_schedule_resume, KF_TRUSTED_ARGS)
BTF_ID_FLAGS(func, bpf_in_softirq_context)
BTF_ID_FLAGS(func, bpf_in_hardirq_context)
BTF_ID_FLAGS(func, bpf_in_task_context)
BTF_ID_FLAGS(func, bpf_in_nmi_context)
BTF_KFUNCS_END(common_btf_ids)

static const struct btf_kfunc_id_set common_kfunc_set = {
Expand Down
32 changes: 32 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/context.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0
#include <error.h>
#include <test_progs.h>
#include "context_prog.skel.h"

void test_context(void)
{
struct context_prog *skel = NULL;

skel = context_prog__open_and_load();
if (!ASSERT_OK_PTR(skel, "loading prog fail"))
return;

context_prog__attach(skel);
getuid();
sleep(5);

if (!ASSERT_EQ(1, skel->bss->in_hardirq, "hardirq not triggered"))
goto out;
if (!ASSERT_EQ(1, skel->bss->in_softriq, "softirq not triggered"))
goto out;
if (!ASSERT_EQ(1, skel->bss->in_task, "task context not triggered"))
goto out;
out:
context_prog__destroy(skel);
}

void test_bpf_context(void)
{
if (test__start_subtest("context"))
test_context();
}
33 changes: 33 additions & 0 deletions tools/testing/selftests/bpf/progs/context_prog.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "bpf_misc.h"
#include "bpf_experimental.h"

int in_hardirq = 0;
int in_softriq = 0;
int in_task = 0;

SEC("tp/irq/irq_handler_entry")
int trace_irq_handler_entry(const void *ctx)
{
in_hardirq = bpf_in_hardirq_context();
return 0;
}

SEC("tp/irq/softirq_entry")
int trace_softirq_entry(const void *ctx)
{
in_softriq = bpf_in_softirq_context();
return 0;
}

SEC("tp/syscalls/sys_enter_getuid")
int trace_syscall(const void *ctx)
{
in_task = bpf_in_task_context();
return 0;
}

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