xref: /openbmc/linux/kernel/up.c (revision f0fffaff)
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)28966a9671SYing Huang 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