// SPDX-License-Identifier: GPL-2.0-only1/* Copyright (c) 2023 Meta, Inc */2#include <linux/bpf.h>3#include <linux/bpf_mem_alloc.h>4#include <linux/btf.h>5#include <linux/btf_ids.h>6#include <linux/cpumask.h>78/**9* struct bpf_cpumask - refcounted BPF cpumask wrapper structure10* @cpumask: The actual cpumask embedded in the struct.11* @usage: Object reference counter. When the refcount goes to 0, the12* memory is released back to the BPF allocator, which provides13* RCU safety.14*15* Note that we explicitly embed a cpumask_t rather than a cpumask_var_t. This16* is done to avoid confusing the verifier due to the typedef of cpumask_var_t17* changing depending on whether CONFIG_CPUMASK_OFFSTACK is defined or not. See18* the details in <linux/cpumask.h>. The consequence is that this structure is19* likely a bit larger than it needs to be when CONFIG_CPUMASK_OFFSTACK is20* defined due to embedding the whole NR_CPUS-size bitmap, but the extra memory21* overhead is minimal. For the more typical case of CONFIG_CPUMASK_OFFSTACK22* not being defined, the structure is the same size regardless.23*/24struct bpf_cpumask {25cpumask_t cpumask;26refcount_t usage;27};2829static struct bpf_mem_alloc bpf_cpumask_ma;3031static bool cpu_valid(u32 cpu)32{33return cpu < nr_cpu_ids;34}3536__bpf_kfunc_start_defs();3738/**39* bpf_cpumask_create() - Create a mutable BPF cpumask.40*41* Allocates a cpumask that can be queried, mutated, acquired, and released by42* a BPF program. The cpumask returned by this function must either be embedded43* in a map as a kptr, or freed with bpf_cpumask_release().44*45* bpf_cpumask_create() allocates memory using the BPF memory allocator, and46* will not block. It may return NULL if no memory is available.47*48* Return:49* * A pointer to a new struct bpf_cpumask instance on success.50* * NULL if the BPF memory allocator is out of memory.51*/52__bpf_kfunc struct bpf_cpumask *bpf_cpumask_create(void)53{54struct bpf_cpumask *cpumask;5556/* cpumask must be the first element so struct bpf_cpumask be cast to struct cpumask. */57BUILD_BUG_ON(offsetof(struct bpf_cpumask, cpumask) != 0);5859cpumask = bpf_mem_cache_alloc(&bpf_cpumask_ma);60if (!cpumask)61return NULL;6263memset(cpumask, 0, sizeof(*cpumask));64refcount_set(&cpumask->usage, 1);6566return cpumask;67}6869/**70* bpf_cpumask_acquire() - Acquire a reference to a BPF cpumask.71* @cpumask: The BPF cpumask being acquired. The cpumask must be a trusted72* pointer.73*74* Acquires a reference to a BPF cpumask. The cpumask returned by this function75* must either be embedded in a map as a kptr, or freed with76* bpf_cpumask_release().77*78* Return:79* * The struct bpf_cpumask pointer passed to the function.80*81*/82__bpf_kfunc struct bpf_cpumask *bpf_cpumask_acquire(struct bpf_cpumask *cpumask)83{84refcount_inc(&cpumask->usage);85return cpumask;86}8788/**89* bpf_cpumask_release() - Release a previously acquired BPF cpumask.90* @cpumask: The cpumask being released.91*92* Releases a previously acquired reference to a BPF cpumask. When the final93* reference of the BPF cpumask has been released, it is subsequently freed in94* an RCU callback in the BPF memory allocator.95*/96__bpf_kfunc void bpf_cpumask_release(struct bpf_cpumask *cpumask)97{98if (!refcount_dec_and_test(&cpumask->usage))99return;100101bpf_mem_cache_free_rcu(&bpf_cpumask_ma, cpumask);102}103104__bpf_kfunc void bpf_cpumask_release_dtor(void *cpumask)105{106bpf_cpumask_release(cpumask);107}108CFI_NOSEAL(bpf_cpumask_release_dtor);109110/**111* bpf_cpumask_first() - Get the index of the first nonzero bit in the cpumask.112* @cpumask: The cpumask being queried.113*114* Find the index of the first nonzero bit of the cpumask. A struct bpf_cpumask115* pointer may be safely passed to this function.116*117* Return:118* * The index of the first nonzero bit in the struct cpumask.119*/120__bpf_kfunc u32 bpf_cpumask_first(const struct cpumask *cpumask)121{122return cpumask_first(cpumask);123}124125/**126* bpf_cpumask_first_zero() - Get the index of the first unset bit in the127* cpumask.128* @cpumask: The cpumask being queried.129*130* Find the index of the first unset bit of the cpumask. A struct bpf_cpumask131* pointer may be safely passed to this function.132*133* Return:134* * The index of the first zero bit in the struct cpumask.135*/136__bpf_kfunc u32 bpf_cpumask_first_zero(const struct cpumask *cpumask)137{138return cpumask_first_zero(cpumask);139}140141/**142* bpf_cpumask_first_and() - Return the index of the first nonzero bit from the143* AND of two cpumasks.144* @src1: The first cpumask.145* @src2: The second cpumask.146*147* Find the index of the first nonzero bit of the AND of two cpumasks.148* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.149*150* Return:151* * The index of the first bit that is nonzero in both cpumask instances.152*/153__bpf_kfunc u32 bpf_cpumask_first_and(const struct cpumask *src1,154const struct cpumask *src2)155{156return cpumask_first_and(src1, src2);157}158159/**160* bpf_cpumask_set_cpu() - Set a bit for a CPU in a BPF cpumask.161* @cpu: The CPU to be set in the cpumask.162* @cpumask: The BPF cpumask in which a bit is being set.163*/164__bpf_kfunc void bpf_cpumask_set_cpu(u32 cpu, struct bpf_cpumask *cpumask)165{166if (!cpu_valid(cpu))167return;168169cpumask_set_cpu(cpu, (struct cpumask *)cpumask);170}171172/**173* bpf_cpumask_clear_cpu() - Clear a bit for a CPU in a BPF cpumask.174* @cpu: The CPU to be cleared from the cpumask.175* @cpumask: The BPF cpumask in which a bit is being cleared.176*/177__bpf_kfunc void bpf_cpumask_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask)178{179if (!cpu_valid(cpu))180return;181182cpumask_clear_cpu(cpu, (struct cpumask *)cpumask);183}184185/**186* bpf_cpumask_test_cpu() - Test whether a CPU is set in a cpumask.187* @cpu: The CPU being queried for.188* @cpumask: The cpumask being queried for containing a CPU.189*190* Return:191* * true - @cpu is set in the cpumask192* * false - @cpu was not set in the cpumask, or @cpu is an invalid cpu.193*/194__bpf_kfunc bool bpf_cpumask_test_cpu(u32 cpu, const struct cpumask *cpumask)195{196if (!cpu_valid(cpu))197return false;198199return cpumask_test_cpu(cpu, (struct cpumask *)cpumask);200}201202/**203* bpf_cpumask_test_and_set_cpu() - Atomically test and set a CPU in a BPF cpumask.204* @cpu: The CPU being set and queried for.205* @cpumask: The BPF cpumask being set and queried for containing a CPU.206*207* Return:208* * true - @cpu is set in the cpumask209* * false - @cpu was not set in the cpumask, or @cpu is invalid.210*/211__bpf_kfunc bool bpf_cpumask_test_and_set_cpu(u32 cpu, struct bpf_cpumask *cpumask)212{213if (!cpu_valid(cpu))214return false;215216return cpumask_test_and_set_cpu(cpu, (struct cpumask *)cpumask);217}218219/**220* bpf_cpumask_test_and_clear_cpu() - Atomically test and clear a CPU in a BPF221* cpumask.222* @cpu: The CPU being cleared and queried for.223* @cpumask: The BPF cpumask being cleared and queried for containing a CPU.224*225* Return:226* * true - @cpu is set in the cpumask227* * false - @cpu was not set in the cpumask, or @cpu is invalid.228*/229__bpf_kfunc bool bpf_cpumask_test_and_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask)230{231if (!cpu_valid(cpu))232return false;233234return cpumask_test_and_clear_cpu(cpu, (struct cpumask *)cpumask);235}236237/**238* bpf_cpumask_setall() - Set all of the bits in a BPF cpumask.239* @cpumask: The BPF cpumask having all of its bits set.240*/241__bpf_kfunc void bpf_cpumask_setall(struct bpf_cpumask *cpumask)242{243cpumask_setall((struct cpumask *)cpumask);244}245246/**247* bpf_cpumask_clear() - Clear all of the bits in a BPF cpumask.248* @cpumask: The BPF cpumask being cleared.249*/250__bpf_kfunc void bpf_cpumask_clear(struct bpf_cpumask *cpumask)251{252cpumask_clear((struct cpumask *)cpumask);253}254255/**256* bpf_cpumask_and() - AND two cpumasks and store the result.257* @dst: The BPF cpumask where the result is being stored.258* @src1: The first input.259* @src2: The second input.260*261* Return:262* * true - @dst has at least one bit set following the operation263* * false - @dst is empty following the operation264*265* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.266*/267__bpf_kfunc bool bpf_cpumask_and(struct bpf_cpumask *dst,268const struct cpumask *src1,269const struct cpumask *src2)270{271return cpumask_and((struct cpumask *)dst, src1, src2);272}273274/**275* bpf_cpumask_or() - OR two cpumasks and store the result.276* @dst: The BPF cpumask where the result is being stored.277* @src1: The first input.278* @src2: The second input.279*280* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.281*/282__bpf_kfunc void bpf_cpumask_or(struct bpf_cpumask *dst,283const struct cpumask *src1,284const struct cpumask *src2)285{286cpumask_or((struct cpumask *)dst, src1, src2);287}288289/**290* bpf_cpumask_xor() - XOR two cpumasks and store the result.291* @dst: The BPF cpumask where the result is being stored.292* @src1: The first input.293* @src2: The second input.294*295* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.296*/297__bpf_kfunc void bpf_cpumask_xor(struct bpf_cpumask *dst,298const struct cpumask *src1,299const struct cpumask *src2)300{301cpumask_xor((struct cpumask *)dst, src1, src2);302}303304/**305* bpf_cpumask_equal() - Check two cpumasks for equality.306* @src1: The first input.307* @src2: The second input.308*309* Return:310* * true - @src1 and @src2 have the same bits set.311* * false - @src1 and @src2 differ in at least one bit.312*313* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.314*/315__bpf_kfunc bool bpf_cpumask_equal(const struct cpumask *src1, const struct cpumask *src2)316{317return cpumask_equal(src1, src2);318}319320/**321* bpf_cpumask_intersects() - Check two cpumasks for overlap.322* @src1: The first input.323* @src2: The second input.324*325* Return:326* * true - @src1 and @src2 have at least one of the same bits set.327* * false - @src1 and @src2 don't have any of the same bits set.328*329* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.330*/331__bpf_kfunc bool bpf_cpumask_intersects(const struct cpumask *src1, const struct cpumask *src2)332{333return cpumask_intersects(src1, src2);334}335336/**337* bpf_cpumask_subset() - Check if a cpumask is a subset of another.338* @src1: The first cpumask being checked as a subset.339* @src2: The second cpumask being checked as a superset.340*341* Return:342* * true - All of the bits of @src1 are set in @src2.343* * false - At least one bit in @src1 is not set in @src2.344*345* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.346*/347__bpf_kfunc bool bpf_cpumask_subset(const struct cpumask *src1, const struct cpumask *src2)348{349return cpumask_subset(src1, src2);350}351352/**353* bpf_cpumask_empty() - Check if a cpumask is empty.354* @cpumask: The cpumask being checked.355*356* Return:357* * true - None of the bits in @cpumask are set.358* * false - At least one bit in @cpumask is set.359*360* A struct bpf_cpumask pointer may be safely passed to @cpumask.361*/362__bpf_kfunc bool bpf_cpumask_empty(const struct cpumask *cpumask)363{364return cpumask_empty(cpumask);365}366367/**368* bpf_cpumask_full() - Check if a cpumask has all bits set.369* @cpumask: The cpumask being checked.370*371* Return:372* * true - All of the bits in @cpumask are set.373* * false - At least one bit in @cpumask is cleared.374*375* A struct bpf_cpumask pointer may be safely passed to @cpumask.376*/377__bpf_kfunc bool bpf_cpumask_full(const struct cpumask *cpumask)378{379return cpumask_full(cpumask);380}381382/**383* bpf_cpumask_copy() - Copy the contents of a cpumask into a BPF cpumask.384* @dst: The BPF cpumask being copied into.385* @src: The cpumask being copied.386*387* A struct bpf_cpumask pointer may be safely passed to @src.388*/389__bpf_kfunc void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src)390{391cpumask_copy((struct cpumask *)dst, src);392}393394/**395* bpf_cpumask_any_distribute() - Return a random set CPU from a cpumask.396* @cpumask: The cpumask being queried.397*398* Return:399* * A random set bit within [0, num_cpus) if at least one bit is set.400* * >= num_cpus if no bit is set.401*402* A struct bpf_cpumask pointer may be safely passed to @src.403*/404__bpf_kfunc u32 bpf_cpumask_any_distribute(const struct cpumask *cpumask)405{406return cpumask_any_distribute(cpumask);407}408409/**410* bpf_cpumask_any_and_distribute() - Return a random set CPU from the AND of411* two cpumasks.412* @src1: The first cpumask.413* @src2: The second cpumask.414*415* Return:416* * A random set bit within [0, num_cpus) from the AND of two cpumasks, if at417* least one bit is set.418* * >= num_cpus if no bit is set.419*420* struct bpf_cpumask pointers may be safely passed to @src1 and @src2.421*/422__bpf_kfunc u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1,423const struct cpumask *src2)424{425return cpumask_any_and_distribute(src1, src2);426}427428/**429* bpf_cpumask_weight() - Return the number of bits in @cpumask.430* @cpumask: The cpumask being queried.431*432* Count the number of set bits in the given cpumask.433*434* Return:435* * The number of bits set in the mask.436*/437__bpf_kfunc u32 bpf_cpumask_weight(const struct cpumask *cpumask)438{439return cpumask_weight(cpumask);440}441442/**443* bpf_cpumask_populate() - Populate the CPU mask from the contents of444* a BPF memory region.445*446* @cpumask: The cpumask being populated.447* @src: The BPF memory holding the bit pattern.448* @src__sz: Length of the BPF memory region in bytes.449*450* Return:451* * 0 if the struct cpumask * instance was populated successfully.452* * -EACCES if the memory region is too small to populate the cpumask.453* * -EINVAL if the memory region is not aligned to the size of a long454* and the architecture does not support efficient unaligned accesses.455*/456__bpf_kfunc int bpf_cpumask_populate(struct cpumask *cpumask, void *src, size_t src__sz)457{458unsigned long source = (unsigned long)src;459460/* The memory region must be large enough to populate the entire CPU mask. */461if (src__sz < bitmap_size(nr_cpu_ids))462return -EACCES;463464/* If avoiding unaligned accesses, the input region must be aligned to the nearest long. */465if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&466!IS_ALIGNED(source, sizeof(long)))467return -EINVAL;468469bitmap_copy(cpumask_bits(cpumask), src, nr_cpu_ids);470471return 0;472}473474__bpf_kfunc_end_defs();475476BTF_KFUNCS_START(cpumask_kfunc_btf_ids)477BTF_ID_FLAGS(func, bpf_cpumask_create, KF_ACQUIRE | KF_RET_NULL)478BTF_ID_FLAGS(func, bpf_cpumask_release, KF_RELEASE)479BTF_ID_FLAGS(func, bpf_cpumask_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS)480BTF_ID_FLAGS(func, bpf_cpumask_first, KF_RCU)481BTF_ID_FLAGS(func, bpf_cpumask_first_zero, KF_RCU)482BTF_ID_FLAGS(func, bpf_cpumask_first_and, KF_RCU)483BTF_ID_FLAGS(func, bpf_cpumask_set_cpu, KF_RCU)484BTF_ID_FLAGS(func, bpf_cpumask_clear_cpu, KF_RCU)485BTF_ID_FLAGS(func, bpf_cpumask_test_cpu, KF_RCU)486BTF_ID_FLAGS(func, bpf_cpumask_test_and_set_cpu, KF_RCU)487BTF_ID_FLAGS(func, bpf_cpumask_test_and_clear_cpu, KF_RCU)488BTF_ID_FLAGS(func, bpf_cpumask_setall, KF_RCU)489BTF_ID_FLAGS(func, bpf_cpumask_clear, KF_RCU)490BTF_ID_FLAGS(func, bpf_cpumask_and, KF_RCU)491BTF_ID_FLAGS(func, bpf_cpumask_or, KF_RCU)492BTF_ID_FLAGS(func, bpf_cpumask_xor, KF_RCU)493BTF_ID_FLAGS(func, bpf_cpumask_equal, KF_RCU)494BTF_ID_FLAGS(func, bpf_cpumask_intersects, KF_RCU)495BTF_ID_FLAGS(func, bpf_cpumask_subset, KF_RCU)496BTF_ID_FLAGS(func, bpf_cpumask_empty, KF_RCU)497BTF_ID_FLAGS(func, bpf_cpumask_full, KF_RCU)498BTF_ID_FLAGS(func, bpf_cpumask_copy, KF_RCU)499BTF_ID_FLAGS(func, bpf_cpumask_any_distribute, KF_RCU)500BTF_ID_FLAGS(func, bpf_cpumask_any_and_distribute, KF_RCU)501BTF_ID_FLAGS(func, bpf_cpumask_weight, KF_RCU)502BTF_ID_FLAGS(func, bpf_cpumask_populate, KF_RCU)503BTF_KFUNCS_END(cpumask_kfunc_btf_ids)504505static const struct btf_kfunc_id_set cpumask_kfunc_set = {506.owner = THIS_MODULE,507.set = &cpumask_kfunc_btf_ids,508};509510BTF_ID_LIST(cpumask_dtor_ids)511BTF_ID(struct, bpf_cpumask)512BTF_ID(func, bpf_cpumask_release_dtor)513514static int __init cpumask_kfunc_init(void)515{516int ret;517const struct btf_id_dtor_kfunc cpumask_dtors[] = {518{519.btf_id = cpumask_dtor_ids[0],520.kfunc_btf_id = cpumask_dtor_ids[1]521},522};523524ret = bpf_mem_alloc_init(&bpf_cpumask_ma, sizeof(struct bpf_cpumask), false);525ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &cpumask_kfunc_set);526ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &cpumask_kfunc_set);527ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &cpumask_kfunc_set);528return ret ?: register_btf_id_dtor_kfuncs(cpumask_dtors,529ARRAY_SIZE(cpumask_dtors),530THIS_MODULE);531}532533late_initcall(cpumask_kfunc_init);534535536