1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include "qemu/osdep.h"
17#include "qemu-common.h"
18#include "cpu.h"
19#include "qemu/host-utils.h"
20#include "sysemu/sysemu.h"
21#include "sysemu/kvm.h"
22#include "sysemu/hw_accel.h"
23#include "kvm_i386.h"
24#include "hw/sysbus.h"
25#include "hw/kvm/clock.h"
26#include "qapi/error.h"
27
28#include <linux/kvm.h>
29#include <linux/kvm_para.h>
30
31#define TYPE_KVM_CLOCK "kvmclock"
32#define KVM_CLOCK(obj) OBJECT_CHECK(KVMClockState, (obj), TYPE_KVM_CLOCK)
33
34typedef struct KVMClockState {
35
36 SysBusDevice busdev;
37
38
39 uint64_t clock;
40 bool clock_valid;
41
42
43 bool mach_use_reliable_get_clock;
44
45
46
47 bool clock_is_reliable;
48} KVMClockState;
49
50struct pvclock_vcpu_time_info {
51 uint32_t version;
52 uint32_t pad0;
53 uint64_t tsc_timestamp;
54 uint64_t system_time;
55 uint32_t tsc_to_system_mul;
56 int8_t tsc_shift;
57 uint8_t flags;
58 uint8_t pad[2];
59} __attribute__((__packed__));
60
61static uint64_t kvmclock_current_nsec(KVMClockState *s)
62{
63 CPUState *cpu = first_cpu;
64 CPUX86State *env = cpu->env_ptr;
65 hwaddr kvmclock_struct_pa;
66 uint64_t migration_tsc = env->tsc;
67 struct pvclock_vcpu_time_info time;
68 uint64_t delta;
69 uint64_t nsec_lo;
70 uint64_t nsec_hi;
71 uint64_t nsec;
72
73 cpu_synchronize_state(cpu);
74
75 if (!(env->system_time_msr & 1ULL)) {
76
77 return 0;
78 }
79
80 kvmclock_struct_pa = env->system_time_msr & ~1ULL;
81 cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
82
83 assert(time.tsc_timestamp <= migration_tsc);
84 delta = migration_tsc - time.tsc_timestamp;
85 if (time.tsc_shift < 0) {
86 delta >>= -time.tsc_shift;
87 } else {
88 delta <<= time.tsc_shift;
89 }
90
91 mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul);
92 nsec = (nsec_lo >> 32) | (nsec_hi << 32);
93 return nsec + time.system_time;
94}
95
96static void kvm_update_clock(KVMClockState *s)
97{
98 struct kvm_clock_data data;
99 int ret;
100
101 ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
102 if (ret < 0) {
103 fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
104 abort();
105 }
106 s->clock = data.clock;
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 s->clock_is_reliable = kvm_has_adjust_clock_stable();
148}
149
150static void kvmclock_vm_state_change(void *opaque, int running,
151 RunState state)
152{
153 KVMClockState *s = opaque;
154 CPUState *cpu;
155 int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
156 int ret;
157
158 if (running) {
159 struct kvm_clock_data data = {};
160
161
162
163
164
165 if (!s->clock_is_reliable) {
166 uint64_t pvclock_via_mem = kvmclock_current_nsec(s);
167
168 if (pvclock_via_mem) {
169 s->clock = pvclock_via_mem;
170 }
171 }
172
173 s->clock_valid = false;
174
175 data.clock = s->clock;
176 ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
177 if (ret < 0) {
178 fprintf(stderr, "KVM_SET_CLOCK failed: %s\n", strerror(ret));
179 abort();
180 }
181
182 if (!cap_clock_ctrl) {
183 return;
184 }
185 CPU_FOREACH(cpu) {
186 ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
187 if (ret) {
188 if (ret != -EINVAL) {
189 fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
190 }
191 return;
192 }
193 }
194 } else {
195
196 if (s->clock_valid) {
197 return;
198 }
199
200 kvm_synchronize_all_tsc();
201
202 kvm_update_clock(s);
203
204
205
206
207
208 s->clock_valid = true;
209 }
210}
211
212static void kvmclock_realize(DeviceState *dev, Error **errp)
213{
214 KVMClockState *s = KVM_CLOCK(dev);
215
216 if (!kvm_enabled()) {
217 error_setg(errp, "kvmclock device requires KVM");
218 return;
219 }
220
221 kvm_update_clock(s);
222
223 qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s);
224}
225
226static bool kvmclock_clock_is_reliable_needed(void *opaque)
227{
228 KVMClockState *s = opaque;
229
230 return s->mach_use_reliable_get_clock;
231}
232
233static const VMStateDescription kvmclock_reliable_get_clock = {
234 .name = "kvmclock/clock_is_reliable",
235 .version_id = 1,
236 .minimum_version_id = 1,
237 .needed = kvmclock_clock_is_reliable_needed,
238 .fields = (VMStateField[]) {
239 VMSTATE_BOOL(clock_is_reliable, KVMClockState),
240 VMSTATE_END_OF_LIST()
241 }
242};
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258static int kvmclock_pre_save(void *opaque)
259{
260 KVMClockState *s = opaque;
261
262 kvm_update_clock(s);
263
264 return 0;
265}
266
267static const VMStateDescription kvmclock_vmsd = {
268 .name = "kvmclock",
269 .version_id = 1,
270 .minimum_version_id = 1,
271 .pre_save = kvmclock_pre_save,
272 .fields = (VMStateField[]) {
273 VMSTATE_UINT64(clock, KVMClockState),
274 VMSTATE_END_OF_LIST()
275 },
276 .subsections = (const VMStateDescription * []) {
277 &kvmclock_reliable_get_clock,
278 NULL
279 }
280};
281
282static Property kvmclock_properties[] = {
283 DEFINE_PROP_BOOL("x-mach-use-reliable-get-clock", KVMClockState,
284 mach_use_reliable_get_clock, true),
285 DEFINE_PROP_END_OF_LIST(),
286};
287
288static void kvmclock_class_init(ObjectClass *klass, void *data)
289{
290 DeviceClass *dc = DEVICE_CLASS(klass);
291
292 dc->realize = kvmclock_realize;
293 dc->vmsd = &kvmclock_vmsd;
294 dc->props = kvmclock_properties;
295}
296
297static const TypeInfo kvmclock_info = {
298 .name = TYPE_KVM_CLOCK,
299 .parent = TYPE_SYS_BUS_DEVICE,
300 .instance_size = sizeof(KVMClockState),
301 .class_init = kvmclock_class_init,
302};
303
304
305void kvmclock_create(void)
306{
307 X86CPU *cpu = X86_CPU(first_cpu);
308
309 if (kvm_enabled() &&
310 cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
311 (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
312 sysbus_create_simple(TYPE_KVM_CLOCK, -1, NULL);
313 }
314}
315
316static void kvmclock_register_types(void)
317{
318 type_register_static(&kvmclock_info);
319}
320
321type_init(kvmclock_register_types)
322