~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to hw/i386/kvm/clock.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <linux/kvm.h>
23
23
#include <linux/kvm_para.h>
24
24
 
 
25
#define TYPE_KVM_CLOCK "kvmclock"
 
26
#define KVM_CLOCK(obj) OBJECT_CHECK(KVMClockState, (obj), TYPE_KVM_CLOCK)
 
27
 
25
28
typedef struct KVMClockState {
 
29
    /*< private >*/
26
30
    SysBusDevice busdev;
 
31
    /*< public >*/
 
32
 
27
33
    uint64_t clock;
28
34
    bool clock_valid;
29
35
} KVMClockState;
30
36
 
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
37
 
64
38
static void kvmclock_vm_state_change(void *opaque, int running,
65
39
                                     RunState state)
66
40
{
67
41
    KVMClockState *s = opaque;
68
 
    CPUArchState *penv = first_cpu;
 
42
    CPUState *cpu = first_cpu;
69
43
    int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
70
44
    int ret;
71
45
 
72
46
    if (running) {
 
47
        struct kvm_clock_data data;
 
48
 
73
49
        s->clock_valid = false;
74
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
 
75
59
        if (!cap_clock_ctrl) {
76
60
            return;
77
61
        }
78
 
        for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
79
 
            ret = kvm_vcpu_ioctl(ENV_GET_CPU(penv), KVM_KVMCLOCK_CTRL, 0);
 
62
        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
 
63
            ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
80
64
            if (ret) {
81
65
                if (ret != -EINVAL) {
82
66
                    fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
84
68
                return;
85
69
            }
86
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;
87
91
    }
88
92
}
89
93
 
90
 
static int kvmclock_init(SysBusDevice *dev)
 
94
static void kvmclock_realize(DeviceState *dev, Error **errp)
91
95
{
92
 
    KVMClockState *s = FROM_SYSBUS(KVMClockState, dev);
 
96
    KVMClockState *s = KVM_CLOCK(dev);
93
97
 
94
98
    qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s);
95
 
    return 0;
96
99
}
97
100
 
98
101
static const VMStateDescription kvmclock_vmsd = {
100
103
    .version_id = 1,
101
104
    .minimum_version_id = 1,
102
105
    .minimum_version_id_old = 1,
103
 
    .pre_save = kvmclock_pre_save,
104
 
    .post_load = kvmclock_post_load,
105
106
    .fields = (VMStateField[]) {
106
107
        VMSTATE_UINT64(clock, KVMClockState),
107
108
        VMSTATE_END_OF_LIST()
111
112
static void kvmclock_class_init(ObjectClass *klass, void *data)
112
113
{
113
114
    DeviceClass *dc = DEVICE_CLASS(klass);
114
 
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
115
115
 
116
 
    k->init = kvmclock_init;
 
116
    dc->realize = kvmclock_realize;
117
117
    dc->no_user = 1;
118
118
    dc->vmsd = &kvmclock_vmsd;
119
119
}
120
120
 
121
121
static const TypeInfo kvmclock_info = {
122
 
    .name          = "kvmclock",
 
122
    .name          = TYPE_KVM_CLOCK,
123
123
    .parent        = TYPE_SYS_BUS_DEVICE,
124
124
    .instance_size = sizeof(KVMClockState),
125
125
    .class_init    = kvmclock_class_init,
128
128
/* Note: Must be called after VCPU initialization. */
129
129
void kvmclock_create(void)
130
130
{
 
131
    X86CPU *cpu = X86_CPU(first_cpu);
 
132
 
131
133
    if (kvm_enabled() &&
132
 
        first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
133
 
                                         (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
134
 
        sysbus_create_simple("kvmclock", -1, NULL);
 
134
        cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
 
135
                                       (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
 
136
        sysbus_create_simple(TYPE_KVM_CLOCK, -1, NULL);
135
137
    }
136
138
}
137
139