|
|
1.1 root 1: /*
2: * QEMU KVM support, paravirtual clock device
3: *
4: * Copyright (C) 2011 Siemens AG
5: *
6: * Authors:
7: * Jan Kiszka <[email protected]>
8: *
9: * This work is licensed under the terms of the GNU GPL version 2.
10: * See the COPYING file in the top-level directory.
11: *
12: * Contributions after 2012-01-13 are licensed under the terms of the
13: * GNU GPL, version 2 or (at your option) any later version.
14: */
15:
16: #include "qemu-common.h"
17: #include "sysemu.h"
18: #include "kvm.h"
19: #include "hw/sysbus.h"
20: #include "hw/kvm/clock.h"
21:
22: #include <linux/kvm.h>
23: #include <linux/kvm_para.h>
24:
25: typedef struct KVMClockState {
26: SysBusDevice busdev;
27: uint64_t clock;
28: bool clock_valid;
29: } KVMClockState;
30:
31: static void kvmclock_pre_save(void *opaque)
32: {
33: KVMClockState *s = opaque;
34: struct kvm_clock_data data;
35: int ret;
36:
37: if (s->clock_valid) {
38: return;
39: }
40: ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
41: if (ret < 0) {
42: fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
43: data.clock = 0;
44: }
45: s->clock = data.clock;
46: /*
47: * If the VM is stopped, declare the clock state valid to avoid re-reading
48: * it on next vmsave (which would return a different value). Will be reset
49: * when the VM is continued.
50: */
51: s->clock_valid = !runstate_is_running();
52: }
53:
54: static int kvmclock_post_load(void *opaque, int version_id)
55: {
56: KVMClockState *s = opaque;
57: struct kvm_clock_data data;
58:
59: data.clock = s->clock;
60: data.flags = 0;
61: return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
62: }
63:
64: static void kvmclock_vm_state_change(void *opaque, int running,
65: RunState state)
66: {
67: KVMClockState *s = opaque;
68: CPUArchState *penv = first_cpu;
69: int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
70: int ret;
71:
72: if (running) {
73: s->clock_valid = false;
74:
75: if (!cap_clock_ctrl) {
76: return;
77: }
78: for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
79: ret = kvm_vcpu_ioctl(penv, KVM_KVMCLOCK_CTRL, 0);
80: if (ret) {
81: if (ret != -EINVAL) {
82: fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
83: }
84: return;
85: }
86: }
87: }
88: }
89:
90: static int kvmclock_init(SysBusDevice *dev)
91: {
92: KVMClockState *s = FROM_SYSBUS(KVMClockState, dev);
93:
94: qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s);
95: return 0;
96: }
97:
98: static const VMStateDescription kvmclock_vmsd = {
99: .name = "kvmclock",
100: .version_id = 1,
101: .minimum_version_id = 1,
102: .minimum_version_id_old = 1,
103: .pre_save = kvmclock_pre_save,
104: .post_load = kvmclock_post_load,
105: .fields = (VMStateField[]) {
106: VMSTATE_UINT64(clock, KVMClockState),
107: VMSTATE_END_OF_LIST()
108: }
109: };
110:
111: static void kvmclock_class_init(ObjectClass *klass, void *data)
112: {
113: DeviceClass *dc = DEVICE_CLASS(klass);
114: SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
115:
116: k->init = kvmclock_init;
117: dc->no_user = 1;
118: dc->vmsd = &kvmclock_vmsd;
119: }
120:
121: static TypeInfo kvmclock_info = {
122: .name = "kvmclock",
123: .parent = TYPE_SYS_BUS_DEVICE,
124: .instance_size = sizeof(KVMClockState),
125: .class_init = kvmclock_class_init,
126: };
127:
128: /* Note: Must be called after VCPU initialization. */
129: void kvmclock_create(void)
130: {
131: if (kvm_enabled() &&
132: first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
133: (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
134: sysbus_create_simple("kvmclock", -1, NULL);
135: }
136: }
137:
138: static void kvmclock_register_types(void)
139: {
140: type_register_static(&kvmclock_info);
141: }
142:
143: type_init(kvmclock_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.