Line data Source code
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 0 : int smp_call_function_single(int cpu, void (*func) (void *info), void *info, 13 : int wait) 14 : { 15 : unsigned long flags; 16 : 17 0 : if (cpu != 0) 18 : return -ENXIO; 19 : 20 0 : local_irq_save(flags); 21 0 : func(info); 22 0 : local_irq_restore(flags); 23 : 24 0 : return 0; 25 : } 26 : EXPORT_SYMBOL(smp_call_function_single); 27 : 28 0 : int smp_call_function_single_async(int cpu, struct __call_single_data *csd) 29 : { 30 : unsigned long flags; 31 : 32 0 : local_irq_save(flags); 33 0 : csd->func(csd->info); 34 0 : local_irq_restore(flags); 35 0 : 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 0 : 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 0 : preempt_disable(); 49 0 : if ((!cond_func || cond_func(0, info)) && cpumask_test_cpu(0, mask)) { 50 0 : local_irq_save(flags); 51 0 : func(info); 52 0 : local_irq_restore(flags); 53 : } 54 0 : preempt_enable(); 55 0 : } 56 : EXPORT_SYMBOL(on_each_cpu_cond_mask); 57 : 58 0 : int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys) 59 : { 60 : int ret; 61 : 62 0 : if (cpu != 0) 63 : return -ENXIO; 64 : 65 : if (phys) 66 : hypervisor_pin_vcpu(0); 67 0 : ret = func(par); 68 : if (phys) 69 : hypervisor_pin_vcpu(-1); 70 : 71 0 : return ret; 72 : } 73 : EXPORT_SYMBOL_GPL(smp_call_on_cpu);