QEMU 7.0.0 adds a new property tsc-clear-on-reset to x86 CPU, corresponding to Libvirt's <tsc on_reboot="clear"/> element. Plumb it in the validation, command line handling and tests. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 4 +++ src/qemu/qemu_validate.c | 36 +++++++++++++------ .../caps_7.0.0.x86_64.replies | 4 +++ .../caps_7.0.0.x86_64.xml | 1 + ...uency.args => cpu-tsc-clear-on-reset.args} | 2 +- ... cpu-tsc-clear-on-reset.x86_64-7.0.0.args} | 6 ++-- ...equency.xml => cpu-tsc-clear-on-reset.xml} | 2 +- tests/qemuxml2argvtest.c | 2 ++ 10 files changed, 44 insertions(+), 16 deletions(-) copy tests/qemuxml2argvdata/{cpu-tsc-frequency.args => cpu-tsc-clear-on-reset.args} (97%) copy tests/qemuxml2argvdata/{virtio-rng-builtin.x86_64-latest.args => cpu-tsc-clear-on-reset.x86_64-7.0.0.args} (77%) copy tests/qemuxml2argvdata/{cpu-tsc-frequency.xml => cpu-tsc-clear-on-reset.xml} (95%) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 32980e7330..d22bbee70e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -668,6 +668,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 425 */ "blockdev.nbd.tls-hostname", /* QEMU_CAPS_BLOCKDEV_NBD_TLS_HOSTNAME */ + "x86-cpu.tsc-clear-on-reset", /* QEMU_CAPS_X86_CPU_TSC_CLEAR_ON_RESET */ ); @@ -1775,6 +1776,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendMemfd[] static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxCPU[] = { { "unavailable-features", QEMU_CAPS_CPU_UNAVAILABLE_FEATURES }, { "kvm-no-adjvtime", QEMU_CAPS_CPU_KVM_NO_ADJVTIME }, + { "tsc-clear-on-reset", QEMU_CAPS_X86_CPU_TSC_CLEAR_ON_RESET }, { "migratable", QEMU_CAPS_CPU_MIGRATABLE }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 0a215a11d5..7aee73a725 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -643,6 +643,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ /* 425 */ QEMU_CAPS_BLOCKDEV_NBD_TLS_HOSTNAME, /* tls hostname can be overriden for NBD clients */ + QEMU_CAPS_X86_CPU_TSC_CLEAR_ON_RESET, /* x86-cpu.tsc-clear-on-reset */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index c836799888..8ecede0ade 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6613,6 +6613,10 @@ qemuBuildCpuCommandLine(virCommand *cmd, case VIR_DOMAIN_TIMER_NAME_TSC: if (timer->frequency > 0) virBufferAsprintf(&buf, ",tsc-frequency=%llu", timer->frequency); + if (timer->reboot == VIR_DOMAIN_TIMER_REBOOT_MODE_CLEAR) + virBufferAddLit(&buf, ",tsc-clear-on-reset=on"); + else if (timer->reboot == VIR_DOMAIN_TIMER_REBOOT_MODE_KEEP) + virBufferAddLit(&buf, ",tsc-clear-on-reset=off"); break; case VIR_DOMAIN_TIMER_NAME_ARMVTIMER: switch (timer->tickpolicy) { diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index f27e480696..c4ab2976dc 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -396,10 +396,11 @@ static int qemuValidateDomainDefClockTimers(const virDomainDef *def, virQEMUCaps *qemuCaps) { + virDomainTimerDef *timer; size_t i; for (i = 0; i < def->clock.ntimers; i++) { - virDomainTimerDef *timer = def->clock.timers[i]; + timer = def->clock.timers[i]; switch ((virDomainTimerNameType)timer->name) { case VIR_DOMAIN_TIMER_NAME_PLATFORM: @@ -409,20 +410,25 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def, return -1; case VIR_DOMAIN_TIMER_NAME_TSC: - case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: - case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK: - if (!ARCH_IS_X86(def->os.arch) && timer->present == VIR_TRISTATE_BOOL_YES) { + if (!ARCH_IS_X86(def->os.arch) && timer->present == VIR_TRISTATE_BOOL_YES) + goto no_support; + + if (timer->reboot != VIR_DOMAIN_TIMER_REBOOT_MODE_DEFAULT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_X86_CPU_TSC_CLEAR_ON_RESET)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Configuring the '%s' timer is not supported " - "for virtType=%s arch=%s machine=%s guests"), - virDomainTimerNameTypeToString(timer->name), - virDomainVirtTypeToString(def->virtType), - virArchToString(def->os.arch), - def->os.machine); + _("Configuring the '%s' timer to reset on reboot is not supported " + "with this QEMU binary"), + virDomainTimerNameTypeToString(timer->name)); return -1; } break; + case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: + case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK: + if (!ARCH_IS_X86(def->os.arch) && timer->present == VIR_TRISTATE_BOOL_YES) + goto no_support; + break; + case VIR_DOMAIN_TIMER_NAME_LAST: break; @@ -540,6 +546,16 @@ qemuValidateDomainDefClockTimers(const virDomainDef *def, } return 0; + + no_support: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Configuring the '%s' timer is not supported " + "for virtType=%s arch=%s machine=%s guests"), + virDomainTimerNameTypeToString(timer->name), + virDomainVirtTypeToString(def->virtType), + virArchToString(def->os.arch), + def->os.machine); + return -1; } diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies index 82ccbab6eb..d919caf7f3 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies @@ -28849,6 +28849,10 @@ { "name": "sse4_1", "type": "bool" + }, + { + "name": "tsc-clear-on-reset", + "type": "bool" } ], "id": "libvirt-41" diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml index 0f34a341af..d36237364f 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml @@ -244,6 +244,7 @@ <flag name='calc-dirty-rate'/> <flag name='dirtyrate-param.mode'/> <flag name='blockdev.nbd.tls-hostname'/> + <flag name='x86-cpu.tsc-clear-on-reset'/> <version>6002050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> diff --git a/tests/qemuxml2argvdata/cpu-tsc-frequency.args b/tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.args similarity index 97% copy from tests/qemuxml2argvdata/cpu-tsc-frequency.args copy to tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.args index 4a032f5d85..f2b8a98968 100644 --- a/tests/qemuxml2argvdata/cpu-tsc-frequency.args +++ b/tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.args @@ -13,7 +13,7 @@ QEMU_AUDIO_DRV=none \ -object secret,id=masterKey0,format=raw,file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ -machine pc,usb=off,dump-guest-core=off \ -accel kvm \ --cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,invtsc=on,tsc-frequency=4567890000 \ +-cpu Haswell,vme=on,ds=on,acpi=on,ss=on,ht=on,tm=on,pbe=on,dtes64=on,monitor=on,ds-cpl=on,vmx=on,smx=on,est=on,tm2=on,xtpr=on,pdcm=on,f16c=on,rdrand=on,pdpe1gb=on,abm=on,lahf-lm=on,invtsc=on,tsc-clear-on-reset=on \ -m 214 \ -realtime mlock=off \ -smp 1,sockets=1,cores=1,threads=1 \ diff --git a/tests/qemuxml2argvdata/virtio-rng-builtin.x86_64-latest.args b/tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.x86_64-7.0.0.args similarity index 77% copy from tests/qemuxml2argvdata/virtio-rng-builtin.x86_64-latest.args copy to tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.x86_64-7.0.0.args index a0aeb74319..59f1d66ed4 100644 --- a/tests/qemuxml2argvdata/virtio-rng-builtin.x86_64-latest.args +++ b/tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.x86_64-7.0.0.args @@ -10,9 +10,9 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ -name guest=QEMUGuest1,debug-threads=on \ -S \ -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ --machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram \ +-machine pc-i440fx-7.0,usb=off,dump-guest-core=off,memory-backend=pc.ram \ -accel kvm \ --cpu qemu64 \ +-cpu EPYC-Rome,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,stibp=on,arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,svme-addr-chk=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,invtsc=on,tsc-clear-on-reset=on \ -m 214 \ -object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \ -overcommit mem-lock=off \ @@ -30,7 +30,5 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x2"}' \ --object '{"qom-type":"rng-builtin","id":"objrng0"}' \ --device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.0","addr":"0x3"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -msg timestamp=on diff --git a/tests/qemuxml2argvdata/cpu-tsc-frequency.xml b/tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.xml similarity index 95% copy from tests/qemuxml2argvdata/cpu-tsc-frequency.xml copy to tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.xml index afaef6e8e5..2521349ce7 100644 --- a/tests/qemuxml2argvdata/cpu-tsc-frequency.xml +++ b/tests/qemuxml2argvdata/cpu-tsc-clear-on-reset.xml @@ -18,7 +18,7 @@ <feature policy='require' name='invtsc'/> </cpu> <clock offset='utc'> - <timer name='tsc' frequency='4567890000'/> + <timer name='tsc' on_reboot='clear'/> </clock> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index e7fecb24d3..9d5aba85a1 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2094,6 +2094,8 @@ mymain(void) DO_TEST("cpu-Haswell-noTSX", QEMU_CAPS_KVM); DO_TEST_NOCAPS("cpu-host-model-cmt"); DO_TEST_CAPS_VER("cpu-host-model-cmt", "4.0.0"); + DO_TEST("cpu-tsc-clear-on-reset", QEMU_CAPS_X86_CPU_TSC_CLEAR_ON_RESET); + DO_TEST_CAPS_VER("cpu-tsc-clear-on-reset", "7.0.0"); DO_TEST("cpu-tsc-frequency", QEMU_CAPS_KVM); DO_TEST_CAPS_VER("cpu-tsc-frequency", "4.0.0"); DO_TEST_CAPS_VER("cpu-translation", "4.0.0"); -- 2.35.1