Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Uniprocessor-only support functions.  The counterpart to kernel/smp.c
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  * Preemption is disabled here to make sure the cond_func is called under the
0041  * same conditions in UP and SMP.
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);