From 6b9aed5d14f800a2f47e6b34460bd618237c0f57 Mon Sep 17 00:00:00 2001 Message-Id: <6b9aed5d14f800a2f47e6b34460bd618237c0f57@dist-git> From: Peter Krempa Date: Mon, 10 Feb 2014 14:02:49 +0100 Subject: [PATCH] qemu: hyperv: Add support for timer enlightenments https://bugzilla.redhat.com/show_bug.cgi?id=1056205 Add a new for the HyperV reference time counter enlightenment and the iTSC reference page for Windows guests. This feature provides a paravirtual approach to track timer events for the guest (similar to kvmclock) with the option to use real hardware clock on systems with a iTSC with compensation across various hosts. Tweaks: tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args: - removed QEMU_AUDIO_DRV env var (cherry picked from commit 600bca592b2352b683856f4b7f2694f366feac36) Signed-off-by: Jiri Denemark --- docs/formatdomain.html.in | 8 +++++- 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, 66 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 fc8a397..994ebed 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1365,7 +1365,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 f75bf78..551e82b 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -849,7 +849,10 @@ - kvmclock + + kvmclock + hypervclock + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d6c5b3b..6359805 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -713,7 +713,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", @@ -2806,7 +2807,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 ed40def..824fb8e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1724,6 +1724,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 a0ae10c..debafa2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6544,20 +6544,23 @@ qemuBuildCpuArgStr(const 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; } } @@ -7798,8 +7801,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, @@ -7808,7 +7810,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 0000000..368b4c5 --- /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 \ +/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..596e619 --- /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 88ebc18..0e2435b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -440,6 +440,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 92504ad..d16fdc3 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -152,6 +152,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"); -- 1.8.5.4