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 = env->system_time_msr & ~1ULL;
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 cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time));
81
82 assert(time.tsc_timestamp <= migration_tsc);
83 delta = migration_tsc - time.tsc_timestamp;
84 if (time.tsc_shift < 0) {
85 delta >>= -time.tsc_shift;
86 } else {
87 delta <<= time.tsc_shift;
88 }
89
90 mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul);
91 nsec = (nsec_lo >> 32) | (nsec_hi << 32);
92 return nsec + time.system_time;
93}
94
95static void kvm_update_clock(KVMClockState *s)
96{
97 struct kvm_clock_data data;
98 int ret;
99
100 ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
101 if (ret < 0) {
102 fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
103 abort();
104 }
105 s->clock = data.clock;
106
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 s->clock_is_reliable = kvm_has_adjust_clock_stable();
147}
148
149static void kvmclock_vm_state_change(void *opaque, int running,
150 RunState state)
151{
152 KVMClockState *s = opaque;
153 CPUState *cpu;
154 int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
155 int ret;
156
157 if (running) {
158 struct kvm_clock_data data = {};
159
160
161
162
163
164 if (!s->clock_is_reliable) {
165 uint64_t pvclock_via_mem = kvmclock_current_nsec(s);
166
167 if (pvclock_via_mem) {
168 s->clock = pvclock_via_mem;
169 }
170 }
171
172 s->clock_valid = false;
173
174 data.clock = s->clock;
175 ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
176 if (ret < 0) {
177 fprintf(stderr, "KVM_SET_CLOCK failed: %s\n", strerror(ret));
178 abort();
179 }
180
181 if (!cap_clock_ctrl) {
182 return;
183 }
184 CPU_FOREACH(cpu) {
185 ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
186 if (ret) {
187 if (ret != -EINVAL) {
188 fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
189 }
190 return;
191 }
192 }
193 } else {
194
195 if (s->clock_valid) {
196 return;
197 }
198
199 kvm_synchronize_all_tsc();
200
201 kvm_update_clock(s);
202
203
204
205
206
207 s->clock_valid = true;
208 }
209}
210
211static void kvmclock_realize(DeviceState *dev, Error **errp)
212{
213 KVMClockState *s = KVM_CLOCK(dev);
214
215 if (!kvm_enabled()) {
216 error_setg(errp, "kvmclock device requires KVM");
217 return;
218 }
219
220 kvm_update_clock(s);
221
222 qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s);
223}
224
225static bool kvmclock_clock_is_reliable_needed(void *opaque)
226{
227 KVMClockState *s = opaque;
228
229 return s->mach_use_reliable_get_clock;
230}
231
232static const VMStateDescription kvmclock_reliable_get_clock = {
233 .name = "kvmclock/clock_is_reliable",
234 .version_id = 1,
235 .minimum_version_id = 1,
236 .needed = kvmclock_clock_is_reliable_needed,
237 .fields = (VMStateField[]) {
238 VMSTATE_BOOL(clock_is_reliable, KVMClockState),
239 VMSTATE_END_OF_LIST()
240 }
241};
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257static void kvmclock_pre_save(void *opaque)
258{
259 KVMClockState *s = opaque;
260
261 kvm_update_clock(s);
262}
263
264static const VMStateDescription kvmclock_vmsd = {
265 .name = "kvmclock",
266 .version_id = 1,
267 .minimum_version_id = 1,
268 .pre_save = kvmclock_pre_save,
269 .fields = (VMStateField[]) {
270 VMSTATE_UINT64(clock, KVMClockState),
271 VMSTATE_END_OF_LIST()
272 },
273 .subsections = (const VMStateDescription * []) {
274 &kvmclock_reliable_get_clock,
275 NULL
276 }
277};
278
279static Property kvmclock_properties[] = {
280 DEFINE_PROP_BOOL("x-mach-use-reliable-get-clock", KVMClockState,
281 mach_use_reliable_get_clock, true),
282 DEFINE_PROP_END_OF_LIST(),
283};
284
285static void kvmclock_class_init(ObjectClass *klass, void *data)
286{
287 DeviceClass *dc = DEVICE_CLASS(klass);
288
289 dc->realize = kvmclock_realize;
290 dc->vmsd = &kvmclock_vmsd;
291 dc->props = kvmclock_properties;
292}
293
294static const TypeInfo kvmclock_info = {
295 .name = TYPE_KVM_CLOCK,
296 .parent = TYPE_SYS_BUS_DEVICE,
297 .instance_size = sizeof(KVMClockState),
298 .class_init = kvmclock_class_init,
299};
300
301
302void kvmclock_create(void)
303{
304 X86CPU *cpu = X86_CPU(first_cpu);
305
306 if (kvm_enabled() &&
307 cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
308 (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
309 sysbus_create_simple(TYPE_KVM_CLOCK, -1, NULL);
310 }
311}
312
313static void kvmclock_register_types(void)
314{
315 type_register_static(&kvmclock_info);
316}
317
318type_init(kvmclock_register_types)
319