|
|
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.