in kernel/sbi.c [215:257]
static int __sbi_send_ipi_v02(const unsigned long *hart_mask)
{
unsigned long hartid, hmask_val, hbase;
struct cpumask tmask;
struct sbiret ret = {0};
int result;
if (!hart_mask || !(*hart_mask)) {
riscv_cpuid_to_hartid_mask(cpu_online_mask, &tmask);
hart_mask = cpumask_bits(&tmask);
}
hmask_val = 0;
hbase = 0;
for_each_set_bit(hartid, hart_mask, NR_CPUS) {
if (hmask_val && ((hbase + BITS_PER_LONG) <= hartid)) {
ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI,
hmask_val, hbase, 0, 0, 0, 0);
if (ret.error)
goto ecall_failed;
hmask_val = 0;
hbase = 0;
}
if (!hmask_val)
hbase = hartid;
hmask_val |= 1UL << (hartid - hbase);
}
if (hmask_val) {
ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI,
hmask_val, hbase, 0, 0, 0, 0);
if (ret.error)
goto ecall_failed;
}
return 0;
ecall_failed:
result = sbi_err_map_linux_errno(ret.error);
pr_err("%s: hbase = [%lu] hmask = [0x%lx] failed (error [%d])\n",
__func__, hbase, hmask_val, result);
return result;
}