[PATCH] qemu: introduce the "virtualization" feature
The "virt" board in QEMU has a "virtualization" option that is documented like this: virtualization Set ``on``/``off`` to enable/disable emulating a guest CPU which implements the Arm Virtualization Extensions. The default is ``off``. (from system/arm/virt.rst) According to the documentation, the "virtualiaztion" option is related to the "gic-version" option. Specifically, gic version=4 requires virtualization to be enabled. And gic version=max will use version=4 when virtualization is enabled, and 3 when not. Libvirt does not currently model neither gic version "3" nor "max" though. It is also documented for the "vexpress-a(9|15)" boards, where it is also disabled by default: - QEMU defaults to providing a CPU which does not provide either TrustZone or the Virtualization Extensions: if you want these you must enable them with ``-machine secure=on`` and ``-machine virtualization=on`` (system/arm/vexpress.rst). On the command line it looks like: qemu-system-aarch64 -machine type=virt,virtualization=on .. Model it using the "virtualization" element in the "features" section: <features> <virtualization/> </features> Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- docs/formatdomain.rst | 4 ++ src/conf/domain_conf.c | 4 ++ src/conf/domain_conf.h | 1 + src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 9 ++++ src/qemu/qemu_validate.c | 1 + ...64-virt-virtualization.aarch64-latest.args | 38 ++++++++++++++++ ...h64-virt-virtualization.aarch64-latest.xml | 45 +++++++++++++++++++ .../aarch64-virt-virtualization.xml | 25 +++++++++++ tests/qemuxmlconftest.c | 2 + 10 files changed, 134 insertions(+) create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 04ef319a73..ad74d91950 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2378,6 +2378,10 @@ are: one IMSIC device present per core), or ``none`` (no support for AIA). If the attribute is not defined, the hypervisor default will be used. :since:`Since 11.1.0` (QEMU/KVM and RISC-V guests only) +``virtualization`` + Enable emulating a guest CPU which implements the Arm Virtualization Extensions. + If the attribute is not defined, the hypervisor default will be used. + :since:`Since 12.1.0` (QEMU/KVM and ARM virt guests only) Time keeping ------------ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9ca5c2450c..1a8c5cb5b7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -188,6 +188,7 @@ VIR_ENUM_IMPL(virDomainFeature, "ras", "ps2", "aia", + "virtualization", ); VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, @@ -17480,6 +17481,7 @@ virDomainFeaturesDefParse(virDomainDef *def, case VIR_DOMAIN_FEATURE_PAE: case VIR_DOMAIN_FEATURE_VIRIDIAN: case VIR_DOMAIN_FEATURE_PRIVNET: + case VIR_DOMAIN_FEATURE_VIRTUALIZATION: def->features[val] = VIR_TRISTATE_SWITCH_ON; break; @@ -21636,6 +21638,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src, case VIR_DOMAIN_FEATURE_CCF_ASSIST: case VIR_DOMAIN_FEATURE_RAS: case VIR_DOMAIN_FEATURE_PS2: + case VIR_DOMAIN_FEATURE_VIRTUALIZATION: if (src->features[i] != dst->features[i]) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("State of feature '%1$s' differs: source: '%2$s', destination: '%3$s'"), @@ -28867,6 +28870,7 @@ virDomainDefFormatFeatures(virBuffer *buf, case VIR_DOMAIN_FEATURE_PAE: case VIR_DOMAIN_FEATURE_VIRIDIAN: case VIR_DOMAIN_FEATURE_PRIVNET: + case VIR_DOMAIN_FEATURE_VIRTUALIZATION: /* NOTE: This is for old style <opt/> booleans. New XML * should use the explicit state=on|off output below */ switch ((virTristateSwitch) def->features[i]) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index cb35ff06bd..d0f4c082fd 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2243,6 +2243,7 @@ typedef enum { VIR_DOMAIN_FEATURE_RAS, VIR_DOMAIN_FEATURE_PS2, VIR_DOMAIN_FEATURE_AIA, + VIR_DOMAIN_FEATURE_VIRTUALIZATION, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 114dd3f96f..8669d8f791 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -7180,6 +7180,11 @@ <optional> <ref name="aia"/> </optional> + <optional> + <element name="virtualization"> + <empty/> + </element> + </optional> </interleave> </element> </optional> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0de0a79b46..b410daf156 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7011,6 +7011,15 @@ qemuAppendDomainFeaturesMachineParam(virBuffer *buf, } } + if (def->features[VIR_DOMAIN_FEATURE_VIRTUALIZATION] == VIR_TRISTATE_SWITCH_ON) { + if (virQEMUCapsGetArch(qemuCaps) != VIR_ARCH_AARCH64) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtualization option is not available with this QEMU binary")); + return -1; + } + virBufferAddLit(buf, ",virtualization=on"); + } + if (def->features[VIR_DOMAIN_FEATURE_HTM] != VIR_TRISTATE_SWITCH_ABSENT) { const char *str; str = virTristateSwitchTypeToString(def->features[VIR_DOMAIN_FEATURE_HTM]); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 184c23d307..5474d00ecd 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -182,6 +182,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, break; case VIR_DOMAIN_FEATURE_GIC: + case VIR_DOMAIN_FEATURE_VIRTUALIZATION: if (def->features[i] == VIR_TRISTATE_SWITCH_ON && !qemuDomainIsARMVirt(def)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args b/tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args new file mode 100644 index 0000000000..be04ecc641 --- /dev/null +++ b/tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args @@ -0,0 +1,38 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/var/lib/libvirt/qemu/domain--1-aarch64-virt-default \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-aarch64-virt-default/.local/share \ +XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-aarch64-virt-default/.cache \ +XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-aarch64-virt-default/.config \ +/usr/bin/qemu-system-aarch64 \ +-name guest=aarch64-virt-default-nic,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-aarch64-virt-default/master-key.aes"}' \ +-machine virt,usb=off,gic-version=2,virtualization=on,dump-guest-core=off,memory-backend=mach-virt.ram,acpi=off \ +-accel tcg \ +-cpu cortex-a53 \ +-m size=1048576k \ +-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 6ba410c5-1e5c-4d57-bee7-2228e7ffa32f \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-boot strict=on \ +-kernel /aarch64.kernel \ +-initrd /aarch64.initrd \ +-append console=ttyAMA0 \ +-device '{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x1"}' \ +-device '{"driver":"pcie-root-port","port":9,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x1.0x1"}' \ +-netdev '{"type":"user","id":"hostnet0"}' \ +-device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:09:a4:37","bus":"pci.1","addr":"0x0"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml b/tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml new file mode 100644 index 0000000000..7636046257 --- /dev/null +++ b/tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml @@ -0,0 +1,45 @@ +<domain type='qemu'> + <name>aarch64-virt-default-nic</name> + <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid> + <memory unit='KiB'>1048576</memory> + <currentMemory unit='KiB'>1048576</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='aarch64' machine='virt'>hvm</type> + <kernel>/aarch64.kernel</kernel> + <initrd>/aarch64.initrd</initrd> + <cmdline>console=ttyAMA0</cmdline> + <boot dev='hd'/> + </os> + <features> + <gic version='2'/> + <virtualization/> + </features> + <cpu mode='custom' match='exact' check='none'> + <model fallback='allow'>cortex-a53</model> + </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='pci' index='0' model='pcie-root'/> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='1' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/> + </controller> + <controller type='pci' index='2' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <interface type='user'> + <mac address='52:54:00:09:a4:37'/> + <model type='virtio'/> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </interface> + <audio id='1' type='none'/> + </devices> +</domain> diff --git a/tests/qemuxmlconfdata/aarch64-virt-virtualization.xml b/tests/qemuxmlconfdata/aarch64-virt-virtualization.xml new file mode 100644 index 0000000000..ee7984a736 --- /dev/null +++ b/tests/qemuxmlconfdata/aarch64-virt-virtualization.xml @@ -0,0 +1,25 @@ +<domain type="qemu"> + <name>aarch64-virt-default-nic</name> + <uuid>6ba410c5-1e5c-4d57-bee7-2228e7ffa32f</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>1</vcpu> + <cpu match='exact'> + <model>cortex-a53</model> + </cpu> + <os> + <type arch="aarch64" machine="virt">hvm</type> + <kernel>/aarch64.kernel</kernel> + <initrd>/aarch64.initrd</initrd> + <cmdline>console=ttyAMA0</cmdline> + </os> + <features> + <virtualization/> + </features> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <interface type='user'> + <mac address='52:54:00:09:a4:37'/> + </interface> + </devices> +</domain> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index 89b8ad1a35..c7c1d1da54 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -3322,6 +3322,8 @@ mymain(void) /* MSHV guests should not work on Linux with KVM */ DO_TEST_CAPS_LATEST_PARSE_ERROR("mshv-x86_64-q35-headless"); + DO_TEST_CAPS_ARCH_LATEST("aarch64-virt-virtualization", "aarch64"); + /* check that all input files were actually used here */ if (testConfXMLCheck(existingTestCases) < 0) ret = -1; -- 2.52.0
Roman Bogorodskiy wrote:
The "virt" board in QEMU has a "virtualization" option that is documented like this:
virtualization Set ``on``/``off`` to enable/disable emulating a guest CPU which implements the Arm Virtualization Extensions. The default is ``off``.
(from system/arm/virt.rst)
According to the documentation, the "virtualiaztion" option is related to the "gic-version" option. Specifically, gic version=4 requires virtualization to be enabled. And gic version=max will use version=4 when virtualization is enabled, and 3 when not. Libvirt does not currently model neither gic version "3" nor "max" though.
It is also documented for the "vexpress-a(9|15)" boards, where it is also disabled by default:
- QEMU defaults to providing a CPU which does not provide either TrustZone or the Virtualization Extensions: if you want these you must enable them with ``-machine secure=on`` and ``-machine virtualization=on``
(system/arm/vexpress.rst).
On the command line it looks like:
qemu-system-aarch64 -machine type=virt,virtualization=on ..
Model it using the "virtualization" element in the "features" section:
<features> <virtualization/> </features>
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- docs/formatdomain.rst | 4 ++ src/conf/domain_conf.c | 4 ++ src/conf/domain_conf.h | 1 + src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 9 ++++ src/qemu/qemu_validate.c | 1 + ...64-virt-virtualization.aarch64-latest.args | 38 ++++++++++++++++ ...h64-virt-virtualization.aarch64-latest.xml | 45 +++++++++++++++++++ .../aarch64-virt-virtualization.xml | 25 +++++++++++ tests/qemuxmlconftest.c | 2 + 10 files changed, 134 insertions(+) create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.xml
ping?
On 1/12/26 20:17, Roman Bogorodskiy wrote:
The "virt" board in QEMU has a "virtualization" option that is documented like this:
virtualization Set ``on``/``off`` to enable/disable emulating a guest CPU which implements the Arm Virtualization Extensions. The default is ``off``.
(from system/arm/virt.rst)
According to the documentation, the "virtualiaztion" option is related to the "gic-version" option. Specifically, gic version=4 requires virtualization to be enabled. And gic version=max will use version=4 when virtualization is enabled, and 3 when not. Libvirt does not currently model neither gic version "3" nor "max"
yes we do model GICv3 actually, but not 4. ``gic`` Enable for architectures using a General Interrupt Controller instead of APIC in order to handle interrupts. For example, the 'aarch64' architecture uses ``gic`` instead of ``apic``. The optional attribute ``version`` specifies the GIC version; however, it may not be supported by all hypervisors. Accepted values are ``2``, ``3`` and ``host``. :since:`Since 1.2.16` And there's this one funny comment in hw/arm/virt.c: static VirtGICType finalize_gic_version_do(const char *accel_name, VirtGICType gic_version, int gics_supported, unsigned int max_cpus) { /* Convert host/max/nosel to GIC version number */ switch (gic_version) { case VIRT_GIC_VERSION_HOST: if (!kvm_enabled()) { error_report("gic-version=host requires KVM"); exit(1); } /* For KVM, gic-version=host means gic-version=max */ return finalize_gic_version_do(accel_name, VIRT_GIC_VERSION_MAX, gics_supported, max_cpus);
though.
It is also documented for the "vexpress-a(9|15)" boards, where it is also disabled by default:
- QEMU defaults to providing a CPU which does not provide either TrustZone or the Virtualization Extensions: if you want these you must enable them with ``-machine secure=on`` and ``-machine virtualization=on``
(system/arm/vexpress.rst).
On the command line it looks like:
qemu-system-aarch64 -machine type=virt,virtualization=on ..
Model it using the "virtualization" element in the "features" section:
<features> <virtualization/> </features>
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- docs/formatdomain.rst | 4 ++ src/conf/domain_conf.c | 4 ++ src/conf/domain_conf.h | 1 + src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 9 ++++ src/qemu/qemu_validate.c | 1 + ...64-virt-virtualization.aarch64-latest.args | 38 ++++++++++++++++ ...h64-virt-virtualization.aarch64-latest.xml | 45 +++++++++++++++++++ .../aarch64-virt-virtualization.xml | 25 +++++++++++ tests/qemuxmlconftest.c | 2 + 10 files changed, 134 insertions(+) create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.xml
Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
Michal Prívozník wrote:
On 1/12/26 20:17, Roman Bogorodskiy wrote:
The "virt" board in QEMU has a "virtualization" option that is documented like this:
virtualization Set ``on``/``off`` to enable/disable emulating a guest CPU which implements the Arm Virtualization Extensions. The default is ``off``.
(from system/arm/virt.rst)
According to the documentation, the "virtualiaztion" option is related to the "gic-version" option. Specifically, gic version=4 requires virtualization to be enabled. And gic version=max will use version=4 when virtualization is enabled, and 3 when not. Libvirt does not currently model neither gic version "3" nor "max"
yes we do model GICv3 actually, but not 4.
Sorry, that was a typo, it should have been 'version "4" nor "max"'.
``gic`` Enable for architectures using a General Interrupt Controller instead of APIC in order to handle interrupts. For example, the 'aarch64' architecture uses ``gic`` instead of ``apic``. The optional attribute ``version`` specifies the GIC version; however, it may not be supported by all hypervisors. Accepted values are ``2``, ``3`` and ``host``. :since:`Since 1.2.16`
And there's this one funny comment in hw/arm/virt.c:
static VirtGICType finalize_gic_version_do(const char *accel_name, VirtGICType gic_version, int gics_supported, unsigned int max_cpus) { /* Convert host/max/nosel to GIC version number */ switch (gic_version) { case VIRT_GIC_VERSION_HOST: if (!kvm_enabled()) { error_report("gic-version=host requires KVM"); exit(1); }
/* For KVM, gic-version=host means gic-version=max */ return finalize_gic_version_do(accel_name, VIRT_GIC_VERSION_MAX, gics_supported, max_cpus);
though.
It is also documented for the "vexpress-a(9|15)" boards, where it is also disabled by default:
- QEMU defaults to providing a CPU which does not provide either TrustZone or the Virtualization Extensions: if you want these you must enable them with ``-machine secure=on`` and ``-machine virtualization=on``
(system/arm/vexpress.rst).
On the command line it looks like:
qemu-system-aarch64 -machine type=virt,virtualization=on ..
Model it using the "virtualization" element in the "features" section:
<features> <virtualization/> </features>
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- docs/formatdomain.rst | 4 ++ src/conf/domain_conf.c | 4 ++ src/conf/domain_conf.h | 1 + src/conf/schemas/domaincommon.rng | 5 +++ src/qemu/qemu_command.c | 9 ++++ src/qemu/qemu_validate.c | 1 + ...64-virt-virtualization.aarch64-latest.args | 38 ++++++++++++++++ ...h64-virt-virtualization.aarch64-latest.xml | 45 +++++++++++++++++++ .../aarch64-virt-virtualization.xml | 25 +++++++++++ tests/qemuxmlconftest.c | 2 + 10 files changed, 134 insertions(+) create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.args create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.aarch64-latest.xml create mode 100644 tests/qemuxmlconfdata/aarch64-virt-virtualization.xml
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Michal
participants (2)
-
Michal Prívozník -
Roman Bogorodskiy