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");