[libvirt] [PATCH 00/11] qemu: Introduce SMMUv3 IOMMU support

This is the ARM equivalent of Intel IOMMU. Andrea Bolognani (11): qemu: Fix switch() statements for virDomainIOMMUModel qemu: Drop 'ret' from qemuBuildIOMMUCommandLine() qemu: Use VIR_AUTOCLEAN() in qemuBuildIOMMUCommandLine() qemu: Move virBuffer inside switch() statement qemu: Move capability checks inside switch() statements qemu: Introduce QEMU_CAPS_MACHINE_VIRT_IOMMU conf: Parse and format SMMUv3 IOMMU qemu: Add validation for SMMUv3 IOMMU qemu: Move capability checks for IOMMU features qemu: Format SMMUv3 IOMMU news: Update for SMMUv3 IOMMU support docs/formatdomain.html.in | 7 +- docs/news.xml | 8 + docs/schemas/domaincommon.rng | 5 +- src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 8 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 63 ++++--- src/qemu/qemu_domain.c | 73 +++++--- .../caps_2.12.0.aarch64.replies | 166 +++++++++++++++-- .../caps_3.0.0.riscv32.replies | 131 +++++++++++++- .../caps_3.0.0.riscv64.replies | 131 +++++++++++++- .../caps_4.0.0.aarch64.replies | 171 ++++++++++++++++-- .../caps_4.0.0.aarch64.xml | 1 + .../caps_4.0.0.riscv32.replies | 129 ++++++++++++- .../caps_4.0.0.riscv64.replies | 129 ++++++++++++- .../iommu-smmuv3.aarch64-latest.args | 31 ++++ tests/qemuxml2argvdata/iommu-smmuv3.xml | 15 ++ tests/qemuxml2argvtest.c | 1 + .../iommu-smmuv3.aarch64-latest.xml | 25 +++ tests/qemuxml2xmltest.c | 1 + 21 files changed, 985 insertions(+), 113 deletions(-) create mode 100644 tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/iommu-smmuv3.xml create mode 100644 tests/qemuxml2xmloutdata/iommu-smmuv3.aarch64-latest.xml -- 2.21.0

Ensure unexpected values are dealt with correctly, that is by invoking virReportEnumRangeError() and immediately returning a negative value to the caller. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 10 ++++++++-- src/qemu/qemu_domain.c | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5bf6c704e0..fcc6caf42f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6961,8 +6961,12 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, virBufferAsprintf(&opts, ",device-iotlb=%s", virTristateSwitchTypeToString(iommu->iotlb)); } - case VIR_DOMAIN_IOMMU_MODEL_LAST: break; + + case VIR_DOMAIN_IOMMU_MODEL_LAST: + default: + virReportEnumRangeError(virDomainIOMMUModel, iommu->model); + return -1; } virCommandAddArg(cmd, "-device"); virCommandAddArgBuffer(cmd, &opts); @@ -7609,7 +7613,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, virBufferAddLit(&buf, ",iommu=on"); break; case VIR_DOMAIN_IOMMU_MODEL_LAST: - break; + default: + virReportEnumRangeError(virDomainIOMMUModel, def->iommu->model); + return -1; } } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e50e84a3b2..366ebe1604 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6138,6 +6138,7 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, iommu->model); + return -1; } return 0; -- 2.21.0

On Tue, May 28, 2019 at 05:28:54PM +0200, Andrea Bolognani wrote:
Ensure unexpected values are dealt with correctly, that is by invoking virReportEnumRangeError() and immediately returning a negative value to the caller.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 10 ++++++++-- src/qemu/qemu_domain.c | 1 + 2 files changed, 9 insertions(+), 2 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fcc6caf42f..4a3aa26d7e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6930,7 +6930,6 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, { virBuffer opts = VIR_BUFFER_INITIALIZER; const virDomainIOMMUDef *iommu = def->iommu; - int ret = -1; if (!iommu) return 0; @@ -6971,9 +6970,8 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, virCommandAddArg(cmd, "-device"); virCommandAddArgBuffer(cmd, &opts); - ret = 0; virBufferFreeAndReset(&opts); - return ret; + return 0; } -- 2.21.0

On Tue, May 28, 2019 at 05:28:55PM +0200, Andrea Bolognani wrote:
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4a3aa26d7e..dd7ea0941d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6928,7 +6928,7 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, const virDomainDef *def, virQEMUCapsPtr qemuCaps) { - virBuffer opts = VIR_BUFFER_INITIALIZER; + VIR_AUTOCLEAN(virBuffer) opts = VIR_BUFFER_INITIALIZER; const virDomainIOMMUDef *iommu = def->iommu; if (!iommu) @@ -6970,7 +6970,6 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, virCommandAddArg(cmd, "-device"); virCommandAddArgBuffer(cmd, &opts); - virBufferFreeAndReset(&opts); return 0; } -- 2.21.0

On Tue, May 28, 2019 at 05:28:56PM +0200, Andrea Bolognani wrote:
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This doesn't make a whole lot of difference now, but once we introduce more virDomainIOMMUModel values the current structure will no longer work. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index dd7ea0941d..d5016cc99c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6928,7 +6928,6 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, const virDomainDef *def, virQEMUCapsPtr qemuCaps) { - VIR_AUTOCLEAN(virBuffer) opts = VIR_BUFFER_INITIALIZER; const virDomainIOMMUDef *iommu = def->iommu; if (!iommu) @@ -6942,7 +6941,9 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, return 0; switch (iommu->model) { - case VIR_DOMAIN_IOMMU_MODEL_INTEL: + case VIR_DOMAIN_IOMMU_MODEL_INTEL: { + VIR_AUTOCLEAN(virBuffer) opts = VIR_BUFFER_INITIALIZER; + virBufferAddLit(&opts, "intel-iommu"); if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&opts, ",intremap=%s", @@ -6960,15 +6961,17 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, virBufferAsprintf(&opts, ",device-iotlb=%s", virTristateSwitchTypeToString(iommu->iotlb)); } + + virCommandAddArg(cmd, "-device"); + virCommandAddArgBuffer(cmd, &opts); break; + } case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, iommu->model); return -1; } - virCommandAddArg(cmd, "-device"); - virCommandAddArgBuffer(cmd, &opts); return 0; } -- 2.21.0

On Tue, May 28, 2019 at 05:28:57PM +0200, Andrea Bolognani wrote:
This doesn't make a whole lot of difference now, but once we introduce more virDomainIOMMUModel values the current structure will no longer work.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Current capability checks are specific to Intel IOMMU, so we need to move them inside the switch() statement before we can introduce more virDomainIOMMUModel values. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d5016cc99c..b2b9bef772 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6933,17 +6933,17 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, if (!iommu) return 0; - /* qemuDomainDeviceDefValidate() already made sure we have one of - * QEMU_CAPS_DEVICE_INTEL_IOMMU or QEMU_CAPS_MACHINE_IOMMU: here we - * handle the former case, while the latter is taken care of in - * qemuBuildMachineCommandLine() */ - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU)) - return 0; - switch (iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: { VIR_AUTOCLEAN(virBuffer) opts = VIR_BUFFER_INITIALIZER; + /* qemuDomainDeviceDefValidateIOMMU() already made sure we have + * one of QEMU_CAPS_DEVICE_INTEL_IOMMU or QEMU_CAPS_MACHINE_IOMMU: + * here we handle the former case, while the latter is taken care + * of in qemuBuildMachineCommandLine() */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_INTEL_IOMMU)) + return 0; + virBufferAddLit(&opts, "intel-iommu"); if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT) { virBufferAsprintf(&opts, ",intremap=%s", @@ -7602,15 +7602,15 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, } } - /* qemuDomainDeviceDefValidate() already made sure we have one of - * QEMU_CAPS_DEVICE_INTEL_IOMMU or QEMU_CAPS_MACHINE_IOMMU: here we - * handle the latter case, while the former is taken care of in - * qemuBuildIOMMUCommandLine() */ - if (def->iommu && - virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU)) { + if (def->iommu) { switch (def->iommu->model) { case VIR_DOMAIN_IOMMU_MODEL_INTEL: - virBufferAddLit(&buf, ",iommu=on"); + /* qemuDomainDeviceDefValidateIOMMU() already made sure we have + * one of QEMU_CAPS_DEVICE_INTEL_IOMMU or QEMU_CAPS_MACHINE_IOMMU: + * here we handle the latter case, while the former is taken care + * of in qemuBuildIOMMUCommandLine() */ + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU)) + virBufferAddLit(&buf, ",iommu=on"); break; case VIR_DOMAIN_IOMMU_MODEL_LAST: default: -- 2.21.0

On Tue, May 28, 2019 at 05:28:58PM +0200, Andrea Bolognani wrote:
Current capability checks are specific to Intel IOMMU, so we need to move them inside the switch() statement before we can introduce more virDomainIOMMUModel values.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This capability can be used to figure out whether the QEMU binary at hand supports the machine type property we need in order to enable SMMUv3 IOMMU support. Unfortunately we can't avoid probing the RISC-V binaries along with the ARM ones, since both architectures have their own 'virt' machine type. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 8 + src/qemu/qemu_capabilities.h | 1 + .../caps_2.12.0.aarch64.replies | 166 +++++++++++++++-- .../caps_3.0.0.riscv32.replies | 131 +++++++++++++- .../caps_3.0.0.riscv64.replies | 131 +++++++++++++- .../caps_4.0.0.aarch64.replies | 171 ++++++++++++++++-- .../caps_4.0.0.aarch64.xml | 1 + .../caps_4.0.0.riscv32.replies | 129 ++++++++++++- .../caps_4.0.0.riscv64.replies | 129 ++++++++++++- 9 files changed, 805 insertions(+), 62 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a827bd24e3..bf069fa8ea 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -525,6 +525,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "virtio-pci-non-transitional", "overcommit", "query-current-machine", + "machine.virt.iommu", ); @@ -1406,10 +1407,17 @@ static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsPSeries[] = { { "cap-nested-hv", QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV }, }; +static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsVirt[] = { + { "iommu", QEMU_CAPS_MACHINE_VIRT_IOMMU }, +}; + static virQEMUCapsObjectTypeProps virQEMUCapsMachineProps[] = { { "pseries", virQEMUCapsMachinePropsPSeries, ARRAY_CARDINALITY(virQEMUCapsMachinePropsPSeries), -1 }, + { "virt", virQEMUCapsMachinePropsVirt, + ARRAY_CARDINALITY(virQEMUCapsMachinePropsVirt), + -1 }, }; static void diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 67c8e80462..0f282ad239 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -507,6 +507,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_VIRTIO_PCI_TRANSITIONAL, /* virtio *-pci-{non-}transitional devices */ QEMU_CAPS_OVERCOMMIT, /* -overcommit */ QEMU_CAPS_QUERY_CURRENT_MACHINE, /* query-current-machine command */ + QEMU_CAPS_MACHINE_VIRT_IOMMU, /* -machine virt,iommu */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies index 67553451fc..7a3d0fe0e4 100644 --- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.replies @@ -5633,10 +5633,148 @@ } { - "execute": "query-cpu-definitions", + "execute": "qom-list-properties", + "arguments": { + "typename": "virt-2.12-machine" + }, "id": "libvirt-32" } +{ + "return": [ + { + "name": "graphics", + "description": "Set on/off to enable/disable graphics emulation", + "type": "bool" + }, + { + "name": "phandle-start", + "description": "The first phandle ID we may generate dynamically", + "type": "int" + }, + { + "name": "dump-guest-core", + "description": "Include guest memory in a core dump", + "type": "bool" + }, + { + "name": "kernel-irqchip", + "description": "Configure KVM in-kernel irqchip", + "type": "on|off|split" + }, + { + "name": "accel", + "description": "Accelerator list", + "type": "string" + }, + { + "name": "append", + "description": "Linux kernel command line", + "type": "string" + }, + { + "name": "dumpdtb", + "description": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "memory-encryption", + "description": "Set memory encyption object to use", + "type": "string" + }, + { + "name": "igd-passthru", + "description": "Set on/off to enable/disable igd passthrou", + "type": "bool" + }, + { + "name": "dt-compatible", + "description": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "kernel", + "description": "Linux kernel image file", + "type": "string" + }, + { + "name": "usb", + "description": "Set on/off to enable/disable usb", + "type": "bool" + }, + { + "name": "suppress-vmdesc", + "description": "Set on to disable self-describing migration", + "type": "bool" + }, + { + "name": "dtb", + "description": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "firmware", + "description": "Firmware image", + "type": "string" + }, + { + "name": "mem-merge", + "description": "Enable/disable memory merge support", + "type": "bool" + }, + { + "name": "initrd", + "description": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "enforce-config-section", + "description": "Set on to enforce configuration section migration", + "type": "bool" + }, + { + "name": "kvm-shadow-mem", + "description": "KVM shadow MMU size", + "type": "int" + }, + { + "name": "virtualization", + "description": "Set on/off to enable/disable emulating a guest CPU which implements the ARM Virtualization Extensions", + "type": "bool" + }, + { + "name": "type", + "type": "string" + }, + { + "name": "its", + "description": "Set on/off to enable/disable ITS instantiation", + "type": "bool" + }, + { + "name": "gic-version", + "description": "Set GIC version. Valid values are 2, 3 and host", + "type": "string" + }, + { + "name": "highmem", + "description": "Set on/off to enable/disable using physical address space above 32 bits", + "type": "bool" + }, + { + "name": "secure", + "description": "Set on/off to enable/disable the ARM Security Extensions (TrustZone)", + "type": "bool" + } + ], + "id": "libvirt-32" +} + +{ + "execute": "query-cpu-definitions", + "id": "libvirt-33" +} + { "return": [ { @@ -5810,35 +5948,35 @@ "static": false } ], - "id": "libvirt-32" + "id": "libvirt-33" } { "execute": "query-tpm-models", - "id": "libvirt-33" + "id": "libvirt-34" } { "return": [ ], - "id": "libvirt-33" + "id": "libvirt-34" } { "execute": "query-tpm-types", - "id": "libvirt-34" + "id": "libvirt-35" } { "return": [ "emulator" ], - "id": "libvirt-34" + "id": "libvirt-35" } { "execute": "query-command-line-options", - "id": "libvirt-35" + "id": "libvirt-36" } { @@ -6999,12 +7137,12 @@ "option": "drive" } ], - "id": "libvirt-35" + "id": "libvirt-36" } { "execute": "query-migrate-capabilities", - "id": "libvirt-36" + "id": "libvirt-37" } { @@ -7066,12 +7204,12 @@ "capability": "dirty-bitmaps" } ], - "id": "libvirt-36" + "id": "libvirt-37" } { "execute": "query-qmp-schema", - "id": "libvirt-37" + "id": "libvirt-38" } { @@ -18439,12 +18577,12 @@ "meta-type": "object" } ], - "id": "libvirt-37" + "id": "libvirt-38" } { "execute": "query-gic-capabilities", - "id": "libvirt-38" + "id": "libvirt-39" } { @@ -18460,7 +18598,7 @@ "kernel": false } ], - "id": "libvirt-38" + "id": "libvirt-39" } { diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.replies b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.replies index 389fc95e0e..8159b26d19 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.replies +++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.replies @@ -1698,32 +1698,145 @@ } { - "execute": "query-tpm-models", + "execute": "qom-list-properties", + "arguments": { + "typename": "virt-machine" + }, "id": "libvirt-28" } { "return": [ + { + "name": "enforce-config-section", + "description": "Set on to enforce configuration section migration", + "type": "bool" + }, + { + "name": "kernel", + "description": "Linux kernel image file", + "type": "string" + }, + { + "name": "dt-compatible", + "description": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "initrd", + "description": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "graphics", + "description": "Set on/off to enable/disable graphics emulation", + "type": "bool" + }, + { + "name": "kernel-irqchip", + "description": "Configure KVM in-kernel irqchip", + "type": "on|off|split" + }, + { + "name": "usb", + "description": "Set on/off to enable/disable usb", + "type": "bool" + }, + { + "name": "firmware", + "description": "Firmware image", + "type": "string" + }, + { + "name": "memory-encryption", + "description": "Set memory encyption object to use", + "type": "string" + }, + { + "name": "dump-guest-core", + "description": "Include guest memory in a core dump", + "type": "bool" + }, + { + "name": "kvm-shadow-mem", + "description": "KVM shadow MMU size", + "type": "int" + }, + { + "name": "igd-passthru", + "description": "Set on/off to enable/disable igd passthrou", + "type": "bool" + }, + { + "name": "phandle-start", + "description": "The first phandle ID we may generate dynamically", + "type": "int" + }, + { + "name": "dumpdtb", + "description": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "mem-merge", + "description": "Enable/disable memory merge support", + "type": "bool" + }, + { + "name": "dtb", + "description": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "accel", + "description": "Accelerator list", + "type": "string" + }, + { + "name": "append", + "description": "Linux kernel command line", + "type": "string" + }, + { + "name": "suppress-vmdesc", + "description": "Set on to disable self-describing migration", + "type": "bool" + }, + { + "name": "type", + "type": "string" + } ], "id": "libvirt-28" } { - "execute": "query-tpm-types", + "execute": "query-tpm-models", "id": "libvirt-29" } +{ + "return": [ + ], + "id": "libvirt-29" +} + +{ + "execute": "query-tpm-types", + "id": "libvirt-30" +} + { "return": [ "passthrough", "emulator" ], - "id": "libvirt-29" + "id": "libvirt-30" } { "execute": "query-command-line-options", - "id": "libvirt-30" + "id": "libvirt-31" } { @@ -2848,12 +2961,12 @@ "option": "drive" } ], - "id": "libvirt-30" + "id": "libvirt-31" } { "execute": "query-migrate-capabilities", - "id": "libvirt-31" + "id": "libvirt-32" } { @@ -2923,12 +3036,12 @@ "capability": "late-block-activate" } ], - "id": "libvirt-31" + "id": "libvirt-32" } { "execute": "query-qmp-schema", - "id": "libvirt-32" + "id": "libvirt-33" } { @@ -14603,5 +14716,5 @@ "meta-type": "object" } ], - "id": "libvirt-32" + "id": "libvirt-33" } diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.replies b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.replies index 65da947c60..995ca86784 100644 --- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.replies +++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.replies @@ -1698,32 +1698,145 @@ } { - "execute": "query-tpm-models", + "execute": "qom-list-properties", + "arguments": { + "typename": "virt-machine" + }, "id": "libvirt-28" } { "return": [ + { + "name": "enforce-config-section", + "description": "Set on to enforce configuration section migration", + "type": "bool" + }, + { + "name": "kernel", + "description": "Linux kernel image file", + "type": "string" + }, + { + "name": "dt-compatible", + "description": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "initrd", + "description": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "graphics", + "description": "Set on/off to enable/disable graphics emulation", + "type": "bool" + }, + { + "name": "kernel-irqchip", + "description": "Configure KVM in-kernel irqchip", + "type": "on|off|split" + }, + { + "name": "usb", + "description": "Set on/off to enable/disable usb", + "type": "bool" + }, + { + "name": "firmware", + "description": "Firmware image", + "type": "string" + }, + { + "name": "memory-encryption", + "description": "Set memory encyption object to use", + "type": "string" + }, + { + "name": "dump-guest-core", + "description": "Include guest memory in a core dump", + "type": "bool" + }, + { + "name": "kvm-shadow-mem", + "description": "KVM shadow MMU size", + "type": "int" + }, + { + "name": "igd-passthru", + "description": "Set on/off to enable/disable igd passthrou", + "type": "bool" + }, + { + "name": "phandle-start", + "description": "The first phandle ID we may generate dynamically", + "type": "int" + }, + { + "name": "dumpdtb", + "description": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "mem-merge", + "description": "Enable/disable memory merge support", + "type": "bool" + }, + { + "name": "dtb", + "description": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "accel", + "description": "Accelerator list", + "type": "string" + }, + { + "name": "append", + "description": "Linux kernel command line", + "type": "string" + }, + { + "name": "suppress-vmdesc", + "description": "Set on to disable self-describing migration", + "type": "bool" + }, + { + "name": "type", + "type": "string" + } ], "id": "libvirt-28" } { - "execute": "query-tpm-types", + "execute": "query-tpm-models", "id": "libvirt-29" } +{ + "return": [ + ], + "id": "libvirt-29" +} + +{ + "execute": "query-tpm-types", + "id": "libvirt-30" +} + { "return": [ "passthrough", "emulator" ], - "id": "libvirt-29" + "id": "libvirt-30" } { "execute": "query-command-line-options", - "id": "libvirt-30" + "id": "libvirt-31" } { @@ -2848,12 +2961,12 @@ "option": "drive" } ], - "id": "libvirt-30" + "id": "libvirt-31" } { "execute": "query-migrate-capabilities", - "id": "libvirt-31" + "id": "libvirt-32" } { @@ -2923,12 +3036,12 @@ "capability": "late-block-activate" } ], - "id": "libvirt-31" + "id": "libvirt-32" } { "execute": "query-qmp-schema", - "id": "libvirt-32" + "id": "libvirt-33" } { @@ -14603,5 +14716,5 @@ "meta-type": "object" } ], - "id": "libvirt-32" + "id": "libvirt-33" } diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies index 128ee04e86..91943860b1 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies +++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.replies @@ -6211,10 +6211,153 @@ } { - "execute": "query-cpu-definitions", + "execute": "qom-list-properties", + "arguments": { + "typename": "virt-4.0-machine" + }, + "id": "libvirt-33" +} + +{ + "return": [ + { + "name": "type", + "type": "string" + }, + { + "name": "graphics", + "description": "Set on/off to enable/disable graphics emulation", + "type": "bool" + }, + { + "name": "phandle-start", + "description": "The first phandle ID we may generate dynamically", + "type": "int" + }, + { + "name": "dump-guest-core", + "description": "Include guest memory in a core dump", + "type": "bool" + }, + { + "name": "kernel-irqchip", + "description": "Configure KVM in-kernel irqchip", + "type": "on|off|split" + }, + { + "name": "accel", + "description": "Accelerator list", + "type": "string" + }, + { + "name": "append", + "description": "Linux kernel command line", + "type": "string" + }, + { + "name": "dumpdtb", + "description": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "memory-encryption", + "description": "Set memory encryption object to use", + "type": "string" + }, + { + "name": "igd-passthru", + "description": "Set on/off to enable/disable igd passthrou", + "type": "bool" + }, + { + "name": "dt-compatible", + "description": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "kernel", + "description": "Linux kernel image file", + "type": "string" + }, + { + "name": "usb", + "description": "Set on/off to enable/disable usb", + "type": "bool" + }, + { + "name": "suppress-vmdesc", + "description": "Set on to disable self-describing migration", + "type": "bool" + }, + { + "name": "dtb", + "description": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "firmware", + "description": "Firmware image", + "type": "string" + }, + { + "name": "mem-merge", + "description": "Enable/disable memory merge support", + "type": "bool" + }, + { + "name": "initrd", + "description": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "enforce-config-section", + "description": "Set on to enforce configuration section migration", + "type": "bool" + }, + { + "name": "kvm-shadow-mem", + "description": "KVM shadow MMU size", + "type": "int" + }, + { + "name": "virtualization", + "description": "Set on/off to enable/disable emulating a guest CPU which implements the ARM Virtualization Extensions", + "type": "bool" + }, + { + "name": "its", + "description": "Set on/off to enable/disable ITS instantiation", + "type": "bool" + }, + { + "name": "gic-version", + "description": "Set GIC version. Valid values are 2, 3 and host", + "type": "string" + }, + { + "name": "highmem", + "description": "Set on/off to enable/disable using physical address space above 32 bits", + "type": "bool" + }, + { + "name": "secure", + "description": "Set on/off to enable/disable the ARM Security Extensions (TrustZone)", + "type": "bool" + }, + { + "name": "iommu", + "description": "Set the IOMMU type. Valid values are none and smmuv3", + "type": "string" + } + ], "id": "libvirt-33" } +{ + "execute": "query-cpu-definitions", + "id": "libvirt-34" +} + { "return": [ { @@ -6403,34 +6546,34 @@ "static": false } ], - "id": "libvirt-33" + "id": "libvirt-34" } { "execute": "query-tpm-models", - "id": "libvirt-34" + "id": "libvirt-35" } { "return": [ ], - "id": "libvirt-34" + "id": "libvirt-35" } { "execute": "query-tpm-types", - "id": "libvirt-35" + "id": "libvirt-36" } { "return": [ ], - "id": "libvirt-35" + "id": "libvirt-36" } { "execute": "query-command-line-options", - "id": "libvirt-36" + "id": "libvirt-37" } { @@ -7578,12 +7721,12 @@ "option": "drive" } ], - "id": "libvirt-36" + "id": "libvirt-37" } { "execute": "query-migrate-capabilities", - "id": "libvirt-37" + "id": "libvirt-38" } { @@ -7657,12 +7800,12 @@ "capability": "x-ignore-shared" } ], - "id": "libvirt-37" + "id": "libvirt-38" } { "execute": "query-qmp-schema", - "id": "libvirt-38" + "id": "libvirt-39" } { @@ -19749,12 +19892,12 @@ ] } ], - "id": "libvirt-38" + "id": "libvirt-39" } { "execute": "query-gic-capabilities", - "id": "libvirt-39" + "id": "libvirt-40" } { @@ -19770,7 +19913,7 @@ "kernel": false } ], - "id": "libvirt-39" + "id": "libvirt-40" } { diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml index 7bcda0b402..e071bc0c8d 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml @@ -160,6 +160,7 @@ <flag name='virtio-pci-non-transitional'/> <flag name='overcommit'/> <flag name='query-current-machine'/> + <flag name='machine.virt.iommu'/> <version>4000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>61700758</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.replies b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.replies index 053b714825..c2ca623a0b 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.replies +++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv32.replies @@ -4080,18 +4080,120 @@ } { - "execute": "query-tpm-models", + "execute": "qom-list-properties", + "arguments": { + "typename": "virt-machine" + }, "id": "libvirt-34" } { "return": [ + { + "name": "type", + "type": "string" + }, + { + "name": "enforce-config-section", + "description": "Set on to enforce configuration section migration", + "type": "bool" + }, + { + "name": "kernel", + "description": "Linux kernel image file", + "type": "string" + }, + { + "name": "dt-compatible", + "description": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "initrd", + "description": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "graphics", + "description": "Set on/off to enable/disable graphics emulation", + "type": "bool" + }, + { + "name": "kernel-irqchip", + "description": "Configure KVM in-kernel irqchip", + "type": "on|off|split" + }, + { + "name": "usb", + "description": "Set on/off to enable/disable usb", + "type": "bool" + }, + { + "name": "firmware", + "description": "Firmware image", + "type": "string" + }, + { + "name": "memory-encryption", + "description": "Set memory encryption object to use", + "type": "string" + }, + { + "name": "dump-guest-core", + "description": "Include guest memory in a core dump", + "type": "bool" + }, + { + "name": "kvm-shadow-mem", + "description": "KVM shadow MMU size", + "type": "int" + }, + { + "name": "igd-passthru", + "description": "Set on/off to enable/disable igd passthrou", + "type": "bool" + }, + { + "name": "phandle-start", + "description": "The first phandle ID we may generate dynamically", + "type": "int" + }, + { + "name": "dumpdtb", + "description": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "mem-merge", + "description": "Enable/disable memory merge support", + "type": "bool" + }, + { + "name": "dtb", + "description": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "accel", + "description": "Accelerator list", + "type": "string" + }, + { + "name": "append", + "description": "Linux kernel command line", + "type": "string" + }, + { + "name": "suppress-vmdesc", + "description": "Set on to disable self-describing migration", + "type": "bool" + } ], "id": "libvirt-34" } { - "execute": "query-tpm-types", + "execute": "query-tpm-models", "id": "libvirt-35" } @@ -4102,10 +4204,21 @@ } { - "execute": "query-command-line-options", + "execute": "query-tpm-types", "id": "libvirt-36" } +{ + "return": [ + ], + "id": "libvirt-36" +} + +{ + "execute": "query-command-line-options", + "id": "libvirt-37" +} + { "return": [ { @@ -5375,12 +5488,12 @@ "option": "drive" } ], - "id": "libvirt-36" + "id": "libvirt-37" } { "execute": "query-migrate-capabilities", - "id": "libvirt-37" + "id": "libvirt-38" } { @@ -5454,12 +5567,12 @@ "capability": "x-ignore-shared" } ], - "id": "libvirt-37" + "id": "libvirt-38" } { "execute": "query-qmp-schema", - "id": "libvirt-38" + "id": "libvirt-39" } { @@ -17738,5 +17851,5 @@ ] } ], - "id": "libvirt-38" + "id": "libvirt-39" } diff --git a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.replies b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.replies index 2db59687aa..0cccbdb4e0 100644 --- a/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.replies +++ b/tests/qemucapabilitiesdata/caps_4.0.0.riscv64.replies @@ -4080,18 +4080,120 @@ } { - "execute": "query-tpm-models", + "execute": "qom-list-properties", + "arguments": { + "typename": "virt-machine" + }, "id": "libvirt-34" } { "return": [ + { + "name": "type", + "type": "string" + }, + { + "name": "enforce-config-section", + "description": "Set on to enforce configuration section migration", + "type": "bool" + }, + { + "name": "kernel", + "description": "Linux kernel image file", + "type": "string" + }, + { + "name": "dt-compatible", + "description": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "initrd", + "description": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "graphics", + "description": "Set on/off to enable/disable graphics emulation", + "type": "bool" + }, + { + "name": "kernel-irqchip", + "description": "Configure KVM in-kernel irqchip", + "type": "on|off|split" + }, + { + "name": "usb", + "description": "Set on/off to enable/disable usb", + "type": "bool" + }, + { + "name": "firmware", + "description": "Firmware image", + "type": "string" + }, + { + "name": "memory-encryption", + "description": "Set memory encryption object to use", + "type": "string" + }, + { + "name": "dump-guest-core", + "description": "Include guest memory in a core dump", + "type": "bool" + }, + { + "name": "kvm-shadow-mem", + "description": "KVM shadow MMU size", + "type": "int" + }, + { + "name": "igd-passthru", + "description": "Set on/off to enable/disable igd passthrou", + "type": "bool" + }, + { + "name": "phandle-start", + "description": "The first phandle ID we may generate dynamically", + "type": "int" + }, + { + "name": "dumpdtb", + "description": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "mem-merge", + "description": "Enable/disable memory merge support", + "type": "bool" + }, + { + "name": "dtb", + "description": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "accel", + "description": "Accelerator list", + "type": "string" + }, + { + "name": "append", + "description": "Linux kernel command line", + "type": "string" + }, + { + "name": "suppress-vmdesc", + "description": "Set on to disable self-describing migration", + "type": "bool" + } ], "id": "libvirt-34" } { - "execute": "query-tpm-types", + "execute": "query-tpm-models", "id": "libvirt-35" } @@ -4102,10 +4204,21 @@ } { - "execute": "query-command-line-options", + "execute": "query-tpm-types", "id": "libvirt-36" } +{ + "return": [ + ], + "id": "libvirt-36" +} + +{ + "execute": "query-command-line-options", + "id": "libvirt-37" +} + { "return": [ { @@ -5375,12 +5488,12 @@ "option": "drive" } ], - "id": "libvirt-36" + "id": "libvirt-37" } { "execute": "query-migrate-capabilities", - "id": "libvirt-37" + "id": "libvirt-38" } { @@ -5454,12 +5567,12 @@ "capability": "x-ignore-shared" } ], - "id": "libvirt-37" + "id": "libvirt-38" } { "execute": "query-qmp-schema", - "id": "libvirt-38" + "id": "libvirt-39" } { @@ -17738,5 +17851,5 @@ ] } ], - "id": "libvirt-38" + "id": "libvirt-39" } -- 2.21.0

On Tue, May 28, 2019 at 05:28:59PM +0200, Andrea Bolognani wrote:
This capability can be used to figure out whether the QEMU binary at hand supports the machine type property we need in order to enable SMMUv3 IOMMU support.
Unfortunately we can't avoid probing the RISC-V binaries along with the ARM ones, since both architectures have their own 'virt' machine type.
We can, but I don't think we want to.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_capabilities.c | 8 + src/qemu/qemu_capabilities.h | 1 + .../caps_2.12.0.aarch64.replies | 166 +++++++++++++++-- .../caps_3.0.0.riscv32.replies | 131 +++++++++++++- .../caps_3.0.0.riscv64.replies | 131 +++++++++++++- .../caps_4.0.0.aarch64.replies | 171 ++++++++++++++++-- .../caps_4.0.0.aarch64.xml | 1 + .../caps_4.0.0.riscv32.replies | 129 ++++++++++++- .../caps_4.0.0.riscv64.replies | 129 ++++++++++++- 9 files changed, 805 insertions(+), 62 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/formatdomain.html.in | 7 +++-- docs/schemas/domaincommon.rng | 5 ++- src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 7 +++++ src/qemu/qemu_domain.c | 3 ++ .../iommu-smmuv3.aarch64-latest.args | 31 +++++++++++++++++++ tests/qemuxml2argvdata/iommu-smmuv3.xml | 15 +++++++++ tests/qemuxml2argvtest.c | 1 + .../iommu-smmuv3.aarch64-latest.xml | 25 +++++++++++++++ tests/qemuxml2xmltest.c | 1 + 11 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/iommu-smmuv3.xml create mode 100644 tests/qemuxml2xmloutdata/iommu-smmuv3.aarch64-latest.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c843b1d667..22ddcb71d3 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -8675,14 +8675,17 @@ qemu-kvm -net nic,model=? /dev/null <dt><code>model</code></dt> <dd> <p> - Currently only the <code>intel</code> model is supported. + Supported values are <code>intel</code> (for Q35 guests) and, + <span class="since">since 5.5.0</span>, <code>smmuv3</code> (for + ARM virt guests). </p> </dd> <dt><code>driver</code></dt> <dd> <p> The <code>driver</code> subelement can be used to configure - additional options: + additional options, some of which might only be available for + certain IOMMU models: </p> <dl> <dt><code>intremap</code></dt> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 111b85c36f..4bd75e3055 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4375,7 +4375,10 @@ <define name="iommu"> <element name="iommu"> <attribute name="model"> - <value>intel</value> + <choice> + <value>intel</value> + <value>smmuv3</value> + </choice> </attribute> <optional> <element name="driver"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 006920e954..97ba8bd53a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1122,6 +1122,7 @@ VIR_ENUM_IMPL(virDomainTPMVersion, VIR_ENUM_IMPL(virDomainIOMMUModel, VIR_DOMAIN_IOMMU_MODEL_LAST, "intel", + "smmuv3", ); VIR_ENUM_IMPL(virDomainVsockModel, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index fa0756b634..4c3ab07062 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2296,6 +2296,7 @@ struct _virDomainSEVDef { typedef enum { VIR_DOMAIN_IOMMU_MODEL_INTEL, + VIR_DOMAIN_IOMMU_MODEL_SMMUV3, VIR_DOMAIN_IOMMU_MODEL_LAST } virDomainIOMMUModel; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b2b9bef772..a11b6d40da 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6967,6 +6967,9 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, break; } + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + break; + case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, iommu->model); @@ -7612,6 +7615,10 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_IOMMU)) virBufferAddLit(&buf, ",iommu=on"); break; + + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + break; + case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, def->iommu->model); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 366ebe1604..9802952046 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6135,6 +6135,9 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, } break; + case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + break; + case VIR_DOMAIN_IOMMU_MODEL_LAST: default: virReportEnumRangeError(virDomainIOMMUModel, iommu->model); diff --git a/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args b/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args new file mode 100644 index 0000000000..a96669078b --- /dev/null +++ b/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args @@ -0,0 +1,31 @@ +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=tcg,usb=off,dump-guest-core=off,gic-version=2 \ +-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/iommu-smmuv3.xml b/tests/qemuxml2argvdata/iommu-smmuv3.xml new file mode 100644 index 0000000000..2683ce6459 --- /dev/null +++ b/tests/qemuxml2argvdata/iommu-smmuv3.xml @@ -0,0 +1,15 @@ +<domain type='qemu'> + <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> + <devices> + <emulator>/usr/bin/qemu-system-aarch64</emulator> + <controller type='usb' model='none'/> + <memballoon model='none'/> + <iommu model='smmuv3'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index ec58074798..49220733ae 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -2813,6 +2813,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-eim"); DO_TEST_CAPS_LATEST("intel-iommu-device-iotlb"); DO_TEST_PARSE_ERROR("intel-iommu-wrong-machine", NONE); + DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); DO_TEST("cpu-hotplug-startup", QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS); DO_TEST_PARSE_ERROR("cpu-hotplug-granularity", diff --git a/tests/qemuxml2xmloutdata/iommu-smmuv3.aarch64-latest.xml b/tests/qemuxml2xmloutdata/iommu-smmuv3.aarch64-latest.xml new file mode 100644 index 0000000000..93e8566dea --- /dev/null +++ b/tests/qemuxml2xmloutdata/iommu-smmuv3.aarch64-latest.xml @@ -0,0 +1,25 @@ +<domain type='qemu'> + <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='2'/> + </features> + <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'/> + <iommu model='smmuv3'/> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index d1e7fe1015..06d1ad5ec0 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1207,6 +1207,7 @@ mymain(void) DO_TEST_CAPS_LATEST("intel-iommu-caching-mode"); DO_TEST_CAPS_LATEST("intel-iommu-eim"); DO_TEST_CAPS_LATEST("intel-iommu-device-iotlb"); + DO_TEST_CAPS_ARCH_LATEST("iommu-smmuv3", "aarch64"); DO_TEST("cpu-check-none", NONE); DO_TEST("cpu-check-partial", NONE); -- 2.21.0

On Tue, May 28, 2019 at 05:29:00PM +0200, Andrea Bolognani wrote:
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Given the diffstat, it would be nice to have something in the commit message, e.g. a copy of the text from the news or an XML snippet.
--- docs/formatdomain.html.in | 7 +++-- docs/schemas/domaincommon.rng | 5 ++- src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 7 +++++ src/qemu/qemu_domain.c | 3 ++ .../iommu-smmuv3.aarch64-latest.args | 31 +++++++++++++++++++ tests/qemuxml2argvdata/iommu-smmuv3.xml | 15 +++++++++ tests/qemuxml2argvtest.c | 1 + .../iommu-smmuv3.aarch64-latest.xml | 25 +++++++++++++++ tests/qemuxml2xmltest.c | 1 + 11 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args create mode 100644 tests/qemuxml2argvdata/iommu-smmuv3.xml create mode 100644 tests/qemuxml2xmloutdata/iommu-smmuv3.aarch64-latest.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9802952046..3290cdae5f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6136,6 +6136,20 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, break; case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + if (!qemuDomainIsARMVirt(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is only supported with " + "ARM Virt machines"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_VIRT_IOMMU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOMMU device: '%s' is not supported with " + "this QEMU binary"), + virDomainIOMMUModelTypeToString(iommu->model)); + return -1; + } break; case VIR_DOMAIN_IOMMU_MODEL_LAST: -- 2.21.0

On Tue, May 28, 2019 at 05:29:01PM +0200, Andrea Bolognani wrote:
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

All current IOMMU features are specific to Intel IOMMU, so understandably we check for the corresponding capabilities inside the Intel-specific switch() branch; however, we want to make sure SMMUv3 IOMMU users get an error if they try to enable any of those features in their guest, and performing the capability checks unconditionally is both the easiest way to achieve that, as well as the one least likely to result in us inadvertently letting users enable some new Intel-specific IOMMU feature for ARM guests later on. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 63 +++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 3290cdae5f..195124daa3 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6105,34 +6105,6 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, virDomainIOMMUModelTypeToString(iommu->model)); return -1; } - if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: interrupt remapping is not supported " - "with this QEMU binary")); - return -1; - } - if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_CACHING_MODE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: caching mode is not supported " - "with this QEMU binary")); - return -1; - } - if (iommu->eim != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: eim is not supported " - "with this QEMU binary")); - return -1; - } - if (iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("iommu: device IOTLB is not supported " - "with this QEMU binary")); - return -1; - } break; case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: @@ -6158,6 +6130,41 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, return -1; } + /* These capability checks ensure we're not trying to use features + * of Intel IOMMU that the QEMU binary does not support, but they + * also make sure we report an error when trying to use features + * that are not implemented by SMMUv3, so they must be here instead + * of inside the switch() statement above */ + + if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: interrupt remapping is not supported " + "with this QEMU binary")); + return -1; + } + if (iommu->caching_mode != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_CACHING_MODE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: caching mode is not supported " + "with this QEMU binary")); + return -1; + } + if (iommu->eim != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_EIM)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: eim is not supported " + "with this QEMU binary")); + return -1; + } + if (iommu->iotlb != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: device IOTLB is not supported " + "with this QEMU binary")); + return -1; + } + return 0; } -- 2.21.0

On Tue, May 28, 2019 at 05:29:02PM +0200, Andrea Bolognani wrote:
All current IOMMU features are specific to Intel IOMMU, so understandably we check for the corresponding capabilities inside the Intel-specific switch() branch; however, we want to make sure SMMUv3 IOMMU users get an error if they try to enable any of those features in their guest, and performing the capability checks unconditionally is both the easiest way to achieve that, as well as the one least likely to result in us inadvertently letting users enable some new Intel-specific IOMMU feature for ARM guests later on.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_domain.c | 63 +++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 28 deletions(-)
@@ -6158,6 +6130,41 @@ qemuDomainDeviceDefValidateIOMMU(const virDomainIOMMUDef *iommu, return -1; }
+ /* These capability checks ensure we're not trying to use features + * of Intel IOMMU that the QEMU binary does not support, but they + * also make sure we report an error when trying to use features + * that are not implemented by SMMUv3,
so they must be here instead + * of inside the switch() statement above */
This part of the sentence is not really necessary.
+ + if (iommu->intremap != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_INTEL_IOMMU_INTREMAP)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("iommu: interrupt remapping is not supported " + "with this QEMU binary")); + return -1; + }
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

https://bugzilla.redhat.com/show_bug.cgi?id=1575526 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 4 +++- tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a11b6d40da..59dc134785 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6968,7 +6968,8 @@ qemuBuildIOMMUCommandLine(virCommandPtr cmd, } case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: - break; + /* There is no -device for SMMUv3, so nothing to be done here */ + return 0; case VIR_DOMAIN_IOMMU_MODEL_LAST: default: @@ -7617,6 +7618,7 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, break; case VIR_DOMAIN_IOMMU_MODEL_SMMUV3: + virBufferAddLit(&buf, ",iommu=smmuv3"); break; case VIR_DOMAIN_IOMMU_MODEL_LAST: diff --git a/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args b/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args index a96669078b..3d4bf3f0d6 100644 --- a/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args +++ b/tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args @@ -12,7 +12,7 @@ QEMU_AUDIO_DRV=none \ -S \ -object secret,id=masterKey0,format=raw,\ file=/tmp/lib/domain--1-guest/master-key.aes \ --machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \ +-machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2,iommu=smmuv3 \ -m 1024 \ -overcommit mem-lock=off \ -smp 1,sockets=1,cores=1,threads=1 \ -- 2.21.0

On Tue, May 28, 2019 at 05:29:03PM +0200, Andrea Bolognani wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1575526
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/qemu/qemu_command.c | 4 +++- tests/qemuxml2argvdata/iommu-smmuv3.aarch64-latest.args | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/news.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 9922cd4de0..792293686f 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -41,6 +41,14 @@ <libvirt> <release version="v5.4.0" date="unreleased"> <section title="New features"> + <change> + <summary> + qemu: Support SMMUv3 IOMMU + </summary> + <description> + SMMUv3 is an IOMMU implementation for ARM virt guests. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.21.0

On Tue, May 28, 2019 at 05:29:04PM +0200, Andrea Bolognani wrote:
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- docs/news.xml | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml index 9922cd4de0..792293686f 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -41,6 +41,14 @@ <libvirt> <release version="v5.4.0" date="unreleased">
This version obviously does not match the one mentioned in the docs patch. I trust that when rebasing this commit, you will remember that nobody reads the news(TM).
<section title="New features"> + <change> + <summary> + qemu: Support SMMUv3 IOMMU + </summary> + <description> + SMMUv3 is an IOMMU implementation for ARM virt guests. + </description> + </change> </section> <section title="Improvements"> </section>
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Andrea Bolognani
-
Ján Tomko