[libvirt] [PATCH 0/4] Fix host-model CPUs on hosts with CMT

Since the introduction of CMT features (commit v1.3.5-461-gf294b83) starting a domain with host-model CPU on a host which supports CMT fails because QEMU complains about unknown 'cmt' feature: qemu-system-x86_64: CPU feature cmt not found https://bugzilla.redhat.com/show_bug.cgi?id=1355857 Jiri Denemark (4): cpu_x86: Introduce x86FeatureIsMigratable cpu_x86: Properly drop non-migratable features tests: Add a test for host-model CPU with CMT feature cpu_x86: Fix host-model CPUs on hosts with CMT src/cpu/cpu_x86.c | 53 +++++++++++++++------- .../qemuxml2argv-cpu-host-model-cmt.args | 22 +++++++++ .../qemuxml2argv-cpu-host-model-cmt.xml | 19 ++++++++ tests/qemuxml2argvtest.c | 1 + tests/testutilsqemu.c | 1 + 5 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.xml -- 2.9.2

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu/cpu_x86.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index d9646eb..7bb2bb6 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -767,6 +767,22 @@ x86FeatureFindInternal(const char *name) } +static bool +x86FeatureIsMigratable(const char *name, + void *cpu_map) +{ + virCPUx86MapPtr map = cpu_map; + size_t i; + + for (i = 0; i < map->nblockers; i++) { + if (STREQ(name, map->migrate_blockers[i]->name)) + return false; + } + + return true; +} + + static char * x86FeatureNames(virCPUx86MapPtr map, const char *separator, @@ -1801,14 +1817,10 @@ x86Decode(virCPUDefPtr cpu, * features directly */ if (flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE) { for (i = 0; i < cpuModel->nfeatures; i++) { - size_t j; - for (j = 0; j < map->nblockers; j++) { - if (STREQ(map->migrate_blockers[j]->name, - cpuModel->features[i].name)) { - VIR_FREE(cpuModel->features[i].name); - VIR_DELETE_ELEMENT_INPLACE(cpuModel->features, i, - cpuModel->nfeatures); - } + if (!x86FeatureIsMigratable(cpuModel->features[i].name, map)) { + VIR_FREE(cpuModel->features[i].name); + VIR_DELETE_ELEMENT_INPLACE(cpuModel->features, i, + cpuModel->nfeatures); } } } @@ -2531,12 +2543,9 @@ x86UpdateHostModel(virCPUDefPtr guest, * Note: this only works as long as no CPU model contains non-migratable * features directly */ for (i = 0; i < guest->nfeatures; i++) { - size_t j; - for (j = 0; j < map->nblockers; j++) { - if (STREQ(map->migrate_blockers[j]->name, guest->features[i].name)) { - VIR_FREE(guest->features[i].name); - VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures); - } + if (!x86FeatureIsMigratable(guest->features[i].name, map)) { + VIR_FREE(guest->features[i].name); + VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures); } } for (i = 0; !passthrough && i < oldguest->nfeatures; i++) { -- 2.9.2

By removing a non-migratable feature in a for loop we would fail to drop every second non-migratable feature if the features array contained several of them in a row. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu/cpu_x86.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 7bb2bb6..24ef76b 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -1816,8 +1816,11 @@ x86Decode(virCPUDefPtr cpu, * Note: this only works as long as no CPU model contains non-migratable * features directly */ if (flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE) { - for (i = 0; i < cpuModel->nfeatures; i++) { - if (!x86FeatureIsMigratable(cpuModel->features[i].name, map)) { + i = 0; + while (i < cpuModel->nfeatures) { + if (x86FeatureIsMigratable(cpuModel->features[i].name, map)) { + i++; + } else { VIR_FREE(cpuModel->features[i].name); VIR_DELETE_ELEMENT_INPLACE(cpuModel->features, i, cpuModel->nfeatures); @@ -2542,8 +2545,11 @@ x86UpdateHostModel(virCPUDefPtr guest, /* Remove non-migratable features by default * Note: this only works as long as no CPU model contains non-migratable * features directly */ - for (i = 0; i < guest->nfeatures; i++) { - if (!x86FeatureIsMigratable(guest->features[i].name, map)) { + i = 0; + while (i < guest->nfeatures) { + if (x86FeatureIsMigratable(guest->features[i].name, map)) { + i++; + } else { VIR_FREE(guest->features[i].name); VIR_DELETE_ELEMENT_INPLACE(guest->features, i, guest->nfeatures); } -- 2.9.2

The generated command line wouldn't work since QEMU doesn't know what 'cmt' is. The following patch will fix this issue. https://bugzilla.redhat.com/show_bug.cgi?id=1355857 Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- .../qemuxml2argv-cpu-host-model-cmt.args | 22 ++++++++++++++++++++++ .../qemuxml2argv-cpu-host-model-cmt.xml | 19 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/testutilsqemu.c | 1 + 4 files changed, 43 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args new file mode 100644 index 0000000..8f6e74f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args @@ -0,0 +1,22 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-cpu Haswell,+vme,+ds,+acpi,+ss,+ht,+tm,+pbe,+dtes64,+monitor,+ds_cpl,+vmx,\ ++smx,+est,+tm2,+xtpr,+pdcm,+osxsave,+f16c,+rdrand,+cmt,+pdpe1gb,+abm \ +-m 214 \ +-smp 6,sockets=6,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \ +-no-acpi \ +-boot n \ +-usb \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.xml new file mode 100644 index 0000000..7e3f617 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.xml @@ -0,0 +1,19 @@ +<domain type='qemu'> + <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='x86_64' machine='pc'>hvm</type> + <boot dev='network'/> + </os> + <cpu mode='host-model'/> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d594836..75ac62e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1392,6 +1392,7 @@ mymain(void) DO_TEST("cpu-Haswell2", QEMU_CAPS_KVM); DO_TEST("cpu-Haswell3", QEMU_CAPS_KVM); DO_TEST("cpu-Haswell-noTSX", QEMU_CAPS_KVM); + DO_TEST("cpu-host-model-cmt", NONE); driver.caps->host.cpu = cpuDefault; DO_TEST("encrypted-disk", NONE); diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index 133de29..11dd20e 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -54,6 +54,7 @@ static virCPUFeatureDef cpuHaswellFeatures[] = { { (char *) "invtsc", -1 }, { (char *) "abm", -1 }, { (char *) "pdpe1gb", -1 }, + { (char *) "cmt", -1 }, { (char *) "rdrand", -1 }, { (char *) "f16c", -1 }, { (char *) "osxsave", -1 }, -- 2.9.2

Since the introduction of CMT features (commit v1.3.5-461-gf294b83) starting a domain with host-model CPU on a host which supports CMT fails because QEMU complains about unknown 'cmt' feature: qemu-system-x86_64: CPU feature cmt not found https://bugzilla.redhat.com/show_bug.cgi?id=1355857 Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/cpu/cpu_x86.c | 8 ++++++-- tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 24ef76b..670b02e 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -2542,12 +2542,16 @@ x86UpdateHostModel(virCPUDefPtr guest, goto cleanup; } - /* Remove non-migratable features by default + /* Remove non-migratable features and CMT related features which QEMU + * knows nothing about. * Note: this only works as long as no CPU model contains non-migratable * features directly */ i = 0; while (i < guest->nfeatures) { - if (x86FeatureIsMigratable(guest->features[i].name, map)) { + if (x86FeatureIsMigratable(guest->features[i].name, map) && + STRNEQ(guest->features[i].name, "cmt") && + STRNEQ(guest->features[i].name, "mbm_total") && + STRNEQ(guest->features[i].name, "mbm_local")) { i++; } else { VIR_FREE(guest->features[i].name); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args index 8f6e74f..e29daf7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-cmt.args @@ -9,7 +9,7 @@ QEMU_AUDIO_DRV=none \ -S \ -M pc \ -cpu Haswell,+vme,+ds,+acpi,+ss,+ht,+tm,+pbe,+dtes64,+monitor,+ds_cpl,+vmx,\ -+smx,+est,+tm2,+xtpr,+pdcm,+osxsave,+f16c,+rdrand,+cmt,+pdpe1gb,+abm \ ++smx,+est,+tm2,+xtpr,+pdcm,+osxsave,+f16c,+rdrand,+pdpe1gb,+abm \ -m 214 \ -smp 6,sockets=6,cores=1,threads=1 \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ -- 2.9.2

On Tue, Aug 09, 2016 at 03:58:39PM +0200, Jiri Denemark wrote:
Since the introduction of CMT features (commit v1.3.5-461-gf294b83) starting a domain with host-model CPU on a host which supports CMT fails because QEMU complains about unknown 'cmt' feature:
qemu-system-x86_64: CPU feature cmt not found
ACK series

On Wed, Aug 10, 2016 at 14:19:32 +0200, Pavel Hrdina wrote:
On Tue, Aug 09, 2016 at 03:58:39PM +0200, Jiri Denemark wrote:
Since the introduction of CMT features (commit v1.3.5-461-gf294b83) starting a domain with host-model CPU on a host which supports CMT fails because QEMU complains about unknown 'cmt' feature:
qemu-system-x86_64: CPU feature cmt not found
ACK series
Thanks, pushed. Jirka
participants (2)
-
Jiri Denemark
-
Pavel Hrdina