[libvirt] [PATCH 3/3] qemu: hyperv: Add support for reference time couter enlightenment

Peter Krempa pkrempa at redhat.com
Wed Feb 5 11:02:02 UTC 2014


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




More information about the libvir-list mailing list