Add a new <timer> for the HyperV reference time counter enlightenment for Windows guests. This feature provides a paravirtual approach to track timer events for the quest (similar to kvmclock). --- docs/formatdomain.html.in | 7 ++++- docs/schemas/domaincommon.rng | 5 +++- src/conf/domain_conf.c | 6 +++-- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 30 ++++++++++++---------- .../qemuxml2argv-clock-timer-hyperv-rtc.args | 5 ++++ .../qemuxml2argv-clock-timer-hyperv-rtc.xml | 26 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmltest.c | 1 + 9 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fd02864..451ce8f 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1367,7 +1367,12 @@ 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 "hyperv_rtc" + (qemu - <span class="since">since 1.2.2</span>). + + The <code>hyperv_rtc</code> timer adds support for the + "reference time counter" feature for guests running the + Microsoft Windows operating system. </dd> <dt><code>track</code></dt> <dd> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 12fc0db..96e62d3 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -915,7 +915,10 @@ </group> <group> <attribute name="name"> - <value>kvmclock</value> + <choice> + <value>kvmclock</value> + <value>hyperv_rtc</value> + </choice> </attribute> </group> </choice> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b6c984b..33b5bee 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", + "hyperv_rtc"); 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_HYPERV_RTC) { 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 d8f2e49..300ba26 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_HYPERV_RTC, VIR_DOMAIN_TIMER_NAME_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index eef65ae..bc5219c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6728,20 +6728,23 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, } } - /* Now force kvmclock on/off based on the corresponding <timer> 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_HYPERV_RTC && + timer->present) { + virBufferAsprintf(&buf, "%s,hv_time", + have_cpu ? "" : default_model); have_cpu = true; - break; } } @@ -8003,8 +8006,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, @@ -8013,7 +8015,9 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: - /* This is handled when building -cpu. */ + case VIR_DOMAIN_TIMER_NAME_HYPERV_RTC: + /* 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 0000000..1905875 --- /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 0000000..47c7c42 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml @@ -0,0 +1,26 @@ +<domain type='kvm'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>6</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='network'/> + </os> + <features> + <pae/> + </features> + <clock offset='utc'> + <timer name='hyperv_rtc' present='yes'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/kvm</emulator> + <controller type='usb' index='0'/> + <controller type='pci' index='0' model='pci-root'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a25264e..1394d68 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -628,6 +628,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 41d1904..e12a0ab 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -159,6 +159,7 @@ mymain(void) DO_TEST("cpu-kvmclock"); DO_TEST("cpu-host-kvmclock"); DO_TEST("kvmclock"); + DO_TEST("clock-timer-hyperv-rtc"); DO_TEST("cpu-eoi-disabled"); DO_TEST("cpu-eoi-enabled"); -- 1.8.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list