1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Uniprocessor-only support functions. The counterpart to kernel/smp.c |
4 | */ |
5 | |
6 | #include <linux/interrupt.h> |
7 | #include <linux/kernel.h> |
8 | #include <linux/export.h> |
9 | #include <linux/smp.h> |
10 | #include <linux/hypervisor.h> |
11 | |
12 | int smp_call_function_single(int cpu, void (*func) (void *info), void *info, |
13 | int wait) |
14 | { |
15 | unsigned long flags; |
16 | |
17 | if (cpu != 0) |
18 | return -ENXIO; |
19 | |
20 | local_irq_save(flags); |
21 | func(info); |
22 | local_irq_restore(flags); |
23 | |
24 | return 0; |
25 | } |
26 | EXPORT_SYMBOL(smp_call_function_single); |
27 | |
28 | int smp_call_function_single_async(int cpu, call_single_data_t *csd) |
29 | { |
30 | unsigned long flags; |
31 | |
32 | local_irq_save(flags); |
33 | csd->func(csd->info); |
34 | local_irq_restore(flags); |
35 | return 0; |
36 | } |
37 | EXPORT_SYMBOL(smp_call_function_single_async); |
38 | |
39 | /* |
40 | * Preemption is disabled here to make sure the cond_func is called under the |
41 | * same conditions in UP and SMP. |
42 | */ |
43 | void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func, |
44 | void *info, bool wait, const struct cpumask *mask) |
45 | { |
46 | unsigned long flags; |
47 | |
48 | preempt_disable(); |
49 | if ((!cond_func || cond_func(0, info)) && cpumask_test_cpu(cpu: 0, cpumask: mask)) { |
50 | local_irq_save(flags); |
51 | func(info); |
52 | local_irq_restore(flags); |
53 | } |
54 | preempt_enable(); |
55 | } |
56 | EXPORT_SYMBOL(on_each_cpu_cond_mask); |
57 | |
58 | int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys) |
59 | { |
60 | int ret; |
61 | |
62 | if (cpu != 0) |
63 | return -ENXIO; |
64 | |
65 | if (phys) |
66 | hypervisor_pin_vcpu(cpu: 0); |
67 | ret = func(par); |
68 | if (phys) |
69 | hypervisor_pin_vcpu(cpu: -1); |
70 | |
71 | return ret; |
72 | } |
73 | EXPORT_SYMBOL_GPL(smp_call_on_cpu); |
74 | |