0001
0002
0003
0004
0005
0006 #include <linux/interrupt.h>
0007 #include <linux/kernel.h>
0008 #include <linux/export.h>
0009 #include <linux/smp.h>
0010 #include <linux/hypervisor.h>
0011
0012 int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
0013 int wait)
0014 {
0015 unsigned long flags;
0016
0017 if (cpu != 0)
0018 return -ENXIO;
0019
0020 local_irq_save(flags);
0021 func(info);
0022 local_irq_restore(flags);
0023
0024 return 0;
0025 }
0026 EXPORT_SYMBOL(smp_call_function_single);
0027
0028 int smp_call_function_single_async(int cpu, struct __call_single_data *csd)
0029 {
0030 unsigned long flags;
0031
0032 local_irq_save(flags);
0033 csd->func(csd->info);
0034 local_irq_restore(flags);
0035 return 0;
0036 }
0037 EXPORT_SYMBOL(smp_call_function_single_async);
0038
0039
0040
0041
0042
0043 void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func,
0044 void *info, bool wait, const struct cpumask *mask)
0045 {
0046 unsigned long flags;
0047
0048 preempt_disable();
0049 if ((!cond_func || cond_func(0, info)) && cpumask_test_cpu(0, mask)) {
0050 local_irq_save(flags);
0051 func(info);
0052 local_irq_restore(flags);
0053 }
0054 preempt_enable();
0055 }
0056 EXPORT_SYMBOL(on_each_cpu_cond_mask);
0057
0058 int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys)
0059 {
0060 int ret;
0061
0062 if (cpu != 0)
0063 return -ENXIO;
0064
0065 if (phys)
0066 hypervisor_pin_vcpu(0);
0067 ret = func(par);
0068 if (phys)
0069 hypervisor_pin_vcpu(-1);
0070
0071 return ret;
0072 }
0073 EXPORT_SYMBOL_GPL(smp_call_on_cpu);