[libvirt] [PATCH 00/11] qemu: Add support for ARM CPU features

Starting with QEMU 4.2.0, ARM guests support CPU features similarly to what's been the case on x86 since forever; notably, it's now possible to enable SVE (Scalable Vector Extension). Some of the patches in the series (notably 1/11) are snipped; the unabridged version can be obtained with $ git fetch https://gitlab.com/abologna/libvirt.git sve Andrea Bolognani (11): tests: Update capabilities for QEMU 4.2.0 on aarch64 qemu: Rename virQEMUCapsObjectPropsMaxX86CPU qemu: Introduce QEMU_CAPS_ARM_MAX_CPU qemu: Query max-arm-cpu properties qemu: Update query-cpu-model-expansion check qemu: Perform full expansion on ARM cpu_map: Introduce ARM CPU features cpu: Validate ARM CPU features qemu: Validate ARM CPU features tests: Introduce tests for ARM CPU features news: Update for ARM CPU features docs/news.xml | 9 + src/cpu/cpu_arm.c | 157 + src/cpu_map/arm_features.xml | 22 + src/cpu_map/index.xml | 4 + src/qemu/qemu_capabilities.c | 20 +- src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_command.c | 3 +- src/qemu/qemu_domain.c | 37 + .../qemu_4.2.0-virt.aarch64.xml | 2 +- tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 2 +- .../caps_2.12.0.aarch64.replies | 159 +- .../caps_2.12.0.aarch64.xml | 1 + .../caps_4.0.0.aarch64.replies | 159 +- .../caps_4.0.0.aarch64.xml | 1 + .../caps_4.2.0.aarch64.replies | 3755 ++++++++++------- .../caps_4.2.0.aarch64.xml | 52 +- .../aarch64-features-sve-disabled.xml | 18 + .../aarch64-features-sve.aarch64-latest.args | 32 + .../qemuxml2argvdata/aarch64-features-sve.xml | 20 + .../aarch64-features-wrong.xml | 17 + tests/qemuxml2argvtest.c | 9 + .../aarch64-features-sve.aarch64-latest.xml | 31 + tests/qemuxml2xmltest.c | 3 + 23 files changed, 3029 insertions(+), 1487 deletions(-) create mode 100644 src/cpu_map/arm_features.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve-disabled.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-wrong.xml create mode 100644 tests/qemuxml2xmloutdata/aarch64-features-sve.aarch64-latest.xml -- 2.21.0

Unfortunately this results in a lot of churn because of the eigth hundred and change QEMU commits since the file was last touched, but the only part we actually care about is the fact that the query-cpu-model-expansion QMP command is now available on aarch64. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- This patch is heavily snipped. .../qemu_4.2.0-virt.aarch64.xml | 2 +- tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 2 +- .../caps_4.2.0.aarch64.replies | 3394 ++++++++++------- .../caps_4.2.0.aarch64.xml | 9 +- 4 files changed, 2001 insertions(+), 1406 deletions(-) diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies index 08987b91d3..a51a3a42bd 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies @@ -21,7 +21,7 @@ "minor": 1, "major": 4 }, - "package": "v4.1.0-1378-g98b2e3c9ab" + "package": "v4.1.0-2221-g36609b4fa3" }, "id": "libvirt-2" } @@ -20476,6 +21030,25 @@ "id": "libvirt-40" } +{ + "execute": "query-cpu-model-expansion", + "arguments": { + "type": "static", + "model": { + "name": "host" + } + }, + "id": "libvirt-41" +} + +{ + "id": "libvirt-41", + "error": { + "class": "GenericError", + "desc": "The requested expansion type is not supported" + } +} + { "execute": "qmp_capabilities", "id": "libvirt-1" @@ -20682,3 +21255,22 @@ ], "id": "libvirt-2" } + +{ + "execute": "query-cpu-model-expansion", + "arguments": { + "type": "static", + "model": { + "name": "max" + } + }, + "id": "libvirt-3" +} + +{ + "id": "libvirt-3", + "error": { + "class": "GenericError", + "desc": "The requested expansion type is not supported" + } +} diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml index 7b13da4dca..15a6050dd3 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml @@ -109,6 +110,7 @@ <flag name='gluster.debug_level'/> <flag name='vhost-scsi'/> <flag name='drive-iotune-group'/> + <flag name='query-cpu-model-expansion'/> <flag name='virtio-net.host_mtu'/> <flag name='pcie-root-port'/> <flag name='query-cpu-definitions'/> @@ -170,7 +172,7 @@ <version>4001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700242</microcodeVersion> - <package>v4.1.0-1378-g98b2e3c9ab</package> + <package>v4.1.0-2221-g36609b4fa3</package> <arch>aarch64</arch> <cpu type='kvm' name='pxa262'/> <cpu type='kvm' name='pxa270-a0'/> -- 2.21.0

We're going to use it on non-x86 soon, so it needs a more generic name: virQEMUCapsObjectPropsMaxCPU. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/qemu/qemu_capabilities.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 9bb3c96448..c11756dc42 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1421,7 +1421,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMemoryBackendMemfd[] { "hugetlb", QEMU_CAPS_OBJECT_MEMORY_MEMFD_HUGETLB }, }; -static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxX86CPU[] = { +static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsMaxCPU[] = { { "unavailable-features", QEMU_CAPS_CPU_UNAVAILABLE_FEATURES }, }; @@ -1432,8 +1432,8 @@ static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { { "memory-backend-memfd", virQEMUCapsObjectPropsMemoryBackendMemfd, G_N_ELEMENTS(virQEMUCapsObjectPropsMemoryBackendMemfd), QEMU_CAPS_OBJECT_MEMORY_MEMFD }, - { "max-x86_64-cpu", virQEMUCapsObjectPropsMaxX86CPU, - G_N_ELEMENTS(virQEMUCapsObjectPropsMaxX86CPU), + { "max-x86_64-cpu", virQEMUCapsObjectPropsMaxCPU, + G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU), QEMU_CAPS_X86_MAX_CPU }, }; -- 2.21.0

Mirrors the existing QEMU_CAPS_X86_MAX_CPU. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/qemu/qemu_capabilities.c | 4 ++++ src/qemu/qemu_capabilities.h | 3 +++ tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml | 1 + 5 files changed, 10 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index c11756dc42..6c8e119e56 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -547,6 +547,9 @@ VIR_ENUM_IMPL(virQEMUCaps, "query-cpu-model-comparison", "ramfb", "machine.pseries.cap-ccf-assist", + + /* 345 */ + "arm-max-cpu", ); @@ -1141,6 +1144,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "vhost-user-gpu", QEMU_CAPS_DEVICE_VHOST_USER_GPU }, { "vhost-user-vga", QEMU_CAPS_DEVICE_VHOST_USER_VGA }, { "ramfb", QEMU_CAPS_DEVICE_RAMFB }, + { "max-arm-cpu", QEMU_CAPS_ARM_MAX_CPU }, }; static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 10f0ce2654..32e9798cda 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -529,6 +529,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DEVICE_RAMFB, /* -device ramfb */ QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST, /* -machine pseries.cap-ccf-assist */ + /* 345 */ + QEMU_CAPS_ARM_MAX_CPU, /* max-arm-cpu type exists */ + QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml index 1787248110..0a2f801f53 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml @@ -153,6 +153,7 @@ <flag name='memory-backend-memfd.hugetlb'/> <flag name='iothread.poll-max-ns'/> <flag name='memory-backend-file.align'/> + <flag name='arm-max-cpu'/> <version>2012000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700289</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml index 66e3ca9205..83459c33cf 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml @@ -166,6 +166,7 @@ <flag name='bochs-display'/> <flag name='migration-file-drop-cache'/> <flag name='ramfb'/> + <flag name='arm-max-cpu'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700240</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml index 15a6050dd3..a4cb7ba4e6 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml @@ -169,6 +169,7 @@ <flag name='migration-file-drop-cache'/> <flag name='vhost-user-gpu'/> <flag name='ramfb'/> + <flag name='arm-max-cpu'/> <version>4001050</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700242</microcodeVersion> -- 2.21.0

Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- This patch is heavily snipped. src/qemu/qemu_capabilities.c | 3 + .../caps_2.12.0.aarch64.replies | 159 ++++++++++-- .../caps_4.0.0.aarch64.replies | 159 ++++++++++-- .../caps_4.2.0.aarch64.replies | 235 ++++++++++++++++-- 4 files changed, 500 insertions(+), 56 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 6c8e119e56..363fb0e197 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1439,6 +1439,9 @@ static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { { "max-x86_64-cpu", virQEMUCapsObjectPropsMaxCPU, G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU), QEMU_CAPS_X86_MAX_CPU }, + { "max-arm-cpu", virQEMUCapsObjectPropsMaxCPU, + G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU), + QEMU_CAPS_ARM_MAX_CPU }, }; static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsPSeries[] = { diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies index c4d9c42d72..2e1d8d345d 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies @@ -5376,10 +5376,133 @@ } { - "execute": "query-machines", + "execute": "qom-list-properties", + "arguments": { + "typename": "max-arm-cpu" + }, "id": "libvirt-31" } +{ + "return": [ + { + "name": "pmu", + "type": "bool" + }, + { + "name": "midr", + "type": "uint32" + }, + { + "name": "mp-affinity", + "type": "uint64" + }, + { + "name": "hotpluggable", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[0]", + "type": "child<irq>" + }, + { + "name": "cfgend", + "type": "bool" + }, + { + "name": "psci-conduit", + "type": "uint32" + }, + { + "name": "reset-hivecs", + "type": "bool" + }, + { + "name": "memory", + "type": "link<qemu:memory-region>" + }, + { + "name": "unnamed-gpio-out[2]", + "type": "link<irq>" + }, + { + "name": "hotplugged", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[3]", + "type": "link<irq>" + }, + { + "name": "parent_bus", + "type": "link<bus>" + }, + { + "name": "node-id", + "type": "int32" + }, + { + "name": "start-powered-off", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[1]", + "type": "link<irq>" + }, + { + "name": "core-count", + "type": "int32" + }, + { + "name": "unnamed-gpio-out[0]", + "type": "link<irq>" + }, + { + "name": "gicv3-maintenance-interrupt[0]", + "type": "link<irq>" + }, + { + "name": "rvbar", + "type": "uint64" + }, + { + "name": "type", + "type": "string" + }, + { + "name": "pmu-interrupt[0]", + "type": "link<irq>" + }, + { + "name": "aarch64", + "description": "Set on/off to enable/disable aarch64 execution state ", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[2]", + "type": "child<irq>" + }, + { + "name": "unnamed-gpio-in[3]", + "type": "child<irq>" + }, + { + "name": "realized", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[1]", + "type": "child<irq>" + } + ], + "id": "libvirt-31" +} + +{ + "execute": "query-machines", + "id": "libvirt-32" +} + { "return": [ { diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies index 91943860b1..3a9b1b8dc7 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies @@ -5864,10 +5864,133 @@ } { - "execute": "query-machines", + "execute": "qom-list-properties", + "arguments": { + "typename": "max-arm-cpu" + }, "id": "libvirt-32" } +{ + "return": [ + { + "name": "type", + "type": "string" + }, + { + "name": "pmu", + "type": "bool" + }, + { + "name": "midr", + "type": "uint32" + }, + { + "name": "mp-affinity", + "type": "uint64" + }, + { + "name": "hotpluggable", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[0]", + "type": "child<irq>" + }, + { + "name": "psci-conduit", + "type": "uint32" + }, + { + "name": "reset-hivecs", + "type": "bool" + }, + { + "name": "memory", + "type": "link<qemu:memory-region>" + }, + { + "name": "unnamed-gpio-out[2]", + "type": "link<irq>" + }, + { + "name": "hotplugged", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[3]", + "type": "link<irq>" + }, + { + "name": "parent_bus", + "type": "link<bus>" + }, + { + "name": "node-id", + "type": "int32" + }, + { + "name": "start-powered-off", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[1]", + "type": "link<irq>" + }, + { + "name": "core-count", + "type": "int32" + }, + { + "name": "unnamed-gpio-out[0]", + "type": "link<irq>" + }, + { + "name": "gicv3-maintenance-interrupt[0]", + "type": "link<irq>" + }, + { + "name": "rvbar", + "type": "uint64" + }, + { + "name": "cfgend", + "type": "bool" + }, + { + "name": "pmu-interrupt[0]", + "type": "link<irq>" + }, + { + "name": "aarch64", + "description": "Set on/off to enable/disable aarch64 execution state ", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[2]", + "type": "child<irq>" + }, + { + "name": "unnamed-gpio-in[3]", + "type": "child<irq>" + }, + { + "name": "realized", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[1]", + "type": "child<irq>" + } + ], + "id": "libvirt-32" +} + +{ + "execute": "query-machines", + "id": "libvirt-33" +} + { "return": [ { diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies index a51a3a42bd..efd193d90d 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies @@ -6236,10 +6236,205 @@ } { - "execute": "query-machines", + "execute": "qom-list-properties", + "arguments": { + "typename": "max-arm-cpu" + }, + "id": "libvirt-32" +} + +{ + "return": [ + { + "name": "type", + "type": "string" + }, + { + "name": "sve640", + "type": "bool" + }, + { + "name": "psci-conduit", + "type": "uint32" + }, + { + "name": "sve128", + "type": "bool" + }, + { + "name": "sve1152", + "type": "bool" + }, + { + "name": "node-id", + "type": "int32" + }, + { + "name": "sve1408", + "type": "bool" + }, + { + "name": "memory", + "type": "link<qemu:memory-region>" + }, + { + "name": "unnamed-gpio-in[3]", + "type": "child<irq>" + }, + { + "name": "core-count", + "type": "int32" + }, + { + "name": "sve2048", + "type": "bool" + }, + { + "name": "aarch64", + "description": "Set on/off to enable/disable aarch64 execution state ", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[1]", + "type": "child<irq>" + }, + { + "name": "sve1664", + "type": "bool" + }, + { + "name": "realized", + "type": "bool" + }, + { + "name": "rvbar", + "type": "uint64" + }, + { + "name": "sve384", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[2]", + "type": "link<irq>" + }, + { + "name": "mp-affinity", + "type": "uint64" + }, + { + "name": "sve512", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[0]", + "type": "link<irq>" + }, + { + "name": "parent_bus", + "type": "link<bus>" + }, + { + "name": "hotplugged", + "type": "bool" + }, + { + "name": "gicv3-maintenance-interrupt[0]", + "type": "link<irq>" + }, + { + "name": "sve896", + "type": "bool" + }, + { + "name": "sve1024", + "type": "bool" + }, + { + "name": "pmu-interrupt[0]", + "type": "link<irq>" + }, + { + "name": "sve1280", + "type": "bool" + }, + { + "name": "sve1536", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[2]", + "type": "child<irq>" + }, + { + "name": "sve-max-vq", + "type": "uint32" + }, + { + "name": "sve", + "type": "bool" + }, + { + "name": "start-powered-off", + "type": "bool" + }, + { + "name": "unnamed-gpio-in[0]", + "type": "child<irq>" + }, + { + "name": "sve256", + "type": "bool" + }, + { + "name": "sve1792", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[3]", + "type": "link<irq>" + }, + { + "name": "cfgend", + "type": "bool" + }, + { + "name": "midr", + "type": "uint32" + }, + { + "name": "hotpluggable", + "type": "bool" + }, + { + "name": "pmu", + "type": "bool" + }, + { + "name": "unnamed-gpio-out[1]", + "type": "link<irq>" + }, + { + "name": "sve1920", + "type": "bool" + }, + { + "name": "reset-hivecs", + "type": "bool" + }, + { + "name": "sve768", + "type": "bool" + } + ], "id": "libvirt-32" } +{ + "execute": "query-machines", + "id": "libvirt-33" +} + { "return": [ { -- 2.21.0

CPU features are available on ARM only wherever the query-cpu-model-expansion QMP command is available, same as on s390. Update qemuBuildCpuModelArgStr() to reflect this fact. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/qemu/qemu_command.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index be9839cc64..f37aecda37 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6703,7 +6703,8 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, break; } - if (ARCH_IS_S390(def->os.arch) && cpu->features && + if ((ARCH_IS_S390(def->os.arch) || ARCH_IS_ARM(def->os.arch)) && + cpu->features && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("CPU features not supported by hypervisor for %s " -- 2.21.0

The ARM implementation of query-cpu-model-expansion only supports full expansion, so we have to make sure we're using that expansion mode if we want to obtain any useful data. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/qemu/qemu_capabilities.c | 7 +- .../caps_4.2.0.aarch64.replies | 100 ++++++++++++++++-- .../caps_4.2.0.aarch64.xml | 42 ++++++++ 3 files changed, 141 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 363fb0e197..fc6473651c 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2559,10 +2559,13 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps, * the initial static expansion to get all variants of feature names. */ if (ARCH_IS_X86(qemuCaps->arch) && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES)) + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CANONICAL_CPU_FEATURES)) { type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL; - else + } else if (ARCH_IS_ARM(qemuCaps->arch)) { + type = QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL; + } else { type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC; + } /* Older s390 models do not report a feature set */ if (ARCH_IS_S390(qemuCaps->arch)) diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies index efd193d90d..127f121680 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.replies @@ -21228,7 +21228,7 @@ { "execute": "query-cpu-model-expansion", "arguments": { - "type": "static", + "type": "full", "model": { "name": "host" } @@ -21237,10 +21237,54 @@ } { - "id": "libvirt-42", + "return": { + "model": { + "name": "host", + "props": { + "sve768": false, + "sve128": true, + "sve1024": false, + "sve1280": false, + "sve896": false, + "sve256": true, + "sve1536": false, + "sve1792": false, + "sve384": false, + "sve": true, + "sve2048": false, + "sve512": true, + "aarch64": true, + "pmu": true, + "sve1920": false, + "sve1152": false, + "sve640": false, + "sve1408": false, + "sve1664": false + } + } + }, + "id": "libvirt-42" +} + +{ + "execute": "query-cpu-model-expansion", + "arguments": { + "type": "full", + "model": { + "name": "host", + "props": { + "migratable": false + } + } + }, + "id": "libvirt-43" +} + +{ + "id": "libvirt-43", "error": { "class": "GenericError", - "desc": "The requested expansion type is not supported" + "desc": "Parameter 'migratable' is unexpected" } } @@ -21454,7 +21498,7 @@ { "execute": "query-cpu-model-expansion", "arguments": { - "type": "static", + "type": "full", "model": { "name": "max" } @@ -21463,9 +21507,53 @@ } { - "id": "libvirt-3", + "return": { + "model": { + "name": "max", + "props": { + "sve768": true, + "sve128": true, + "sve1024": true, + "sve1280": true, + "sve896": true, + "sve256": true, + "sve1536": true, + "sve1792": true, + "sve384": true, + "sve": true, + "sve2048": true, + "sve512": true, + "aarch64": true, + "pmu": true, + "sve1920": true, + "sve1152": true, + "sve640": true, + "sve1408": true, + "sve1664": true + } + } + }, + "id": "libvirt-3" +} + +{ + "execute": "query-cpu-model-expansion", + "arguments": { + "type": "full", + "model": { + "name": "max", + "props": { + "migratable": false + } + } + }, + "id": "libvirt-4" +} + +{ + "id": "libvirt-4", "error": { "class": "GenericError", - "desc": "The requested expansion type is not supported" + "desc": "Parameter 'migratable' is unexpected" } } diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml index a4cb7ba4e6..17960460fb 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.aarch64.xml @@ -175,6 +175,48 @@ <microcodeVersion>61700242</microcodeVersion> <package>v4.1.0-2221-g36609b4fa3</package> <arch>aarch64</arch> + <hostCPU type='kvm' model='host' migratability='no'> + <property name='sve768' type='boolean' value='false'/> + <property name='sve128' type='boolean' value='true'/> + <property name='sve1024' type='boolean' value='false'/> + <property name='sve1280' type='boolean' value='false'/> + <property name='sve896' type='boolean' value='false'/> + <property name='sve256' type='boolean' value='true'/> + <property name='sve1536' type='boolean' value='false'/> + <property name='sve1792' type='boolean' value='false'/> + <property name='sve384' type='boolean' value='false'/> + <property name='sve' type='boolean' value='true'/> + <property name='sve2048' type='boolean' value='false'/> + <property name='sve512' type='boolean' value='true'/> + <property name='aarch64' type='boolean' value='true'/> + <property name='pmu' type='boolean' value='true'/> + <property name='sve1920' type='boolean' value='false'/> + <property name='sve1152' type='boolean' value='false'/> + <property name='sve640' type='boolean' value='false'/> + <property name='sve1408' type='boolean' value='false'/> + <property name='sve1664' type='boolean' value='false'/> + </hostCPU> + <hostCPU type='tcg' model='max' migratability='no'> + <property name='sve768' type='boolean' value='true'/> + <property name='sve128' type='boolean' value='true'/> + <property name='sve1024' type='boolean' value='true'/> + <property name='sve1280' type='boolean' value='true'/> + <property name='sve896' type='boolean' value='true'/> + <property name='sve256' type='boolean' value='true'/> + <property name='sve1536' type='boolean' value='true'/> + <property name='sve1792' type='boolean' value='true'/> + <property name='sve384' type='boolean' value='true'/> + <property name='sve' type='boolean' value='true'/> + <property name='sve2048' type='boolean' value='true'/> + <property name='sve512' type='boolean' value='true'/> + <property name='aarch64' type='boolean' value='true'/> + <property name='pmu' type='boolean' value='true'/> + <property name='sve1920' type='boolean' value='true'/> + <property name='sve1152' type='boolean' value='true'/> + <property name='sve640' type='boolean' value='true'/> + <property name='sve1408' type='boolean' value='true'/> + <property name='sve1664' type='boolean' value='true'/> + </hostCPU> <cpu type='kvm' name='pxa262'/> <cpu type='kvm' name='pxa270-a0'/> <cpu type='kvm' name='arm1136'/> -- 2.21.0

The only feature we care about for the moment is SVE, which can be controlled both with a coarse granularity by turning it on/off completely and with a finer granularity by enabling/disabling individual vector lengths. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/cpu_map/arm_features.xml | 22 ++++++++++++++++++++++ src/cpu_map/index.xml | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 src/cpu_map/arm_features.xml diff --git a/src/cpu_map/arm_features.xml b/src/cpu_map/arm_features.xml new file mode 100644 index 0000000000..8a53384463 --- /dev/null +++ b/src/cpu_map/arm_features.xml @@ -0,0 +1,22 @@ +<cpus> + + <!-- SVE vector lengths --> + <feature name='sve'/> + <feature name='sve128'/> + <feature name='sve256'/> + <feature name='sve384'/> + <feature name='sve512'/> + <feature name='sve640'/> + <feature name='sve768'/> + <feature name='sve896'/> + <feature name='sve1024'/> + <feature name='sve1152'/> + <feature name='sve1280'/> + <feature name='sve1408'/> + <feature name='sve1536'/> + <feature name='sve1664'/> + <feature name='sve1792'/> + <feature name='sve1920'/> + <feature name='sve2048'/> + +</cpus> diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml index 3c6885f60c..ed45083dca 100644 --- a/src/cpu_map/index.xml +++ b/src/cpu_map/index.xml @@ -75,4 +75,8 @@ <include filename="ppc64_POWERPC_e5500.xml"/> <include filename="ppc64_POWERPC_e6500.xml"/> </arch> + + <arch name='arm'> + <include filename='arm_features.xml'/> + </arch> </cpus> -- 2.21.0

For now we only perform very basic validation, such as making sure that the user is not trying to enable/disable unknown CPU features and the like. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/cpu/cpu_arm.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index a102c6fda4..70dba6021c 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -23,7 +23,9 @@ #include "viralloc.h" #include "cpu.h" +#include "cpu_map.h" #include "virstring.h" +#include "virxml.h" #define VIR_FROM_THIS VIR_FROM_CPU @@ -34,6 +36,137 @@ static const virArch archs[] = { VIR_ARCH_AARCH64, }; +typedef struct _virCPUarmFeature virCPUarmFeature; +typedef virCPUarmFeature *virCPUarmFeaturePtr; +struct _virCPUarmFeature { + char *name; +}; + +static virCPUarmFeaturePtr +virCPUarmFeatureNew(void) +{ + return g_new0(virCPUarmFeature, 1); +} + +static void +virCPUarmFeatureFree(virCPUarmFeaturePtr feature) +{ + if (!feature) + return; + + g_free(feature->name); + + g_free(feature); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmFeature, virCPUarmFeatureFree); + +typedef struct _virCPUarmMap virCPUarmMap; +typedef virCPUarmMap *virCPUarmMapPtr; +struct _virCPUarmMap { + GPtrArray *features; +}; + +static virCPUarmMapPtr +virCPUarmMapNew(void) +{ + virCPUarmMapPtr map; + + map = g_new0(virCPUarmMap, 1); + + map->features = g_ptr_array_new(); + g_ptr_array_set_free_func(map->features, + (GDestroyNotify) virCPUarmFeatureFree); + + return map; +} + +static void +virCPUarmMapFree(virCPUarmMapPtr map) +{ + if (!map) + return; + + g_ptr_array_free(map->features, TRUE); + + g_free(map); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmMap, virCPUarmMapFree); + +static virCPUarmFeaturePtr +virCPUarmMapFeatureFind(virCPUarmMapPtr map, + const char *name) +{ + size_t i; + + for (i = 0; i < map->features->len; i++) { + virCPUarmFeaturePtr feature = g_ptr_array_index(map->features, i); + + if (STREQ(feature->name, name)) + return feature; + } + + return NULL; +} + +static int +virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED, + const char *name, + void *data) +{ + g_autoptr(virCPUarmFeature) feature = NULL; + virCPUarmMapPtr map = data; + + if (virCPUarmMapFeatureFind(map, name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU feature %s already defined"), name); + return -1; + } + + feature = virCPUarmFeatureNew(); + feature->name = g_strdup(name); + + g_ptr_array_add(map->features, g_steal_pointer(&feature)); + + return 0; +} + +static virCPUarmMapPtr +virCPUarmLoadMap(void) +{ + g_autoptr(virCPUarmMap) map = NULL; + + map = virCPUarmMapNew(); + + if (cpuMapLoad("arm", NULL, virCPUarmMapFeatureParse, NULL, map) < 0) + return NULL; + + return g_steal_pointer(&map); +} + +static virCPUarmMapPtr cpuMap; + +int virCPUarmDriverOnceInit(void); +VIR_ONCE_GLOBAL_INIT(virCPUarmDriver); + +int +virCPUarmDriverOnceInit(void) +{ + if (!(cpuMap = virCPUarmLoadMap())) + return -1; + + return 0; +} + +static virCPUarmMapPtr +virCPUarmGetMap(void) +{ + if (virCPUarmDriverInitialize() < 0) + return NULL; + + return cpuMap; +} static int virCPUarmUpdate(virCPUDefPtr guest, @@ -99,6 +232,29 @@ virCPUarmCompare(virCPUDefPtr host G_GNUC_UNUSED, return VIR_CPU_COMPARE_IDENTICAL; } +static int +virCPUarmValidateFeatures(virCPUDefPtr cpu) +{ + virCPUarmMapPtr map; + size_t i; + + if (!(map = virCPUarmGetMap())) + return -1; + + for (i = 0; i < cpu->nfeatures; i++) { + virCPUFeatureDefPtr feature = &cpu->features[i]; + + if (!virCPUarmMapFeatureFind(map, feature->name)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown CPU feature: %s"), + feature->name); + return -1; + } + } + + return 0; +} + struct cpuArchDriver cpuDriverArm = { .name = "arm", .arch = archs, @@ -108,4 +264,5 @@ struct cpuArchDriver cpuDriverArm = { .encode = NULL, .baseline = virCPUarmBaseline, .update = virCPUarmUpdate, + .validateFeatures = virCPUarmValidateFeatures, }; -- 2.21.0

This introduces semantic validation for SVE-related features, preventing the user from combining them in invalid ways; it also automatically enables overall SVE support if any SVE vector length has been enabled by the user to make sure QEMU behaves correctly. Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- src/qemu/qemu_domain.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 667cc89072..bda357ceb9 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4465,6 +4465,10 @@ qemuDomainDefVcpusPostParse(virDomainDefPtr def) static int qemuDomainDefCPUPostParse(virDomainDefPtr def) { + virCPUFeatureDefPtr sveFeature = NULL; + bool sveVectorLengthsProvided = false; + size_t i; + if (!def->cpu) return 0; @@ -4522,6 +4526,39 @@ qemuDomainDefCPUPostParse(virDomainDefPtr def) } } + for (i = 0; i < def->cpu->nfeatures; i++) { + virCPUFeatureDefPtr feature = &def->cpu->features[i]; + + if (STREQ(feature->name, "sve")) { + sveFeature = feature; + } else if (STRPREFIX(feature->name, "sve")) { + sveVectorLengthsProvided = true; + } + } + + if (sveVectorLengthsProvided) { + if (sveFeature) { + if (sveFeature->policy == VIR_CPU_FEATURE_DISABLE || + sveFeature->policy == VIR_CPU_FEATURE_FORBID) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("SVE disabled, but SVE vector lengths provided")); + return -1; + } else { + sveFeature->policy = VIR_CPU_FEATURE_REQUIRE; + } + } else { + if (VIR_RESIZE_N(def->cpu->features, def->cpu->nfeatures_max, + def->cpu->nfeatures, 1) < 0) { + return -1; + } + + def->cpu->features[def->cpu->nfeatures].name = g_strdup("sve"); + def->cpu->features[def->cpu->nfeatures].policy = VIR_CPU_FEATURE_REQUIRE; + + def->cpu->nfeatures++; + } + } + /* Nothing to be done if only CPU topology is specified. */ if (def->cpu->mode == VIR_CPU_MODE_CUSTOM && !def->cpu->model) -- 2.21.0

Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- .../aarch64-features-sve-disabled.xml | 18 +++++++++++ .../aarch64-features-sve.aarch64-latest.args | 32 +++++++++++++++++++ .../qemuxml2argvdata/aarch64-features-sve.xml | 20 ++++++++++++ .../aarch64-features-wrong.xml | 17 ++++++++++ tests/qemuxml2argvtest.c | 9 ++++++ .../aarch64-features-sve.aarch64-latest.xml | 31 ++++++++++++++++++ tests/qemuxml2xmltest.c | 3 ++ 7 files changed, 130 insertions(+) create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve-disabled.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-wrong.xml create mode 100644 tests/qemuxml2xmloutdata/aarch64-features-sve.aarch64-latest.xml diff --git a/tests/qemuxml2argvdata/aarch64-features-sve-disabled.xml b/tests/qemuxml2argvdata/aarch64-features-sve-disabled.xml new file mode 100644 index 0000000000..0fa8b1314d --- /dev/null +++ b/tests/qemuxml2argvdata/aarch64-features-sve-disabled.xml @@ -0,0 +1,18 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + </os> + <cpu mode='host-passthrough'> + <feature policy='disable' name='sve'/> + <feature policy='require' name='sve128'/> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/aarch64-features-sve.aarch64-latest.args b/tests/qemuxml2argvdata/aarch64-features-sve.aarch64-latest.args new file mode 100644 index 0000000000..6852f5d54d --- /dev/null +++ b/tests/qemuxml2argvdata/aarch64-features-sve.aarch64-latest.args @@ -0,0 +1,32 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-guest \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-guest/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-guest/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-guest/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-aarch64 \ +-name guest=guest,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-guest/master-key.aes \ +-machine virt,accel=kvm,usb=off,dump-guest-core=off,gic-version=3 \ +-cpu host,sve512=on,sve384=off,sve256=on,sve128=on,sve=on \ +-m 1024 \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/aarch64-features-sve.xml b/tests/qemuxml2argvdata/aarch64-features-sve.xml new file mode 100644 index 0000000000..0147a9b19d --- /dev/null +++ b/tests/qemuxml2argvdata/aarch64-features-sve.xml @@ -0,0 +1,20 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + </os> + <cpu mode='host-passthrough'> + <feature policy='require' name='sve512'/> + <feature policy='disable' name='sve384'/> + <feature policy='require' name='sve256'/> + <feature policy='require' name='sve128'/> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/aarch64-features-wrong.xml b/tests/qemuxml2argvdata/aarch64-features-wrong.xml new file mode 100644 index 0000000000..f4a883c9f6 --- /dev/null +++ b/tests/qemuxml2argvdata/aarch64-features-wrong.xml @@ -0,0 +1,17 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>1048576</memory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + </os> + <cpu mode='host-passthrough'> + <feature policy='disable' name='vmx'/> + </cpu> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index fd330df3e0..8c8743abc1 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2669,6 +2669,15 @@ mymain(void) DO_TEST("aarch64-noacpi-nouefi", NONE); DO_TEST_PARSE_ERROR("aarch64-acpi-nouefi", NONE); + /* QEMU 4.0.0 didn't have support for aarch64 CPU features */ + DO_TEST_CAPS_ARCH_VER_FAILURE("aarch64-features-sve", "aarch64", "4.0.0"); + /* aarch64 doesn't support the same CPU features as x86 */ + DO_TEST_CAPS_ARCH_LATEST_FAILURE("aarch64-features-wrong", "aarch64"); + /* Can't enable vector lengths when SVE is overall disabled */ + DO_TEST_CAPS_ARCH_LATEST_PARSE_ERROR("aarch64-features-sve-disabled", "aarch64"); + /* SVE aarch64 CPU features work on modern QEMU */ + DO_TEST_CAPS_ARCH_LATEST("aarch64-features-sve", "aarch64"); + qemuTestSetHostArch(driver.caps, VIR_ARCH_NONE); DO_TEST("kvm-pit-delay", QEMU_CAPS_KVM_PIT_TICK_POLICY); diff --git a/tests/qemuxml2xmloutdata/aarch64-features-sve.aarch64-latest.xml b/tests/qemuxml2xmloutdata/aarch64-features-sve.aarch64-latest.xml new file mode 100644 index 0000000000..914cc7957a --- /dev/null +++ b/tests/qemuxml2xmloutdata/aarch64-features-sve.aarch64-latest.xml @@ -0,0 +1,31 @@ +<domain type='kvm'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <gic version='3'/> + </features> + <cpu mode='host-passthrough' check='none'> + <feature policy='require' name='sve512'/> + <feature policy='disable' name='sve384'/> + <feature policy='require' name='sve256'/> + <feature policy='require' name='sve128'/> + <feature policy='require' name='sve'/> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' index='0' model='none'/> + <controller type='pci' index='0' model='pcie-root'/> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 89c9494e6c..a6c6c20ac1 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1142,6 +1142,9 @@ mymain(void) ARG_GIC, GIC_BOTH, ARG_QEMU_CAPS, NONE); + /* SVE aarch64 CPU features work on modern QEMU */ + DO_TEST_CAPS_ARCH_LATEST("aarch64-features-sve", "aarch64"); + DO_TEST("memory-hotplug", NONE); DO_TEST("memory-hotplug-nonuma", NONE); DO_TEST("memory-hotplug-dimm", NONE); -- 2.21.0

Signed-off-by: Andrea Bolognani <abologna@redhat.com> Tested-by: Andrew Jones <drjones@redhat.com> --- docs/news.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 4dd8dd6dcc..dc91368790 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -44,6 +44,15 @@ <libvirt> <release version="v5.10.0" date="unreleased"> <section title="New features"> + <change> + <summary> + qemu: Introduce support for ARM CPU features + </summary> + <description> + The only features supported at the moment are SVE vector lengths, + which were introduced in QEMU 4.2.0. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.21.0

On 11/6/19 4:47 PM, Andrea Bolognani wrote:
Starting with QEMU 4.2.0, ARM guests support CPU features similarly to what's been the case on x86 since forever; notably, it's now possible to enable SVE (Scalable Vector Extension).
Some of the patches in the series (notably 1/11) are snipped; the unabridged version can be obtained with
$ git fetch https://gitlab.com/abologna/libvirt.git sve
Andrea Bolognani (11): tests: Update capabilities for QEMU 4.2.0 on aarch64 qemu: Rename virQEMUCapsObjectPropsMaxX86CPU qemu: Introduce QEMU_CAPS_ARM_MAX_CPU qemu: Query max-arm-cpu properties qemu: Update query-cpu-model-expansion check qemu: Perform full expansion on ARM cpu_map: Introduce ARM CPU features cpu: Validate ARM CPU features qemu: Validate ARM CPU features tests: Introduce tests for ARM CPU features news: Update for ARM CPU features
docs/news.xml | 9 + src/cpu/cpu_arm.c | 157 + src/cpu_map/arm_features.xml | 22 + src/cpu_map/index.xml | 4 + src/qemu/qemu_capabilities.c | 20 +- src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_command.c | 3 +- src/qemu/qemu_domain.c | 37 + .../qemu_4.2.0-virt.aarch64.xml | 2 +- tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 2 +- .../caps_2.12.0.aarch64.replies | 159 +- .../caps_2.12.0.aarch64.xml | 1 + .../caps_4.0.0.aarch64.replies | 159 +- .../caps_4.0.0.aarch64.xml | 1 + .../caps_4.2.0.aarch64.replies | 3755 ++++++++++------- .../caps_4.2.0.aarch64.xml | 52 +- .../aarch64-features-sve-disabled.xml | 18 + .../aarch64-features-sve.aarch64-latest.args | 32 + .../qemuxml2argvdata/aarch64-features-sve.xml | 20 + .../aarch64-features-wrong.xml | 17 + tests/qemuxml2argvtest.c | 9 + .../aarch64-features-sve.aarch64-latest.xml | 31 + tests/qemuxml2xmltest.c | 3 + 23 files changed, 3029 insertions(+), 1487 deletions(-) create mode 100644 src/cpu_map/arm_features.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve-disabled.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/aarch64-features-sve.xml create mode 100644 tests/qemuxml2argvdata/aarch64-features-wrong.xml create mode 100644 tests/qemuxml2xmloutdata/aarch64-features-sve.aarch64-latest.xml
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Andrea Bolognani
-
Michal Privoznik