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