On Tue, May 06, 2014 at 03:27:20PM +0200, Ján Tomko wrote: > Not yet merged in upstream QEMU: > https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg05024.html > > Add support for invariant TSC timer running at constant rate in > all ACPI P-, C- and T-states. > > It can be enabled by specifying: > <clock> > <timer name='invtsc' present='yes'/> > </clock> > in the domain XML. > > Migration and saving the domain does not work with this timer. > > The support for this timer is indicated by bit 8 of EDX after calling > CPUID with 0x80000007. It does not show up in /proc/cpuinfo [1] > and since we're calling qemu without 'enforce', it doesn't error > out if the host doesn't support this. It is not a timer, really, but a CPU flag. > Alternatively, we could expose it in libvirt as a cpu flag: > <cpu mode='custom' match='exact'> > <model fallback='forbid'>qemu64</model> > <feature policy='require' name='invtsc'/> > </cpu> Would prefer that option. Can't one modify QEMU's "-cpu" parameters, via libvirt XML? > or maybe add +invtsc to qemu args when the 'nonstop_tsc' flag is > requested? No, since it blocks migration better not condition "+invtsc" on presence of 'nonstop_tsc' flag. > > [1]: > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/cpu/powerflags.c?id=30321c7b#n18 > --- > docs/formatdomain.html.in | 9 ++++++-- > docs/schemas/domaincommon.rng | 1 + > src/conf/domain_conf.c | 6 +++-- > src/conf/domain_conf.h | 1 + > src/qemu/qemu_command.c | 6 +++++ > src/qemu/qemu_migration.c | 14 ++++++++++++ > .../qemuxml2argv-clock-timer-inv-tsc.args | 5 +++++ > .../qemuxml2argv-clock-timer-inv-tsc.xml | 26 ++++++++++++++++++++++ > tests/qemuxml2argvtest.c | 1 + > tests/qemuxml2xmltest.c | 1 + > 10 files changed, 66 insertions(+), 4 deletions(-) > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.xml > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index 4f19473..1d3fd93 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -1368,13 +1368,18 @@ > being modified, and can be one of > "platform" (currently unsupported), > "hpet" (libxl, xen, qemu), "kvmclock" (qemu), > - "pit" (qemu), "rtc" (qemu), "tsc" (libxl) or "hypervclock" > - (qemu - <span class="since">since 1.2.2</span>). > + "pit" (qemu), "rtc" (qemu), "tsc" (libxl), "hypervclock" > + (qemu - <span class="since">since 1.2.2</span>) or > + "invtsc" (qemu - <span class="since">since 1.2.5</span>). > > The <code>hypervclock</code> timer adds support for the > reference time counter and the reference page for iTSC > feature for guests running the Microsoft Windows > operating system. > + > + The <code>invtsc</code> timer adds support for the invariant > + TSC. It runs at a constant rate in all ACPI P- C- and T-states. > + A guest with this timer enabled cannot be migrated or saved. > </dd> > <dt><code>track</code></dt> > <dd> > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng > index 4249ed5..5154826 100644 > --- a/docs/schemas/domaincommon.rng > +++ b/docs/schemas/domaincommon.rng > @@ -918,6 +918,7 @@ > <choice> > <value>kvmclock</value> > <value>hypervclock</value> > + <value>invtsc</value> > </choice> > </attribute> > </group> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 6c3bdad..893d904 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -706,7 +706,8 @@ VIR_ENUM_IMPL(virDomainTimerName, VIR_DOMAIN_TIMER_NAME_LAST, > "hpet", > "tsc", > "kvmclock", > - "hypervclock"); > + "hypervclock", > + "invtsc"); > > VIR_ENUM_IMPL(virDomainTimerTrack, VIR_DOMAIN_TIMER_TRACK_LAST, > "boot", > @@ -2931,7 +2932,8 @@ virDomainDefPostParseInternal(virDomainDefPtr def, > virDomainTimerDefPtr timer = def->clock.timers[i]; > > if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK || > - timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK) { > + timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK || > + timer->name == VIR_DOMAIN_TIMER_NAME_INVTSC) { > 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 a92f0f3..53c02e6 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -1635,6 +1635,7 @@ enum virDomainTimerNameType { > VIR_DOMAIN_TIMER_NAME_TSC, > VIR_DOMAIN_TIMER_NAME_KVMCLOCK, > VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK, > + VIR_DOMAIN_TIMER_NAME_INVTSC, > > VIR_DOMAIN_TIMER_NAME_LAST > }; > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > index 6c1e17d..2994427 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -6736,6 +6736,11 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, > have_cpu ? "" : default_model, > timer->present ? '+' : '-'); > have_cpu = true; > + } else if (timer->name == VIR_DOMAIN_TIMER_NAME_INVTSC) { > + virBufferAsprintf(&buf, "%s,%cinvtsc", > + have_cpu ? "" : default_model, > + timer->present ? '+' : '-'); > + have_cpu = true; > } else if (timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK && > timer->present) { > virBufferAsprintf(&buf, "%s,hv_time", > @@ -8063,6 +8068,7 @@ qemuBuildCommandLine(virConnectPtr conn, > > case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: > case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK: > + case VIR_DOMAIN_TIMER_NAME_INVTSC: > /* Timers above are handled when building -cpu. */ > case VIR_DOMAIN_TIMER_NAME_LAST: > break; > diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c > index a9f7fea..c1ffc0f 100644 > --- a/src/qemu/qemu_migration.c > +++ b/src/qemu/qemu_migration.c > @@ -1513,6 +1513,20 @@ qemuMigrationIsAllowed(virQEMUDriverPtr driver, virDomainObjPtr vm, > return false; > } > > + for (i = 0; i < def->clock.ntimers; i++) { > + virDomainTimerDefPtr timer = def->clock.timers[i]; > + > + if (timer->present != 1) > + continue; > + > + if (timer->name == VIR_DOMAIN_TIMER_NAME_INVTSC) { > + virReportError(VIR_ERR_OPERATION_INVALID, > + _("domain has '%s' timer"), > + virDomainTimerNameTypeToString(timer->name)); > + return false; > + } > + } > + > return true; > } > > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.args > new file mode 100644 > index 0000000..ae74ae8 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.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,+invtsc -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-inv-tsc.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.xml > new file mode 100644 > index 0000000..b4a82e8 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-timer-inv-tsc.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='invtsc' 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 14482fd..3c5024e 100644 > --- a/tests/qemuxml2argvtest.c > +++ b/tests/qemuxml2argvtest.c > @@ -641,6 +641,7 @@ mymain(void) > 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("clock-timer-inv-tsc", 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 3ea03e6..a659cd0 100644 > --- a/tests/qemuxml2xmltest.c > +++ b/tests/qemuxml2xmltest.c > @@ -185,6 +185,7 @@ mymain(void) > DO_TEST("clock-catchup"); > DO_TEST("kvmclock"); > DO_TEST("clock-timer-hyperv-rtc"); > + DO_TEST("clock-timer-inv-tsc"); > > DO_TEST("cpu-eoi-disabled"); > DO_TEST("cpu-eoi-enabled"); > -- > 1.8.3.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list