Merge branch 'bpf-s390-implement-get_preempt_count'

Ilya Leoshkevich says:

====================
bpf/s390: Implement get_preempt_count()

This series adds get_preempt_count() BPF implementation for s390.
On s390 preempt_count lives in lowcore: a per-cpu data structure
mapped at virtual address 0 or 0x70000 depending on the kernel
command line.

Patch 1 adds a kfunc to obtain lowcore address.
Patch 2 is the implementation that delegates to it.
====================

Link: https://patch.msgid.link/20260217160813.100855-1-iii@linux.ibm.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Alexei Starovoitov 2026-03-03 08:35:07 -08:00
commit 74fef05ef1
4 changed files with 28 additions and 0 deletions

View File

@ -80,5 +80,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_pai.o
obj-$(CONFIG_TRACEPOINTS) += trace.o
obj-$(CONFIG_BPF_SYSCALL) += bpf.o
# vdso
obj-y += vdso/

12
arch/s390/kernel/bpf.c Normal file
View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
#include <asm/lowcore.h>
#include <linux/btf.h>
__bpf_kfunc_start_defs();
__bpf_kfunc struct lowcore *bpf_get_lowcore(void)
{
return get_lowcore();
}
__bpf_kfunc_end_defs();

View File

@ -4578,6 +4578,9 @@ BTF_ID_FLAGS(func, bpf_key_put, KF_RELEASE)
BTF_ID_FLAGS(func, bpf_verify_pkcs7_signature, KF_SLEEPABLE)
#endif
#endif
#ifdef CONFIG_S390
BTF_ID_FLAGS(func, bpf_get_lowcore)
#endif
BTF_KFUNCS_END(generic_btf_ids)
static const struct btf_kfunc_id_set generic_kfunc_set = {

View File

@ -627,6 +627,10 @@ struct task_struct___preempt_rt {
int softirq_disable_cnt;
} __attribute__((preserve_access_index));
#ifdef bpf_target_s390
extern struct lowcore *bpf_get_lowcore(void) __weak __ksym;
#endif
static inline int get_preempt_count(void)
{
#if defined(bpf_target_x86)
@ -647,6 +651,8 @@ static inline int get_preempt_count(void)
return bpf_get_current_task_btf()->thread_info.preempt.count;
#elif defined(bpf_target_powerpc)
return bpf_get_current_task_btf()->thread_info.preempt_count;
#elif defined(bpf_target_s390)
return bpf_get_lowcore()->preempt_count;
#endif
return 0;
}
@ -656,6 +662,7 @@ static inline int get_preempt_count(void)
* * x86
* * arm64
* * powerpc64
* * s390x
*/
static inline int bpf_in_interrupt(void)
{
@ -676,6 +683,7 @@ static inline int bpf_in_interrupt(void)
* * x86
* * arm64
* * powerpc64
* * s390x
*/
static inline int bpf_in_nmi(void)
{
@ -687,6 +695,7 @@ static inline int bpf_in_nmi(void)
* * x86
* * arm64
* * powerpc64
* * s390x
*/
static inline int bpf_in_hardirq(void)
{
@ -698,6 +707,7 @@ static inline int bpf_in_hardirq(void)
* * x86
* * arm64
* * powerpc64
* * s390x
*/
static inline int bpf_in_serving_softirq(void)
{
@ -717,6 +727,7 @@ static inline int bpf_in_serving_softirq(void)
* * x86
* * arm64
* * powerpc64
* * s390x
*/
static inline int bpf_in_task(void)
{