[libvirt] [PATCH] qemu: hyperv: Add enlightenment support for TSC timekeeping

The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu. --- Notes: This feature is still under development in qemu. I will wait until it's finished before pushing this: http://lists.nongnu.org/archive/html/qemu-devel/2014-01/msg02569.html docs/formatdomain.html.in | 7 +++++++ src/conf/domain_conf.c | 6 +++++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index ff50214..6e1f93a 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1194,6 +1194,7 @@ <hyperv> <relaxed state='on'/> <vapic state='on'/> + <time state='on'/> <spinlocks state='on' retries='4096'/> </hyperv> <pvspinlock/> @@ -1266,6 +1267,12 @@ <td>on, off; retries - at least 4095</td> <td><span class="since">1.1.0 (QEMU only)</span></td> </tr> + <tr> + <td>time</td> + <td>Ease timekeeping in guests by providing reference TSC offsets</td> + <td>on, off</td> + <td><span class="since">1.2.2 (QEMU only)</span></td> + </tr> </table> </dd> <dt><code>pvspinlock</code></dt> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 28e24f9..a3f7284 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -153,7 +153,8 @@ VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST, VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST, "relaxed", "vapic", - "spinlocks") + "spinlocks", + "time") VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST, "destroy", @@ -11720,6 +11721,7 @@ virDomainDefParseXML(xmlDocPtr xml, switch ((enum virDomainHyperv) feature) { case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_VAPIC: + case VIR_DOMAIN_HYPERV_TIME: if (!(tmp = virXPathString("string(./@state)", ctxt))) { virReportError(VIR_ERR_XML_ERROR, _("missing 'state' attribute for " @@ -13744,6 +13746,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, switch ((enum virDomainHyperv) i) { case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_VAPIC: + case VIR_DOMAIN_HYPERV_TIME: if (src->hyperv_features[i] != dst->hyperv_features[i]) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("State of HyperV enlightenment " @@ -17226,6 +17229,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, switch ((enum virDomainHyperv) j) { case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_VAPIC: + case VIR_DOMAIN_HYPERV_TIME: if (def->hyperv_features[j]) virBufferAsprintf(buf, " <%s state='%s'/>\n", virDomainHypervTypeToString(j), diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d8f2e49..2516341 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1658,6 +1658,7 @@ enum virDomainHyperv { VIR_DOMAIN_HYPERV_RELAXED = 0, VIR_DOMAIN_HYPERV_VAPIC, VIR_DOMAIN_HYPERV_SPINLOCKS, + VIR_DOMAIN_HYPERV_TIME, VIR_DOMAIN_HYPERV_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 96b8825..7cf9ec9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6779,6 +6779,7 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, switch ((enum virDomainHyperv) i) { case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_VAPIC: + case VIR_DOMAIN_HYPERV_TIME: if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON) virBufferAsprintf(&buf, ",hv_%s", virDomainHypervTypeToString(i)); @@ -10971,6 +10972,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, switch ((enum virDomainHyperv) f) { case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_VAPIC: + case VIR_DOMAIN_HYPERV_TIME: if (value) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("HyperV feature '%s' should not " -- 1.8.5.3

On 01/21/2014 10:54 AM, Peter Krempa wrote:
The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu. ---
Notes: This feature is still under development in qemu. I will wait until it's finished before pushing this:
http://lists.nongnu.org/archive/html/qemu-devel/2014-01/msg02569.html
Looks okay code-wise, but I agree with holding off in libvirt.git until after the qemu.git commit id is known. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Tue, Jan 21, 2014 at 06:54:34PM +0100, Peter Krempa wrote:
The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu.
I'm not sure I entirely understand what this is doing with TSC, but we do have a generic <timer> element for controlling various attributes of platform timers. I can't help thinking it'd be better to keep this TSC related setting there instead 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 :|

[adding Vadim as he implemented the qemu/kvm parts] On 01/22/14 11:35, Daniel P. Berrange wrote:
On Tue, Jan 21, 2014 at 06:54:34PM +0100, Peter Krempa wrote:
The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu.
I'm not sure I entirely understand what this is doing with TSC, but we do have a generic <timer> element for controlling various attributes of platform timers. I can't help thinking it'd be better to keep this TSC related setting there instead
This functionality provides hypercalls defined by the Microsoft's "enlightenment" standards. These provide calibration data and actual values that can be used by the guest to calculate time. [1] The actual implementation uses data provided by the kvmclock code: + case HV_X64_MSR_TIME_REF_COUNT: { + data = + div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100); + break; + } along with a few values that will allow the guest to use the data. Technically this is a new timer for VM's running windows and as with kvmclock, cpu features are used to show the availability of this feature to the guest. There is yet another "enlightenment" option for windows guests that run on platforms that support the invariant TSC (iTSC). This option will add hypercall to retrieve calibration data so that the host processors iTSC will be used as the timing source eliminating the need to read the timer value via a hypercall. I agree on your idea of moving this option into the <timer> section. How about naming it <timer name="hv-rtc"> ?
Daniel
Peter [1]: http://msdn.microsoft.com/en-us/library/windows/hardware/ff542637(v=vs.85).a...

On Tue, Feb 04, 2014 at 04:04:06PM +0100, Peter Krempa wrote:
[adding Vadim as he implemented the qemu/kvm parts]
On 01/22/14 11:35, Daniel P. Berrange wrote:
On Tue, Jan 21, 2014 at 06:54:34PM +0100, Peter Krempa wrote:
The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu.
I'm not sure I entirely understand what this is doing with TSC, but we do have a generic <timer> element for controlling various attributes of platform timers. I can't help thinking it'd be better to keep this TSC related setting there instead
This functionality provides hypercalls defined by the Microsoft's "enlightenment" standards. These provide calibration data and actual values that can be used by the guest to calculate time. [1]
The actual implementation uses data provided by the kvmclock code:
+ case HV_X64_MSR_TIME_REF_COUNT: { + data = + div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100); + break; + }
along with a few values that will allow the guest to use the data.
Technically this is a new timer for VM's running windows and as with kvmclock, cpu features are used to show the availability of this feature to the guest.
There is yet another "enlightenment" option for windows guests that run on platforms that support the invariant TSC (iTSC). This option will add hypercall to retrieve calibration data so that the host processors iTSC will be used as the timing source eliminating the need to read the timer value via a hypercall.
I agree on your idea of moving this option into the <timer> section. How about naming it <timer name="hv-rtc"> ?
Sounds reasonable, or hyperv-rtc since 'hv' can be misinterpreted to just mean 'hypervisor' 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 Tue, 2014-02-04 at 16:04 +0100, Peter Krempa wrote:
[adding Vadim as he implemented the qemu/kvm parts]
On 01/22/14 11:35, Daniel P. Berrange wrote:
On Tue, Jan 21, 2014 at 06:54:34PM +0100, Peter Krempa wrote:
The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu.
I'm not sure I entirely understand what this is doing with TSC, but we do have a generic <timer> element for controlling various attributes of platform timers. I can't help thinking it'd be better to keep this TSC related setting there instead
This functionality provides hypercalls defined by the Microsoft's "enlightenment" standards. These provide calibration data and actual values that can be used by the guest to calculate time. [1]
The actual implementation uses data provided by the kvmclock code:
+ case HV_X64_MSR_TIME_REF_COUNT: { + data = + div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100); + break; + }
along with a few values that will allow the guest to use the data.
Technically this is a new timer for VM's running windows and as with kvmclock, cpu features are used to show the availability of this feature to the guest.
There is yet another "enlightenment" option for windows guests that run on platforms that support the invariant TSC (iTSC). This option will add hypercall to retrieve calibration data so that the host processors iTSC will be used as the timing source eliminating the need to read the timer value via a hypercall.
Technically, it is not a hypercall, just a normal call RDTSC, but then kernel normalizes the returned value to 10MHz and adds offset. Kernel (KVM) shares scale and offset date with a guest through a dedicated page allocated by guest. We have pretty good working prototype at the moment, but this part has not been committed to upstream yet. Best regards, Vadim.
I agree on your idea of moving this option into the <timer> section. How about naming it <timer name="hv-rtc"> ?
Daniel
Peter
[1]: http://msdn.microsoft.com/en-us/library/windows/hardware/ff542637(v=vs.85).a...
participants (4)
-
Daniel P. Berrange
-
Eric Blake
-
Peter Krempa
-
Vadim Rozenfeld