3 * smp_call_function_single() is not exported below 2.6.20.
6 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
8 #undef smp_call_function_single
10 #include <linux/spinlock.h>
11 #include <linux/smp.h>
13 struct scfs_thunk_info
{
15 void (*func
)(void *info
);
19 static void scfs_thunk(void *_thunk
)
21 struct scfs_thunk_info
*thunk
= _thunk
;
23 if (raw_smp_processor_id() == thunk
->cpu
)
24 thunk
->func(thunk
->info
);
27 int kvm_smp_call_function_single(int cpu
, void (*func
)(void *info
),
28 void *info
, int nonatomic
, int wait
)
31 struct scfs_thunk_info thunk
;
34 WARN_ON(irqs_disabled());
35 if (cpu
== this_cpu
) {
44 r
= smp_call_function(scfs_thunk
, &thunk
, 0, 1);
50 #define smp_call_function_single kvm_smp_call_function_single
52 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
54 * pre 2.6.23 doesn't handle smp_call_function_single on current cpu
57 #undef smp_call_function_single
59 #include <linux/smp.h>
61 int kvm_smp_call_function_single(int cpu
, void (*func
)(void *info
),
62 void *info
, int nonatomic
, int wait
)
67 WARN_ON(irqs_disabled());
68 if (cpu
== this_cpu
) {
74 r
= smp_call_function_single(cpu
, func
, info
, nonatomic
, wait
);
79 #define smp_call_function_single kvm_smp_call_function_single
83 /* div64_64 is fairly new */
84 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21)
88 /* 64bit divisor, dividend and result. dynamic precision */
89 uint64_t div64_64(uint64_t dividend
, uint64_t divisor
)
95 unsigned int shift
= fls(high
);
112 * smp_call_function_mask() is not defined/exported below 2.6.24
115 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
117 #include <linux/smp.h>
119 struct kvm_call_data_struct
{
120 void (*func
) (void *info
);
127 static void kvm_ack_smp_call(void *_data
)
129 struct kvm_call_data_struct
*data
= _data
;
130 /* if wait == 0, data can be out of scope
131 * after atomic_inc(info->started)
133 void (*func
) (void *info
) = data
->func
;
134 void *info
= data
->info
;
135 int wait
= data
->wait
;
138 atomic_inc(&data
->started
);
142 atomic_inc(&data
->finished
);
146 int kvm_smp_call_function_mask(cpumask_t mask
,
147 void (*func
) (void *info
), void *info
, int wait
)
149 struct kvm_call_data_struct data
;
150 cpumask_t allbutself
;
156 WARN_ON(irqs_disabled());
157 allbutself
= cpu_online_map
;
158 cpu_clear(me
, allbutself
);
160 cpus_and(mask
, mask
, allbutself
);
161 cpus
= cpus_weight(mask
);
168 atomic_set(&data
.started
, 0);
171 atomic_set(&data
.finished
, 0);
173 for (cpu
= first_cpu(mask
); cpu
!= NR_CPUS
; cpu
= next_cpu(cpu
, mask
))
174 smp_call_function_single(cpu
, kvm_ack_smp_call
, &data
, 1, 0);
176 while (atomic_read(&data
.started
) != cpus
) {
184 while (atomic_read(&data
.finished
) != cpus
) {