Creating part of the -cpu command-line from something other than the <cpu> XML element introduces some ugliness. --- src/qemu/qemu_command.c | 72 ++++++++++++++++++-- tests/qemuargv2xmltest.c | 4 + .../qemuxml2argv-cpu-host-kvmclock.args | 4 + .../qemuxml2argv-cpu-host-kvmclock.xml | 23 ++++++ .../qemuxml2argv-cpu-kvmclock.args | 4 + .../qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml | 24 +++++++ tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args | 4 + tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml | 21 ++++++ tests/qemuxml2argvtest.c | 3 + tests/qemuxml2xmltest.c | 3 + 10 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7c4460e..24e3adf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3500,7 +3500,9 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, virCPUDefPtr cpu = NULL; unsigned int ncpus = 0; const char **cpus = NULL; + const char *default_model; union cpuData *data = NULL; + bool have_cpu = false; int ret = -1; virBuffer buf = VIR_BUFFER_INITIALIZER; int i; @@ -3517,6 +3519,11 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, goto cleanup; } + if (STREQ(def->os.arch, "i686")) + default_model = "qemu32"; + else + default_model = "qemu64"; + if (cpu) { virCPUCompareResult cmp; const char *preferred; @@ -3594,6 +3601,7 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, virBufferAsprintf(&buf, ",%c%s", sign, guest->features[i].name); } } + have_cpu = true; } else { /* * Need to force a 32-bit guest CPU type if @@ -3610,8 +3618,26 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, if (STREQ(def->os.arch, "i686") && ((STREQ(ut->machine, "x86_64") && strstr(emulator, "kvm")) || - strstr(emulator, "x86_64"))) - virBufferAddLit(&buf, "qemu32"); + strstr(emulator, "x86_64"))) { + virBufferAdd(&buf, default_model, -1); + have_cpu = true; + } + } + + /* Now force kvmclock on/off based on the corresponding <timer> element. */ + 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 = '-'; + virBufferAsprintf(&buf, "%s,%ckvmclock", + have_cpu ? "" : default_model, + sign); + break; + } } if (virBufferError(&buf)) @@ -4091,6 +4117,10 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainTimerNameTypeToString(def->clock.timers[i]->name)); goto error; + case VIR_DOMAIN_TIMER_NAME_KVMCLOCK: + /* This is handled when building -cpu. */ + break; + case VIR_DOMAIN_TIMER_NAME_RTC: /* This has already been taken care of (in qemuBuildClockArgStr) if QEMU_CAPS_RTC is set (mutually exclusive with @@ -6822,10 +6852,42 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, if (!feature) goto no_memory; - if (!cpu && !(cpu = qemuInitGuestCPU(dom))) - goto error; + if (STREQ(feature, "kvmclock")) { + bool present = (policy == VIR_CPU_FEATURE_REQUIRE); + int i; + + for (i = 0; i < dom->clock.ntimers; i++) { + if (dom->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { + break; + } + } + + if (i == dom->clock.ntimers) { + if (VIR_REALLOC_N(dom->clock.timers, i+1) < 0 || + VIR_ALLOC(dom->clock.timers[i]) < 0) + goto no_memory; + dom->clock.timers[i]->name = VIR_DOMAIN_TIMER_NAME_KVMCLOCK; + dom->clock.timers[i]->present = -1; + dom->clock.timers[i]->tickpolicy = -1; + dom->clock.timers[i]->track = -1; + dom->clock.ntimers++; + } + + if (dom->clock.timers[i]->present != -1 && + dom->clock.timers[i]->present != present) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("multiple occurrences of kvmclock feature")); + goto error; + } + dom->clock.timers[i]->present = present; + ret = 0; + } else { + if (!cpu && !(cpu = qemuInitGuestCPU(dom))) + goto error; + + ret = virCPUDefAddFeature(cpu, feature, policy); + } - ret = virCPUDefAddFeature(cpu, feature, policy); VIR_FREE(feature); if (ret < 0) goto error; diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index cb3cafd..28434ff 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -144,6 +144,10 @@ mymain(void) DO_TEST("boot-cdrom"); DO_TEST("boot-network"); DO_TEST("boot-floppy"); + DO_TEST("kvmclock"); + /* This needs <emulator>./qemu.sh</emulator> which doesn't work here. */ + /*DO_TEST("cpu-kvmclock");*/ + /* Can't roundtrip xenner arch */ /*DO_TEST("bootloader");*/ DO_TEST("clock-utc"); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.args new file mode 100644 index 0000000..6a5df28 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test ./qemu.sh -S -M pc \ +-cpu host,-kvmclock -m 214 -smp 6 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot n -net \ +none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.xml new file mode 100644 index 0000000..15a9e44 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.xml @@ -0,0 +1,23 @@ +<domain type='kvm'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219100</memory> + <currentMemory>219100</currentMemory> + <vcpu>6</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='network'/> + </os> + <cpu mode='host-passthrough'> + </cpu> + <clock offset='utc'> + <timer name='kvmclock' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/./qemu.sh</emulator> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.args new file mode 100644 index 0000000..f7c33fb --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test ./qemu.sh -S -M pc \ +-cpu core2duo,-kvmclock -m 214 -smp 6 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot n -net \ +none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml new file mode 100644 index 0000000..e8b0bb1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml @@ -0,0 +1,24 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219100</memory> + <currentMemory>219100</currentMemory> + <vcpu>6</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='network'/> + </os> + <cpu mode='custom' match='exact'> + <model fallback='allow'>core2duo</model> + </cpu> + <clock offset='utc'> + <timer name='kvmclock' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/./qemu.sh</emulator> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args b/tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args new file mode 100644 index 0000000..4c7aa3b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-kvm -S -M pc \ +-cpu qemu32,-kvmclock -m 214 -smp 6 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot n -net \ +none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml new file mode 100644 index 0000000..2e090ae --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml @@ -0,0 +1,21 @@ +<domain type='kvm'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219100</memory> + <currentMemory>219100</currentMemory> + <vcpu>6</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='network'/> + </os> + <clock offset='utc'> + <timer name='kvmclock' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-kvm</emulator> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d40b37e..ddb4369 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -385,6 +385,9 @@ mymain(void) DO_TEST("clock-variable", false, QEMU_CAPS_RTC); */ DO_TEST("clock-france", false, QEMU_CAPS_RTC); + DO_TEST("cpu-kvmclock", false, NONE); + DO_TEST("cpu-host-kvmclock", false, QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST); + DO_TEST("kvmclock", false, NONE); DO_TEST("hugepages", false, QEMU_CAPS_MEM_PATH); DO_TEST("disk-cdrom", false, NONE); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 293c2a7..caff5c6 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -124,6 +124,9 @@ mymain(void) DO_TEST("bootloader"); DO_TEST("clock-utc"); DO_TEST("clock-localtime"); + DO_TEST("cpu-kvmclock"); + DO_TEST("cpu-host-kvmclock"); + DO_TEST("kvmclock"); DO_TEST("hugepages"); DO_TEST("disk-aio"); DO_TEST("disk-cdrom"); -- 1.7.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list