1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
253ce3d95SAndrew Morton /*
353ce3d95SAndrew Morton * Uniprocessor-only support functions. The counterpart to kernel/smp.c
453ce3d95SAndrew Morton */
553ce3d95SAndrew Morton
66e962814SIngo Molnar #include <linux/interrupt.h>
753ce3d95SAndrew Morton #include <linux/kernel.h>
89984de1aSPaul Gortmaker #include <linux/export.h>
953ce3d95SAndrew Morton #include <linux/smp.h>
1047ae4b05SJuergen Gross #include <linux/hypervisor.h>
1153ce3d95SAndrew Morton
smp_call_function_single(int cpu,void (* func)(void * info),void * info,int wait)1253ce3d95SAndrew Morton int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
1353ce3d95SAndrew Morton int wait)
1453ce3d95SAndrew Morton {
15081192b2SDavid Daney unsigned long flags;
16081192b2SDavid Daney
171e474b28SPaul E. McKenney if (cpu != 0)
181e474b28SPaul E. McKenney return -ENXIO;
1993423b86SIngo Molnar
20081192b2SDavid Daney local_irq_save(flags);
21081192b2SDavid Daney func(info);
22081192b2SDavid Daney local_irq_restore(flags);
2393423b86SIngo Molnar
2453ce3d95SAndrew Morton return 0;
2553ce3d95SAndrew Morton }
2653ce3d95SAndrew Morton EXPORT_SYMBOL(smp_call_function_single);
27fa688207SDavid Daney
smp_call_function_single_async(int cpu,struct __call_single_data * csd)281139aeb1SArnd Bergmann int smp_call_function_single_async(int cpu, struct __call_single_data *csd)
2940c01e8bSChristoph Hellwig {
3040c01e8bSChristoph Hellwig unsigned long flags;
3140c01e8bSChristoph Hellwig
3240c01e8bSChristoph Hellwig local_irq_save(flags);
3340c01e8bSChristoph Hellwig csd->func(csd->info);
3440c01e8bSChristoph Hellwig local_irq_restore(flags);
3508eed44cSJan Kara return 0;
3640c01e8bSChristoph Hellwig }
37c46fff2aSFrederic Weisbecker EXPORT_SYMBOL(smp_call_function_single_async);
3840c01e8bSChristoph Hellwig
39fa688207SDavid Daney /*
40fa688207SDavid Daney * Preemption is disabled here to make sure the cond_func is called under the
41*f0fffaffSBhaskar Chowdhury * same conditions in UP and SMP.
42fa688207SDavid Daney */
on_each_cpu_cond_mask(smp_cond_func_t cond_func,smp_call_func_t func,void * info,bool wait,const struct cpumask * mask)435671d814SSebastian Andrzej Siewior void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func,
44cb923159SSebastian Andrzej Siewior void *info, bool wait, const struct cpumask *mask)
45fa688207SDavid Daney {
46fa688207SDavid Daney unsigned long flags;
47fa688207SDavid Daney
48fa688207SDavid Daney preempt_disable();
49a5aa5ce3SNadav Amit if ((!cond_func || cond_func(0, info)) && cpumask_test_cpu(0, mask)) {
50fa688207SDavid Daney local_irq_save(flags);
51fa688207SDavid Daney func(info);
52fa688207SDavid Daney local_irq_restore(flags);
53fa688207SDavid Daney }
54fa688207SDavid Daney preempt_enable();
55fa688207SDavid Daney }
567d49b28aSRik van Riel EXPORT_SYMBOL(on_each_cpu_cond_mask);
577d49b28aSRik van Riel
smp_call_on_cpu(unsigned int cpu,int (* func)(void *),void * par,bool phys)58df8ce9d7SJuergen Gross int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys)
59df8ce9d7SJuergen Gross {
60df8ce9d7SJuergen Gross int ret;
61df8ce9d7SJuergen Gross
62df8ce9d7SJuergen Gross if (cpu != 0)
63df8ce9d7SJuergen Gross return -ENXIO;
64df8ce9d7SJuergen Gross
65df8ce9d7SJuergen Gross if (phys)
66df8ce9d7SJuergen Gross hypervisor_pin_vcpu(0);
67df8ce9d7SJuergen Gross ret = func(par);
68df8ce9d7SJuergen Gross if (phys)
69df8ce9d7SJuergen Gross hypervisor_pin_vcpu(-1);
70df8ce9d7SJuergen Gross
71df8ce9d7SJuergen Gross return ret;
72df8ce9d7SJuergen Gross }
73df8ce9d7SJuergen Gross EXPORT_SYMBOL_GPL(smp_call_on_cpu);
74