[libvirt] [PATCHv2 0/3] add support for HyperV RTC enlightenment

Version 2 now adds the as a timer mode instead of the hyperv feature as this is a timer in fact. Peter Krempa (3): schema: Fix guest timer specification schema according to the docs conf: Enforce supported options for certain timers qemu: hyperv: Add support for reference time couter enlightenment docs/formatdomain.html.in | 7 +- docs/schemas/domaincommon.rng | 156 +++++++++++++-------- src/conf/domain_conf.c | 59 +++++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 31 ++-- .../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, 212 insertions(+), 75 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml -- 1.8.5.3

According to the documentation describing various tunables for domain timers not all the fields are supported by all the driver types. Express these in the RNG: - rtc, platform: Only these support the "track" attribute. - tsc: only one to support "frequency" and "mode" attributes - hpet, pit: tickpolicy/catchup attribute/element - kvmclock: no extra attributes are supported --- docs/schemas/domaincommon.rng | 153 +++++++++++++++++++++++++----------------- 1 file changed, 93 insertions(+), 60 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 7f55f24..12fc0db 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -857,54 +857,68 @@ </define> <define name="timer"> <element name="timer"> - <attribute name="name"> - <choice> - <value>platform</value> - <value>hpet</value> - <value>kvmclock</value> - <value>pit</value> - <value>rtc</value> - <value>tsc</value> - </choice> - </attribute> - <optional> - <attribute name="track"> - <choice> - <value>boot</value> - <value>guest</value> - <value>wall</value> - </choice> - </attribute> - </optional> - <optional> - <attribute name="tickpolicy"> - <choice> - <value>delay</value> - <value>catchup</value> - <value>merge</value> - <value>discard</value> - </choice> - </attribute> - </optional> - <optional> - <ref name="catchup"/> - </optional> - <optional> - <attribute name="frequency"> - <ref name="unsignedInt"/> - </attribute> - </optional> - <optional> - <attribute name="mode"> - <choice> - <value>auto</value> - <value>native</value> - <value>emulate</value> - <value>paravirt</value> - <value>smpsafe</value> - </choice> - </attribute> - </optional> + <choice> + <group> + <attribute name="name"> + <choice> + <value>platform</value> + <value>rtc</value> + </choice> + </attribute> + <optional> + <attribute name="track"> + <choice> + <value>boot</value> + <value>guest</value> + <value>wall</value> + </choice> + </attribute> + </optional> + <optional> + <ref name="tickpolicy"/> + </optional> + </group> + <group> + <attribute name="name"> + <value>tsc</value> + </attribute> + <optional> + <ref name="tickpolicy"/> + </optional> + <optional> + <attribute name="frequency"> + <ref name="unsignedInt"/> + </attribute> + </optional> + <optional> + <attribute name="mode"> + <choice> + <value>auto</value> + <value>native</value> + <value>emulate</value> + <value>paravirt</value> + <value>smpsafe</value> + </choice> + </attribute> + </optional> + </group> + <group> + <attribute name="name"> + <choice> + <value>hpet</value> + <value>pit</value> + </choice> + </attribute> + <optional> + <ref name="tickpolicy"/> + </optional> + </group> + <group> + <attribute name="name"> + <value>kvmclock</value> + </attribute> + </group> + </choice> <optional> <attribute name="present"> <choice> @@ -916,20 +930,39 @@ <empty/> </element> </define> - <define name="catchup"> - <element name="catchup"> - <optional> - <attribute name="threshold"> - <ref name="unsignedInt"/> - </attribute> - <attribute name="slew"> - <ref name="unsignedInt"/> + + <define name="tickpolicy"> + <choice> + <group> + <attribute name="tickpolicy"> + <choice> + <value>delay</value> + <value>merge</value> + <value>discard</value> + </choice> </attribute> - <attribute name="limit"> - <ref name="unsignedInt"/> + </group> + <group> + <attribute name="tickpolicy"> + <value>catchup</value> </attribute> - </optional> - </element> + <optional> + <element name="catchup"> + <optional> + <attribute name="threshold"> + <ref name="unsignedInt"/> + </attribute> + <attribute name="slew"> + <ref name="unsignedInt"/> + </attribute> + <attribute name="limit"> + <ref name="unsignedInt"/> + </attribute> + </optional> + </element> + </optional> + </group> + </choice> </define> <!-- A bootloader may be used to extract the OS information instead of -- 1.8.5.3

According to the documentation various timer options are only supported by certain timer types. Add a post parse check to verify that the user didn't specify invalid options. Also fix the qemu command line parsing function to set correct default values for the kvmclock timer so that it passes the new check. --- src/conf/domain_conf.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_command.c | 1 + 2 files changed, 56 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 28e24f9..b6c984b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2924,6 +2924,61 @@ virDomainDefPostParseInternal(virDomainDefPtr def, if (virDomainDefRejectDuplicateControllers(def) < 0) return -1; + + /* verify settings of guest timers */ + for (i = 0; i < def->clock.ntimers; i++) { + virDomainTimerDefPtr timer = def->clock.timers[i]; + + if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { + if (timer->tickpolicy != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("timer %s doesn't support setting of " + "timer tickpolicy"), + virDomainTimerNameTypeToString(timer->name)); + return -1; + } + } + + if (timer->tickpolicy != VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP && + (timer->catchup.threshold != 0 || + timer->catchup.limit != 0 || + timer->catchup.slew != 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("setting of timer catchup policies is only " + "supported with tickpolicy='catchup'")); + return -1; + } + + if (timer->name != VIR_DOMAIN_TIMER_NAME_TSC) { + if (timer->frequency != 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("timer %s doesn't support setting of " + "timer frequency"), + virDomainTimerNameTypeToString(timer->name)); + return -1; + } + + if (timer->mode != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("timer %s doesn't support setting of " + "timer mode"), + virDomainTimerNameTypeToString(timer->name)); + return -1; + } + } + + if (timer->name != VIR_DOMAIN_TIMER_NAME_PLATFORM && + timer->name != VIR_DOMAIN_TIMER_NAME_RTC) { + if (timer->track != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("timer %s doesn't support setting of " + "timer track"), + virDomainTimerNameTypeToString(timer->name)); + return -1; + } + } + } + return 0; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5b94de1..eef65ae 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -10920,6 +10920,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, dom->clock.timers[j]->present = present; dom->clock.timers[j]->tickpolicy = -1; dom->clock.timers[j]->track = -1; + dom->clock.timers[j]->mode = -1; dom->clock.ntimers++; } else if (dom->clock.timers[j]->present != -1 && dom->clock.timers[j]->present != present) { -- 1.8.5.3

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

Il 05/02/2014 12:02, Peter Krempa ha scritto:
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).
RTC can be confusing because the same acronym expands to both "real-time clock" and "reference time counter". By the way, the same <timer> will drive two things: the reference time counter, and the reference TSC page. In current kernels, the reference TSC page just tells the guest "use the reference time counter", but this can be changed in the future without breaking the guest ABI. So, what about naming it hv_clock or hyperv_clock or hyperv_ref? Paolo
--- 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");

On 02/07/14 12:03, Paolo Bonzini wrote:
Il 05/02/2014 12:02, Peter Krempa ha scritto:
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).
RTC can be confusing because the same acronym expands to both "real-time clock" and "reference time counter".
I was confused too, when I saw it the first time.
By the way, the same <timer> will drive two things: the reference time counter, and the reference TSC page. In current kernels, the reference TSC page just tells the guest "use the reference time counter", but this can be changed in the future without breaking the guest ABI.
That's right, the feature is actually backwards compatible to a great extent and even tolerates the iTSC vanishing at migration. This makes our lives really easier.
So, what about naming it hv_clock or hyperv_clock or hyperv_ref?
hyperv_clock then. DanPB was concerned that hv could mean "hypervisor" to some people.
Paolo
Thanks for the feedback. Peter

On Fri, Feb 07, 2014 at 02:58:19PM +0100, Peter Krempa wrote:
On 02/07/14 12:03, Paolo Bonzini wrote:
Il 05/02/2014 12:02, Peter Krempa ha scritto:
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).
RTC can be confusing because the same acronym expands to both "real-time clock" and "reference time counter".
I was confused too, when I saw it the first time.
By the way, the same <timer> will drive two things: the reference time counter, and the reference TSC page. In current kernels, the reference TSC page just tells the guest "use the reference time counter", but this can be changed in the future without breaking the guest ABI.
That's right, the feature is actually backwards compatible to a great extent and even tolerates the iTSC vanishing at migration. This makes our lives really easier.
So, what about naming it hv_clock or hyperv_clock or hyperv_ref?
hyperv_clock then. DanPB was concerned that hv could mean "hypervisor" to some people.
If we go for consistency with 'kvmclock', then we might as well remove the underscore too eg 'hypervclock' Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 02/05/14 12:01, Peter Krempa wrote:
Version 2 now adds the as a timer mode instead of the hyperv feature as this is a timer in fact. Peter Krempa (3): schema: Fix guest timer specification schema according to the docs conf: Enforce supported options for certain timers qemu: hyperv: Add support for reference time couter enlightenment
docs/formatdomain.html.in | 7 +- docs/schemas/domaincommon.rng | 156 +++++++++++++-------- src/conf/domain_conf.c | 59 +++++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 31 ++-- .../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, 212 insertions(+), 75 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml
qemu now pulled the changes needed for this feature to work as: commit 48a5f3bcbbbe59a3120a39106bfda59fd1933fbc Author: Vadim Rozenfeld <vrozenfe@redhat.com> Date: Fri Jan 24 00:40:49 2014 +1100 kvm: add support for hyper-v timers http://msdn.microsoft.com/en-us/library/windows/hardware/ff541625%28v=vs.85%... This code is generic for activating reference time counter or virtual reference time stamp counter Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com> Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
participants (3)
-
Daniel P. Berrange
-
Paolo Bonzini
-
Peter Krempa