diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fd02864d63..ab9cd4c63d 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1367,7 +1367,13 @@ being modified, and can be one of "platform" (currently unsupported), "hpet" (libxl, xen, qemu), "kvmclock" (qemu), - "pit" (qemu), "rtc" (qemu), or "tsc" (libxl). + "pit" (qemu), "rtc" (qemu), "tsc" (libxl) or "hypervclock" + (qemu - since 1.2.2). + + The hypervclock timer adds support for the + reference time counter and the reference page for iTSC + feature for guests running the Microsoft Windows + operating system.
track
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 63e02e4b14..5b33f4d8c5 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -915,7 +915,10 @@ - kvmclock + + kvmclock + hypervclock + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 627951c071..f3e965bf3f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -726,7 +726,8 @@ VIR_ENUM_IMPL(virDomainTimerName, VIR_DOMAIN_TIMER_NAME_LAST, "rtc", "hpet", "tsc", - "kvmclock"); + "kvmclock", + "hypervclock"); VIR_ENUM_IMPL(virDomainTimerTrack, VIR_DOMAIN_TIMER_TRACK_LAST, "boot", @@ -2929,7 +2930,8 @@ virDomainDefPostParseInternal(virDomainDefPtr def, for (i = 0; i < def->clock.ntimers; i++) { virDomainTimerDefPtr timer = def->clock.timers[i]; - if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { + if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK || + timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK) { if (timer->tickpolicy != -1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("timer %s doesn't support setting of " diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9acb105124..41aa457ada 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1750,6 +1750,7 @@ enum virDomainTimerNameType { VIR_DOMAIN_TIMER_NAME_HPET, VIR_DOMAIN_TIMER_NAME_TSC, VIR_DOMAIN_TIMER_NAME_KVMCLOCK, + VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK, VIR_DOMAIN_TIMER_NAME_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index dddd9d0b6b..7b2b91b9fc 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6732,20 +6732,23 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, } } - /* Now force kvmclock on/off based on the corresponding element. */ + /* Handle paravirtual timers */ for (i = 0; i < def->clock.ntimers; i++) { - if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK && - def->clock.timers[i]->present != -1) { - char sign; - if (def->clock.timers[i]->present) - sign = '+'; - else - sign = '-'; + virDomainTimerDefPtr timer = def->clock.timers[i]; + + if (timer->present == -1) + continue; + + if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { virBufferAsprintf(&buf, "%s,%ckvmclock", have_cpu ? "" : default_model, - sign); + timer->present ? '+' : '-'); + have_cpu = true; + } else if (timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK && + timer->present) { + virBufferAsprintf(&buf, "%s,hv_time", + have_cpu ? "" : default_model); have_cpu = true; - break; } } @@ -8007,8 +8010,7 @@ qemuBuildCommandLine(virConnectPtr conn, } for (i = 0; i < def->clock.ntimers; i++) { - switch (def->clock.timers[i]->name) { - default: + switch ((enum virDomainTimerNameType) def->clock.timers[i]->name) { case VIR_DOMAIN_TIMER_NAME_PLATFORM: case VIR_DOMAIN_TIMER_NAME_TSC: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -8017,7 +8019,9 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: - /* This is handled when building -cpu. */ + case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK: + /* Timers above are handled when building -cpu. */ + case VIR_DOMAIN_TIMER_NAME_LAST: break; case VIR_DOMAIN_TIMER_NAME_RTC: diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args new file mode 100644 index 0000000000..1905875d06 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/kvm -S -M pc \ +-cpu qemu32,hv_time -m 214 -smp 6 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot n -usb -net \ +none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml new file mode 100644 index 0000000000..596e61927f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml @@ -0,0 +1,26 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 6 + + hvm + + + + + + + + + destroy + restart + destroy + + /usr/bin/kvm + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 8f26618cc9..9d2d6e8d49 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -637,6 +637,7 @@ mymain(void) DO_TEST("cpu-kvmclock", QEMU_CAPS_ENABLE_KVM); DO_TEST("cpu-host-kvmclock", QEMU_CAPS_ENABLE_KVM, QEMU_CAPS_CPU_HOST); DO_TEST("kvmclock", QEMU_CAPS_KVM); + DO_TEST("clock-timer-hyperv-rtc", QEMU_CAPS_KVM); DO_TEST("cpu-eoi-disabled", QEMU_CAPS_ENABLE_KVM); DO_TEST("cpu-eoi-enabled", QEMU_CAPS_ENABLE_KVM); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0270eee5c7..4988a20de3 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -160,6 +160,7 @@ mymain(void) DO_TEST("cpu-host-kvmclock"); DO_TEST("clock-catchup"); DO_TEST("kvmclock"); + DO_TEST("clock-timer-hyperv-rtc"); DO_TEST("cpu-eoi-disabled"); DO_TEST("cpu-eoi-enabled");