1 /* 2 * QEMU KVM support, paravirtual clock device 3 * 4 * Copyright (C) 2011 Siemens AG 5 * 6 * Authors: 7 * Jan Kiszka <jan.kiszka@siemens.com> 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/sysemu.h" 18 #include "sysemu/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 #define TYPE_KVM_CLOCK "kvmclock" 26 #define KVM_CLOCK(obj) OBJECT_CHECK(KVMClockState, (obj), TYPE_KVM_CLOCK) 27 28 typedef struct KVMClockState { 29 /*< private >*/ 30 SysBusDevice busdev; 31 /*< public >*/ 32 33 uint64_t clock; 34 bool clock_valid; 35 } KVMClockState; 36 37 38 static void kvmclock_vm_state_change(void *opaque, int running, 39 RunState state) 40 { 41 KVMClockState *s = opaque; 42 CPUState *cpu; 43 int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL); 44 int ret; 45 46 if (running) { 47 struct kvm_clock_data data; 48 49 s->clock_valid = false; 50 51 data.clock = s->clock; 52 data.flags = 0; 53 ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); 54 if (ret < 0) { 55 fprintf(stderr, "KVM_SET_CLOCK failed: %s\n", strerror(ret)); 56 abort(); 57 } 58 59 if (!cap_clock_ctrl) { 60 return; 61 } 62 CPU_FOREACH(cpu) { 63 ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0); 64 if (ret) { 65 if (ret != -EINVAL) { 66 fprintf(stderr, "%s: %s\n", __func__, strerror(-ret)); 67 } 68 return; 69 } 70 } 71 } else { 72 struct kvm_clock_data data; 73 int ret; 74 75 if (s->clock_valid) { 76 return; 77 } 78 ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); 79 if (ret < 0) { 80 fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); 81 abort(); 82 } 83 s->clock = data.clock; 84 85 /* 86 * If the VM is stopped, declare the clock state valid to 87 * avoid re-reading it on next vmsave (which would return 88 * a different value). Will be reset when the VM is continued. 89 */ 90 s->clock_valid = true; 91 } 92 } 93 94 static void kvmclock_realize(DeviceState *dev, Error **errp) 95 { 96 KVMClockState *s = KVM_CLOCK(dev); 97 98 qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s); 99 } 100 101 static const VMStateDescription kvmclock_vmsd = { 102 .name = "kvmclock", 103 .version_id = 1, 104 .minimum_version_id = 1, 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 115 dc->realize = kvmclock_realize; 116 dc->vmsd = &kvmclock_vmsd; 117 } 118 119 static const TypeInfo kvmclock_info = { 120 .name = TYPE_KVM_CLOCK, 121 .parent = TYPE_SYS_BUS_DEVICE, 122 .instance_size = sizeof(KVMClockState), 123 .class_init = kvmclock_class_init, 124 }; 125 126 /* Note: Must be called after VCPU initialization. */ 127 void kvmclock_create(void) 128 { 129 X86CPU *cpu = X86_CPU(first_cpu); 130 131 if (kvm_enabled() && 132 cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) | 133 (1ULL << KVM_FEATURE_CLOCKSOURCE2))) { 134 sysbus_create_simple(TYPE_KVM_CLOCK, -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) 144