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
),
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
),
67 WARN_ON(irqs_disabled());
68 if (cpu
== this_cpu
) {
74 r
= smp_call_function_single(cpu
, func
, info
, 0, wait
);
79 #define smp_call_function_single kvm_smp_call_function_single
81 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
83 /* The 'nonatomic' argument was removed in 2.6.27. */
85 #undef smp_call_function_single
87 #include <linux/smp.h>
89 int kvm_smp_call_function_single(int cpu
, void (*func
)(void *info
),
92 return smp_call_function_single(cpu
, func
, info
, 0, wait
);
95 #define smp_call_function_single kvm_smp_call_function_single
99 /* div64_u64 is fairly new */
100 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
104 /* 64bit divisor, dividend and result. dynamic precision */
105 uint64_t div64_u64(uint64_t dividend
, uint64_t divisor
)
109 high
= divisor
>> 32;
111 unsigned int shift
= fls(high
);
113 d
= divisor
>> shift
;
128 * smp_call_function_mask() is not defined/exported below 2.6.24
131 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
133 #include <linux/smp.h>
135 struct kvm_call_data_struct
{
136 void (*func
) (void *info
);
143 static void kvm_ack_smp_call(void *_data
)
145 struct kvm_call_data_struct
*data
= _data
;
146 /* if wait == 0, data can be out of scope
147 * after atomic_inc(info->started)
149 void (*func
) (void *info
) = data
->func
;
150 void *info
= data
->info
;
151 int wait
= data
->wait
;
154 atomic_inc(&data
->started
);
158 atomic_inc(&data
->finished
);
162 int kvm_smp_call_function_mask(cpumask_t mask
,
163 void (*func
) (void *info
), void *info
, int wait
)
165 struct kvm_call_data_struct data
;
166 cpumask_t allbutself
;
172 WARN_ON(irqs_disabled());
173 allbutself
= cpu_online_map
;
174 cpu_clear(me
, allbutself
);
176 cpus_and(mask
, mask
, allbutself
);
177 cpus
= cpus_weight(mask
);
184 atomic_set(&data
.started
, 0);
187 atomic_set(&data
.finished
, 0);
189 for (cpu
= first_cpu(mask
); cpu
!= NR_CPUS
; cpu
= next_cpu(cpu
, mask
))
190 smp_call_function_single(cpu
, kvm_ack_smp_call
, &data
, 0);
192 while (atomic_read(&data
.started
) != cpus
) {
200 while (atomic_read(&data
.finished
) != cpus
) {
211 /* manually export hrtimer_init/start/cancel */
212 void (*hrtimer_init_p
)(struct hrtimer
*timer
, clockid_t which_clock
,
213 enum hrtimer_mode mode
);
214 int (*hrtimer_start_p
)(struct hrtimer
*timer
, ktime_t tim
,
215 const enum hrtimer_mode mode
);
216 int (*hrtimer_cancel_p
)(struct hrtimer
*timer
);
218 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
220 static void kvm_set_normalized_timespec(struct timespec
*ts
, time_t sec
,
223 while (nsec
>= NSEC_PER_SEC
) {
224 nsec
-= NSEC_PER_SEC
;
228 nsec
+= NSEC_PER_SEC
;
235 struct timespec
kvm_ns_to_timespec(const s64 nsec
)
240 return (struct timespec
) {0, 0};
242 ts
.tv_sec
= div_long_long_rem_signed(nsec
, NSEC_PER_SEC
, &ts
.tv_nsec
);
243 if (unlikely(nsec
< 0))
244 kvm_set_normalized_timespec(&ts
, ts
.tv_sec
, ts
.tv_nsec
);
251 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
253 #include <linux/pci.h>
255 struct pci_dev
*pci_get_bus_and_slot(unsigned int bus
, unsigned int devfn
)
257 struct pci_dev
*dev
= NULL
;
259 while ((dev
= pci_get_device(PCI_ANY_ID
, PCI_ANY_ID
, dev
)) != NULL
) {
260 if (pci_domain_nr(dev
->bus
) == 0 &&
261 (dev
->bus
->number
== bus
&& dev
->devfn
== devfn
))